File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpc / src / upnpcommands.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:21:37 2023 UTC (8 months, 4 weeks ago) by misho
Branches: miniupnpc, MAIN
CVS tags: v2_2_5p0, HEAD
Version 2.2.5p0

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

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