source: trunk/third-party/miniupnp/upnpcommands.c @ 12593

Last change on this file since 12593 was 12593, checked in by livings124, 10 years ago

#4387 Update miniupnpc to 1.6

File size: 30.1 KB
Line 
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
15static UNSIGNED_INTEGER
16my_atoui(const char * s)
17{
18        return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
19}
20
21/*
22 * */
23LIBSPEC UNSIGNED_INTEGER
24UPNP_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 * */
47LIBSPEC UNSIGNED_INTEGER
48UPNP_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 * */
71LIBSPEC UNSIGNED_INTEGER
72UPNP_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 * */
95LIBSPEC UNSIGNED_INTEGER
96UPNP_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 */
119LIBSPEC int
120UPNP_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 */
184LIBSPEC int
185UPNP_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 */
227LIBSPEC int
228UPNP_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 */
296LIBSPEC int
297UPNP_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
336LIBSPEC int
337UPNP_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
397LIBSPEC int
398UPNP_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
441LIBSPEC int
442UPNP_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
536LIBSPEC int
537UPNP_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 */
577LIBSPEC int
578UPNP_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 */
668LIBSPEC int
669UPNP_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 */ 
750LIBSPEC int
751UPNP_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
794LIBSPEC int
795UPNP_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
849LIBSPEC int
850UPNP_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
928LIBSPEC int
929UPNP_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
970LIBSPEC int
971UPNP_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
1009LIBSPEC int
1010UPNP_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
1054LIBSPEC int
1055UPNP_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
Note: See TracBrowser for help on using the repository browser.