void UPnP::ClosePort() { if(remote_port_ == 0) return; #ifdef _MSC_VER HRESULT hr; IUPnPNAT* upnpnat; hr = CoCreateInstance (CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void**)&upnpnat); if(FAILED(hr) || !upnpnat) return; IStaticPortMappingCollection* upnpspmc = NULL; hr = upnpnat->get_StaticPortMappingCollection(&upnpspmc); if(FAILED(hr) || !upnpspmc) return; BSTR bstrProtocol = A2BSTR("TCP"); hr = upnpspmc->Remove(remote_port_, bstrProtocol); if(FAILED(hr)) LOG.getlasterror("Automatisches Entfernen des Portforwardings mit UPnP fehlgeschlagen\nFehler"); SysFreeString(bstrProtocol); if(FAILED(hr)) return; #else int hr; UPNPDev* devicelist = NULL; #ifdef UPNPDISCOVER_SUCCESS int upnperror = 0; devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror); #else devicelist = upnpDiscover(2000, NULL, NULL, 0); #endif if(!devicelist) return; UPNPUrls urls; IGDdatas data; hr = UPNP_GetValidIGD(devicelist, &urls, &data, NULL, 0); if(hr == 1 || hr == 2) { std::stringstream p; p << remote_port_; hr = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), "TCP", NULL); } freeUPNPDevlist(devicelist); if(hr != 0) return; #endif remote_port_ = 0; }
void UPnP::Destroy() { IUPnPNAT * Nat = NULL; IStaticPortMappingCollection * PortMappingCollection = NULL; HRESULT Result; wchar_t Protocol[256]; WORD Port; if(m_Port == 0) return; Port = m_Port; m_Port = 0; #ifdef MFC TRACE("UPnP: Removing Port\n"); #endif wcscpy_s(Protocol, L"TCP"); // Create IUPnPNat Result = CoCreateInstance(CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void **)&Nat); if(FAILED(Result)) { #ifdef MFC TRACE("UPnP: Unable to create UPnPNAT interface\n"); #endif return; } Result = Nat->get_StaticPortMappingCollection(&PortMappingCollection); if(!PortMappingCollection || FAILED(Result)) { if(PortMappingCollection) PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable to acquire a static portmapping collection\n"); #endif return; } Result = PortMappingCollection->Remove(Port, Protocol); if(FAILED(Result)) { PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable to remove port\n"); #endif return; } }
/** * Erstellt per UPnP ein Portforwarding. * * @author FloSoft */ bool UPnP::OpenPort(const unsigned short& port) { if(remote_port_ != 0) ClosePort(); remote_port_ = port; #ifdef _MSC_VER HRESULT hr; CoInitialize(NULL); IUPnPNAT* upnpnat; hr = CoCreateInstance (CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void**)&upnpnat); if(FAILED(hr) || !upnpnat) { if(!upnpnat) hr = E_NOINTERFACE; SetLastError(hr); return false; } IStaticPortMappingCollection* upnpspmc = NULL; hr = upnpnat->get_StaticPortMappingCollection(&upnpspmc); if(FAILED(hr) || !upnpspmc) { if(!upnpspmc) hr = E_NOINTERFACE; SetLastError(hr); return false; } std::string local_address; std::vector<std::string> addresses = GetAllv4Addresses(); // if we have multiple addresses, search the private one if(addresses.size() > 1) { for(std::vector<std::string>::iterator addr = addresses.begin(); addr != addresses.end(); ++addr) { std::string ss = *addr; std::stringstream s, sc; s << ss; std::getline(s, ss, '.'); sc << ss << " "; std::getline(s, ss, '.'); sc << ss << " "; int a, b; sc >> a; sc >> b; int ab = (a << 24) | (b << 16); if( (ab & 0xff000000) == 0x0a000000 || // 10.0.0.0/8 (ab & 0xff000000) == 0x7f000000 || // 127.0.0.0/8 (ab & 0xfff00000) == 0xac100000 || // 172.16.0.0/12 (ab & 0xffff0000) == 0xc0a80000 ) // 192.168.0.0/16 local_address = *addr; } } // otherwise use the first one if(local_address == "" && !addresses.empty()) local_address = addresses.front(); // I hope we found one ... if(local_address == "") { SetLastError(E_FAIL); return false; } BSTR bstrProtocol = A2BSTR("TCP"); BSTR bstrLocalAddress = A2BSTR(local_address.c_str()); BSTR bstrDescription = A2BSTR("Return To The Roots"); IStaticPortMapping* upnpspm = NULL; hr = upnpspmc->Add(port, bstrProtocol, port, bstrLocalAddress, VARIANT_TRUE, bstrDescription, &upnpspm); SysFreeString(bstrProtocol); SysFreeString(bstrLocalAddress); SysFreeString(bstrDescription); if(SUCCEEDED(hr) && !upnpspm) hr = E_NOINTERFACE; SetLastError(hr); if(SUCCEEDED(hr) && upnpspm) return true; #else int hr; UPNPDev* devicelist = NULL; #ifdef UPNPDISCOVER_SUCCESS int upnperror = 0; devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror); #else devicelist = upnpDiscover(2000, NULL, NULL, 0); #endif if(!devicelist) return false; UPNPUrls urls; IGDdatas data; char lanAddr[64]; hr = UPNP_GetValidIGD(devicelist, &urls, &data, lanAddr, sizeof(lanAddr)); if(hr == 1 || hr == 2) { std::stringstream p; p << port; #ifdef UPNPDISCOVER_SUCCESS hr = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), p.str().c_str(), lanAddr, "Return To The Roots", "TCP", NULL, NULL); #else hr = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), p.str().c_str(), lanAddr, "Return To The Roots", "TCP", NULL); #endif } freeUPNPDevlist(devicelist); if(hr == 0) return true; #endif return false; }
bool UPnP::Create(u16 Port) { IUPnPNAT * Nat = NULL; IStaticPortMappingCollection * PortMappingCollection = NULL; IStaticPortMapping * PortMap = NULL; HRESULT Result; wchar_t Protocol[256]; wchar_t InternalClient[256]; wchar_t Description[256]; Destroy(); #ifdef MFC TRACE("UPnP: Adding port\n"); #endif if(!GetIp()) { return false; } size_t num_chars_converted{}; mbstowcs_s(&num_chars_converted, InternalClient, m_Address, 256); wcscpy_s(Protocol, L"UDP"); wcscpy_s(Description, L"Gunz"); // Create IUPnPNat Result = CoCreateInstance(CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void **)&Nat); if(FAILED(Result)) { #ifdef MFC TRACE("UPnP: Unable to create UPnPNAT interface\n"); #endif return false; } Result = Nat->get_StaticPortMappingCollection(&PortMappingCollection); if(!PortMappingCollection || FAILED(Result)) { if(PortMappingCollection) PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable to acquire a static portmapping collection\n"); #endif return false; } Result = PortMappingCollection->Add(Port, Protocol, Port, InternalClient, VARIANT_TRUE, Description, &PortMap); if(!PortMap || FAILED(Result)) { if(PortMap) PortMap->Release(); PortMappingCollection->Release(); Nat->Release(); #ifdef MFC TRACE("UPnP: Unable add port\n"); #endif return false; } #ifdef MFC TRACE("UPnP: Port %d forwarded to %s\n", Port, m_Address); #endif PortMap->Release(); PortMappingCollection->Release(); Nat->Release(); m_Port = Port; return true; }
// Add a UPnP port bool Win32UPnPAddPort(UINT outside_port, UINT inside_port, bool udp, char *local_ip, wchar_t *description, bool remove_before_add) { bool ret = false; HRESULT hr; IUPnPNAT *nat = NULL; wchar_t ip_str[MAX_SIZE]; BSTR bstr_ip, bstr_description, bstr_protocol; wchar_t *protocol_str = (udp ? L"UDP" : L"TCP"); // Validate arguments if (outside_port == 0 || outside_port >= 65536 || inside_port == 0 || inside_port >= 65536 || IsEmptyStr(local_ip) || UniIsEmptyStr(description)) { return false; } StrToUni(ip_str, sizeof(ip_str), local_ip); bstr_ip = SysAllocString(ip_str); bstr_description = SysAllocString(description); bstr_protocol = SysAllocString(protocol_str); hr = CoCreateInstance(CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void **)&nat); if (SUCCEEDED(hr)) { if (nat != NULL) { IStaticPortMappingCollection *collection = NULL; hr = nat->get_StaticPortMappingCollection(&collection); if (SUCCEEDED(hr)) { if (collection != NULL) { IStaticPortMapping *mapping = NULL; if (remove_before_add) { hr = collection->Remove((long)outside_port, bstr_protocol); } hr = collection->Add((long)outside_port, bstr_protocol, (long)inside_port, bstr_ip, VARIANT_TRUE, bstr_description, &mapping); if (SUCCEEDED(hr)) { ret = true; if (mapping != NULL) { mapping->Release(); } } collection->Release(); } else { WHERE; } } else { WHERE; } nat->Release(); } else { WHERE; } } else { WHERE; } SysFreeString(bstr_ip); SysFreeString(bstr_description); SysFreeString(bstr_protocol); return ret; }
int SetPortForwarding(char *localIP, char *description, int internalPort, int *externalPort) { CoInitialize(NULL); int errorCode = 0; IUPnPNAT *nat = NULL; IStaticPortMappingCollection *mappingCollection = NULL; IStaticPortMapping *mapping = NULL; if( !SUCCEEDED( CoCreateInstance(__uuidof(UPnPNAT), NULL, CLSCTX_ALL, __uuidof(IUPnPNAT), (void **)&nat) ) || ( nat==NULL ) ) { errorCode = ERROR_COCREATEINSTANCE; goto ERROR_EXIT; } if ( !SUCCEEDED( nat->get_StaticPortMappingCollection(&mappingCollection) ) || (mappingCollection==NULL ) ) { errorCode = ERROR_UPNP_NOT_FOUNDED; goto ERROR_EXIT; } while( TRUE ) { IStaticPortMapping *existMapping = NULL; BOOL hasMappingInformation = SUCCEEDED( mappingCollection->get_Item(*externalPort, L"TCP", &existMapping) ); if ( hasMappingInformation ) { //printf( "hasMappingInformation \n" ); BSTR bStrIP = NULL; existMapping->get_InternalClient(&bStrIP); BSTR bstrDescryption = NULL; existMapping->get_Description(&bstrDescryption); long iExistInternalPort = 0; existMapping->get_InternalPort(&iExistInternalPort); if( bStrIP != NULL && bstrDescryption != NULL ) { //printf( "bStrIP != NULL && bstrDescryption != NULL \n" ); USES_CONVERSION; char *sClientIP = OLE2A(bStrIP); char *sDescryption = OLE2A(bstrDescryption); BOOL hasMapping = ( strcmp(sClientIP, localIP) == 0 ) && ( strcmp(sDescryption, description) == 0) && ( iExistInternalPort == internalPort ); if ( hasMapping ) { //printf( "hasMapping \n" ); SysFreeString(bStrIP); SysFreeString(bstrDescryption); break; } SysFreeString(bStrIP); SysFreeString(bstrDescryption); } existMapping->Release(); (*externalPort)++; //printf( "(*externalPort)++: %d \n", *externalPort ); } else { //printf( "not hasMappingInformation \n" ); VARIANT_BOOL vb = VARIANT_TRUE; USES_CONVERSION; BOOL isNewMappingRegistered = SUCCEEDED( mappingCollection->Add(*externalPort, L"TCP", internalPort, A2W(localIP), vb, A2W(description), &mapping) ); if( ! isNewMappingRegistered ) { //printf( "not isNewMappingRegistered \n" ); errorCode = ERROR_PORTMAPPING_FAILED; goto ERROR_EXIT; } break; } } ERROR_EXIT: if ( NULL != mapping ) { mapping->Release(); mapping = NULL; } if ( NULL != mappingCollection ) { mappingCollection->Release(); mappingCollection = NULL; } if ( NULL != nat ) { nat->Release(); nat = NULL; } CoUninitialize(); return errorCode; }