/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc, * remoteHost) * protocol is 'UDP' or 'TCP' */ static PyObject * UPnP_addanyportmapping(UPnPObject *self, PyObject *args) { char extPort[6]; unsigned short ePort; char inPort[6]; unsigned short iPort; char reservedPort[6]; const char * proto; const char * host; const char * desc; const char * remoteHost; const char * leaseDuration = "0"; int r; if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) return NULL; Py_BEGIN_ALLOW_THREADS sprintf(extPort, "%hu", ePort); sprintf(inPort, "%hu", iPort); r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype, extPort, inPort, host, desc, proto, remoteHost, leaseDuration, reservedPort); Py_END_ALLOW_THREADS if(r==UPNPCOMMAND_SUCCESS) { return Py_BuildValue("i", atoi(reservedPort)); } else { /* TODO: have our own exception type ! */ PyErr_SetString(PyExc_Exception, strupnperror(r)); return NULL; } }
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 }
/* 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, int addAny) { char externalIPAddress[40]; char intClient[40]; char intPort[6]; char reservedPort[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; } r = UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, externalIPAddress); if(r!=UPNPCOMMAND_SUCCESS) printf("GetExternalIPAddress failed.\n"); else printf("ExternalIPAddress = %s\n", externalIPAddress); if (addAny) { r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, eport, iport, iaddr, description, proto, 0, leaseDuration, reservedPort); if(r==UPNPCOMMAND_SUCCESS) eport = reservedPort; else printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", eport, iport, iaddr, r, strupnperror(r)); } else { 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)); else { 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); } }