bool Mapper_MiniUPnPc::add(const string& port, const Protocol protocol, const string& description) { #ifdef HAVE_OLD_MINIUPNPC return UPNP_AddPortMapping(url.c_str(), service.c_str(), port.c_str(), port.c_str(), localIp.c_str(), description.c_str(), protocols[protocol], 0) == UPNPCOMMAND_SUCCESS; #else return UPNP_AddPortMapping(url.c_str(), service.c_str(), port.c_str(), port.c_str(), localIp.c_str(), description.c_str(), protocols[protocol], 0, 0) == UPNPCOMMAND_SUCCESS; #endif }
int upnpAddPortMapping( struct upnp_handle_t *handle, const char *proto, unsigned short port ) { char extPort[6]; char inPort[6]; snprintf( extPort, sizeof(extPort), "%hu", port ); snprintf( inPort, sizeof(inPort), "%hu", port ); #if (MINIUPNPC_API_VERSION <= 5) return UPNP_AddPortMapping( handle->urls.controlURL, handle->data.first.servicetype, extPort, inPort, handle->addr, NULL, proto, NULL ); #else return UPNP_AddPortMapping( handle->urls.controlURL, handle->data.first.servicetype, extPort, inPort, handle->addr, NULL, proto, NULL, NULL ); #endif }
bool CUPnPImplMiniLib::CStartDiscoveryThread::OpenPort(uint16 nPort, bool bTCP, char* pachLANIP){ const char achTCP[] = "TCP"; const char achUDP[] = "UDP"; const char achDescTCP[] = "eMule_TCP"; const char achDescUDP[] = "eMule_UDP"; char achPort[10]; sprintf(achPort, "%u", nPort); if (m_pOwner->m_bAbortDiscovery) return false; int nResult; if (bTCP) nResult = UPNP_AddPortMapping(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype , achPort, achPort, pachLANIP, achDescTCP, achTCP); else nResult = UPNP_AddPortMapping(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype , achPort, achPort, pachLANIP, achDescUDP, achUDP); if (nResult != UPNPCOMMAND_SUCCESS){ DebugLog(_T("Adding PortMapping failed, Error Code %u"), nResult); return false; } if (m_pOwner->m_bAbortDiscovery) return false; // make sure it really worked char achOutIP[20]; achOutIP[0] = 0; if (bTCP) nResult = UPNP_GetSpecificPortMappingEntry(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype , achPort, achTCP, achOutIP, achPort); else nResult = UPNP_GetSpecificPortMappingEntry(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype , achPort, achUDP, achOutIP, achPort); if (nResult == UPNPCOMMAND_SUCCESS && achOutIP[0] != 0){ DebugLog(_T("Sucessfully added mapping for port %u (%s) on local IP %S"), nPort, bTCP ? _T("TCP") : _T("UDP"), achOutIP); return true; } else { DebugLogWarning(_T("Failed to verfiy mapping for port %u (%s) on local IP %S - considering as failed"), nPort, bTCP ? _T("TCP") : _T("UDP"), achOutIP); // maybe counting this as error is a bit harsh as this may lead to false negatives, however if we would risk false postives // this would mean that the fallback implementations are not tried because eMule thinks it worked out fine return false; } }
Utils::UPnPResult ModuleUPnP::UPnPForwardPort(bool tcp, int externalport, int internalport, const std::string & ruleName) { struct UPNPUrls urls; struct IGDdatas data; char lanaddr[16]; if (upnpDiscoverError != UPNPDISCOVER_SUCCESS || upnpDevice == nullptr) return Utils::UPnPResult(Utils::UPnPErrorType::DiscoveryError, upnpDiscoverError); int ret = UPNP_GetValidIGD(upnpDevice, &urls, &data, lanaddr, sizeof(lanaddr)); if (ret != Utils::UPNP_IGD_VALID_CONNECTED) return Utils::UPnPResult(Utils::UPnPErrorType::IGDError, ret); ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, std::to_string(externalport).c_str(), std::to_string(internalport).c_str(), lanaddr, ruleName.c_str(), tcp ? "TCP" : "UDP", NULL, NULL); Utils::UPnPErrorType type = Utils::UPnPErrorType::None; if (ret != UPNPCOMMAND_SUCCESS) type = Utils::UPnPErrorType::PortMapError; return Utils::UPnPResult(type, ret); }
/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc) * protocol is 'UDP' or 'TCP' */ static PyObject * UPnP_addportmapping(UPnPObject *self, PyObject *args) { char extPort[6]; unsigned short ePort; char inPort[6]; unsigned short iPort; const char * proto; const char * host; const char * desc; int r; if (!PyArg_ParseTuple(args, "HssHs", &ePort, &proto, &host, &iPort, &desc)) return NULL; sprintf(extPort, "%hu", ePort); sprintf(inPort, "%hu", iPort); r = UPNP_AddPortMapping(self->urls.controlURL, self->data.servicetype, extPort, inPort, host, desc, proto); if(r) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } }
int tor_upnp_add_tcp_mapping(uint16_t internal_port, uint16_t external_port, int is_verbose, void *backend_state) { int retval; char internal_port_str[6]; char external_port_str[6]; miniupnpc_state_t *state = (miniupnpc_state_t *) backend_state; if (!state->init) { fprintf(stderr, "E: %s but state is not initialized.\n", __func__); return -1; } if (is_verbose) fprintf(stderr, "V: UPnP: internal port: %u, external port: %u\n", internal_port, external_port); tor_snprintf(internal_port_str, sizeof(internal_port_str), "%u", internal_port); tor_snprintf(external_port_str, sizeof(external_port_str), "%u", external_port); retval = UPNP_AddPortMapping(state->urls.controlURL, state->data.first.servicetype, external_port_str, internal_port_str, #ifdef MINIUPNPC15 state->lanaddr, UPNP_DESC, "TCP", 0); #else state->lanaddr, UPNP_DESC, "TCP", 0, 0); #endif return (retval == UPNP_ERR_SUCCESS) ? 0 : -1; }
/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc, * remoteHost) * protocol is 'UDP' or 'TCP' */ static PyObject * UPnP_addportmapping(UPnPObject *self, PyObject *args) { char extPort[6]; unsigned short ePort; char inPort[6]; unsigned short iPort; const char * proto; const char * host; const char * desc; const char * remoteHost; int r; if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) return NULL; sprintf(extPort, "%hu", ePort); sprintf(inPort, "%hu", iPort); r = UPNP_AddPortMapping(self->urls.controlURL, self->data.servicetype, extPort, inPort, host, desc, proto, remoteHost); if(r==UPNPCOMMAND_SUCCESS) { Py_RETURN_TRUE; } else { // TODO: RAISE an Exception. See upnpcommands.h for errors codes. // upnperrors.c //Py_RETURN_FALSE; /* TODO: have our own exception type ! */ PyErr_SetString(PyExc_Exception, strupnperror(r)); return NULL; } }
int AddPortMapping(unsigned int extPort, unsigned int intPort, const char* protocol, const char* intClient) { char myextPort[6] = {0}; char myintPort[6] = {0}; char desc[80] = {0}; char leaseDuration[16] = {0}; sprintf(myextPort, "%d", extPort); sprintf(myintPort, "%d", intPort); sprintf(desc, "%s", "my_upnp_test"); sprintf(leaseDuration, "%d", 0); printf("***extPort:%s, intPort:%s, %s, %s***\n", myextPort, myintPort, intClient, protocol); printf("***%s, %s***\n", desc, leaseDuration); int result = UPNP_AddPortMapping(g_urls->controlURL, g_data->first.servicetype, myextPort, myintPort, intClient, desc, protocol, NULL, leaseDuration); if(0 == result) { printf("add port mapping ok\n"); } else { printf("add port mapping failed: %d\n", result); } return 0; }
boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLocalPort, int actualPublicPort) { if (!p->isValid) { return boost::optional<NATPortMapping>(); } NATPortMapping mapping(actualLocalPort, actualPublicPort, NATPortMapping::TCP); 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_AddPortMapping( p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), localPort.c_str(), p->localAddress.c_str(), "Swift", mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str()); if (ret == UPNPCOMMAND_SUCCESS) { return mapping; } else { return boost::optional<NATPortMapping>(); } }
bool Gateway::addTCPPortMapping(const char *ip, unsigned short iport, unsigned short eport) { if (UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, ulong2CString(iport), ulong2CString(eport), ip, "IPCameraGenius", "TCP", 0, 0) != 0) { return false; } return true; }
static inline void I_UPnP_add(const char * addr, const char *port, const char * servicetype) { if (addr == NULL) addr = lanaddr; if (!urls.controlURL || urls.controlURL[0] == '\0') return; UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port, port, addr, "SRB2", servicetype, NULL, NULL); }
/* Test function * 1 - get connection type * 2 - get extenal ip address * 3 - Add port mapping * 4 - get this port mapping from the IGD */ static void SetRedirectAndTest(struct UPNPUrls * urls, struct IGDdatas * data, const char * iaddr, const char * iport, const char * eport, const char * proto, const char * leaseDuration, const char * description) { char externalIPAddress[40]; char intClient[40]; char intPort[6]; char duration[16]; int r; if(!iaddr || !iport || !eport || !proto) { fprintf(stderr, "Wrong arguments\n"); return; } proto = protofix(proto); if(!proto) { fprintf(stderr, "invalid protocol\n"); return; } UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, externalIPAddress); if(externalIPAddress[0]) printf("ExternalIPAddress = %s\n", externalIPAddress); else printf("GetExternalIPAddress failed.\n"); r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, eport, iport, iaddr, description, proto, 0, leaseDuration); if(r!=UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", eport, iport, iaddr, r, strupnperror(r)); r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, data->first.servicetype, eport, proto, NULL/*remoteHost*/, intClient, intPort, NULL/*desc*/, NULL/*enabled*/, duration); if(r!=UPNPCOMMAND_SUCCESS) printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", r, strupnperror(r)); if(intClient[0]) { printf("InternalIP:Port = %s:%s\n", intClient, intPort); printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", externalIPAddress, eport, proto, intClient, intPort, duration); } }
static int tr_upnpAddPortMapping (const tr_upnp * handle, const char * proto, tr_port port, const char * desc) { int err; const int old_errno = errno; char portStr[16]; errno = 0; tr_snprintf (portStr, sizeof (portStr), "%d", (int)port); #if (MINIUPNPC_API_VERSION >= 8) err = UPNP_AddPortMapping (handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, proto, NULL, NULL); #else err = UPNP_AddPortMapping (handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, proto, NULL); #endif if (err) tr_logAddNamedDbg (getKey (), "%s Port forwarding failed with error %d (errno %d - %s)", proto, err, errno, tr_strerror (errno)); errno = old_errno; return err; }
static switch_status_t switch_nat_add_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_AddPortMapping(nat_globals.urls.controlURL, nat_globals.data.servicetype, port_str, port_str, nat_globals.pvt_addr, "FreeSWITCH", "TCP", 0); } else if (proto == SWITCH_NAT_UDP) { r = UPNP_AddPortMapping(nat_globals.urls.controlURL, nat_globals.data.servicetype, port_str, port_str, nat_globals.pvt_addr, "FreeSWITCH", "UDP", 0); } if (r == UPNPCOMMAND_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mapped 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::AddPortMapping(const PortMapping& mapping) { if (!initialized) return; // Catches the case that UPnP initialization failed auto eport = std::to_string(mapping.external_port); auto iport = std::to_string(mapping.internal_port); int r = UPNP_AddPortMapping(upnp_urls.controlURL, igd_data.first.servicetype, eport.c_str(), iport.c_str(), lanaddr, description, mapping.protocol.c_str(), 0, 0); if (r == UPNPCOMMAND_SUCCESS) ThreadLogS("UPnP: Added mapping %s %s -> %s:%s", mapping.protocol.c_str(), eport.c_str(), lanaddr, iport.c_str()); else ThreadLog("UPnP: AddPortMapping failed with code %d (%s)", r, strupnperror(r)); }
// called from ---UPnP--- thread // Attempt to portforward! static bool MapPort(const char* addr, const u16 port) { if (s_mapped > 0) UnmapPort(s_mapped); std::string port_str = std::to_string(port); int result = UPNP_AddPortMapping( s_urls.controlURL, s_data.first.servicetype, port_str.c_str(), port_str.c_str(), addr, (std::string("dolphin-emu UDP on ") + addr).c_str(), "UDP", nullptr, nullptr); if (result != 0) return false; s_mapped = port; return true; }
void UPnP::TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address) { std::string strType (GetProto (address)), strPort (std::to_string (address->port)); int r; std::string strDesc; i2p::config::GetOption("upnp.name", strDesc); r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0"); if (r!=UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: AddPortMapping (", m_NetworkAddr, ":", strPort, ") failed with code ", r); return; } else { LogPrint (eLogDebug, "UPnP: Port Mapping successful. (", m_NetworkAddr ,":", strPort, " type ", strType, " -> ", m_externalIPAddress ,":", strPort ,")"); return; } }
// called from ---UPnP--- thread // Attempt to portforward! bool NetPlayServer::UPnPMapPort(const std::string& addr, const u16 port) { if (m_upnp_mapped > 0) UPnPUnmapPort(m_upnp_mapped); std::string port_str = StringFromFormat("%d", port); int result = UPNP_AddPortMapping(m_upnp_urls.controlURL, m_upnp_data.first.servicetype, port_str.c_str(), port_str.c_str(), addr.c_str(), (std::string("dolphin-emu TCP on ") + addr).c_str(), "TCP", nullptr, nullptr); if (result != 0) return false; m_upnp_mapped = port; return true; }
/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc, * remoteHost, leaseDuration) * protocol is 'UDP' or 'TCP' */ static PyObject * UPnP_addportmapping(UPnPObject *self, PyObject *args) { char extPort[6]; unsigned short ePort; char inPort[6]; unsigned short iPort; const char * proto; const char * host; const char * desc; const char * remoteHost; unsigned int intLeaseDuration = 0; char strLeaseDuration[12]; int r; #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) if (!PyArg_ParseTuple(args, "HssHzz|I", &ePort, &proto, &host, &iPort, &desc, &remoteHost, &intLeaseDuration)) #else if (!PyArg_ParseTuple(args, "HssHzz|i", &ePort, &proto, &host, &iPort, &desc, &remoteHost, (int *)&intLeaseDuration)) #endif return NULL; Py_BEGIN_ALLOW_THREADS sprintf(extPort, "%hu", ePort); sprintf(inPort, "%hu", iPort); sprintf(strLeaseDuration, "%u", intLeaseDuration); r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype, extPort, inPort, host, desc, proto, remoteHost, strLeaseDuration); Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { Py_RETURN_TRUE; } else { // TODO: RAISE an Exception. See upnpcommands.h for errors codes. // upnperrors.c //Py_RETURN_FALSE; /* TODO: have our own exception type ! */ PyErr_SetString(PyExc_Exception, strupnperror(r)); return NULL; } }
// called from ---UPnP--- thread // Attempt to portforward! bool NetPlayServer::UPnPMapPort(const std::string& addr, const u16 port) { char port_str[6] = { 0 }; int result; if (m_upnp_mapped > 0) UPnPUnmapPort(m_upnp_mapped); sprintf(port_str, "%d", port); result = UPNP_AddPortMapping(m_upnp_urls.controlURL, m_upnp_data.first.servicetype, port_str, port_str, addr.c_str(), (std::string("dolphin-emu TCP on ") + addr).c_str(), "TCP", NULL, NULL); if(result != 0) return false; m_upnp_mapped = port; return true; }
bool Portfwd::add( unsigned short port ) { char port_str[16]; int r; printf("Portfwd::add (%s, %d)\n", m_lanip.c_str(), port); if(urls->controlURL[0] == '\0') { printf("Portfwd - the init was not done !\n"); return false; } sprintf(port_str, "%d", port); r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, port_str, port_str, m_lanip.c_str(), 0, "TCP", NULL); if(r!=0) { printf("AddPortMapping(%s, %s, %s) failed, code %d\n", port_str, port_str, m_lanip.c_str(), r); return false; } return true; }
void upnp_add_redir (const char * addr, int port) { char port_str[16]; int r; if (!sv_upnp || !is_upnp_ok) return; if(urls.controlURL == NULL) return; sprintf(port_str, "%d", port); // Set a description if none exists if (!sv_upnp_description.cstring()[0]) { std::stringstream desc; desc << "Odasrv " << "(" << addr << ":" << port_str << ")"; sv_upnp_description.Set(desc.str().c_str()); } r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port_str, port_str, addr, sv_upnp_description.cstring(), "UDP", NULL, 0); if (r != 0) { Printf(PRINT_HIGH, "UPnP: AddPortMapping failed: %d\n", r); is_upnp_ok = false; } else { Printf(PRINT_HIGH, "UPnP: Port mapping added to router: %s", sv_upnp_description.cstring()); is_upnp_ok = true; } }
/** Add a TCP port mapping for a single port stored in <b>tor_fw_options</b> * and store the results in <b>backend_state</b>. */ int tor_upnp_add_tcp_mapping(tor_fw_options_t *options, void *backend_state) { miniupnpc_state_t *state = (miniupnpc_state_t *) backend_state; int r; char internal_port_str[6]; char external_port_str[6]; if (!state->init) { r = tor_upnp_init(options, state); if (r != UPNP_ERR_SUCCESS) return r; } if (options->verbose) fprintf(stdout, "V: internal port: %d, external port: %d\n", (int)options->internal_port, (int)options->external_port); tor_snprintf(internal_port_str, sizeof(internal_port_str), "%d", (int)options->internal_port); tor_snprintf(external_port_str, sizeof(external_port_str), "%d", (int)options->external_port); r = UPNP_AddPortMapping(state->urls.controlURL, state->data.first.servicetype, external_port_str, internal_port_str, #ifdef MINIUPNPC15 state->lanaddr, UPNP_DESC, "TCP", 0); #else state->lanaddr, UPNP_DESC, "TCP", 0, 0); #endif if (r != UPNPCOMMAND_SUCCESS) return UPNP_ERR_ADDPORTMAPPING; options->upnp_status = 1; return UPNP_ERR_SUCCESS; }
static bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t addrlen, enum socket_protocol proto) { #ifndef HAVE_SOCKET_LEGACY #if HAVE_MINIUPNPC int r; char host[PATH_MAX_LENGTH], ext_host[PATH_MAX_LENGTH], port_str[6], ext_port_str[6]; struct addrinfo hints = {0}; const char *proto_str = NULL; struct addrinfo *ext_addrinfo = NULL; /* if NAT traversal is uninitialized or unavailable, oh well */ if (!urls.controlURL || !urls.controlURL[0]) return false; /* figure out the internal info */ if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, port_str, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0) return false; proto_str = (proto == SOCKET_PROTOCOL_UDP) ? "UDP" : "TCP"; /* add the port mapping */ r = UPNP_AddAnyPortMapping(urls.controlURL, data.first.servicetype, port_str, port_str, host, "retroarch", proto_str, NULL, "3600", ext_port_str); if (r != 0) { /* try the older AddPortMapping */ memcpy(ext_port_str, port_str, 6); r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port_str, port_str, host, "retroarch", proto_str, NULL, "3600"); } if (r != 0) return false; /* get the external IP */ r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, ext_host); if (r != 0) return false; /* update the status */ if (getaddrinfo_retro(ext_host, ext_port_str, &hints, &ext_addrinfo) != 0) return false; if (ext_addrinfo->ai_family == AF_INET && ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in)) { status->have_inet4 = true; status->ext_inet4_addr = *((struct sockaddr_in *) ext_addrinfo->ai_addr); } #if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY) else if (ext_addrinfo->ai_family == AF_INET6 && ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in6)) { status->have_inet6 = true; status->ext_inet6_addr = *((struct sockaddr_in6 *) ext_addrinfo->ai_addr); } #endif else { freeaddrinfo_retro(ext_addrinfo); return false; } freeaddrinfo_retro(ext_addrinfo); return true; #else return false; #endif #else return false; #endif }
void* CNetServerWorker::SetupUPnP(void*) { // Values we want to set. char psPort[6]; sprintf_s(psPort, ARRAY_SIZE(psPort), "%d", PS_DEFAULT_PORT); const char* leaseDuration = "0"; // Indefinite/permanent lease duration. const char* description = "0AD Multiplayer"; const char* protocall = "UDP"; char internalIPAddress[64]; char externalIPAddress[40]; // Variables to hold the values that actually get set. char intClient[40]; char intPort[6]; char duration[16]; // Intermediate variables. struct UPNPUrls urls; struct IGDdatas data; struct UPNPDev* devlist = NULL; // Cached root descriptor URL. std::string rootDescURL; CFG_GET_VAL("network.upnprootdescurl", rootDescURL); if (!rootDescURL.empty()) LOGMESSAGE("Net server: attempting to use cached root descriptor URL: %s", rootDescURL.c_str()); int ret = 0; bool allocatedUrls = false; // Try a cached URL first if (!rootDescURL.empty() && UPNP_GetIGDFromUrl(rootDescURL.c_str(), &urls, &data, internalIPAddress, sizeof(internalIPAddress))) { LOGMESSAGE("Net server: using cached IGD = %s", urls.controlURL); ret = 1; } // No cached URL, or it did not respond. Try getting a valid UPnP device for 10 seconds. else if ((devlist = upnpDiscover(10000, 0, 0, 0, 0, 0)) != NULL) { ret = UPNP_GetValidIGD(devlist, &urls, &data, internalIPAddress, sizeof(internalIPAddress)); allocatedUrls = ret != 0; // urls is allocated on non-zero return values } else { LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL."); return NULL; } switch (ret) { case 0: LOGMESSAGE("Net server: No IGD found"); break; case 1: LOGMESSAGE("Net server: found valid IGD = %s", urls.controlURL); break; case 2: LOGMESSAGE("Net server: found a valid, not connected IGD = %s, will try to continue anyway", urls.controlURL); break; case 3: LOGMESSAGE("Net server: found a UPnP device unrecognized as IGD = %s, will try to continue anyway", urls.controlURL); break; default: debug_warn(L"Unrecognized return value from UPNP_GetValidIGD"); } // Try getting our external/internet facing IP. TODO: Display this on the game-setup page for conviniance. ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); if (ret != UPNPCOMMAND_SUCCESS) { LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret)); return NULL; } LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress); // Try to setup port forwarding. ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, psPort, psPort, internalIPAddress, description, protocall, 0, leaseDuration); if (ret != UPNPCOMMAND_SUCCESS) { LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)", psPort, psPort, internalIPAddress, ret, strupnperror(ret)); return NULL; } // Check that the port was actually forwarded. ret = UPNP_GetSpecificPortMappingEntry(urls.controlURL, data.first.servicetype, psPort, protocall, #if defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 10 NULL/*remoteHost*/, #endif intClient, intPort, NULL/*desc*/, NULL/*enabled*/, duration); if (ret != UPNPCOMMAND_SUCCESS) { LOGMESSAGE("Net server: GetSpecificPortMappingEntry() failed with code %d (%s)", ret, strupnperror(ret)); return NULL; } LOGMESSAGE("Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)", externalIPAddress, psPort, protocall, intClient, intPort, duration); // Cache root descriptor URL to try to avoid discovery next time. g_ConfigDB.SetValueString(CFG_USER, "network.upnprootdescurl", urls.controlURL); g_ConfigDB.WriteFile(CFG_USER); LOGMESSAGE("Net server: cached UPnP root descriptor URL as %s", urls.controlURL); // Make sure everything is properly freed. if (allocatedUrls) FreeUPNPUrls(&urls); freeUPNPDevlist(devlist); return NULL; }
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" ); }
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 threadMain() throw() { char lanaddr[4096]; char externalip[4096]; // no range checking? so make these buffers larger than any UDP packet a uPnP server could send us as a precaution :P char inport[16]; char outport[16]; struct UPNPUrls urls; struct IGDdatas data; #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: started for UDP port %d"ZT_EOL_S,localPort); #endif unsigned int tryPortStart = 0; Utils::getSecureRandom(&tryPortStart,sizeof(tryPortStart)); tryPortStart = (tryPortStart % (65535 - 1025)) + 1025; while (run) { { int upnpError = 0; UPNPDev *devlist = upnpDiscover(2000,(const char *)0,(const char *)0,0,0,0,&upnpError); if (devlist) { #ifdef ZT_UPNP_TRACE { UPNPDev *dev = devlist; while (dev) { fprintf(stderr,"UPNPClient: found device at URL '%s': %s"ZT_EOL_S,dev->descURL,dev->st); dev = dev->pNext; } } #endif memset(lanaddr,0,sizeof(lanaddr)); memset(externalip,0,sizeof(externalip)); memset(&urls,0,sizeof(urls)); memset(&data,0,sizeof(data)); Utils::snprintf(inport,sizeof(inport),"%d",localPort); if ((UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: my LAN IP address: %s"ZT_EOL_S,lanaddr); #endif if ((UPNP_GetExternalIPAddress(urls.controlURL,data.first.servicetype,externalip) == UPNPCOMMAND_SUCCESS)&&(externalip[0])) { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: my external IP address: %s"ZT_EOL_S,externalip); #endif for(int tries=0;tries<64;++tries) { int tryPort = (int)tryPortStart + tries; if (tryPort >= 65535) tryPort = (tryPort - 65535) + 1025; Utils::snprintf(outport,sizeof(outport),"%u",tryPort); int mapResult = 0; if ((mapResult = UPNP_AddPortMapping(urls.controlURL,data.first.servicetype,outport,inport,lanaddr,"ZeroTier","UDP",(const char *)0,"0")) == UPNPCOMMAND_SUCCESS) { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: reserved external port: %s"ZT_EOL_S,outport); #endif { Mutex::Lock sl(surface_l); surface.clear(); InetAddress tmp(externalip); tmp.setPort(tryPort); surface.push_back(tmp); } break; } else { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: UPNP_AddAnyPortMapping(%s) failed: %d"ZT_EOL_S,outport,mapResult); #endif Thread::sleep(1000); } } } else { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: UPNP_GetExternalIPAddress failed"ZT_EOL_S); #endif } } else { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: UPNP_GetValidIGD failed"ZT_EOL_S); #endif } freeUPNPDevlist(devlist); } else { #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: upnpDiscover error code: %d"ZT_EOL_S,upnpError); #endif } } #ifdef ZT_UPNP_TRACE fprintf(stderr,"UPNPClient: rescanning in %d ms"ZT_EOL_S,ZT_UPNP_CLIENT_REFRESH_DELAY); #endif Thread::sleep(ZT_UPNP_CLIENT_REFRESH_DELAY); } delete this; }
/** * 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; }
int vino_upnp_add_port (VinoUpnp *upnp, int port) { char *ext_port, *int_port, *desc; int err, local_port; char int_client_tmp[16], int_port_tmp[6]; g_return_val_if_fail (VINO_IS_UPNP (upnp), -1); if (!update_upnp_status (upnp)) return -1; vino_upnp_remove_port (upnp); local_port = port; do { ext_port = g_strdup_printf ("%d", local_port); dprintf (UPNP, "UPnP: Trying to forward port %d...: ", local_port); UPNP_GetSpecificPortMappingEntry (upnp->priv->urls->controlURL, upnp->priv->data->servicetype, ext_port, "TCP", int_client_tmp, int_port_tmp); if ( (strcmp (int_client_tmp, upnp->priv->lanaddr) == 0) && (strcmp (int_port_tmp, ext_port) == 0) ) { dprintf (UPNP, "UPnP: Found a previous redirect\n"); break; } else if (int_client_tmp[0]) { dprintf (UPNP, "Failed, this port is already forwarded to %s:%s\n", int_client_tmp, int_port_tmp); g_free (ext_port); } else { dprintf (UPNP, "OK, this port is free on the router\n"); break; } local_port++; } while (local_port < INT_MAX); if (local_port == INT_MAX) { dprintf (UPNP, "UPnP: Not forwarding any port, tried so much\n"); return -1; } int_port = g_strdup_printf ("%d", port); desc = g_strdup_printf ("VNC: %s@%s", g_get_user_name (), g_get_host_name ()); err = UPNP_AddPortMapping (upnp->priv->urls->controlURL, upnp->priv->data->servicetype, ext_port, int_port, upnp->priv->lanaddr, desc, "TCP"); if (err == 0) { upnp->priv->port = local_port; upnp->priv->internal_port = port; dprintf (UPNP, "UPnP: Successfuly forwarded port %d\n", local_port); } else dprintf (UPNP, "Failed to forward port %d, with status %d\n", local_port, err); g_free (ext_port); g_free (int_port); g_free (desc); return upnp->priv->port; }