Introduction
This article introducing a portmapping method and some IGD's UPnP SOAP actions using C++ without the Microsoft's COM library for the UPnP. So sorry, you have to setup libraries and VC paths like an image[red square] below. This project using boost-cpplib and xerces (DOM parsing). But I couldn't upload libraries with my source code because of an upload timeout with large file size.
I had just tested soap responses from UPnP-enabled routers. I had not tested the connections and data streams as points of this article.
Sorry for potential bugs and my poor English.
- Multiple NICs and multiple routers are supported. But CASCADED NATs are not supported.
Background
I want to implement the portmapping without third party (UPnP
) libraries and attempt to write platform independent code AS POSSIBLE.
Using the Code
#include "stdafx.h"
#include "Manager/ApplicationManager.h"
#include "Manager/COMManager.h"
#include "Network/NetworkManager.h"
#include "Network/NetworkHelper.h"
#include "NATBreak/UPNPNATServiceTypes.h"
#include "NATBreak/IGDDiscoverProcess.h"
#include "NATBreak/UPNPNATHTTPClient.h"
using namespace std;
using namespace boost;
thread_group tg;
int _tmain(int argc, _TCHAR* argv[])
{
ApplicationManager am;
NetworkManager nm;
try
{
IGDDiscoverProcess discoverer( 500000 );
tg.create_thread( ref( discoverer ) );
tg.join_all();
IGDDiscoverProcess::IGDControlInformations cinfos =
discoverer.GetAllIGDControlInformations();
boost_foreach( IGDDiscoverProcess::ControlInfo info, cinfos )
{
if( info.has_problem )
{
cout << "has problem" << endl;
continue;
}
if( info.service_type == UPNPSERVICE_LAYER3FORWARDING1 )
{
UPNPNATHTTPClient soap( info.ip, info.port );
soap.GetDefaultConnectionService
( info.control_url, info.service_type );
}
else if( info.service_type == UPNPSERVICE_WANIPCONNECTION1 )
{
UPNPNATHTTPClient soap( info.ip, info.port );
string ip;
UPNPNATHTTPClient::SoapResult res =
soap.GetWANIPAddress(
ip, info.control_url, info.service_type
);
cout << "WAN IP : " << ip << endl;
UPNPNATHTTPClient::SoapResult soap_res;
soap_res = soap.AddPortMapping(
string("test"), 12345, 12345, string("UDP"),
string("192.168.0.2"),
info.control_url, info.service_type
);
if( UPNPNATHTTPClient::SoapSucceeded == soap_res )
{
cout << "portmapping succeeded." << endl;
}
soap_res = soap.DeletePortMapping(
12345, string("UDP"), info.control_url,
info.service_type
);
if( UPNPNATHTTPClient::SoapSucceeded == soap_res )
{
cout << "delete portmapping succeeded."
<< endl;
}
}
else if( info.service_type ==
UPNPSERVICE_WANCOMMONINTERFACECONFIG1 )
{
UPNPNATHTTPClient soap( info.ip, info.port );
string ip;
soap.GetActiveConnection( 0,
info.service_type, info.control_url );
}
}
}
catch( IGDDiscoverProcess::exception &e )
{
cout << e.what() << endl;
}
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
return 0;
}
Points of Interest
- In case when multiple UPnP-enabled NATs are cascaded
- IPv6 support
History
This is the first version.
The sample code has been fixed. The fixed part seems "string("192.168.0.2"),
". This address means an own nic's address to send a m-search message.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.