Annotation of embedaddon/miniupnpc/upnpcommands.c, revision 1.1.1.1
1.1 misho 1: /* $Id: upnpcommands.c,v 1.37 2011/06/04 15:56:23 nanard Exp $ */
2: /* Project : miniupnp
3: * Author : Thomas Bernard
4: * Copyright (c) 2005-2011 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>