transmission 2.51 update
[tomato.git] / release / src / router / transmission / third-party / miniupnp / upnpcommands.c
blob6928de6d03d7b6920ef5c3a5374dbbb7506cc535
1 /* $Id: upnpcommands.c,v 1.38 2012/03/05 19:42:47 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"
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 char * intClient,
583 char * intPort,
584 char * desc,
585 char * enabled,
586 char * leaseDuration)
588 struct NameValueParserData pdata;
589 struct UPNParg * GetPortMappingArgs;
590 char * buffer;
591 int bufsize;
592 char * p;
593 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
595 if(!intPort || !intClient || !extPort || !proto)
596 return UPNPCOMMAND_INVALID_ARGS;
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;
611 /*DisplayNameValueList(buffer, bufsize);*/
612 ParseNameValue(buffer, bufsize, &pdata);
613 free(buffer); buffer = NULL;
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';
623 p = GetValueFromNameValueList(&pdata, "NewInternalPort");
624 if(p) {
625 strncpy(intPort, p, 6);
626 intPort[5] = '\0';
627 } else
628 intPort[0] = '\0';
630 p = GetValueFromNameValueList(&pdata, "NewEnabled");
631 if(p && enabled) {
632 strncpy(enabled, p, 4);
633 enabled[3] = '\0';
636 p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
637 if(p && desc) {
638 strncpy(desc, p, 80);
639 desc[79] = '\0';
642 p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
643 if(p && leaseDuration)
645 strncpy(leaseDuration, p, 16);
646 leaseDuration[15] = '\0';
649 p = GetValueFromNameValueList(&pdata, "errorCode");
650 if(p) {
651 ret = UPNPCOMMAND_UNKNOWN_ERROR;
652 sscanf(p, "%d", &ret);
655 ClearNameValueList(&pdata);
656 free(GetPortMappingArgs);
657 return ret;
660 /* UPNP_GetListOfPortMappings()
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.
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)
677 struct NameValueParserData pdata;
678 struct UPNParg * GetListOfPortMappingsArgs;
679 const char * p;
680 char * buffer;
681 int bufsize;
682 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
684 if(!startPort || !endPort || !protocol)
685 return UPNPCOMMAND_INVALID_ARGS;
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";
699 if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
700 "GetListOfPortMappings",
701 GetListOfPortMappingsArgs, &bufsize))) {
702 free(GetListOfPortMappingsArgs);
703 return UPNPCOMMAND_HTTP_ERROR;
705 free(GetListOfPortMappingsArgs);
707 /*DisplayNameValueList(buffer, bufsize);*/
708 ParseNameValue(buffer, bufsize, &pdata);
709 free(buffer); buffer = NULL;
711 /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
712 /*if(p) {
713 printf("NewPortListing : %s\n", p);
715 /*printf("NewPortListing(%d chars) : %s\n",
716 pdata.portListingLength, pdata.portListing);*/
717 if(pdata.portListing)
719 /*struct PortMapping * pm;
720 int i = 0;*/
721 ParsePortListing(pdata.portListing, pdata.portListingLength,
722 data);
723 ret = UPNPCOMMAND_SUCCESS;
725 for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
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++;
734 /*FreePortListing(&data);*/
737 p = GetValueFromNameValueList(&pdata, "errorCode");
738 if(p) {
739 ret = UPNPCOMMAND_UNKNOWN_ERROR;
740 sscanf(p, "%d", &ret);
742 ClearNameValueList(&pdata);
744 //printf("%.*s", bufsize, buffer);
746 return ret;
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)
756 struct NameValueParserData pdata;
757 char * buffer;
758 int bufsize;
759 char * fe, *ipa, *p;
760 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
762 if(!firewallEnabled && !inboundPinholeAllowed)
763 return UPNPCOMMAND_INVALID_ARGS;
765 buffer = simpleUPnPcommand(-1, controlURL, servicetype,
766 "GetFirewallStatus", 0, &bufsize);
767 if(!buffer) {
768 return UPNPCOMMAND_HTTP_ERROR;
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)
787 ret = UPNPCOMMAND_UNKNOWN_ERROR;
788 sscanf(p, "%d", &ret);
790 ClearNameValueList(&pdata);
791 return ret;
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)
803 struct UPNParg * GetOutboundPinholeTimeoutArgs;
804 char * buffer;
805 int bufsize;
806 struct NameValueParserData pdata;
807 const char * resVal;
808 char * p;
809 int ret;
811 if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
812 return UPNPCOMMAND_INVALID_ARGS;
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)
834 ret = UPNPCOMMAND_UNKNOWN_ERROR;
835 sscanf(resVal, "%d", &ret);
837 else
839 ret = UPNPCOMMAND_SUCCESS;
840 p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
841 if(p)
842 *opTimeout = my_atoui(p);
844 ClearNameValueList(&pdata);
845 free(GetOutboundPinholeTimeoutArgs);
846 return ret;
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)
859 struct UPNParg * AddPinholeArgs;
860 char * buffer;
861 int bufsize;
862 struct NameValueParserData pdata;
863 const char * resVal;
864 char * p;
865 int ret;
867 if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
868 return UPNPCOMMAND_INVALID_ARGS;
870 AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
871 // RemoteHost can be wilcarded
872 if(strncmp(remoteHost, "empty", 5)==0)
874 AddPinholeArgs[0].elt = "RemoteHost";
875 AddPinholeArgs[0].val = "";
877 else
879 AddPinholeArgs[0].elt = "RemoteHost";
880 AddPinholeArgs[0].val = remoteHost;
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)
890 AddPinholeArgs[4].elt = "InternalClient";
891 AddPinholeArgs[4].val = "";
893 else
895 AddPinholeArgs[4].elt = "InternalClient";
896 AddPinholeArgs[4].val = intClient;
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)
909 strncpy(uniqueID, p, 8);
910 uniqueID[7] = '\0';
912 resVal = GetValueFromNameValueList(&pdata, "errorCode");
913 if(resVal)
915 //printf("AddPortMapping errorCode = '%s'\n", resVal);
916 ret = UPNPCOMMAND_UNKNOWN_ERROR;
917 sscanf(resVal, "%d", &ret);
919 else
921 ret = UPNPCOMMAND_SUCCESS;
923 ClearNameValueList(&pdata);
924 free(AddPinholeArgs);
925 return ret;
928 LIBSPEC int
929 UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
930 const char * uniqueID,
931 const char * leaseTime)
933 struct UPNParg * UpdatePinholeArgs;
934 char * buffer;
935 int bufsize;
936 struct NameValueParserData pdata;
937 const char * resVal;
938 int ret;
940 if(!uniqueID || !leaseTime)
941 return UPNPCOMMAND_INVALID_ARGS;
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)
957 /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
958 ret = UPNPCOMMAND_UNKNOWN_ERROR;
959 sscanf(resVal, "%d", &ret);
961 else
963 ret = UPNPCOMMAND_SUCCESS;
965 ClearNameValueList(&pdata);
966 free(UpdatePinholeArgs);
967 return ret;
970 LIBSPEC int
971 UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
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;
981 if(!uniqueID)
982 return UPNPCOMMAND_INVALID_ARGS;
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)
997 ret = UPNPCOMMAND_UNKNOWN_ERROR;
998 sscanf(resVal, "%d", &ret);
1000 else
1002 ret = UPNPCOMMAND_SUCCESS;
1004 ClearNameValueList(&pdata);
1005 free(DeletePinholeArgs);
1006 return ret;
1009 LIBSPEC int
1010 UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
1011 const char * uniqueID, int * isWorking)
1013 struct NameValueParserData pdata;
1014 struct UPNParg * CheckPinholeWorkingArgs;
1015 char * buffer;
1016 int bufsize;
1017 char * p;
1018 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
1020 if(!uniqueID)
1021 return UPNPCOMMAND_INVALID_ARGS;
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;
1033 p = GetValueFromNameValueList(&pdata, "IsWorking");
1034 if(p)
1036 *isWorking=my_atoui(p);
1037 ret = UPNPCOMMAND_SUCCESS;
1039 else
1040 *isWorking = 0;
1042 p = GetValueFromNameValueList(&pdata, "errorCode");
1043 if(p)
1045 ret = UPNPCOMMAND_UNKNOWN_ERROR;
1046 sscanf(p, "%d", &ret);
1049 ClearNameValueList(&pdata);
1050 free(CheckPinholeWorkingArgs);
1051 return ret;
1054 LIBSPEC int
1055 UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
1056 const char * uniqueID, int * packets)
1058 struct NameValueParserData pdata;
1059 struct UPNParg * GetPinholePacketsArgs;
1060 char * buffer;
1061 int bufsize;
1062 char * p;
1063 int ret = UPNPCOMMAND_UNKNOWN_ERROR;
1065 if(!uniqueID)
1066 return UPNPCOMMAND_INVALID_ARGS;
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;
1078 p = GetValueFromNameValueList(&pdata, "PinholePackets");
1079 if(p)
1081 *packets=my_atoui(p);
1082 ret = UPNPCOMMAND_SUCCESS;
1085 p = GetValueFromNameValueList(&pdata, "errorCode");
1086 if(p)
1088 ret = UPNPCOMMAND_UNKNOWN_ERROR;
1089 sscanf(p, "%d", &ret);
1092 ClearNameValueList(&pdata);
1093 free(GetPinholePacketsArgs);
1094 return ret;