File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpc / upnpcommands.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 00:36:10 2013 UTC (10 years, 10 months ago) by misho
Branches: miniupnpc, elwix, MAIN
CVS tags: v1_8p0, v1_8, HEAD
1.8

    1: /* $Id: upnpcommands.c,v 1.1.1.2 2013/07/22 00:36:10 misho Exp $ */
    2: /* Project : miniupnp
    3:  * Author : Thomas Bernard
    4:  * Copyright (c) 2005-2012 Thomas Bernard
    5:  * This software is subject to the conditions detailed in the
    6:  * LICENCE file provided in this distribution.
    7:  * */
    8: #include <stdlib.h>
    9: #include <stdio.h>
   10: #include <string.h>
   11: #include "upnpcommands.h"
   12: #include "miniupnpc.h"
   13: #include "portlistingparse.h"
   14: 
   15: static UNSIGNED_INTEGER
   16: my_atoui(const char * s)
   17: {
   18: 	return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
   19: }
   20: 
   21: /*
   22:  * */
   23: LIBSPEC UNSIGNED_INTEGER
   24: UPNP_GetTotalBytesSent(const char * controlURL,
   25: 					const char * servicetype)
   26: {
   27: 	struct NameValueParserData pdata;
   28: 	char * buffer;
   29: 	int bufsize;
   30: 	unsigned int r = 0;
   31: 	char * p;
   32: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
   33: 	                                "GetTotalBytesSent", 0, &bufsize))) {
   34: 		return UPNPCOMMAND_HTTP_ERROR;
   35: 	}
   36: 	ParseNameValue(buffer, bufsize, &pdata);
   37: 	/*DisplayNameValueList(buffer, bufsize);*/
   38: 	free(buffer); buffer = NULL;
   39: 	p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
   40: 	r = my_atoui(p);
   41: 	ClearNameValueList(&pdata);
   42: 	return r;
   43: }
   44: 
   45: /*
   46:  * */
   47: LIBSPEC UNSIGNED_INTEGER
   48: UPNP_GetTotalBytesReceived(const char * controlURL,
   49: 						const char * servicetype)
   50: {
   51: 	struct NameValueParserData pdata;
   52: 	char * buffer;
   53: 	int bufsize;
   54: 	unsigned int r = 0;
   55: 	char * p;
   56: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
   57: 	                                "GetTotalBytesReceived", 0, &bufsize))) {
   58: 		return UPNPCOMMAND_HTTP_ERROR;
   59: 	}
   60: 	ParseNameValue(buffer, bufsize, &pdata);
   61: 	/*DisplayNameValueList(buffer, bufsize);*/
   62: 	free(buffer); buffer = NULL;
   63: 	p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
   64: 	r = my_atoui(p);
   65: 	ClearNameValueList(&pdata);
   66: 	return r;
   67: }
   68: 
   69: /*
   70:  * */
   71: LIBSPEC UNSIGNED_INTEGER
   72: UPNP_GetTotalPacketsSent(const char * controlURL,
   73: 						const char * servicetype)
   74: {
   75: 	struct NameValueParserData pdata;
   76: 	char * buffer;
   77: 	int bufsize;
   78: 	unsigned int r = 0;
   79: 	char * p;
   80: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
   81: 	                                "GetTotalPacketsSent", 0, &bufsize))) {
   82: 		return UPNPCOMMAND_HTTP_ERROR;
   83: 	}
   84: 	ParseNameValue(buffer, bufsize, &pdata);
   85: 	/*DisplayNameValueList(buffer, bufsize);*/
   86: 	free(buffer); buffer = NULL;
   87: 	p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
   88: 	r = my_atoui(p);
   89: 	ClearNameValueList(&pdata);
   90: 	return r;
   91: }
   92: 
   93: /*
   94:  * */
   95: LIBSPEC UNSIGNED_INTEGER
   96: UPNP_GetTotalPacketsReceived(const char * controlURL,
   97: 						const char * servicetype)
   98: {
   99: 	struct NameValueParserData pdata;
  100: 	char * buffer;
  101: 	int bufsize;
  102: 	unsigned int r = 0;
  103: 	char * p;
  104: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  105: 	                                "GetTotalPacketsReceived", 0, &bufsize))) {
  106: 		return UPNPCOMMAND_HTTP_ERROR;
  107: 	}
  108: 	ParseNameValue(buffer, bufsize, &pdata);
  109: 	/*DisplayNameValueList(buffer, bufsize);*/
  110: 	free(buffer); buffer = NULL;
  111: 	p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
  112: 	r = my_atoui(p);
  113: 	ClearNameValueList(&pdata);
  114: 	return r;
  115: }
  116: 
  117: /* UPNP_GetStatusInfo() call the corresponding UPNP method
  118:  * returns the current status and uptime */
  119: LIBSPEC int
  120: UPNP_GetStatusInfo(const char * controlURL,
  121: 				const char * servicetype,
  122: 				char * status,
  123: 				unsigned int * uptime,
  124: 				char * lastconnerror)
  125: {
  126: 	struct NameValueParserData pdata;
  127: 	char * buffer;
  128: 	int bufsize;
  129: 	char * p;
  130: 	char * up;
  131: 	char * err;
  132: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  133: 
  134: 	if(!status && !uptime)
  135: 		return UPNPCOMMAND_INVALID_ARGS;
  136: 
  137: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  138: 	                                "GetStatusInfo", 0, &bufsize))) {
  139: 		return UPNPCOMMAND_HTTP_ERROR;
  140: 	}
  141: 	ParseNameValue(buffer, bufsize, &pdata);
  142: 	/*DisplayNameValueList(buffer, bufsize);*/
  143: 	free(buffer); buffer = NULL;
  144: 	up = GetValueFromNameValueList(&pdata, "NewUptime");
  145: 	p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
  146: 	err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
  147: 	if(p && up)
  148: 	  ret = UPNPCOMMAND_SUCCESS;
  149: 
  150: 	if(status) {
  151: 		if(p){
  152: 			strncpy(status, p, 64 );
  153: 			status[63] = '\0';
  154: 		}else
  155: 			status[0]= '\0';
  156: 	}
  157: 
  158: 	if(uptime) {
  159: 		if(up)
  160: 			sscanf(up,"%u",uptime);
  161: 		else
  162: 			uptime = 0;
  163: 	}
  164: 
  165: 	if(lastconnerror) {
  166: 		if(err) {
  167: 			strncpy(lastconnerror, err, 64 );
  168: 			lastconnerror[63] = '\0';
  169: 		} else
  170: 			lastconnerror[0] = '\0';
  171: 	}
  172: 
  173: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  174: 	if(p) {
  175: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  176: 		sscanf(p, "%d", &ret);
  177: 	}
  178: 	ClearNameValueList(&pdata);
  179: 	return ret;
  180: }
  181: 
  182: /* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
  183:  * returns the connection type */
  184: LIBSPEC int
  185: UPNP_GetConnectionTypeInfo(const char * controlURL,
  186:                            const char * servicetype,
  187:                            char * connectionType)
  188: {
  189: 	struct NameValueParserData pdata;
  190: 	char * buffer;
  191: 	int bufsize;
  192: 	char * p;
  193: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  194: 
  195: 	if(!connectionType)
  196: 		return UPNPCOMMAND_INVALID_ARGS;
  197: 
  198: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  199: 	                                "GetConnectionTypeInfo", 0, &bufsize))) {
  200: 		return UPNPCOMMAND_HTTP_ERROR;
  201: 	}
  202: 	ParseNameValue(buffer, bufsize, &pdata);
  203: 	free(buffer); buffer = NULL;
  204: 	p = GetValueFromNameValueList(&pdata, "NewConnectionType");
  205: 	/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
  206: 	/* PossibleConnectionTypes will have several values.... */
  207: 	if(p) {
  208: 		strncpy(connectionType, p, 64 );
  209: 		connectionType[63] = '\0';
  210: 		ret = UPNPCOMMAND_SUCCESS;
  211: 	} else
  212: 		connectionType[0] = '\0';
  213: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  214: 	if(p) {
  215: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  216: 		sscanf(p, "%d", &ret);
  217: 	}
  218: 	ClearNameValueList(&pdata);
  219: 	return ret;
  220: }
  221: 
  222: /* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
  223:  * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
  224:  * One of the values can be null
  225:  * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
  226:  * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
  227: LIBSPEC int
  228: UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
  229:                              const char * servicetype,
  230:                              unsigned int * bitrateDown,
  231:                              unsigned int * bitrateUp)
  232: {
  233: 	struct NameValueParserData pdata;
  234: 	char * buffer;
  235: 	int bufsize;
  236: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  237: 	char * down;
  238: 	char * up;
  239: 	char * p;
  240: 
  241: 	if(!bitrateDown && !bitrateUp)
  242: 		return UPNPCOMMAND_INVALID_ARGS;
  243: 
  244: 	/* shouldn't we use GetCommonLinkProperties ? */
  245: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  246: 	                                "GetCommonLinkProperties", 0, &bufsize))) {
  247: 	                              /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
  248: 		return UPNPCOMMAND_HTTP_ERROR;
  249: 	}
  250: 	/*DisplayNameValueList(buffer, bufsize);*/
  251: 	ParseNameValue(buffer, bufsize, &pdata);
  252: 	free(buffer); buffer = NULL;
  253: 	/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
  254: 	/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
  255: 	down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
  256: 	up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
  257: 	/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
  258: 	/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
  259: 	if(down && up)
  260: 		ret = UPNPCOMMAND_SUCCESS;
  261: 
  262: 	if(bitrateDown) {
  263: 		if(down)
  264: 			sscanf(down,"%u",bitrateDown);
  265: 		else
  266: 			*bitrateDown = 0;
  267: 	}
  268: 
  269: 	if(bitrateUp) {
  270: 		if(up)
  271: 			sscanf(up,"%u",bitrateUp);
  272: 		else
  273: 			*bitrateUp = 0;
  274: 	}
  275: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  276: 	if(p) {
  277: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  278: 		sscanf(p, "%d", &ret);
  279: 	}
  280: 	ClearNameValueList(&pdata);
  281: 	return ret;
  282: }
  283: 
  284: 
  285: /* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
  286:  * if the third arg is not null the value is copied to it.
  287:  * at least 16 bytes must be available
  288:  *
  289:  * Return values :
  290:  * 0 : SUCCESS
  291:  * NON ZERO : ERROR Either an UPnP error code or an unknown error.
  292:  *
  293:  * 402 Invalid Args - See UPnP Device Architecture section on Control.
  294:  * 501 Action Failed - See UPnP Device Architecture section on Control.
  295:  */
  296: LIBSPEC int
  297: UPNP_GetExternalIPAddress(const char * controlURL,
  298:                           const char * servicetype,
  299:                           char * extIpAdd)
  300: {
  301: 	struct NameValueParserData pdata;
  302: 	char * buffer;
  303: 	int bufsize;
  304: 	char * p;
  305: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  306: 
  307: 	if(!extIpAdd || !controlURL || !servicetype)
  308: 		return UPNPCOMMAND_INVALID_ARGS;
  309: 
  310: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  311: 	                                "GetExternalIPAddress", 0, &bufsize))) {
  312: 		return UPNPCOMMAND_HTTP_ERROR;
  313: 	}
  314: 	/*DisplayNameValueList(buffer, bufsize);*/
  315: 	ParseNameValue(buffer, bufsize, &pdata);
  316: 	free(buffer); buffer = NULL;
  317: 	/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
  318: 	p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
  319: 	if(p) {
  320: 		strncpy(extIpAdd, p, 16 );
  321: 		extIpAdd[15] = '\0';
  322: 		ret = UPNPCOMMAND_SUCCESS;
  323: 	} else
  324: 		extIpAdd[0] = '\0';
  325: 
  326: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  327: 	if(p) {
  328: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  329: 		sscanf(p, "%d", &ret);
  330: 	}
  331: 
  332: 	ClearNameValueList(&pdata);
  333: 	return ret;
  334: }
  335: 
  336: LIBSPEC int
  337: UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
  338:                     const char * extPort,
  339: 					const char * inPort,
  340: 					const char * inClient,
  341: 					const char * desc,
  342: 					const char * proto,
  343:                     const char * remoteHost,
  344:                     const char * leaseDuration)
  345: {
  346: 	struct UPNParg * AddPortMappingArgs;
  347: 	char * buffer;
  348: 	int bufsize;
  349: 	struct NameValueParserData pdata;
  350: 	const char * resVal;
  351: 	int ret;
  352: 
  353: 	if(!inPort || !inClient || !proto || !extPort)
  354: 		return UPNPCOMMAND_INVALID_ARGS;
  355: 
  356: 	AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
  357: 	AddPortMappingArgs[0].elt = "NewRemoteHost";
  358: 	AddPortMappingArgs[0].val = remoteHost;
  359: 	AddPortMappingArgs[1].elt = "NewExternalPort";
  360: 	AddPortMappingArgs[1].val = extPort;
  361: 	AddPortMappingArgs[2].elt = "NewProtocol";
  362: 	AddPortMappingArgs[2].val = proto;
  363: 	AddPortMappingArgs[3].elt = "NewInternalPort";
  364: 	AddPortMappingArgs[3].val = inPort;
  365: 	AddPortMappingArgs[4].elt = "NewInternalClient";
  366: 	AddPortMappingArgs[4].val = inClient;
  367: 	AddPortMappingArgs[5].elt = "NewEnabled";
  368: 	AddPortMappingArgs[5].val = "1";
  369: 	AddPortMappingArgs[6].elt = "NewPortMappingDescription";
  370: 	AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
  371: 	AddPortMappingArgs[7].elt = "NewLeaseDuration";
  372: 	AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
  373: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  374: 	                                "AddPortMapping", AddPortMappingArgs,
  375: 	                                &bufsize))) {
  376: 		free(AddPortMappingArgs);
  377: 		return UPNPCOMMAND_HTTP_ERROR;
  378: 	}
  379: 	/*DisplayNameValueList(buffer, bufsize);*/
  380: 	/*buffer[bufsize] = '\0';*/
  381: 	/*puts(buffer);*/
  382: 	ParseNameValue(buffer, bufsize, &pdata);
  383: 	free(buffer); buffer = NULL;
  384: 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
  385: 	if(resVal) {
  386: 		/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  387: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  388: 		sscanf(resVal, "%d", &ret);
  389: 	} else {
  390: 		ret = UPNPCOMMAND_SUCCESS;
  391: 	}
  392: 	ClearNameValueList(&pdata);
  393: 	free(AddPortMappingArgs);
  394: 	return ret;
  395: }
  396: 
  397: LIBSPEC int
  398: UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
  399:                        const char * extPort, const char * proto,
  400:                        const char * remoteHost)
  401: {
  402: 	/*struct NameValueParserData pdata;*/
  403: 	struct UPNParg * DeletePortMappingArgs;
  404: 	char * buffer;
  405: 	int bufsize;
  406: 	struct NameValueParserData pdata;
  407: 	const char * resVal;
  408: 	int ret;
  409: 
  410: 	if(!extPort || !proto)
  411: 		return UPNPCOMMAND_INVALID_ARGS;
  412: 
  413: 	DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
  414: 	DeletePortMappingArgs[0].elt = "NewRemoteHost";
  415: 	DeletePortMappingArgs[0].val = remoteHost;
  416: 	DeletePortMappingArgs[1].elt = "NewExternalPort";
  417: 	DeletePortMappingArgs[1].val = extPort;
  418: 	DeletePortMappingArgs[2].elt = "NewProtocol";
  419: 	DeletePortMappingArgs[2].val = proto;
  420: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  421: 	                               "DeletePortMapping",
  422: 	                               DeletePortMappingArgs, &bufsize))) {
  423: 		free(DeletePortMappingArgs);
  424: 		return UPNPCOMMAND_HTTP_ERROR;
  425: 	}
  426: 	/*DisplayNameValueList(buffer, bufsize);*/
  427: 	ParseNameValue(buffer, bufsize, &pdata);
  428: 	free(buffer); buffer = NULL;
  429: 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
  430: 	if(resVal) {
  431: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  432: 		sscanf(resVal, "%d", &ret);
  433: 	} else {
  434: 		ret = UPNPCOMMAND_SUCCESS;
  435: 	}
  436: 	ClearNameValueList(&pdata);
  437: 	free(DeletePortMappingArgs);
  438: 	return ret;
  439: }
  440: 
  441: LIBSPEC int
  442: UPNP_GetGenericPortMappingEntry(const char * controlURL,
  443:                                 const char * servicetype,
  444: 							 const char * index,
  445: 							 char * extPort,
  446: 							 char * intClient,
  447: 							 char * intPort,
  448: 							 char * protocol,
  449: 							 char * desc,
  450: 							 char * enabled,
  451: 							 char * rHost,
  452: 							 char * duration)
  453: {
  454: 	struct NameValueParserData pdata;
  455: 	struct UPNParg * GetPortMappingArgs;
  456: 	char * buffer;
  457: 	int bufsize;
  458: 	char * p;
  459: 	int r = UPNPCOMMAND_UNKNOWN_ERROR;
  460: 	if(!index)
  461: 		return UPNPCOMMAND_INVALID_ARGS;
  462: 	intClient[0] = '\0';
  463: 	intPort[0] = '\0';
  464: 	GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
  465: 	GetPortMappingArgs[0].elt = "NewPortMappingIndex";
  466: 	GetPortMappingArgs[0].val = index;
  467: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  468: 	                               "GetGenericPortMappingEntry",
  469: 	                               GetPortMappingArgs, &bufsize))) {
  470: 		free(GetPortMappingArgs);
  471: 		return UPNPCOMMAND_HTTP_ERROR;
  472: 	}
  473: 	ParseNameValue(buffer, bufsize, &pdata);
  474: 	free(buffer); buffer = NULL;
  475: 
  476: 	p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
  477: 	if(p && rHost)
  478: 	{
  479: 		strncpy(rHost, p, 64);
  480: 		rHost[63] = '\0';
  481: 	}
  482: 	p = GetValueFromNameValueList(&pdata, "NewExternalPort");
  483: 	if(p && extPort)
  484: 	{
  485: 		strncpy(extPort, p, 6);
  486: 		extPort[5] = '\0';
  487: 		r = UPNPCOMMAND_SUCCESS;
  488: 	}
  489: 	p = GetValueFromNameValueList(&pdata, "NewProtocol");
  490: 	if(p && protocol)
  491: 	{
  492: 		strncpy(protocol, p, 4);
  493: 		protocol[3] = '\0';
  494: 	}
  495: 	p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  496: 	if(p && intClient)
  497: 	{
  498: 		strncpy(intClient, p, 16);
  499: 		intClient[15] = '\0';
  500: 		r = 0;
  501: 	}
  502: 	p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  503: 	if(p && intPort)
  504: 	{
  505: 		strncpy(intPort, p, 6);
  506: 		intPort[5] = '\0';
  507: 	}
  508: 	p = GetValueFromNameValueList(&pdata, "NewEnabled");
  509: 	if(p && enabled)
  510: 	{
  511: 		strncpy(enabled, p, 4);
  512: 		enabled[3] = '\0';
  513: 	}
  514: 	p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  515: 	if(p && desc)
  516: 	{
  517: 		strncpy(desc, p, 80);
  518: 		desc[79] = '\0';
  519: 	}
  520: 	p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  521: 	if(p && duration)
  522: 	{
  523: 		strncpy(duration, p, 16);
  524: 		duration[15] = '\0';
  525: 	}
  526: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  527: 	if(p) {
  528: 		r = UPNPCOMMAND_UNKNOWN_ERROR;
  529: 		sscanf(p, "%d", &r);
  530: 	}
  531: 	ClearNameValueList(&pdata);
  532: 	free(GetPortMappingArgs);
  533: 	return r;
  534: }
  535: 
  536: LIBSPEC int
  537: UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
  538:                                    const char * servicetype,
  539:                                    unsigned int * numEntries)
  540: {
  541:  	struct NameValueParserData pdata;
  542:  	char * buffer;
  543:  	int bufsize;
  544:  	char* p;
  545: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  546:  	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  547: 	                                "GetPortMappingNumberOfEntries", 0,
  548: 	                                &bufsize))) {
  549: 		return UPNPCOMMAND_HTTP_ERROR;
  550: 	}
  551: #ifdef DEBUG
  552: 	DisplayNameValueList(buffer, bufsize);
  553: #endif
  554:  	ParseNameValue(buffer, bufsize, &pdata);
  555: 	free(buffer); buffer = NULL;
  556: 
  557:  	p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
  558:  	if(numEntries && p) {
  559: 		*numEntries = 0;
  560:  		sscanf(p, "%u", numEntries);
  561: 		ret = UPNPCOMMAND_SUCCESS;
  562:  	}
  563: 
  564: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  565: 	if(p) {
  566: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  567: 		sscanf(p, "%d", &ret);
  568: 	}
  569: 
  570:  	ClearNameValueList(&pdata);
  571: 	return ret;
  572: }
  573: 
  574: /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
  575:  * the result is returned in the intClient and intPort strings
  576:  * please provide 16 and 6 bytes of data */
  577: LIBSPEC int
  578: UPNP_GetSpecificPortMappingEntry(const char * controlURL,
  579:                                  const char * servicetype,
  580:                                  const char * extPort,
  581: 							     const char * proto,
  582:                                  char * intClient,
  583:                                  char * intPort,
  584:                                  char * desc,
  585:                                  char * enabled,
  586:                                  char * leaseDuration)
  587: {
  588: 	struct NameValueParserData pdata;
  589: 	struct UPNParg * GetPortMappingArgs;
  590: 	char * buffer;
  591: 	int bufsize;
  592: 	char * p;
  593: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  594: 
  595: 	if(!intPort || !intClient || !extPort || !proto)
  596: 		return UPNPCOMMAND_INVALID_ARGS;
  597: 
  598: 	GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
  599: 	GetPortMappingArgs[0].elt = "NewRemoteHost";
  600: 	/* TODO : add remote host ? */
  601: 	GetPortMappingArgs[1].elt = "NewExternalPort";
  602: 	GetPortMappingArgs[1].val = extPort;
  603: 	GetPortMappingArgs[2].elt = "NewProtocol";
  604: 	GetPortMappingArgs[2].val = proto;
  605: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  606: 	                                "GetSpecificPortMappingEntry",
  607: 	                                GetPortMappingArgs, &bufsize))) {
  608: 		free(GetPortMappingArgs);
  609: 		return UPNPCOMMAND_HTTP_ERROR;
  610: 	}
  611: 	/*DisplayNameValueList(buffer, bufsize);*/
  612: 	ParseNameValue(buffer, bufsize, &pdata);
  613: 	free(buffer); buffer = NULL;
  614: 
  615: 	p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  616: 	if(p) {
  617: 		strncpy(intClient, p, 16);
  618: 		intClient[15] = '\0';
  619: 		ret = UPNPCOMMAND_SUCCESS;
  620: 	} else
  621: 		intClient[0] = '\0';
  622: 
  623: 	p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  624: 	if(p) {
  625: 		strncpy(intPort, p, 6);
  626: 		intPort[5] = '\0';
  627: 	} else
  628: 		intPort[0] = '\0';
  629: 
  630: 	p = GetValueFromNameValueList(&pdata, "NewEnabled");
  631: 	if(p && enabled) {
  632: 		strncpy(enabled, p, 4);
  633: 		enabled[3] = '\0';
  634: 	}
  635: 
  636: 	p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  637: 	if(p && desc) {
  638: 		strncpy(desc, p, 80);
  639: 		desc[79] = '\0';
  640: 	}
  641: 
  642: 	p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  643: 	if(p && leaseDuration)
  644: 	{
  645: 		strncpy(leaseDuration, p, 16);
  646: 		leaseDuration[15] = '\0';
  647: 	}
  648: 
  649: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  650: 	if(p) {
  651: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  652: 		sscanf(p, "%d", &ret);
  653: 	}
  654: 
  655: 	ClearNameValueList(&pdata);
  656: 	free(GetPortMappingArgs);
  657: 	return ret;
  658: }
  659: 
  660: /* UPNP_GetListOfPortMappings()
  661:  *
  662:  * Possible UPNP Error codes :
  663:  * 606 Action not Authorized
  664:  * 730 PortMappingNotFound - no port mapping is found in the specified range.
  665:  * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
  666:  *                              consistent.
  667:  */
  668: LIBSPEC int
  669: UPNP_GetListOfPortMappings(const char * controlURL,
  670:                            const char * servicetype,
  671:                            const char * startPort,
  672:                            const char * endPort,
  673:                            const char * protocol,
  674:                            const char * numberOfPorts,
  675:                            struct PortMappingParserData * data)
  676: {
  677: 	struct NameValueParserData pdata;
  678: 	struct UPNParg * GetListOfPortMappingsArgs;
  679: 	const char * p;
  680: 	char * buffer;
  681: 	int bufsize;
  682: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  683: 
  684: 	if(!startPort || !endPort || !protocol)
  685: 		return UPNPCOMMAND_INVALID_ARGS;
  686: 
  687: 	GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
  688: 	GetListOfPortMappingsArgs[0].elt = "NewStartPort";
  689: 	GetListOfPortMappingsArgs[0].val = startPort;
  690: 	GetListOfPortMappingsArgs[1].elt = "NewEndPort";
  691: 	GetListOfPortMappingsArgs[1].val = endPort;
  692: 	GetListOfPortMappingsArgs[2].elt = "NewProtocol";
  693: 	GetListOfPortMappingsArgs[2].val = protocol;
  694: 	GetListOfPortMappingsArgs[3].elt = "NewManage";
  695: 	GetListOfPortMappingsArgs[3].val = "1";
  696: 	GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
  697: 	GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
  698: 
  699: 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  700: 	                                "GetListOfPortMappings",
  701: 	                                GetListOfPortMappingsArgs, &bufsize))) {
  702: 		free(GetListOfPortMappingsArgs);
  703: 		return UPNPCOMMAND_HTTP_ERROR;
  704: 	}
  705: 	free(GetListOfPortMappingsArgs);
  706: 
  707: 	/*DisplayNameValueList(buffer, bufsize);*/
  708: 	ParseNameValue(buffer, bufsize, &pdata);
  709: 	free(buffer); buffer = NULL;
  710: 
  711: 	/*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
  712: 	/*if(p) {
  713: 		printf("NewPortListing : %s\n", p);
  714: 	}*/
  715: 	/*printf("NewPortListing(%d chars) : %s\n",
  716: 	       pdata.portListingLength, pdata.portListing);*/
  717: 	if(pdata.portListing)
  718: 	{
  719: 		/*struct PortMapping * pm;
  720: 		int i = 0;*/
  721: 		ParsePortListing(pdata.portListing, pdata.portListingLength,
  722: 		                 data);
  723: 		ret = UPNPCOMMAND_SUCCESS;
  724: 		/*
  725: 		for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
  726: 		{
  727: 			printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
  728: 			       i, pm->protocol, pm->externalPort, pm->internalClient,
  729: 			       pm->internalPort,
  730: 			       pm->description, pm->remoteHost);
  731: 			i++;
  732: 		}
  733: 		*/
  734: 		/*FreePortListing(&data);*/
  735: 	}
  736: 
  737: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  738: 	if(p) {
  739: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  740: 		sscanf(p, "%d", &ret);
  741: 	}
  742: 	ClearNameValueList(&pdata);
  743: 
  744: 	/*printf("%.*s", bufsize, buffer);*/
  745: 
  746: 	return ret;
  747: }
  748: 
  749: /* IGD:2, functions for service WANIPv6FirewallControl:1 */
  750: LIBSPEC int
  751: UPNP_GetFirewallStatus(const char * controlURL,
  752: 				const char * servicetype,
  753: 				int * firewallEnabled,
  754: 				int * inboundPinholeAllowed)
  755: {
  756: 	struct NameValueParserData pdata;
  757: 	char * buffer;
  758: 	int bufsize;
  759: 	char * fe, *ipa, *p;
  760: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  761: 
  762: 	if(!firewallEnabled && !inboundPinholeAllowed)
  763: 		return UPNPCOMMAND_INVALID_ARGS;
  764: 
  765: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  766: 	                           "GetFirewallStatus", 0, &bufsize);
  767: 	if(!buffer) {
  768: 		return UPNPCOMMAND_HTTP_ERROR;
  769: 	}
  770: 	ParseNameValue(buffer, bufsize, &pdata);
  771: 	free(buffer); buffer = NULL;
  772: 	fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
  773: 	ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
  774: 	if(ipa && fe)
  775: 		ret = UPNPCOMMAND_SUCCESS;
  776: 	if(fe)
  777: 		*firewallEnabled = my_atoui(fe);
  778: 	/*else
  779: 		*firewallEnabled = 0;*/
  780: 	if(ipa)
  781: 		*inboundPinholeAllowed = my_atoui(ipa);
  782: 	/*else
  783: 		*inboundPinholeAllowed = 0;*/
  784: 	p = GetValueFromNameValueList(&pdata, "errorCode");
  785: 	if(p)
  786: 	{
  787: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  788: 		sscanf(p, "%d", &ret);
  789: 	}
  790: 	ClearNameValueList(&pdata);
  791: 	return ret;
  792: }
  793: 
  794: LIBSPEC int
  795: UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
  796:                     const char * remoteHost,
  797:                     const char * remotePort,
  798:                     const char * intClient,
  799:                     const char * intPort,
  800:                     const char * proto,
  801:                     int * opTimeout)
  802: {
  803: 	struct UPNParg * GetOutboundPinholeTimeoutArgs;
  804: 	char * buffer;
  805: 	int bufsize;
  806: 	struct NameValueParserData pdata;
  807: 	const char * resVal;
  808: 	char * p;
  809: 	int ret;
  810: 
  811: 	if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
  812: 		return UPNPCOMMAND_INVALID_ARGS;
  813: 
  814: 	GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
  815: 	GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
  816: 	GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
  817: 	GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
  818: 	GetOutboundPinholeTimeoutArgs[1].val = remotePort;
  819: 	GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
  820: 	GetOutboundPinholeTimeoutArgs[2].val = proto;
  821: 	GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
  822: 	GetOutboundPinholeTimeoutArgs[3].val = intPort;
  823: 	GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
  824: 	GetOutboundPinholeTimeoutArgs[4].val = intClient;
  825: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  826: 	                           "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
  827: 	if(!buffer)
  828: 		return UPNPCOMMAND_HTTP_ERROR;
  829: 	ParseNameValue(buffer, bufsize, &pdata);
  830: 	free(buffer); buffer = NULL;
  831: 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
  832: 	if(resVal)
  833: 	{
  834: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  835: 		sscanf(resVal, "%d", &ret);
  836: 	}
  837: 	else
  838: 	{
  839: 		ret = UPNPCOMMAND_SUCCESS;
  840: 		p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
  841: 		if(p)
  842: 			*opTimeout = my_atoui(p);
  843: 	}
  844: 	ClearNameValueList(&pdata);
  845: 	free(GetOutboundPinholeTimeoutArgs);
  846: 	return ret;
  847: }
  848: 
  849: LIBSPEC int
  850: UPNP_AddPinhole(const char * controlURL, const char * servicetype,
  851:                     const char * remoteHost,
  852:                     const char * remotePort,
  853:                     const char * intClient,
  854:                     const char * intPort,
  855:                     const char * proto,
  856:                     const char * leaseTime,
  857:                     char * uniqueID)
  858: {
  859: 	struct UPNParg * AddPinholeArgs;
  860: 	char * buffer;
  861: 	int bufsize;
  862: 	struct NameValueParserData pdata;
  863: 	const char * resVal;
  864: 	char * p;
  865: 	int ret;
  866: 
  867: 	if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
  868: 		return UPNPCOMMAND_INVALID_ARGS;
  869: 
  870: 	AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
  871: 	/* RemoteHost can be wilcarded */
  872: 	if(strncmp(remoteHost, "empty", 5)==0)
  873: 	{
  874: 		AddPinholeArgs[0].elt = "RemoteHost";
  875: 		AddPinholeArgs[0].val = "";
  876: 	}
  877: 	else
  878: 	{
  879: 		AddPinholeArgs[0].elt = "RemoteHost";
  880: 		AddPinholeArgs[0].val = remoteHost;
  881: 	}
  882: 	AddPinholeArgs[1].elt = "RemotePort";
  883: 	AddPinholeArgs[1].val = remotePort;
  884: 	AddPinholeArgs[2].elt = "Protocol";
  885: 	AddPinholeArgs[2].val = proto;
  886: 	AddPinholeArgs[3].elt = "InternalPort";
  887: 	AddPinholeArgs[3].val = intPort;
  888: 	if(strncmp(intClient, "empty", 5)==0)
  889: 	{
  890: 		AddPinholeArgs[4].elt = "InternalClient";
  891: 		AddPinholeArgs[4].val = "";
  892: 	}
  893: 	else
  894: 	{
  895: 		AddPinholeArgs[4].elt = "InternalClient";
  896: 		AddPinholeArgs[4].val = intClient;
  897: 	}
  898: 	AddPinholeArgs[5].elt = "LeaseTime";
  899: 	AddPinholeArgs[5].val = leaseTime;
  900: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  901: 	                           "AddPinhole", AddPinholeArgs, &bufsize);
  902: 	if(!buffer)
  903: 		return UPNPCOMMAND_HTTP_ERROR;
  904: 	ParseNameValue(buffer, bufsize, &pdata);
  905: 	free(buffer); buffer = NULL;
  906: 	p = GetValueFromNameValueList(&pdata, "UniqueID");
  907: 	if(p)
  908: 	{
  909: 		strncpy(uniqueID, p, 8);
  910: 		uniqueID[7] = '\0';
  911: 	}
  912: 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
  913: 	if(resVal)
  914: 	{
  915: 		/*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
  916: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  917: 		sscanf(resVal, "%d", &ret);
  918: 	}
  919: 	else
  920: 	{
  921: 		ret = UPNPCOMMAND_SUCCESS;
  922: 	}
  923: 	ClearNameValueList(&pdata);
  924: 	free(AddPinholeArgs);
  925: 	return ret;
  926: }
  927: 
  928: LIBSPEC int
  929: UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
  930:                     const char * uniqueID,
  931:                     const char * leaseTime)
  932: {
  933: 	struct UPNParg * UpdatePinholeArgs;
  934: 	char * buffer;
  935: 	int bufsize;
  936: 	struct NameValueParserData pdata;
  937: 	const char * resVal;
  938: 	int ret;
  939: 
  940: 	if(!uniqueID || !leaseTime)
  941: 		return UPNPCOMMAND_INVALID_ARGS;
  942: 
  943: 	UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
  944: 	UpdatePinholeArgs[0].elt = "UniqueID";
  945: 	UpdatePinholeArgs[0].val = uniqueID;
  946: 	UpdatePinholeArgs[1].elt = "NewLeaseTime";
  947: 	UpdatePinholeArgs[1].val = leaseTime;
  948: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  949: 	                           "UpdatePinhole", UpdatePinholeArgs, &bufsize);
  950: 	if(!buffer)
  951: 		return UPNPCOMMAND_HTTP_ERROR;
  952: 	ParseNameValue(buffer, bufsize, &pdata);
  953: 	free(buffer); buffer = NULL;
  954: 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
  955: 	if(resVal)
  956: 	{
  957: 		/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  958: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  959: 		sscanf(resVal, "%d", &ret);
  960: 	}
  961: 	else
  962: 	{
  963: 		ret = UPNPCOMMAND_SUCCESS;
  964: 	}
  965: 	ClearNameValueList(&pdata);
  966: 	free(UpdatePinholeArgs);
  967: 	return ret;
  968: }
  969: 
  970: LIBSPEC int
  971: UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
  972: {
  973: 	/*struct NameValueParserData pdata;*/
  974: 	struct UPNParg * DeletePinholeArgs;
  975: 	char * buffer;
  976: 	int bufsize;
  977: 	struct NameValueParserData pdata;
  978: 	const char * resVal;
  979: 	int ret;
  980: 
  981: 	if(!uniqueID)
  982: 		return UPNPCOMMAND_INVALID_ARGS;
  983: 
  984: 	DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
  985: 	DeletePinholeArgs[0].elt = "UniqueID";
  986: 	DeletePinholeArgs[0].val = uniqueID;
  987: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  988: 	                           "DeletePinhole", DeletePinholeArgs, &bufsize);
  989: 	if(!buffer)
  990: 		return UPNPCOMMAND_HTTP_ERROR;
  991: 	/*DisplayNameValueList(buffer, bufsize);*/
  992: 	ParseNameValue(buffer, bufsize, &pdata);
  993: 	free(buffer); buffer = NULL;
  994: 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
  995: 	if(resVal)
  996: 	{
  997: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
  998: 		sscanf(resVal, "%d", &ret);
  999: 	}
 1000: 	else
 1001: 	{
 1002: 		ret = UPNPCOMMAND_SUCCESS;
 1003: 	}
 1004: 	ClearNameValueList(&pdata);
 1005: 	free(DeletePinholeArgs);
 1006: 	return ret;
 1007: }
 1008: 
 1009: LIBSPEC int
 1010: UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
 1011:                                  const char * uniqueID, int * isWorking)
 1012: {
 1013: 	struct NameValueParserData pdata;
 1014: 	struct UPNParg * CheckPinholeWorkingArgs;
 1015: 	char * buffer;
 1016: 	int bufsize;
 1017: 	char * p;
 1018: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
 1019: 
 1020: 	if(!uniqueID)
 1021: 		return UPNPCOMMAND_INVALID_ARGS;
 1022: 
 1023: 	CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
 1024: 	CheckPinholeWorkingArgs[0].elt = "UniqueID";
 1025: 	CheckPinholeWorkingArgs[0].val = uniqueID;
 1026: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
 1027: 	                           "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
 1028: 	if(!buffer)
 1029: 		return UPNPCOMMAND_HTTP_ERROR;
 1030: 	ParseNameValue(buffer, bufsize, &pdata);
 1031: 	free(buffer); buffer = NULL;
 1032: 
 1033: 	p = GetValueFromNameValueList(&pdata, "IsWorking");
 1034: 	if(p)
 1035: 	{
 1036: 		*isWorking=my_atoui(p);
 1037: 		ret = UPNPCOMMAND_SUCCESS;
 1038: 	}
 1039: 	else
 1040: 		*isWorking = 0;
 1041: 
 1042: 	p = GetValueFromNameValueList(&pdata, "errorCode");
 1043: 	if(p)
 1044: 	{
 1045: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
 1046: 		sscanf(p, "%d", &ret);
 1047: 	}
 1048: 
 1049: 	ClearNameValueList(&pdata);
 1050: 	free(CheckPinholeWorkingArgs);
 1051: 	return ret;
 1052: }
 1053: 
 1054: LIBSPEC int
 1055: UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
 1056:                                  const char * uniqueID, int * packets)
 1057: {
 1058: 	struct NameValueParserData pdata;
 1059: 	struct UPNParg * GetPinholePacketsArgs;
 1060: 	char * buffer;
 1061: 	int bufsize;
 1062: 	char * p;
 1063: 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
 1064: 
 1065: 	if(!uniqueID)
 1066: 		return UPNPCOMMAND_INVALID_ARGS;
 1067: 
 1068: 	GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
 1069: 	GetPinholePacketsArgs[0].elt = "UniqueID";
 1070: 	GetPinholePacketsArgs[0].val = uniqueID;
 1071: 	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
 1072: 	                           "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
 1073: 	if(!buffer)
 1074: 		return UPNPCOMMAND_HTTP_ERROR;
 1075: 	ParseNameValue(buffer, bufsize, &pdata);
 1076: 	free(buffer); buffer = NULL;
 1077: 
 1078: 	p = GetValueFromNameValueList(&pdata, "PinholePackets");
 1079: 	if(p)
 1080: 	{
 1081: 		*packets=my_atoui(p);
 1082: 		ret = UPNPCOMMAND_SUCCESS;
 1083: 	}
 1084: 
 1085: 	p = GetValueFromNameValueList(&pdata, "errorCode");
 1086: 	if(p)
 1087: 	{
 1088: 		ret = UPNPCOMMAND_UNKNOWN_ERROR;
 1089: 		sscanf(p, "%d", &ret);
 1090: 	}
 1091: 
 1092: 	ClearNameValueList(&pdata);
 1093: 	free(GetPinholePacketsArgs);
 1094: 	return ret;
 1095: }
 1096: 
 1097: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>