transmission 2.83
[tomato.git] / release / src / router / transmission / third-party / miniupnp / upnpcommands.c
blobad69781050058d6c6fb049cdd322156110637285
1 /* $Id: upnpcommands.c,v 1.42 2014/01/31 13:18:25 nanard 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"
15 static UNSIGNED_INTEGER
16 my_atoui(const char * s)
18 return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
22 * */
23 LIBSPEC UNSIGNED_INTEGER
24 UPNP_GetTotalBytesSent(const char * controlURL,
25 const char * servicetype)
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;
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;
46 * */
47 LIBSPEC UNSIGNED_INTEGER
48 UPNP_GetTotalBytesReceived(const char * controlURL,
49 const char * servicetype)
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;
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;
70 * */
71 LIBSPEC UNSIGNED_INTEGER
72 UPNP_GetTotalPacketsSent(const char * controlURL,
73 const char * servicetype)
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;
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;
94 * */
95 LIBSPEC UNSIGNED_INTEGER
96 UPNP_GetTotalPacketsReceived(const char * controlURL,
97 const char * servicetype)
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;
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;
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)
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;
134 if(!status && !uptime)
135 return UPNPCOMMAND_INVALID_ARGS;
137 if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
138 "GetStatusInfo", 0, &bufsize))) {
139 return UPNPCOMMAND_HTTP_ERROR;
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;
150 if(status) {
151 if(p){
152 strncpy(status, p, 64 );
153 status[63] = '\0';
154 }else
155 status[0]= '\0';
158 if(uptime) {
159 if(up)
160 sscanf(up,"%u",uptime);
161 else
162 uptime = 0;
165 if(lastconnerror) {
166 if(err) {
167 strncpy(lastconnerror, err, 64 );
168 lastconnerror[63] = '\0';
169 } else
170 lastconnerror[0] = '\0';
173 p = GetValueFromNameValueList(&pdata, "errorCode");
174 if(p) {
175 ret = UPNPCOMMAND_UNKNOWN_ERROR;
176 sscanf(p, "%d", &ret);
178 ClearNameValueList(&pdata);
179 return ret;
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)
189 struct NameValueParserData pdata;
190 char * buffer;
191 int bufsize;
192 char * p;
193 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
195 if(!connectionType)
196 return UPNPCOMMAND_INVALID_ARGS;
198 if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
199 "GetConnectionTypeInfo", 0, &bufsize))) {
200 return UPNPCOMMAND_HTTP_ERROR;
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);
218 ClearNameValueList(&pdata);
219 return ret;
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)
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;
241 if(!bitrateDown && !bitrateUp)
242 return UPNPCOMMAND_INVALID_ARGS;
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;
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;
262 if(bitrateDown) {
263 if(down)
264 sscanf(down,"%u",bitrateDown);
265 else
266 *bitrateDown = 0;
269 if(bitrateUp) {
270 if(up)
271 sscanf(up,"%u",bitrateUp);
272 else
273 *bitrateUp = 0;
275 p = GetValueFromNameValueList(&pdata, "errorCode");
276 if(p) {
277 ret = UPNPCOMMAND_UNKNOWN_ERROR;
278 sscanf(p, "%d", &ret);
280 ClearNameValueList(&pdata);
281 return ret;
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
289 * Return values :
290 * 0 : SUCCESS
291 * NON ZERO : ERROR Either an UPnP error code or an unknown error.
293 * 402 Invalid Args - See UPnP Device Architecture section on Control.
294 * 501 Action Failed - See UPnP Device Architecture section on Control.
296 LIBSPEC int
297 UPNP_GetExternalIPAddress(const char * controlURL,
298 const char * servicetype,
299 char * extIpAdd)
301 struct NameValueParserData pdata;
302 char * buffer;
303 int bufsize;
304 char * p;
305 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
307 if(!extIpAdd || !controlURL || !servicetype)
308 return UPNPCOMMAND_INVALID_ARGS;
310 if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
311 "GetExternalIPAddress", 0, &bufsize))) {
312 return UPNPCOMMAND_HTTP_ERROR;
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';
326 p = GetValueFromNameValueList(&pdata, "errorCode");
327 if(p) {
328 ret = UPNPCOMMAND_UNKNOWN_ERROR;
329 sscanf(p, "%d", &ret);
332 ClearNameValueList(&pdata);
333 return ret;
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)
346 struct UPNParg * AddPortMappingArgs;
347 char * buffer;
348 int bufsize;
349 struct NameValueParserData pdata;
350 const char * resVal;
351 int ret;
353 if(!inPort || !inClient || !proto || !extPort)
354 return UPNPCOMMAND_INVALID_ARGS;
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;
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;
392 ClearNameValueList(&pdata);
393 free(AddPortMappingArgs);
394 return ret;
397 LIBSPEC int
398 UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
399 const char * extPort, const char * proto,
400 const char * remoteHost)
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;
410 if(!extPort || !proto)
411 return UPNPCOMMAND_INVALID_ARGS;
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;
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;
436 ClearNameValueList(&pdata);
437 free(DeletePortMappingArgs);
438 return ret;
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)
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;
473 ParseNameValue(buffer, bufsize, &pdata);
474 free(buffer); buffer = NULL;
476 p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
477 if(p && rHost)
479 strncpy(rHost, p, 64);
480 rHost[63] = '\0';
482 p = GetValueFromNameValueList(&pdata, "NewExternalPort");
483 if(p && extPort)
485 strncpy(extPort, p, 6);
486 extPort[5] = '\0';
487 r = UPNPCOMMAND_SUCCESS;
489 p = GetValueFromNameValueList(&pdata, "NewProtocol");
490 if(p && protocol)
492 strncpy(protocol, p, 4);
493 protocol[3] = '\0';
495 p = GetValueFromNameValueList(&pdata, "NewInternalClient");
496 if(p && intClient)
498 strncpy(intClient, p, 16);
499 intClient[15] = '\0';
500 r = 0;
502 p = GetValueFromNameValueList(&pdata, "NewInternalPort");
503 if(p && intPort)
505 strncpy(intPort, p, 6);
506 intPort[5] = '\0';
508 p = GetValueFromNameValueList(&pdata, "NewEnabled");
509 if(p && enabled)
511 strncpy(enabled, p, 4);
512 enabled[3] = '\0';
514 p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
515 if(p && desc)
517 strncpy(desc, p, 80);
518 desc[79] = '\0';
520 p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
521 if(p && duration)
523 strncpy(duration, p, 16);
524 duration[15] = '\0';
526 p = GetValueFromNameValueList(&pdata, "errorCode");
527 if(p) {
528 r = UPNPCOMMAND_UNKNOWN_ERROR;
529 sscanf(p, "%d", &r);
531 ClearNameValueList(&pdata);
532 free(GetPortMappingArgs);
533 return r;
536 LIBSPEC int
537 UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
538 const char * servicetype,
539 unsigned int * numEntries)
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;
551 #ifdef DEBUG
552 DisplayNameValueList(buffer, bufsize);
553 #endif
554 ParseNameValue(buffer, bufsize, &pdata);
555 free(buffer); buffer = NULL;
557 p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
558 if(numEntries && p) {
559 *numEntries = 0;
560 sscanf(p, "%u", numEntries);
561 ret = UPNPCOMMAND_SUCCESS;
564 p = GetValueFromNameValueList(&pdata, "errorCode");
565 if(p) {
566 ret = UPNPCOMMAND_UNKNOWN_ERROR;
567 sscanf(p, "%d", &ret);
570 ClearNameValueList(&pdata);
571 return ret;
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 const char * remoteHost,
583 char * intClient,
584 char * intPort,
585 char * desc,
586 char * enabled,
587 char * leaseDuration)
589 struct NameValueParserData pdata;
590 struct UPNParg * GetPortMappingArgs;
591 char * buffer;
592 int bufsize;
593 char * p;
594 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
596 if(!intPort || !intClient || !extPort || !proto)
597 return UPNPCOMMAND_INVALID_ARGS;
599 GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
600 GetPortMappingArgs[0].elt = "NewRemoteHost";
601 GetPortMappingArgs[0].val = remoteHost;
602 GetPortMappingArgs[1].elt = "NewExternalPort";
603 GetPortMappingArgs[1].val = extPort;
604 GetPortMappingArgs[2].elt = "NewProtocol";
605 GetPortMappingArgs[2].val = proto;
606 if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
607 "GetSpecificPortMappingEntry",
608 GetPortMappingArgs, &bufsize))) {
609 free(GetPortMappingArgs);
610 return UPNPCOMMAND_HTTP_ERROR;
612 /*DisplayNameValueList(buffer, bufsize);*/
613 ParseNameValue(buffer, bufsize, &pdata);
614 free(buffer); buffer = NULL;
616 p = GetValueFromNameValueList(&pdata, "NewInternalClient");
617 if(p) {
618 strncpy(intClient, p, 16);
619 intClient[15] = '\0';
620 ret = UPNPCOMMAND_SUCCESS;
621 } else
622 intClient[0] = '\0';
624 p = GetValueFromNameValueList(&pdata, "NewInternalPort");
625 if(p) {
626 strncpy(intPort, p, 6);
627 intPort[5] = '\0';
628 } else
629 intPort[0] = '\0';
631 p = GetValueFromNameValueList(&pdata, "NewEnabled");
632 if(p && enabled) {
633 strncpy(enabled, p, 4);
634 enabled[3] = '\0';
637 p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
638 if(p && desc) {
639 strncpy(desc, p, 80);
640 desc[79] = '\0';
643 p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
644 if(p && leaseDuration)
646 strncpy(leaseDuration, p, 16);
647 leaseDuration[15] = '\0';
650 p = GetValueFromNameValueList(&pdata, "errorCode");
651 if(p) {
652 ret = UPNPCOMMAND_UNKNOWN_ERROR;
653 sscanf(p, "%d", &ret);
656 ClearNameValueList(&pdata);
657 free(GetPortMappingArgs);
658 return ret;
661 /* UPNP_GetListOfPortMappings()
663 * Possible UPNP Error codes :
664 * 606 Action not Authorized
665 * 730 PortMappingNotFound - no port mapping is found in the specified range.
666 * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
667 * consistent.
669 LIBSPEC int
670 UPNP_GetListOfPortMappings(const char * controlURL,
671 const char * servicetype,
672 const char * startPort,
673 const char * endPort,
674 const char * protocol,
675 const char * numberOfPorts,
676 struct PortMappingParserData * data)
678 struct NameValueParserData pdata;
679 struct UPNParg * GetListOfPortMappingsArgs;
680 const char * p;
681 char * buffer;
682 int bufsize;
683 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
685 if(!startPort || !endPort || !protocol)
686 return UPNPCOMMAND_INVALID_ARGS;
688 GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
689 GetListOfPortMappingsArgs[0].elt = "NewStartPort";
690 GetListOfPortMappingsArgs[0].val = startPort;
691 GetListOfPortMappingsArgs[1].elt = "NewEndPort";
692 GetListOfPortMappingsArgs[1].val = endPort;
693 GetListOfPortMappingsArgs[2].elt = "NewProtocol";
694 GetListOfPortMappingsArgs[2].val = protocol;
695 GetListOfPortMappingsArgs[3].elt = "NewManage";
696 GetListOfPortMappingsArgs[3].val = "1";
697 GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
698 GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
700 if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
701 "GetListOfPortMappings",
702 GetListOfPortMappingsArgs, &bufsize))) {
703 free(GetListOfPortMappingsArgs);
704 return UPNPCOMMAND_HTTP_ERROR;
706 free(GetListOfPortMappingsArgs);
708 /*DisplayNameValueList(buffer, bufsize);*/
709 ParseNameValue(buffer, bufsize, &pdata);
710 free(buffer); buffer = NULL;
712 /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
713 /*if(p) {
714 printf("NewPortListing : %s\n", p);
716 /*printf("NewPortListing(%d chars) : %s\n",
717 pdata.portListingLength, pdata.portListing);*/
718 if(pdata.portListing)
720 /*struct PortMapping * pm;
721 int i = 0;*/
722 ParsePortListing(pdata.portListing, pdata.portListingLength,
723 data);
724 ret = UPNPCOMMAND_SUCCESS;
726 for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
728 printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
729 i, pm->protocol, pm->externalPort, pm->internalClient,
730 pm->internalPort,
731 pm->description, pm->remoteHost);
732 i++;
735 /*FreePortListing(&data);*/
738 p = GetValueFromNameValueList(&pdata, "errorCode");
739 if(p) {
740 ret = UPNPCOMMAND_UNKNOWN_ERROR;
741 sscanf(p, "%d", &ret);
743 ClearNameValueList(&pdata);
745 /*printf("%.*s", bufsize, buffer);*/
747 return ret;
750 /* IGD:2, functions for service WANIPv6FirewallControl:1 */
751 LIBSPEC int
752 UPNP_GetFirewallStatus(const char * controlURL,
753 const char * servicetype,
754 int * firewallEnabled,
755 int * inboundPinholeAllowed)
757 struct NameValueParserData pdata;
758 char * buffer;
759 int bufsize;
760 char * fe, *ipa, *p;
761 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
763 if(!firewallEnabled || !inboundPinholeAllowed)
764 return UPNPCOMMAND_INVALID_ARGS;
766 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
767 "GetFirewallStatus", 0, &bufsize);
768 if(!buffer) {
769 return UPNPCOMMAND_HTTP_ERROR;
771 ParseNameValue(buffer, bufsize, &pdata);
772 free(buffer); buffer = NULL;
773 fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
774 ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
775 if(ipa && fe)
776 ret = UPNPCOMMAND_SUCCESS;
777 if(fe)
778 *firewallEnabled = my_atoui(fe);
779 /*else
780 *firewallEnabled = 0;*/
781 if(ipa)
782 *inboundPinholeAllowed = my_atoui(ipa);
783 /*else
784 *inboundPinholeAllowed = 0;*/
785 p = GetValueFromNameValueList(&pdata, "errorCode");
786 if(p)
788 ret = UPNPCOMMAND_UNKNOWN_ERROR;
789 sscanf(p, "%d", &ret);
791 ClearNameValueList(&pdata);
792 return ret;
795 LIBSPEC int
796 UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
797 const char * remoteHost,
798 const char * remotePort,
799 const char * intClient,
800 const char * intPort,
801 const char * proto,
802 int * opTimeout)
804 struct UPNParg * GetOutboundPinholeTimeoutArgs;
805 char * buffer;
806 int bufsize;
807 struct NameValueParserData pdata;
808 const char * resVal;
809 char * p;
810 int ret;
812 if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
813 return UPNPCOMMAND_INVALID_ARGS;
815 GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
816 GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
817 GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
818 GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
819 GetOutboundPinholeTimeoutArgs[1].val = remotePort;
820 GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
821 GetOutboundPinholeTimeoutArgs[2].val = proto;
822 GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
823 GetOutboundPinholeTimeoutArgs[3].val = intPort;
824 GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
825 GetOutboundPinholeTimeoutArgs[4].val = intClient;
826 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
827 "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
828 if(!buffer)
829 return UPNPCOMMAND_HTTP_ERROR;
830 ParseNameValue(buffer, bufsize, &pdata);
831 free(buffer); buffer = NULL;
832 resVal = GetValueFromNameValueList(&pdata, "errorCode");
833 if(resVal)
835 ret = UPNPCOMMAND_UNKNOWN_ERROR;
836 sscanf(resVal, "%d", &ret);
838 else
840 ret = UPNPCOMMAND_SUCCESS;
841 p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
842 if(p)
843 *opTimeout = my_atoui(p);
845 ClearNameValueList(&pdata);
846 free(GetOutboundPinholeTimeoutArgs);
847 return ret;
850 LIBSPEC int
851 UPNP_AddPinhole(const char * controlURL, const char * servicetype,
852 const char * remoteHost,
853 const char * remotePort,
854 const char * intClient,
855 const char * intPort,
856 const char * proto,
857 const char * leaseTime,
858 char * uniqueID)
860 struct UPNParg * AddPinholeArgs;
861 char * buffer;
862 int bufsize;
863 struct NameValueParserData pdata;
864 const char * resVal;
865 char * p;
866 int ret;
868 if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
869 return UPNPCOMMAND_INVALID_ARGS;
871 AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
872 /* RemoteHost can be wilcarded */
873 if(strncmp(remoteHost, "empty", 5)==0)
875 AddPinholeArgs[0].elt = "RemoteHost";
876 AddPinholeArgs[0].val = "";
878 else
880 AddPinholeArgs[0].elt = "RemoteHost";
881 AddPinholeArgs[0].val = remoteHost;
883 AddPinholeArgs[1].elt = "RemotePort";
884 AddPinholeArgs[1].val = remotePort;
885 AddPinholeArgs[2].elt = "Protocol";
886 AddPinholeArgs[2].val = proto;
887 AddPinholeArgs[3].elt = "InternalPort";
888 AddPinholeArgs[3].val = intPort;
889 if(strncmp(intClient, "empty", 5)==0)
891 AddPinholeArgs[4].elt = "InternalClient";
892 AddPinholeArgs[4].val = "";
894 else
896 AddPinholeArgs[4].elt = "InternalClient";
897 AddPinholeArgs[4].val = intClient;
899 AddPinholeArgs[5].elt = "LeaseTime";
900 AddPinholeArgs[5].val = leaseTime;
901 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
902 "AddPinhole", AddPinholeArgs, &bufsize);
903 if(!buffer)
904 return UPNPCOMMAND_HTTP_ERROR;
905 ParseNameValue(buffer, bufsize, &pdata);
906 free(buffer); buffer = NULL;
907 p = GetValueFromNameValueList(&pdata, "UniqueID");
908 if(p)
910 strncpy(uniqueID, p, 8);
911 uniqueID[7] = '\0';
913 resVal = GetValueFromNameValueList(&pdata, "errorCode");
914 if(resVal)
916 /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
917 ret = UPNPCOMMAND_UNKNOWN_ERROR;
918 sscanf(resVal, "%d", &ret);
920 else
922 ret = UPNPCOMMAND_SUCCESS;
924 ClearNameValueList(&pdata);
925 free(AddPinholeArgs);
926 return ret;
929 LIBSPEC int
930 UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
931 const char * uniqueID,
932 const char * leaseTime)
934 struct UPNParg * UpdatePinholeArgs;
935 char * buffer;
936 int bufsize;
937 struct NameValueParserData pdata;
938 const char * resVal;
939 int ret;
941 if(!uniqueID || !leaseTime)
942 return UPNPCOMMAND_INVALID_ARGS;
944 UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
945 UpdatePinholeArgs[0].elt = "UniqueID";
946 UpdatePinholeArgs[0].val = uniqueID;
947 UpdatePinholeArgs[1].elt = "NewLeaseTime";
948 UpdatePinholeArgs[1].val = leaseTime;
949 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
950 "UpdatePinhole", UpdatePinholeArgs, &bufsize);
951 if(!buffer)
952 return UPNPCOMMAND_HTTP_ERROR;
953 ParseNameValue(buffer, bufsize, &pdata);
954 free(buffer); buffer = NULL;
955 resVal = GetValueFromNameValueList(&pdata, "errorCode");
956 if(resVal)
958 /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
959 ret = UPNPCOMMAND_UNKNOWN_ERROR;
960 sscanf(resVal, "%d", &ret);
962 else
964 ret = UPNPCOMMAND_SUCCESS;
966 ClearNameValueList(&pdata);
967 free(UpdatePinholeArgs);
968 return ret;
971 LIBSPEC int
972 UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
974 /*struct NameValueParserData pdata;*/
975 struct UPNParg * DeletePinholeArgs;
976 char * buffer;
977 int bufsize;
978 struct NameValueParserData pdata;
979 const char * resVal;
980 int ret;
982 if(!uniqueID)
983 return UPNPCOMMAND_INVALID_ARGS;
985 DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
986 DeletePinholeArgs[0].elt = "UniqueID";
987 DeletePinholeArgs[0].val = uniqueID;
988 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
989 "DeletePinhole", DeletePinholeArgs, &bufsize);
990 if(!buffer)
991 return UPNPCOMMAND_HTTP_ERROR;
992 /*DisplayNameValueList(buffer, bufsize);*/
993 ParseNameValue(buffer, bufsize, &pdata);
994 free(buffer); buffer = NULL;
995 resVal = GetValueFromNameValueList(&pdata, "errorCode");
996 if(resVal)
998 ret = UPNPCOMMAND_UNKNOWN_ERROR;
999 sscanf(resVal, "%d", &ret);
1001 else
1003 ret = UPNPCOMMAND_SUCCESS;
1005 ClearNameValueList(&pdata);
1006 free(DeletePinholeArgs);
1007 return ret;
1010 LIBSPEC int
1011 UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
1012 const char * uniqueID, int * isWorking)
1014 struct NameValueParserData pdata;
1015 struct UPNParg * CheckPinholeWorkingArgs;
1016 char * buffer;
1017 int bufsize;
1018 char * p;
1019 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
1021 if(!uniqueID)
1022 return UPNPCOMMAND_INVALID_ARGS;
1024 CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
1025 CheckPinholeWorkingArgs[0].elt = "UniqueID";
1026 CheckPinholeWorkingArgs[0].val = uniqueID;
1027 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
1028 "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
1029 if(!buffer)
1030 return UPNPCOMMAND_HTTP_ERROR;
1031 ParseNameValue(buffer, bufsize, &pdata);
1032 free(buffer); buffer = NULL;
1034 p = GetValueFromNameValueList(&pdata, "IsWorking");
1035 if(p)
1037 *isWorking=my_atoui(p);
1038 ret = UPNPCOMMAND_SUCCESS;
1040 else
1041 *isWorking = 0;
1043 p = GetValueFromNameValueList(&pdata, "errorCode");
1044 if(p)
1046 ret = UPNPCOMMAND_UNKNOWN_ERROR;
1047 sscanf(p, "%d", &ret);
1050 ClearNameValueList(&pdata);
1051 free(CheckPinholeWorkingArgs);
1052 return ret;
1055 LIBSPEC int
1056 UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
1057 const char * uniqueID, int * packets)
1059 struct NameValueParserData pdata;
1060 struct UPNParg * GetPinholePacketsArgs;
1061 char * buffer;
1062 int bufsize;
1063 char * p;
1064 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
1066 if(!uniqueID)
1067 return UPNPCOMMAND_INVALID_ARGS;
1069 GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
1070 GetPinholePacketsArgs[0].elt = "UniqueID";
1071 GetPinholePacketsArgs[0].val = uniqueID;
1072 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
1073 "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
1074 if(!buffer)
1075 return UPNPCOMMAND_HTTP_ERROR;
1076 ParseNameValue(buffer, bufsize, &pdata);
1077 free(buffer); buffer = NULL;
1079 p = GetValueFromNameValueList(&pdata, "PinholePackets");
1080 if(p)
1082 *packets=my_atoui(p);
1083 ret = UPNPCOMMAND_SUCCESS;
1086 p = GetValueFromNameValueList(&pdata, "errorCode");
1087 if(p)
1089 ret = UPNPCOMMAND_UNKNOWN_ERROR;
1090 sscanf(p, "%d", &ret);
1093 ClearNameValueList(&pdata);
1094 free(GetPinholePacketsArgs);
1095 return ret;