static int init_upnp(void) { struct UPNPDev *devlist; struct UPNPDev *dev = NULL; struct UPNPDev *trydev = NULL; char *descXML; int descXMLsize = 0; const char *multicastif = 0; const char *minissdpdpath = 0; memset(&nat_globals.urls, 0, sizeof(struct UPNPUrls)); memset(&nat_globals.data, 0, sizeof(struct IGDdatas)); devlist = upnpDiscover(3000, multicastif, minissdpdpath, 0); if (devlist) { dev = devlist; while (dev) { if (strstr(dev->st, "InternetGatewayDevice")) { break; } if (!trydev && !switch_stristr("printer", dev->descURL)) { trydev = dev; } dev = dev->pNext; } } if (!dev && trydev) { dev = trydev; /* defaulting to first device */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No InternetGatewayDevice, using first entry as default (%s).\n", dev->descURL); } else if (devlist && !dev && !trydev) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No InternetGatewayDevice found and I am NOT going to try your printer because printers should not route to the internet, that would be DAFT\n"); } if (dev) { descXML = miniwget(dev->descURL, &descXMLsize); nat_globals.descURL = strdup(dev->descURL); if (descXML) { parserootdesc(descXML, descXMLsize, &nat_globals.data); free(descXML); descXML = 0; GetUPNPUrls(&nat_globals.urls, &nat_globals.data, dev->descURL); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unable to retrieve device description XML (%s).\n", dev->descURL); } freeUPNPDevlist(devlist); } if (get_upnp_pubaddr(nat_globals.pub_addr) == SWITCH_STATUS_SUCCESS) { nat_globals.nat_type = SWITCH_NAT_TYPE_UPNP; return 0; } return -2; }
// called from ---UPnP--- thread // discovers the IGD bool NetPlayServer::initUPnP() { UPNPDev *devlist; std::vector<UPNPDev *> igds; int descXMLsize = 0, upnperror = 0; char *descXML; // Don't init if already inited if (m_upnp_inited) return true; // Don't init if it failed before if (m_upnp_error) return false; memset(&m_upnp_urls, 0, sizeof(UPNPUrls)); memset(&m_upnp_data, 0, sizeof(IGDdatas)); // Find all UPnP devices devlist = upnpDiscover(2000, NULL, NULL, 0, 0, &upnperror); if (!devlist) { WARN_LOG(NETPLAY, "An error occured trying to discover UPnP devices."); m_upnp_error = true; m_upnp_inited = false; return false; } // Look for the IGD for (UPNPDev* dev = devlist; dev; dev = dev->pNext) { if (strstr(dev->st, "InternetGatewayDevice")) igds.push_back(dev); } for (const UPNPDev* dev : igds) { descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0); if (descXML) { parserootdesc(descXML, descXMLsize, &m_upnp_data); free(descXML); descXML = 0; GetUPNPUrls(&m_upnp_urls, &m_upnp_data, dev->descURL, 0); NOTICE_LOG(NETPLAY, "Got info from IGD at %s.", dev->descURL); break; } else { WARN_LOG(NETPLAY, "Error getting info from IGD at %s.", dev->descURL); } } freeUPNPDevlist(devlist); return true; }
bool Portfwd::init(unsigned int timeout) { #ifdef WIN32 WSADATA wsaData; int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(nResult != NO_ERROR) { fprintf(stderr, "WSAStartup() failed.\n"); return -1; } #endif struct UPNPDev * devlist; struct UPNPDev * dev; char * descXML; int descXMLsize = 0; printf("Portfwd::init()\n"); urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls)); data = (IGDdatas*)malloc(sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); memset(data, 0, sizeof(struct IGDdatas)); devlist = upnpDiscover(timeout, NULL, NULL, 0); if (devlist) { dev = devlist; while (dev) { if (strstr (dev->st, "InternetGatewayDevice")) break; dev = dev->pNext; } if (!dev) dev = devlist; /* defaulting to first device */ printf("UPnP device :\n" " desc: %s\n st: %s\n", dev->descURL, dev->st); descXML = (char*)miniwget(dev->descURL, &descXMLsize); if (descXML) { parserootdesc (descXML, descXMLsize, data); free (descXML); descXML = 0; GetUPNPUrls (urls, data, dev->descURL); } // get lan IP: char lanaddr[16]; int i; i = UPNP_GetValidIGD(devlist, urls, data, (char*)&lanaddr, 16); m_lanip = std::string(lanaddr); freeUPNPDevlist(devlist); get_status(); return true; } return false; }
static inline void I_InitUPnP(void) { struct UPNPDev * devlist = NULL; int upnp_error = -2; CONS_Printf(M_GetText("Looking for UPnP Internet Gateway Device\n")); devlist = upnpDiscover(2000, NULL, NULL, 0, false, &upnp_error); if (devlist) { struct UPNPDev *dev = devlist; char * descXML; int descXMLsize = 0; while (dev) { if (strstr (dev->st, "InternetGatewayDevice")) break; dev = dev->pNext; } if (!dev) dev = devlist; /* defaulting to first device */ CONS_Printf(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"), dev->descURL, dev->st); UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); CONS_Printf(M_GetText("Local LAN IP address: %s\n"), lanaddr); descXML = miniwget(dev->descURL, &descXMLsize); if (descXML) { parserootdesc(descXML, descXMLsize, &data); free(descXML); descXML = NULL; memset(&urls, 0, sizeof(struct UPNPUrls)); memset(&data, 0, sizeof(struct IGDdatas)); GetUPNPUrls(&urls, &data, dev->descURL); I_AddExitFunc(I_ShutdownUPnP); } freeUPNPDevlist(devlist); } else if (upnp_error == UPNPDISCOVER_SOCKET_ERROR) { CONS_Printf(M_GetText("No UPnP devices discovered\n")); } }
void natt_init(void) { #ifndef HAVE_SOCKET_LEGACY #if HAVE_MINIUPNPC struct UPNPDev * devlist; struct UPNPDev * dev; char * descXML; int descXMLsize = 0; int upnperror = 0; memset(&urls, 0, sizeof(struct UPNPUrls)); memset(&data, 0, sizeof(struct IGDdatas)); devlist = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &upnperror); if (devlist) { dev = devlist; while (dev) { if (strstr (dev->st, "InternetGatewayDevice")) break; dev = dev->pNext; } if (!dev) dev = devlist; descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0, NULL); if (descXML) { parserootdesc(descXML, descXMLsize, &data); free (descXML); descXML = 0; GetUPNPUrls (&urls, &data, dev->descURL, 0); } freeUPNPDevlist(devlist); } #endif #endif }
/* * Complete an IGDdatas structure with service info */ void fillData(struct IGDdatas* data){ int d,s; int ignored = 0; for(d=0;d < data->devices;d++){ struct IGDdevice * dev = data->dlist[d]; if(!dev) continue; if(!dev->devicetype[0]){ ignored++; continue; } for(s=0;s<dev->services;s++) { struct IGDservice * srv = dev->slist[s]; if(!srv) continue; if(!srv->actions) { char * descXML; int descXMLsize = 0; char descURL[100]; sprintf(descURL,"%s:80%s",data->urlbase,srv->scpdurl); descXML = miniwget(descURL, &descXMLsize); if(descXML){ parseservicedesc(descXML,descXMLsize, data,d,s); free(descXML); } } } } }
/* sample upnp client program */ int main(int argc, char ** argv) { char command = 0; char ** commandargv = 0; int commandargc = 0; struct UPNPDev * devlist = 0; char lanaddr[64]; /* my ip address on the LAN */ int i; const char * rootdescurl = 0; const char * multicastif = 0; const char * minissdpdpath = 0; int retcode = 0; int error = 0; int ipv6 = 0; const char * description = 0; #ifdef _WIN32 WSADATA wsaData; int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(nResult != NO_ERROR) { fprintf(stderr, "WSAStartup() failed.\n"); return -1; } #endif printf("upnpc : miniupnpc library test client. (c) 2005-2014 Thomas Bernard\n"); printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" "for more information.\n"); /* command line processing */ for(i=1; i<argc; i++) { if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h")) { command = 0; break; } if(argv[i][0] == '-') { if(argv[i][1] == 'u') rootdescurl = argv[++i]; else if(argv[i][1] == 'm') multicastif = argv[++i]; else if(argv[i][1] == 'p') minissdpdpath = argv[++i]; else if(argv[i][1] == '6') ipv6 = 1; else if(argv[i][1] == 'e') description = argv[++i]; else { command = argv[i][1]; i++; commandargv = argv + i; commandargc = argc - i; break; } } else { fprintf(stderr, "option '%s' invalid\n", argv[i]); } } if(!command || (command == 'a' && commandargc<4) || (command == 'd' && argc<2) || (command == 'r' && argc<2) || (command == 'A' && commandargc<6) || (command == 'U' && commandargc<2) || (command == 'D' && commandargc<1)) { fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -d external_port protocol <remote host>\n\t\tDelete port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]); fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]); fprintf(stderr, "\nprotocol is UDP or TCP\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -e description : set description for port mapping.\n"); fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n"); fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n"); fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); return 1; } if( rootdescurl || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0/*sameport*/, ipv6, &error))) { struct UPNPDev * device; struct UPNPUrls urls; struct IGDdatas data; if(devlist) { printf("List of UPNP devices found on the network :\n"); for(device = devlist; device; device = device->pNext) { printf(" desc: %s\n st: %s\n\n", device->descURL, device->st); } } else if(!rootdescurl) { printf("upnpDiscover() error code=%d\n", error); } i = 1; if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) { switch(i) { case 1: printf("Found valid IGD : %s\n", urls.controlURL); break; case 2: printf("Found a (not connected?) IGD : %s\n", urls.controlURL); printf("Trying to continue anyway\n"); break; case 3: printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); printf("Trying to continue anyway\n"); break; default: printf("Found device (igd ?) : %s\n", urls.controlURL); printf("Trying to continue anyway\n"); } printf("Local LAN ip address : %s\n", lanaddr); #if 0 printf("getting \"%s\"\n", urls.ipcondescURL); descXML = miniwget(urls.ipcondescURL, &descXMLsize); if(descXML) { /*fwrite(descXML, 1, descXMLsize, stdout);*/ free(descXML); descXML = NULL; } #endif switch(command) { case 'l': DisplayInfos(&urls, &data); ListRedirections(&urls, &data); break; case 'L': NewListRedirections(&urls, &data); break; case 'a': SetRedirectAndTest(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3], (commandargc > 4)?commandargv[4]:"0", description, 0); break; case 'd': RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], commandargc > 2 ? commandargv[2] : NULL); break; case 'n': /* aNy */ SetRedirectAndTest(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3], (commandargc > 4)?commandargv[4]:"0", description, 1); break; case 'N': if (commandargc < 3) fprintf(stderr, "too few arguments\n"); RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargc > 3 ? commandargv[3] : NULL); break; case 's': GetConnectionStatus(&urls, &data); break; case 'r': i=0; while(i<commandargc){ if(!is_int(commandargv[i+1])){ /* 2nd parameter not an integer, so format is '<port> <protocol>' */ /* Note: no 2nd parameter is also not-an-integer, and will lead to a "Wrong arguments" */ SetRedirectAndTest(&urls, &data, lanaddr, commandargv[i], commandargv[i], commandargv[i+1], "0", description, 0); i+=2; /* 2 parameters parsed */ } else { /* 2nd parameter is an integer, so format is '<port> <external_port> <protocol>' */ SetRedirectAndTest(&urls, &data, lanaddr, commandargv[i], commandargv[i+1], commandargv[i+2], "0", description, 0); i+=3; /* 3 parameters parsed */ } } break; case 'A': SetPinholeAndTest(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3], commandargv[4], commandargv[5]); break; case 'U': GetPinholeAndUpdate(&urls, &data, commandargv[0], commandargv[1]); break; case 'C': for(i=0; i<commandargc; i++) { CheckPinhole(&urls, &data, commandargv[i]); } break; case 'K': for(i=0; i<commandargc; i++) { GetPinholePackets(&urls, &data, commandargv[i]); } break; case 'D': for(i=0; i<commandargc; i++) { RemovePinhole(&urls, &data, commandargv[i]); } break; case 'S': GetFirewallStatus(&urls, &data); break; case 'G': GetPinholeOutboundTimeout(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3], commandargv[4]); break; case 'P': printf("Presentation URL found:\n"); printf(" %s\n", data.presentationurl); break; default: fprintf(stderr, "Unknown switch -%c\n", command); retcode = 1; } FreeUPNPUrls(&urls); } else { fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n"); retcode = 1; } freeUPNPDevlist(devlist); devlist = 0; } else { fprintf(stderr, "No IGD UPnP Device found on the network !\n"); retcode = 1; } #ifdef _WIN32 nResult = WSACleanup(); if(nResult != NO_ERROR) { fprintf(stderr, "WSACleanup() failed.\n"); } #endif /* _WIN32 */ return retcode; }
int main(int argc, char ** argv) { char * descURL = NULL; int option_index = 0; int c; int devid = -1; char arguments[1025]; arguments[0]='\0'; char action[129]; action[0]='\0'; char verbose = 0; unsigned int operation = OP_NONE; if(argc == 1) { printUsage(argv[0]); return -1; } while(1){ c = getopt_long(argc,argv,"dlva:p:",long_options,&option_index); if(c == -1) break; switch(c){ case 'd': operation = OP_DISCOVER; break; case 'l': operation = OP_LIST; break; case 'a': operation = OP_CALLOP; if(optarg) strncpy(action,optarg,128); break; case 'p': if(optarg) strncpy(arguments,optarg,1024); break; case 'v': verbose = 1; break; default: printUsage(argv[0]); return 0; } } if(verbose) printf("Universal Plug and Play IGD Tool v0.1\n João Paulo Barraca <*****@*****.**>\n\n"); if(operation == OP_NONE) return 0; descURL = upnpDiscover(5000); // timeout = 5secs if(descURL) { struct IGDdatas *data = (struct IGDdatas*) malloc(sizeof(struct IGDdatas)); struct UPNPUrls urls; memset(data, 0, sizeof(struct IGDdatas)); memset(&urls, 0, sizeof(struct UPNPUrls)); char * descXML; int descXMLsize = 0; descXML = miniwget(descURL, &descXMLsize); parserootdesc(descXML, descXMLsize, data); if(descXML) { switch(operation) { case OP_CALLOP: callUPNPVariable(data,action,arguments, verbose); break; case OP_LIST: listServices(data,devid,verbose); break; case OP_DISCOVER: listDevices(data); break; default: printf("Error: Action not implemented (yet)!\n"); break; } free(descXML); } else { printf("Error: Cannot get XML description of the device.\n"); } freeIGD(data); free(descURL); } else { fprintf(stderr, "Error: No IGD UPnP Device found on the network !\n"); } return 0; }
bool UPnP::start() { int error = 0; UPNPDev *devlist = ::upnpDiscover(2000, NULL, NULL, FALSE, FALSE, &error); UPNPDev *devlistBegin = devlist; // get interface list /*foreach(interface, interfaces) { newdevlist = ::upnpDiscover(2000, interface, NULL, FALSE, FALSE, &error); // go to end of list and append }*/ while (devlist) { UPNPUrls urls; IGDdatas data; char lanaddr[64]; UPnPHash resultHash; int code = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); if (code > 0) // TODO maybe distinguish between the return codes (1,2,3) to add information what happend to the result { resultHash.insert(LanIpAddress, QLatin1String(lanaddr)); char externalIP[40]; if (UPNPCOMMAND_SUCCESS == UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP)) { resultHash.insert(ExternalIpAddress, QLatin1String(externalIP)); } char connectionType[64]; if (UPNPCOMMAND_SUCCESS == UPNP_GetConnectionTypeInfo(urls.controlURL, data.first.servicetype, connectionType)) { resultHash.insert(ConnectionType, QLatin1String(connectionType)); } quint32 uplink, downlink; if (UPNPCOMMAND_SUCCESS == UPNP_GetLinkLayerMaxBitRates(urls.controlURL_CIF, data.CIF.servicetype, &downlink, &uplink)) { resultHash.insert(LinkLayerMaxDownload, downlink); resultHash.insert(LinkLayerMaxUpload, uplink); } quint32 bytesSent, bytesReceived, packetsSent, packetsReceived; bytesSent = UPNP_GetTotalBytesSent(urls.controlURL_CIF, data.CIF.servicetype); if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != bytesSent) { resultHash.insert(TotalBytesSent, bytesSent); } bytesReceived = UPNP_GetTotalBytesReceived(urls.controlURL_CIF, data.CIF.servicetype); if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != bytesReceived) { resultHash.insert(TotalBytesReceived, bytesReceived); } packetsSent = UPNP_GetTotalPacketsSent(urls.controlURL_CIF, data.CIF.servicetype); if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != packetsSent) { resultHash.insert(TotalPacketsSent, packetsSent); } packetsReceived = UPNP_GetTotalPacketsReceived(urls.controlURL_CIF, data.CIF.servicetype); if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != packetsReceived) { resultHash.insert(TotalPacketsReceived, packetsReceived); } char status[100]; unsigned int uptime = 0; char lastConnectionError[128]; if (UPNPCOMMAND_SUCCESS == UPNP_GetStatusInfo(urls.controlURL, data.first.servicetype, status, &uptime, lastConnectionError)) { resultHash.insert(Status, status); resultHash.insert(Uptime, uptime); resultHash.insert(LastConnectionError, lastConnectionError); } quint32 num; if (UPNPCOMMAND_SUCCESS == UPNP_GetPortMappingNumberOfEntries(urls.controlURL, data.first.servicetype, &num)) { resultHash.insert(NumberOfPortMappings, num); } // TODO GetListOfPortMappings do we need this? int firewallEnabled, inboundPinholeAllowed; if (UPNPCOMMAND_SUCCESS == UPNP_GetFirewallStatus(urls.controlURL, data.first.servicetype, &firewallEnabled, &inboundPinholeAllowed)) { resultHash.insert(FirewallEnabled, firewallEnabled); resultHash.insert(InboundPinholeAllowed, inboundPinholeAllowed); } int bufferSize = 0; if (char *buffer = (char *)miniwget(urls.rootdescURL, &bufferSize, 0)) { NameValueParserData pdata; ParseNameValue(buffer, bufferSize, &pdata); free(buffer); buffer = NULL; QStringList modelName = GetValuesFromNameValueList(&pdata, "modelName"); if (!modelName.isEmpty()) { resultHash.insert(ModelName, modelName.last()); } QStringList manufacturer = GetValuesFromNameValueList(&pdata, "manufacturer"); if (!manufacturer.isEmpty()) { resultHash.insert(Manufacturer, manufacturer.last()); } QStringList friendlyName = GetValuesFromNameValueList(&pdata, "friendlyName"); if (!friendlyName.isEmpty()) { resultHash.insert(FriendlyName, friendlyName.last()); } ClearNameValueList(&pdata); } } FreeUPNPUrls(&urls); results.append(resultHash); devlist = devlist->pNext; } freeUPNPDevlist(devlistBegin); emit finished(); return true; // TODO return false if something went wrong or if there are no results }
void init_upnp (void) { struct UPNPDev * devlist; struct UPNPDev * dev; char * descXML; int descXMLsize = 0; int res = 0; char IPAddress[40]; int r; if (!sv_upnp) return; memset(&urls, 0, sizeof(struct UPNPUrls)); memset(&data, 0, sizeof(struct IGDdatas)); Printf(PRINT_HIGH, "UPnP: Discovering router (max 1 unit supported)\n"); devlist = upnpDiscover(sv_upnp_discovertimeout.asInt(), NULL, NULL, 0, 0, &res); if (!devlist || res != UPNPDISCOVER_SUCCESS) { Printf(PRINT_HIGH, "UPnP: Router not found or timed out, error %d\n", res); is_upnp_ok = false; return; } dev = devlist; while (dev) { if (strstr (dev->st, "InternetGatewayDevice")) break; dev = dev->pNext; } if (!dev) dev = devlist; /* defaulting to first device */ //Printf(PRINT_HIGH, "UPnP device :\n" // " desc: %s\n st: %s\n", // dev->descURL, dev->st); descXML = (char *)miniwget(dev->descURL, &descXMLsize, 0); if (descXML) { parserootdesc (descXML, descXMLsize, &data); free (descXML); descXML = NULL; GetUPNPUrls (&urls, &data, dev->descURL, 0); } freeUPNPDevlist(devlist); r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, IPAddress); if (r != 0) { Printf(PRINT_HIGH, "UPnP: Router found but unable to get external IP address\n"); is_upnp_ok = false; } else { Printf(PRINT_HIGH, "UPnP: Router found, external IP address is: %s\n", IPAddress); // Store ip address just in case admin wants it sv_upnp_externalip.ForceSet(IPAddress); is_upnp_ok = true; } }
/* sample upnp client program */ int main(int argc, char ** argv) { char command = 0; char ** commandargv = 0; int commandargc = 0; struct UPNPDev * devlist = 0; char lanaddr[64]; /* my ip address on the LAN */ int i; const char * rootdescurl = 0; const char * multicastif = 0; const char * minissdpdpath = 0; int retcode = 0; #ifdef WIN32 WSADATA wsaData; int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(nResult != NO_ERROR) { fprintf(stderr, "WSAStartup() failed.\n"); return -1; } #endif printf("upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard\n"); printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" "for more information.\n"); /* command line processing */ for(i=1; i<argc; i++) { if(argv[i][0] == '-') { if(argv[i][1] == 'u') rootdescurl = argv[++i]; else if(argv[i][1] == 'm') multicastif = argv[++i]; else if(argv[i][1] == 'p') minissdpdpath = argv[++i]; else { command = argv[i][1]; i++; commandargv = argv + i; commandargc = argc - i; break; } } else { fprintf(stderr, "option '%s' invalid\n", argv[i]); } } if(!command || (command == 'a' && commandargc<4) || (command == 'd' && argc<2) || (command == 'r' && argc<2)) { fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol\n\t\tAdd port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); fprintf(stderr, " \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); fprintf(stderr, "\nprotocol is UDP or TCP\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); fprintf(stderr, " -m address : provide ip address of the interface to use for sending SSDP multicast packets.\n"); fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); return 1; } if( rootdescurl || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0))) { struct UPNPDev * device; struct UPNPUrls urls; struct IGDdatas data; if(devlist) { printf("List of UPNP devices found on the network :\n"); for(device = devlist; device; device = device->pNext) { printf(" desc: %s\n st: %s\n\n", device->descURL, device->st); } } i = 1; if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) { switch(i) { case 1: printf("Found valid IGD : %s\n", urls.controlURL); break; case 2: printf("Found a (not connected?) IGD : %s\n", urls.controlURL); printf("Trying to continue anyway\n"); break; case 3: printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); printf("Trying to continue anyway\n"); break; default: printf("Found device (igd ?) : %s\n", urls.controlURL); printf("Trying to continue anyway\n"); } printf("Local LAN ip address : %s\n", lanaddr); #if 0 printf("getting \"%s\"\n", urls.ipcondescURL); descXML = miniwget(urls.ipcondescURL, &descXMLsize); if(descXML) { /*fwrite(descXML, 1, descXMLsize, stdout);*/ free(descXML); descXML = NULL; } #endif switch(command) { case 'l': DisplayInfos(&urls, &data); ListRedirections(&urls, &data); break; case 'a': SetRedirectAndTest(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3]); break; case 'd': for(i=0; i<commandargc; i+=2) { RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]); } break; case 's': GetConnectionStatus(&urls, &data); break; case 'r': for(i=0; i<commandargc; i+=2) { /*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/ SetRedirectAndTest(&urls, &data, lanaddr, commandargv[i], commandargv[i], commandargv[i+1]); } break; default: fprintf(stderr, "Unknown switch -%c\n", command); retcode = 1; } FreeUPNPUrls(&urls); } else { fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n"); retcode = 1; } freeUPNPDevlist(devlist); devlist = 0; } else { fprintf(stderr, "No IGD UPnP Device found on the network !\n"); retcode = 1; } return retcode; }