// called from ---UPnP--- thread // Attempt to stop portforwarding. // -- // NOTE: It is important that this happens! A few very crappy routers // apparently do not delete UPnP mappings on their own, so if you leave them // hanging, the NVRAM will fill with portmappings, and eventually all UPnP // requests will fail silently, with the only recourse being a factory reset. // -- static bool UnmapPort(const u16 port) { std::string port_str = std::to_string(port); UPNP_DeletePortMapping(s_urls.controlURL, s_data.first.servicetype, port_str.c_str(), "UDP", nullptr); return true; }
void CUPnPImplMiniLib::DeletePorts(bool bSkipLock){ // this function itself blocking, because its called at the end of eMule and we need to wait for it to finish // before going on anyway. It might be caled from the non-blocking StartDiscovery() function too however CSingleLock lockTest(&m_mutBusy); if (bSkipLock || lockTest.Lock(0)){ if (m_nOldTCPPort != 0){ if (m_pURLs == NULL || m_pIGDData == NULL){ ASSERT( false ); return; } const char achTCP[] = "TCP"; char achPort[10]; sprintf(achPort, "%u", m_nOldTCPPort); int nResult = UPNP_DeletePortMapping(m_pURLs->controlURL, m_pIGDData->servicetype, achPort, achTCP); if (nResult == UPNPCOMMAND_SUCCESS){ DebugLog(_T("Sucessfully removed mapping for port %u (%s)"), m_nOldTCPPort, _T("TCP")); m_nOldTCPPort = 0; } else DebugLogWarning(_T("Failed to remove mapping for port %u (%s)"), m_nOldTCPPort, _T("TCP")); } else{ DebugLog(_T("No UPnP Mappings to remove, aborting")); return; // UDP port cannot be set if TCP port was empty } if (m_nOldUDPPort != 0){ const char achTCP[] = "UDP"; char achPort[10]; sprintf(achPort, "%u", m_nOldUDPPort); int nResult = UPNP_DeletePortMapping(m_pURLs->controlURL, m_pIGDData->servicetype, achPort, achTCP); if (nResult == UPNPCOMMAND_SUCCESS){ DebugLog(_T("Sucessfully removed mapping for port %u (%s)"), m_nOldUDPPort, _T("UDP")); m_nOldTCPPort = 0; } else DebugLogWarning(_T("Failed to remove mapping for port %u (%s)"), m_nOldUDPPort, _T("UDP")); } } else DebugLogError(_T("Unable to remove port mappings - implementation still busy")); }
// called from ---UPnP--- thread // Attempt to stop portforwarding. // -- // NOTE: It is important that this happens! A few very crappy routers // apparently do not delete UPnP mappings on their own, so if you leave them // hanging, the NVRAM will fill with portmappings, and eventually all UPnP // requests will fail silently, with the only recourse being a factory reset. // -- bool NetPlayServer::UPnPUnmapPort(const u16 port) { char port_str[6] = { 0 }; sprintf(port_str, "%d", port); UPNP_DeletePortMapping(m_upnp_urls.controlURL, m_upnp_data.first.servicetype, port_str, "TCP", nullptr); return true; }
static void tr_upnpDeletePortMapping (const tr_upnp * handle, const char * proto, tr_port port) { char portStr[16]; tr_snprintf (portStr, sizeof (portStr), "%d", (int)port); UPNP_DeletePortMapping (handle->urls.controlURL, handle->data.first.servicetype, portStr, proto, NULL); }
bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) { if (!p->isValid) { return false; } std::string publicPort = boost::lexical_cast<std::string>(mapping.getPublicPort()); std::string localPort = boost::lexical_cast<std::string>(mapping.getLocalPort()); std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds()); int ret = UPNP_DeletePortMapping(p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", 0); return ret == UPNPCOMMAND_SUCCESS; }
static switch_status_t switch_nat_del_mapping_upnp(switch_port_t port, switch_nat_ip_proto_t proto) { switch_status_t status = SWITCH_STATUS_FALSE; char port_str[IP_LEN]; int r = UPNPCOMMAND_UNKNOWN_ERROR; sprintf(port_str, "%d", port); if (proto == SWITCH_NAT_TCP) { r = UPNP_DeletePortMapping(nat_globals.urls.controlURL, nat_globals.data.servicetype, port_str, "TCP", 0); } else if (proto == SWITCH_NAT_UDP) { r = UPNP_DeletePortMapping(nat_globals.urls.controlURL, nat_globals.data.servicetype, port_str, "UDP", 0); } if (r == UPNPCOMMAND_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unmapped public port %s protocol %s to localport %s\n", port_str, (proto == SWITCH_NAT_TCP) ? "TCP" : (proto == SWITCH_NAT_UDP ? "UDP" : "UNKNOWN"), port_str); status = SWITCH_STATUS_SUCCESS; } return status; }
void C4Network2UPnPP::RemovePortMapping(const PortMapping& mapping) { if(!initialized) return; // Catches the case that UPnP initialization failed auto eport = std::to_string(mapping.external_port); int r = UPNP_DeletePortMapping(upnp_urls.controlURL, igd_data.first.servicetype, eport.c_str(), mapping.protocol.c_str(), 0); if (r == UPNPCOMMAND_SUCCESS) ThreadLogS("UPnP: Removed mapping %s %s", mapping.protocol.c_str(), eport.c_str()); else ThreadLog("UPnP: DeletePortMapping failed with code %d (%s)", r, strupnperror(r)); }
/* DeletePortMapping(extPort, proto) * proto = 'UDP', 'TCP' */ static PyObject * UPnP_deleteportmapping(UPnPObject *self, PyObject *args) { char extPort[6]; unsigned short ePort; const char * proto; if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto)) return NULL; sprintf(extPort, "%hu", ePort); UPNP_DeletePortMapping(self->urls.controlURL, self->data.servicetype, extPort, proto); Py_RETURN_TRUE; }
/* If we want to remove redirects in the future, this is a sample of how to do * that */ void upnp_rem_redir (int port) { char port_str[16]; int t; printf("TB : upnp_rem_redir (%d)\n", port); if(urls.controlURL[0] == '\0') { printf("TB : the init was not done !\n"); return; } sprintf(port_str, "%d", port); UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL); }
bool Portfwd::remove( unsigned short port ) { char port_str[16]; printf("Portfwd::remove(%d)\n", port); if(urls->controlURL[0] == '\0') { printf("Portfwd - the init was not done !\n"); return false; } sprintf(port_str, "%d", port); int r = UPNP_DeletePortMapping(urls->controlURL, data->servicetype, port_str, "TCP", NULL); return r == 0; }
/* DeletePortMapping(extPort, proto) * proto = 'UDP', 'TCP' */ static PyObject * UPnP_deleteportmapping(UPnPObject *self, PyObject *args) { char extPort[6]; unsigned short ePort; const char * proto; int r; if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto)) return NULL; sprintf(extPort, "%hu", ePort); r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.servicetype, extPort, proto); if(r==UPNPCOMMAND_SUCCESS) { Py_RETURN_TRUE; } else { /* TODO: have our own exception type ! */ PyErr_SetString(PyExc_Exception, strupnperror(r)); return NULL; } }
static void RemoveRedirect(struct UPNPUrls * urls, struct IGDdatas * data, const char * eport, const char * proto) { int r; if(!proto || !eport) { fprintf(stderr, "invalid arguments\n"); return; } proto = protofix(proto); if(!proto) { fprintf(stderr, "protocol invalid\n"); return; } r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0); printf("UPNP_DeletePortMapping() returned : %d\n", r); }
void upnp_rem_redir (int port) { char port_str[16]; int r; if (!is_upnp_ok) return; if(urls.controlURL == NULL) return; sprintf(port_str, "%d", port); r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "UDP", 0); if (r != 0) { Printf(PRINT_HIGH, "UPnP: DeletePortMapping failed: %d\n", r); is_upnp_ok = false; } else is_upnp_ok = true; }
int tr_upnpPulse( tr_upnp * handle, int port, int isEnabled, int doPortCheck ) { int ret; if( isEnabled && ( handle->state == TR_UPNP_DISCOVER ) ) { struct UPNPDev * devlist; errno = 0; devlist = upnpDiscover( 2000, NULL, NULL, 0 ); if( devlist == NULL ) { tr_ndbg( getKey( ), "upnpDiscover failed (errno %d - %s)", errno, tr_strerror( errno ) ); } errno = 0; if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data, handle->lanaddr, sizeof( handle->lanaddr ) ) == UPNP_IGD_VALID_CONNECTED ) { tr_ninf( getKey( ), _( "Found Internet Gateway Device \"%s\"" ), handle->urls.controlURL ); tr_ninf( getKey( ), _( "Local Address is \"%s\"" ), handle->lanaddr ); handle->state = TR_UPNP_IDLE; handle->hasDiscovered = 1; } else { handle->state = TR_UPNP_ERR; tr_ndbg( getKey( ), "UPNP_GetValidIGD failed (errno %d - %s)", errno, tr_strerror( errno ) ); tr_ndbg( getKey( ), "If your router supports UPnP, please make sure UPnP is enabled!" ); } freeUPNPDevlist( devlist ); } if( handle->state == TR_UPNP_IDLE ) { if( handle->isMapped && ( !isEnabled || ( handle->port != port ) ) ) handle->state = TR_UPNP_UNMAP; } if( isEnabled && handle->isMapped && doPortCheck ) { char portStr[8]; char intPort[8]; char intClient[16]; tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port ); if( UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, "TCP", intClient, intPort ) != UPNPCOMMAND_SUCCESS || UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, "UDP", intClient, intPort ) != UPNPCOMMAND_SUCCESS ) { tr_ninf( getKey( ), _( "Port %d isn't forwarded" ), handle->port ); handle->isMapped = FALSE; } } if( handle->state == TR_UPNP_UNMAP ) { char portStr[16]; tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port ); UPNP_DeletePortMapping( handle->urls.controlURL, handle->data.first.servicetype, portStr, "TCP", NULL ); UPNP_DeletePortMapping( handle->urls.controlURL, handle->data.first.servicetype, portStr, "UDP", NULL ); tr_ninf( getKey( ), _( "Stopping port forwarding through \"%s\", service \"%s\"" ), handle->urls.controlURL, handle->data.first.servicetype ); handle->isMapped = 0; handle->state = TR_UPNP_IDLE; handle->port = -1; } if( handle->state == TR_UPNP_IDLE ) { if( isEnabled && !handle->isMapped ) handle->state = TR_UPNP_MAP; } if( handle->state == TR_UPNP_MAP ) { int err_tcp = -1; int err_udp = -1; errno = 0; if( !handle->urls.controlURL || !handle->data.first.servicetype ) handle->isMapped = 0; else { char portStr[16]; char desc[64]; const int prev_errno = errno; tr_snprintf( portStr, sizeof( portStr ), "%d", port ); tr_snprintf( desc, sizeof( desc ), "%s at %d", TR_NAME, port ); errno = 0; err_tcp = UPNP_AddPortMapping( handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, "TCP", NULL ); if( err_tcp ) tr_ndbg( getKey( ), "TCP Port forwarding failed with error %d (errno %d - %s)", err_tcp, errno, tr_strerror( errno ) ); errno = 0; err_udp = UPNP_AddPortMapping( handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, "UDP", NULL ); if( err_udp ) tr_ndbg( getKey( ), "UDP Port forwarding failed with error %d (errno %d - %s)", err_udp, errno, tr_strerror( errno ) ); errno = prev_errno; handle->isMapped = !err_tcp | !err_udp; } tr_ninf( getKey( ), _( "Port forwarding through \"%s\", service \"%s\". (local address: %s:%d)" ), handle->urls.controlURL, handle->data.first.servicetype, handle->lanaddr, port ); if( handle->isMapped ) { tr_ninf( getKey( ), "%s", _( "Port forwarding successful!" ) ); handle->port = port; handle->state = TR_UPNP_IDLE; } else { tr_ndbg( getKey( ), "If your router supports UPnP, please make sure UPnP is enabled!" ); handle->port = -1; handle->state = TR_UPNP_ERR; } } switch( handle->state ) { case TR_UPNP_DISCOVER: ret = TR_PORT_UNMAPPED; break; case TR_UPNP_MAP: ret = TR_PORT_MAPPING; break; case TR_UPNP_UNMAP: ret = TR_PORT_UNMAPPING; break; case TR_UPNP_IDLE: ret = handle->isMapped ? TR_PORT_MAPPED : TR_PORT_UNMAPPED; break; default: ret = TR_PORT_ERROR; break; } return ret; }
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.writeLastError("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; #if (MINIUPNPC_API_VERSION >= 14) /* miniUPnPc API version 14 adds TTL parameter */ devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, 2, &upnperror); #else devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror); #endif #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; }
static int upnpPulse( ml_upnpmp_t * map ) { int ret; if( map->enabled && ( map->upnpState == ML_UPNP_DISCOVER ) ) { struct UPNPDev * devlist; errno = 0; devlist = upnpDiscover( 2000, NULL, NULL, 0, 0, 0 ); if( devlist == NULL ) { dbg_printf( "upnpDiscover failed (errno %d - %s)\n", errno, str_errno( errno ) ); } errno = 0; if( UPNP_IGD_VALID_CONNECTED == UPNP_GetValidIGD( devlist, &map->upnpUrls, &map->upnpData, map->lanaddr, sizeof( map->lanaddr ) ) ) { dbg_printf( "Found Internet Gateway Device \"%s\" \n", map->upnpUrls.controlURL ); dbg_printf( "Local Address is \"%s\" \n", map->lanaddr ); map->upnpState = ML_UPNP_IDLE; map->upnpDiscovered = 1; } else { map->upnpState = ML_UPNP_ERR; dbg_printf( "UPNP_GetValidIGD failed (errno %d - %s)\n", errno, str_errno( errno ) ); dbg_printf( "If your router supports UPnP, please make sure UPnP is enabled!\n" ); } freeUPNPDevlist( devlist ); } if( map->upnpState == ML_UPNP_IDLE ) { if( map->upnpMapped && ( !map->enabled ) ) map->upnpState = ML_UPNP_UNMAP; } if( map->enabled && map->upnpMapped && map->doPortCheck ) { char portStr[8]; char intPort[8]; char intClient[16]; char type[8]; int i; snprintf( portStr, sizeof( portStr ), "%d", map->extPort ); snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) ); i = UPNP_GetSpecificPortMappingEntry( map->upnpUrls.controlURL, map->upnpData.first.servicetype, portStr, type, #if MINIUPNPC_API_VERSION >= 10 NULL, /* remoteHost */ #endif intClient, intPort, NULL, NULL, NULL ); if( i != UPNPCOMMAND_SUCCESS ) { dbg_printf( "Port %d isn't forwarded\n", map->extPort ); map->upnpMapped = 0; } map->doPortCheck = 0; } if( map->upnpState == ML_UPNP_UNMAP ) { char portStr[16]; char type[8]; snprintf( portStr, sizeof( portStr ), "%d", map->extPort ); snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) ); UPNP_DeletePortMapping( map->upnpUrls.controlURL, map->upnpData.first.servicetype, portStr, type, NULL ); dbg_printf( "Stopping port forwarding through \"%s\", service \"%s\"\n", map->upnpUrls.controlURL, map->upnpData.first.servicetype ); map->upnpMapped = 0; map->upnpState = ML_UPNP_IDLE; map->extPort = 0; } if( map->upnpState == ML_UPNP_IDLE ) { if( map->enabled && !map->upnpMapped ) map->upnpState = ML_UPNP_MAP; } if( map->upnpState == ML_UPNP_MAP ) { int err = -1; errno = 0; if( !map->upnpUrls.controlURL || !map->upnpData.first.servicetype ) map->upnpMapped = 0; else { char intPortStr[16]; char extPortStr[16]; char desc[64]; char type[8]; snprintf( intPortStr, sizeof( intPortStr ), "%d", map->intPort ); snprintf( extPortStr, sizeof( extPortStr ), "%d", map->extPort ); snprintf( desc, sizeof( desc ), "%s", map->notes ); snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) ); err = UPNP_AddPortMapping( map->upnpUrls.controlURL, map->upnpData.first.servicetype, extPortStr, intPortStr, map->lanaddr, desc, type, NULL, "0" ); map->upnpMapped = !err; } dbg_printf( "Port forwarding through \"%s\", service \"%s\". (local address[%s:%d])\n", map->upnpUrls.controlURL, map->upnpData.first.servicetype, map->lanaddr, map->intPort ); if( map->upnpMapped ) { dbg_printf( "Port forwarding successful!\n" ); //handle->port = port; map->upnpState = ML_UPNP_IDLE; } else { dbg_printf( "Port forwarding failed with error %d (errno %d - %s)\n", err, errno, str_errno( errno ) ); dbg_printf( "If your router supports UPnP, please make sure UPnP is enabled!\n" ); //handle->port = -1; map->upnpState = ML_UPNP_ERR; } } switch( map->upnpState ) { case ML_UPNP_DISCOVER: ret = ML_PORT_UNMAPPED; break; case ML_UPNP_MAP: ret = ML_PORT_MAPPING; break; case ML_UPNP_UNMAP: ret = ML_PORT_UNMAPPING; break; case ML_UPNP_IDLE: ret = map->upnpMapped ? ML_PORT_MAPPED : ML_PORT_UNMAPPED; break; default: ret = ML_PORT_ERROR; break; } return ret; }
void upnp_service::map_port( uint16_t local_port ) { std::string port = fc::variant(local_port).as_string(); my->map_port_complete = my->upnp_thread.async( [=]() { const char * multicastif = 0; const char * minissdpdpath = 0; struct UPNPDev * devlist = 0; char lanaddr[64]; /* miniupnpc 1.6 */ int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); struct UPNPUrls urls; memset( &urls, 0, sizeof(urls) ); struct IGDdatas data; memset( &data, 0, sizeof(data) ); int r; r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); bool port_mapping_added = false; bool port_mapping_added_successfully = false; if (r == 1) { if (true) // TODO config this ? fDiscover) { char externalIPAddress[40]; r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); if(r != UPNPCOMMAND_SUCCESS) wlog("UPnP: GetExternalIPAddress() returned ${code}", ("code", r)); else { if(externalIPAddress[0]) { ulog("UPnP: ExternalIPAddress = ${address}", ("address", externalIPAddress)); my->external_ip = fc::ip::address( std::string(externalIPAddress) ); // AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP); } else wlog("UPnP: GetExternalIPAddress failed."); } } std::string strDesc = "BitShares 0.0"; // TODO + FormatFullVersion(); // try { while(!my->done) // TODO provide way to exit cleanly { /* miniupnpc 1.6 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); port_mapping_added = true; if(r!=UPNPCOMMAND_SUCCESS) wlog("AddPortMapping(${port}, ${port}, ${addr}) failed with code ${code} (${string})", ("port", port)("addr", lanaddr)("code", r)("string", strupnperror(r))); else { if (!port_mapping_added_successfully) ulog("UPnP Port Mapping successful"); port_mapping_added_successfully = true; my->mapped_port = local_port; } fc::usleep( fc::seconds(60*20) ); // Refresh every 20 minutes } } // catch (boost::thread_interrupted) { if( port_mapping_added ) { r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); ilog("UPNP_DeletePortMapping() returned : ${r}", ("r",r)); freeUPNPDevlist(devlist); devlist = 0; FreeUPNPUrls(&urls); } // throw; } } else { //printf("No valid UPnP IGDs found\n"); wlog("No valid UPnP IGDs found"); freeUPNPDevlist(devlist); devlist = 0; if (r != 0) { FreeUPNPUrls(&urls); } } }, "upnp::map_port" ); }
bool UPNPCheckDlg::MiniUPnPc_remove(const unsigned short port, const string& protocol, const string& service, const string& url) { return UPNP_DeletePortMapping(url.c_str(), service.c_str(), Util::toString(port).c_str(), protocol.c_str(), 0) == UPNPCOMMAND_SUCCESS; }
// redirect port on external upnp enabled router to port on *this* host int upnpredirect(const char* eport, const char* iport, const char* proto, const char* description) { // Discovery parameters struct UPNPDev * devlist = 0; struct UPNPUrls urls; struct IGDdatas data; int i; char lanaddr[64]; // my ip address on the LAN const char* leaseDuration="0"; // Redirect & test parameters char intClient[40]; char intPort[6]; char externalIPAddress[40]; char duration[16]; int error=0; // Find UPNP devices on the network if ((devlist=upnpDiscover(2000, 0, 0,0, 0, &error))) { struct UPNPDev * device = 0; printf("UPNP INIALISED: List of UPNP devices found on the network.\n"); for(device = devlist; device; device = device->pNext) { printf("UPNP INFO: dev [%s] \n\t st [%s]\n", device->descURL, device->st); } } else { printf("UPNP ERROR: no device found - MANUAL PORTMAP REQUIRED\n"); return 0; } // Output whether we found a good one or not. if((error = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) { switch(error) { case 1: printf("UPNP OK: Found valid IGD : %s\n", urls.controlURL); break; case 2: printf("UPNP WARN: Found a (not connected?) IGD : %s\n", urls.controlURL); break; case 3: printf("UPNP WARN: UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); break; default: printf("UPNP WARN: Found device (igd ?) : %s\n", urls.controlURL); } printf("UPNP OK: Local LAN ip address : %s\n", lanaddr); } else { printf("UPNP ERROR: no device found - MANUAL PORTMAP REQUIRED\n"); return 0; } // Get the external IP address (just because we can really...) if(UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress)!=UPNPCOMMAND_SUCCESS) printf("UPNP WARN: GetExternalIPAddress failed.\n"); else printf("UPNP OK: ExternalIPAddress = %s\n", externalIPAddress); // Check for existing supernet mapping - from this host and another host // In theory I can adapt this so multiple nodes can exist on same lan and choose a different portmap // for each one :) // At the moment just delete a conflicting portmap and override with the one requested. i=0; error=0; do { char index[6]; char extPort[6]; char desc[80]; char enabled[6]; char rHost[64]; char protocol[4]; snprintf(index, 6, "%d", i++); if(!(error=UPNP_GetGenericPortMappingEntry(urls.controlURL, data.first.servicetype, index, extPort, intClient, intPort, protocol, desc, enabled, rHost, duration))) { // printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",i, protocol, extPort, intClient, intPort,desc, rHost, duration); // check for an existing supernet mapping on this host if(!strcmp(lanaddr, intClient)) { // same host if(!strcmp(protocol,proto)) { //same protocol if(!strcmp(intPort,iport)) { // same port printf("UPNP WARN: existing mapping found (%s:%s)\n",lanaddr,iport); if(!strcmp(extPort,eport)) { printf("UPNP OK: exact mapping already in place (%s:%s->%s)\n", lanaddr, iport, eport); FreeUPNPUrls(&urls); freeUPNPDevlist(devlist); return 1; } else { // delete old mapping printf("UPNP WARN: deleting existing mapping (%s:%s->%s)\n",lanaddr, iport, extPort); if(UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, extPort, proto, rHost)) printf("UPNP WARN: error deleting old mapping (%s:%s->%s) continuing\n", lanaddr, iport, extPort); else printf("UPNP OK: old mapping deleted (%s:%s->%s)\n",lanaddr, iport, extPort); } } } } else { // ipaddr different - check to see if requested port is already mapped if(!strcmp(protocol,proto)) { if(!strcmp(extPort,eport)) { printf("UPNP WARN: EXT port conflict mapped to another ip (%s-> %s vs %s)\n", extPort, lanaddr, intClient); if(UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, extPort, proto, rHost)) printf("UPNP WARN: error deleting conflict mapping (%s:%s) continuing\n", intClient, extPort); else printf("UPNP OK: conflict mapping deleted (%s:%s)\n",intClient, extPort); } } } } else printf("UPNP OK: GetGenericPortMappingEntry() End-of-List (%d entries) \n", i); } while(error==0); // Set the requested port mapping if((i=UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, eport, iport, lanaddr, description, proto, 0, leaseDuration))!=UPNPCOMMAND_SUCCESS) { printf("UPNP ERROR: AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", eport, iport, lanaddr, i, strupnperror(i)); FreeUPNPUrls(&urls); freeUPNPDevlist(devlist); return 0; //error - adding the port map primary failure } if((i=UPNP_GetSpecificPortMappingEntry(urls.controlURL, data.first.servicetype, eport, proto, NULL/*remoteHost*/, intClient, intPort, NULL/*desc*/, NULL/*enabled*/, duration))!=UPNPCOMMAND_SUCCESS) { printf("UPNP ERROR: GetSpecificPortMappingEntry(%s, %s, %s) failed with code %d (%s)\n", eport, iport, lanaddr, i, strupnperror(i)); FreeUPNPUrls(&urls); freeUPNPDevlist(devlist); return 0; //error - port map wasnt returned by query so likely failed. } else printf("UPNP OK: EXT (%s:%s) %s redirected to INT (%s:%s) (duration=%s)\n",externalIPAddress, eport, proto, intClient, intPort, duration); FreeUPNPUrls(&urls); freeUPNPDevlist(devlist); return 1; //ok - we are mapped:) }
bool Mapper_MiniUPnPc::remove(const string& port, const Protocol protocol) { return UPNP_DeletePortMapping(url.c_str(), service.c_str(), port.c_str(), protocols[protocol], 0) == UPNPCOMMAND_SUCCESS; }
int upnpPulse(upnp * handle, int port, int proto, char isEnabled, int doPortCheck, const char* name) { if(isEnabled && (handle->state == UPNP_DISCOVER)) { struct UPNPDev * devlist; devlist = upnpDiscover(200, NULL, NULL, 0); if(UPNP_GetValidIGD(devlist, &handle->urls, &handle->data, handle->lanaddr, sizeof(handle->lanaddr )) == UPNP_IGD_VALID_CONNECTED) { //qDebug() << QString("Found Internet Gateway Device \"%1\"").arg(QString(handle->urls.controlURL)); //qDebug() << QString("Local Address is \"%1\"").arg(QString(handle->lanaddr)); handle->state = UPNP_IDLE; handle->hasDiscovered = 1; } else { handle->state = UPNP_ERR; //qDebug() << QString("UPNP_GetValidIGD failed"); } freeUPNPDevlist(devlist); } if(handle->state == UPNP_IDLE) { if(handle->isMapped && (!isEnabled || handle->port != port)) handle->state = UPNP_UNMAP; } char* protoStr = ""; switch(proto) { case PORT_TCP: protoStr = "TCP"; break; case PORT_UDP: protoStr = "UDP"; break; } if(isEnabled && handle->isMapped && doPortCheck) { char portStr[8]; char intPort[8]; char intClient[16]; snprintf(portStr, sizeof(portStr), "%d", handle->port); if(UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, protoStr, intClient, intPort ) != UPNPCOMMAND_SUCCESS) { //qDebug() << QString("Port %1 isn't forwarded").arg(handle->port); handle->isMapped = 0; } } if( handle->state == UPNP_UNMAP ) { char portStr[16]; snprintf(portStr, sizeof(portStr), "%d", handle->port); UPNP_DeletePortMapping(handle->urls.controlURL, handle->data.first.servicetype, portStr, protoStr, NULL); //qDebug() << QString("Stopping port forwarding through \"%1\", service \"%1\"").arg(QString(handle->urls.controlURL)).arg(QString(handle->data.first.servicetype)); handle->isMapped = 0; handle->state = UPNP_IDLE; handle->port = -1; } if(handle->state == UPNP_IDLE) { if(isEnabled && !handle->isMapped) handle->state = UPNP_MAP; } if(handle->state == UPNP_MAP) { int err = -1; if(!handle->urls.controlURL || !handle->data.first.servicetype) handle->isMapped = 0; else { char portStr[16]; char desc[64]; snprintf(portStr, sizeof(portStr), "%d", port); snprintf(desc, sizeof(desc), "%s at %d", name, port); err = UPNP_AddPortMapping(handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, protoStr, NULL); //if(err) // qDebug() << QString("%1 Port forwarding failed with error %2").arg(QString(protoStr)).arg(err); handle->isMapped = !err; } //qDebug() << QString("Port forwarding through \"%1\", service \"%2\". (local address: %3:%4)") // .arg(QString(handle->urls.controlURL)).arg(QString(handle->data.first.servicetype)).arg(QString(handle->lanaddr)).arg(port); if(handle->isMapped) { //qDebug() << QString("Port forwarding successful!"); handle->port = port; handle->state = UPNP_IDLE; } else { //qDebug() << QString("If your router supports UPnP, please make sure UPnP is enabled!"); handle->port = -1; handle->state = UPNP_ERR; } } switch( handle->state ) { case UPNP_DISCOVER: return PORT_UNMAPPED; case UPNP_MAP: return PORT_MAPPING; case UPNP_UNMAP: return PORT_UNMAPPING; case UPNP_IDLE: return handle->isMapped ? PORT_MAPPED : PORT_UNMAPPED; default: return PORT_ERROR; } }