/* UPNP_GetListOfPortMappings() * * Possible UPNP Error codes : * 606 Action not Authorized * 730 PortMappingNotFound - no port mapping is found in the specified range. * 733 InconsistantParameters - NewStartPort and NewEndPort values are not * consistent. */ MINIUPNP_LIBSPEC int UPNP_GetListOfPortMappings(const char * controlURL, const char * servicetype, const char * startPort, const char * endPort, const char * protocol, const char * numberOfPorts, struct PortMappingParserData * data) { struct NameValueParserData pdata; struct UPNParg * GetListOfPortMappingsArgs; const char * p; char * buffer; int bufsize; int ret = UPNPCOMMAND_UNKNOWN_ERROR; if(!startPort || !endPort || !protocol) return UPNPCOMMAND_INVALID_ARGS; GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg)); if(GetListOfPortMappingsArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; GetListOfPortMappingsArgs[0].elt = "NewStartPort"; GetListOfPortMappingsArgs[0].val = startPort; GetListOfPortMappingsArgs[1].elt = "NewEndPort"; GetListOfPortMappingsArgs[1].val = endPort; GetListOfPortMappingsArgs[2].elt = "NewProtocol"; GetListOfPortMappingsArgs[2].val = protocol; GetListOfPortMappingsArgs[3].elt = "NewManage"; GetListOfPortMappingsArgs[3].val = "1"; GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts"; GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000"; buffer = simpleUPnPcommand(-1, controlURL, servicetype, "GetListOfPortMappings", GetListOfPortMappingsArgs, &bufsize); free(GetListOfPortMappingsArgs); if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } /*DisplayNameValueList(buffer, bufsize);*/ ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/ /*if(p) { printf("NewPortListing : %s\n", p); }*/ /*printf("NewPortListing(%d chars) : %s\n", pdata.portListingLength, pdata.portListing);*/ if(pdata.portListing) { /*struct PortMapping * pm; int i = 0;*/ ParsePortListing(pdata.portListing, pdata.portListingLength, data); ret = UPNPCOMMAND_SUCCESS; /* for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next) { printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n", i, pm->protocol, pm->externalPort, pm->internalClient, pm->internalPort, pm->description, pm->remoteHost); i++; } */ /*FreePortListing(&data);*/ } p = GetValueFromNameValueList(&pdata, "errorCode"); if(p) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(p, "%d", &ret); } ClearNameValueList(&pdata); /*printf("%.*s", bufsize, buffer);*/ return ret; }
/* return the number of differences */ int test(const char * portListingXml, int portListingXmlLen, const struct port_mapping * ref, int count) { int i; int r = 0; struct PortMappingParserData data; struct PortMapping * pm; memset(&data, 0, sizeof(data)); ParsePortListing(portListingXml, portListingXmlLen, &data); for(i = 0, pm = data.l_head; (pm != NULL) && (i < count); i++, pm = pm->l_next) { printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", i, pm->protocol, pm->externalPort, pm->internalClient, pm->internalPort, pm->description, pm->remoteHost, (unsigned)pm->leaseTime); if(0 != strcmp(pm->protocol, ref[i].proto)) { printf("protocol : '%s' != '%s'\n", pm->protocol, ref[i].proto); r++; } if(pm->externalPort != ref[i].externalport) { printf("externalPort : %hu != %hu\n", pm->externalPort, ref[i].externalport); r++; } if(0 != strcmp(pm->internalClient, ref[i].client)) { printf("client : '%s' != '%s'\n", pm->internalClient, ref[i].client); r++; } if(pm->internalPort != ref[i].internalport) { printf("internalPort : %hu != %hu\n", pm->internalPort, ref[i].internalport); r++; } if(0 != strcmp(pm->description, ref[i].desc)) { printf("description : '%s' != '%s'\n", pm->description, ref[i].desc); r++; } if(0 != strcmp(pm->remoteHost, ref[i].remotehost)) { printf("remoteHost : '%s' != '%s'\n", pm->remoteHost, ref[i].remotehost); r++; } if((unsigned)pm->leaseTime != ref[i].leasetime) { printf("leaseTime : %u != %u\n", (unsigned)pm->leaseTime, ref[i].leasetime); r++; } if(pm->enabled != ref[i].enabled) { printf("enabled : %d != %d\n", (int)pm->enabled, (int)ref[i].enabled); r++; } } if((i != count) || (pm != NULL)) { printf("count mismatch : i=%d count=%d pm=%p\n", i, count, pm); r++; } FreePortListing(&data); return r; }