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

Last change on this file since 10739 was 10739, checked in by livings124, 11 years ago

update miniupnpc to 20100609

File size: 16.7 KB
Line 
1/* $Id: upnpcommands.c,v 1.26 2010/06/09 10:59:09 nanard Exp $ */
2/* Project : miniupnp
3 * Author : Thomas Bernard
4 * Copyright (c) 2005-2010 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
14static UNSIGNED_INTEGER
15my_atoui(const char * s)
16{
17        return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
18}
19
20/*
21 * */
22LIBSPEC UNSIGNED_INTEGER
23UPNP_GetTotalBytesSent(const char * controlURL,
24                                        const char * servicetype)
25{
26        struct NameValueParserData pdata;
27        char buffer[4096];
28        int bufsize = 4096;
29        unsigned int r = 0;
30        char * p;
31        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize) < 0) {
32                return UPNPCOMMAND_HTTP_ERROR;
33        }
34        ParseNameValue(buffer, bufsize, &pdata);
35        /*DisplayNameValueList(buffer, bufsize);*/
36        p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
37        r = my_atoui(p);
38        ClearNameValueList(&pdata);
39        return r;
40}
41
42/*
43 * */
44LIBSPEC UNSIGNED_INTEGER
45UPNP_GetTotalBytesReceived(const char * controlURL,
46                                                const char * servicetype)
47{
48        struct NameValueParserData pdata;
49        char buffer[4096];
50        int bufsize = 4096;
51        unsigned int r = 0;
52        char * p;
53        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize) < 0) {
54                return UPNPCOMMAND_HTTP_ERROR;
55        }
56        ParseNameValue(buffer, bufsize, &pdata);
57        /*DisplayNameValueList(buffer, bufsize);*/
58        p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
59        r = my_atoui(p);
60        ClearNameValueList(&pdata);
61        return r;
62}
63
64/*
65 * */
66LIBSPEC UNSIGNED_INTEGER
67UPNP_GetTotalPacketsSent(const char * controlURL,
68                                                const char * servicetype)
69{
70        struct NameValueParserData pdata;
71        char buffer[4096];
72        int bufsize = 4096;
73        unsigned int r = 0;
74        char * p;
75        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize) < 0) {
76                return UPNPCOMMAND_HTTP_ERROR;
77        }
78        ParseNameValue(buffer, bufsize, &pdata);
79        /*DisplayNameValueList(buffer, bufsize);*/
80        p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
81        r = my_atoui(p);
82        ClearNameValueList(&pdata);
83        return r;
84}
85
86/*
87 * */
88LIBSPEC UNSIGNED_INTEGER
89UPNP_GetTotalPacketsReceived(const char * controlURL,
90                                                const char * servicetype)
91{
92        struct NameValueParserData pdata;
93        char buffer[4096];
94        int bufsize = 4096;
95        unsigned int r = 0;
96        char * p;
97        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize) < 0) {
98                return UPNPCOMMAND_HTTP_ERROR;
99        }
100        ParseNameValue(buffer, bufsize, &pdata);
101        /*DisplayNameValueList(buffer, bufsize);*/
102        p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
103        r = my_atoui(p);
104        ClearNameValueList(&pdata);
105        return r;
106}
107
108/* UPNP_GetStatusInfo() call the corresponding UPNP method
109 * returns the current status and uptime */
110LIBSPEC int
111UPNP_GetStatusInfo(const char * controlURL,
112                                const char * servicetype,
113                                char * status, 
114                                unsigned int * uptime,
115                                char * lastconnerror)
116{
117        struct NameValueParserData pdata;
118        char buffer[4096];
119        int bufsize = 4096;
120        char * p;
121        char * up;
122        char * err;
123        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
124
125        if(!status && !uptime)
126                return UPNPCOMMAND_INVALID_ARGS;
127
128        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize) < 0) {
129                return UPNPCOMMAND_HTTP_ERROR;
130        }
131        ParseNameValue(buffer, bufsize, &pdata);
132        /*DisplayNameValueList(buffer, bufsize);*/
133        up = GetValueFromNameValueList(&pdata, "NewUptime");
134        p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
135        err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
136        if(p && up)
137          ret = UPNPCOMMAND_SUCCESS;
138
139        if(status) {
140                if(p){
141                        strncpy(status, p, 64 );
142                        status[63] = '\0';
143                }else
144                        status[0]= '\0';
145        }
146
147        if(uptime) {
148                if(up)
149                        sscanf(up,"%u",uptime);
150                else
151                        uptime = 0;
152        }
153
154        if(lastconnerror) {
155                if(err) {
156                        strncpy(lastconnerror, err, 64 );
157                        lastconnerror[63] = '\0';
158                } else
159                        lastconnerror[0] = '\0';
160        }
161
162        p = GetValueFromNameValueList(&pdata, "errorCode");
163        if(p) {
164                ret = UPNPCOMMAND_UNKNOWN_ERROR;
165                sscanf(p, "%d", &ret);
166        }
167        ClearNameValueList(&pdata);
168        return ret;
169}
170
171/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
172 * returns the connection type */
173LIBSPEC int
174UPNP_GetConnectionTypeInfo(const char * controlURL,
175                           const char * servicetype,
176                           char * connectionType)
177{
178        struct NameValueParserData pdata;
179        char buffer[4096];
180        int bufsize = 4096;
181        char * p;
182        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
183
184        if(!connectionType)
185                return UPNPCOMMAND_INVALID_ARGS;
186
187        if(simpleUPnPcommand(-1, controlURL, servicetype,
188                          "GetConnectionTypeInfo", 0, buffer, &bufsize) < 0) {
189                return UPNPCOMMAND_HTTP_ERROR;
190        }
191        ParseNameValue(buffer, bufsize, &pdata);
192        p = GetValueFromNameValueList(&pdata, "NewConnectionType");
193        /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
194        /* PossibleConnectionTypes will have several values.... */
195        if(p) {
196                strncpy(connectionType, p, 64 );
197                connectionType[63] = '\0';
198                ret = UPNPCOMMAND_SUCCESS;
199        } else
200                connectionType[0] = '\0';
201        p = GetValueFromNameValueList(&pdata, "errorCode");
202        if(p) {
203                ret = UPNPCOMMAND_UNKNOWN_ERROR;
204                sscanf(p, "%d", &ret);
205        }
206        ClearNameValueList(&pdata);
207        return ret;
208}
209
210/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
211 * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
212 * One of the values can be null
213 * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
214 * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
215LIBSPEC int
216UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
217                             const char * servicetype,
218                             unsigned int * bitrateDown,
219                             unsigned int* bitrateUp)
220{
221        struct NameValueParserData pdata;
222        char buffer[4096];
223        int bufsize = 4096;
224        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
225        char * down;
226        char * up;
227        char * p;
228
229        if(!bitrateDown && !bitrateUp)
230                return UPNPCOMMAND_INVALID_ARGS;
231
232        /* shouldn't we use GetCommonLinkProperties ? */
233        if(simpleUPnPcommand(-1, controlURL, servicetype,
234                          "GetCommonLinkProperties", 0, buffer, &bufsize) < 0) {
235                          /*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
236                return UPNPCOMMAND_HTTP_ERROR;
237        }
238        /*DisplayNameValueList(buffer, bufsize);*/
239        ParseNameValue(buffer, bufsize, &pdata);
240        /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
241        /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
242        down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
243        up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
244        /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
245        /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
246        if(down && up)
247                ret = UPNPCOMMAND_SUCCESS;
248
249        if(bitrateDown) {
250                if(down)
251                        sscanf(down,"%u",bitrateDown);
252                else
253                        *bitrateDown = 0;
254        }
255
256        if(bitrateUp) {
257                if(up)
258                        sscanf(up,"%u",bitrateUp);
259                else
260                        *bitrateUp = 0;
261        }
262        p = GetValueFromNameValueList(&pdata, "errorCode");
263        if(p) {
264                ret = UPNPCOMMAND_UNKNOWN_ERROR;
265                sscanf(p, "%d", &ret);
266        }
267        ClearNameValueList(&pdata);
268        return ret;
269}
270
271
272/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
273 * if the third arg is not null the value is copied to it.
274 * at least 16 bytes must be available
275 *
276 * Return values :
277 * 0 : SUCCESS
278 * NON ZERO : ERROR Either an UPnP error code or an unknown error.
279 *
280 * 402 Invalid Args - See UPnP Device Architecture section on Control.
281 * 501 Action Failed - See UPnP Device Architecture section on Control.
282 */
283LIBSPEC int
284UPNP_GetExternalIPAddress(const char * controlURL,
285                          const char * servicetype,
286                          char * extIpAdd)
287{
288        struct NameValueParserData pdata;
289        char buffer[4096];
290        int bufsize = 4096;
291        char * p;
292        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
293
294        if(!extIpAdd || !controlURL || !servicetype)
295                return UPNPCOMMAND_INVALID_ARGS;
296
297        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize) < 0) {
298                return UPNPCOMMAND_HTTP_ERROR;
299        }
300        /*DisplayNameValueList(buffer, bufsize);*/
301        ParseNameValue(buffer, bufsize, &pdata);
302        /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
303        p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
304        if(p) {
305                strncpy(extIpAdd, p, 16 );
306                extIpAdd[15] = '\0';
307                ret = UPNPCOMMAND_SUCCESS;
308        } else
309                extIpAdd[0] = '\0';
310
311        p = GetValueFromNameValueList(&pdata, "errorCode");
312        if(p) {
313                ret = UPNPCOMMAND_UNKNOWN_ERROR;
314                sscanf(p, "%d", &ret);
315        }
316
317        ClearNameValueList(&pdata);
318        return ret;
319}
320
321LIBSPEC int
322UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
323                    const char * extPort,
324                                        const char * inPort,
325                                        const char * inClient,
326                                        const char * desc,
327                                        const char * proto,
328                    const char * remoteHost)
329{
330        struct UPNParg * AddPortMappingArgs;
331        char buffer[4096];
332        int bufsize = 4096;
333        struct NameValueParserData pdata;
334        const char * resVal;
335        int ret;
336
337        if(!inPort || !inClient || !proto || !extPort)
338                return UPNPCOMMAND_INVALID_ARGS;
339
340        AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
341        AddPortMappingArgs[0].elt = "NewRemoteHost";
342        AddPortMappingArgs[0].val = remoteHost;
343        AddPortMappingArgs[1].elt = "NewExternalPort";
344        AddPortMappingArgs[1].val = extPort;
345        AddPortMappingArgs[2].elt = "NewProtocol";
346        AddPortMappingArgs[2].val = proto;
347        AddPortMappingArgs[3].elt = "NewInternalPort";
348        AddPortMappingArgs[3].val = inPort;
349        AddPortMappingArgs[4].elt = "NewInternalClient";
350        AddPortMappingArgs[4].val = inClient;
351        AddPortMappingArgs[5].elt = "NewEnabled";
352        AddPortMappingArgs[5].val = "1";
353        AddPortMappingArgs[6].elt = "NewPortMappingDescription";
354        AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
355        AddPortMappingArgs[7].elt = "NewLeaseDuration";
356        AddPortMappingArgs[7].val = "0";
357        if(simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize) < 0) {
358                free(AddPortMappingArgs);
359                return UPNPCOMMAND_HTTP_ERROR;
360        }
361        /*DisplayNameValueList(buffer, bufsize);*/
362        /*buffer[bufsize] = '\0';*/
363        /*puts(buffer);*/
364        ParseNameValue(buffer, bufsize, &pdata);
365        resVal = GetValueFromNameValueList(&pdata, "errorCode");
366        if(resVal) {
367                /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
368                ret = UPNPCOMMAND_UNKNOWN_ERROR;
369                sscanf(resVal, "%d", &ret);
370        } else {
371                ret = UPNPCOMMAND_SUCCESS;
372        }
373        ClearNameValueList(&pdata);
374        free(AddPortMappingArgs);
375        return ret;
376}
377
378LIBSPEC int
379UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
380                       const char * extPort, const char * proto,
381                       const char * remoteHost)
382{
383        /*struct NameValueParserData pdata;*/
384        struct UPNParg * DeletePortMappingArgs;
385        char buffer[4096];
386        int bufsize = 4096;
387        struct NameValueParserData pdata;
388        const char * resVal;
389        int ret;
390
391        if(!extPort || !proto)
392                return UPNPCOMMAND_INVALID_ARGS;
393
394        DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
395        DeletePortMappingArgs[0].elt = "NewRemoteHost";
396        DeletePortMappingArgs[0].val = remoteHost;
397        DeletePortMappingArgs[1].elt = "NewExternalPort";
398        DeletePortMappingArgs[1].val = extPort;
399        DeletePortMappingArgs[2].elt = "NewProtocol";
400        DeletePortMappingArgs[2].val = proto;
401        if(simpleUPnPcommand(-1, controlURL, servicetype,
402                             "DeletePortMapping",
403                             DeletePortMappingArgs, buffer, &bufsize) < 0 ) {
404                free(DeletePortMappingArgs);
405                return UPNPCOMMAND_HTTP_ERROR;
406        }
407        /*DisplayNameValueList(buffer, bufsize);*/
408        ParseNameValue(buffer, bufsize, &pdata);
409        resVal = GetValueFromNameValueList(&pdata, "errorCode");
410        if(resVal) {
411                ret = UPNPCOMMAND_UNKNOWN_ERROR;
412                sscanf(resVal, "%d", &ret);
413        } else {
414                ret = UPNPCOMMAND_SUCCESS;
415        }
416        ClearNameValueList(&pdata);
417        free(DeletePortMappingArgs);
418        return ret;
419}
420
421LIBSPEC int
422UPNP_GetGenericPortMappingEntry(const char * controlURL,
423                                const char * servicetype,
424                                                         const char * index,
425                                                         char * extPort,
426                                                         char * intClient,
427                                                         char * intPort,
428                                                         char * protocol,
429                                                         char * desc,
430                                                         char * enabled,
431                                                         char * rHost,
432                                                         char * duration)
433{
434        struct NameValueParserData pdata;
435        struct UPNParg * GetPortMappingArgs;
436        char buffer[4096];
437        int bufsize = 4096;
438        char * p;
439        int r = UPNPCOMMAND_UNKNOWN_ERROR;
440        if(!index)
441                return UPNPCOMMAND_INVALID_ARGS;
442        intClient[0] = '\0';
443        intPort[0] = '\0';
444        GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
445        GetPortMappingArgs[0].elt = "NewPortMappingIndex";
446        GetPortMappingArgs[0].val = index;
447        if(simpleUPnPcommand(-1, controlURL, servicetype,
448                          "GetGenericPortMappingEntry",
449                                          GetPortMappingArgs, buffer, &bufsize) < 0) {
450                free(GetPortMappingArgs);
451                return UPNPCOMMAND_HTTP_ERROR;
452        }
453        ParseNameValue(buffer, bufsize, &pdata);
454        p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
455        if(p && rHost)
456        {
457                strncpy(rHost, p, 64);
458                rHost[63] = '\0';
459        }
460        p = GetValueFromNameValueList(&pdata, "NewExternalPort");
461        if(p && extPort)
462        {
463                strncpy(extPort, p, 6);
464                extPort[5] = '\0';
465                r = UPNPCOMMAND_SUCCESS;
466        }
467        p = GetValueFromNameValueList(&pdata, "NewProtocol");
468        if(p && protocol)
469        {
470                strncpy(protocol, p, 4);
471                protocol[3] = '\0';
472        }
473        p = GetValueFromNameValueList(&pdata, "NewInternalClient");
474        if(p && intClient)
475        {
476                strncpy(intClient, p, 16);
477                intClient[15] = '\0';
478                r = 0;
479        }
480        p = GetValueFromNameValueList(&pdata, "NewInternalPort");
481        if(p && intPort)
482        {
483                strncpy(intPort, p, 6);
484                intPort[5] = '\0';
485        }
486        p = GetValueFromNameValueList(&pdata, "NewEnabled");
487        if(p && enabled)
488        {
489                strncpy(enabled, p, 4);
490                enabled[3] = '\0';
491        }
492        p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
493        if(p && desc)
494        {
495                strncpy(desc, p, 80);
496                desc[79] = '\0';
497        }
498        p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
499        if(p && duration)
500        {
501                strncpy(duration, p, 16);
502                duration[15] = '\0';
503        }
504        p = GetValueFromNameValueList(&pdata, "errorCode");
505        if(p) {
506                r = UPNPCOMMAND_UNKNOWN_ERROR;
507                sscanf(p, "%d", &r);
508        }
509        ClearNameValueList(&pdata);
510        free(GetPortMappingArgs);
511        return r;
512}
513
514LIBSPEC int
515UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
516                                   const char * servicetype,
517                                   unsigned int * numEntries)
518{
519        struct NameValueParserData pdata;
520        char buffer[4096];
521        int bufsize = 4096;
522        char* p;
523        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
524        if(simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize) < 0) {
525                return UPNPCOMMAND_HTTP_ERROR;
526        }
527#ifdef DEBUG
528        DisplayNameValueList(buffer, bufsize);
529#endif
530        ParseNameValue(buffer, bufsize, &pdata);
531
532        p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
533        if(numEntries && p) {
534                *numEntries = 0;
535                sscanf(p, "%u", numEntries);
536                ret = UPNPCOMMAND_SUCCESS;
537        }
538
539        p = GetValueFromNameValueList(&pdata, "errorCode");
540        if(p) {
541                ret = UPNPCOMMAND_UNKNOWN_ERROR;
542                sscanf(p, "%d", &ret);
543        }
544
545        ClearNameValueList(&pdata);
546        return ret;
547}
548
549/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
550 * the result is returned in the intClient and intPort strings
551 * please provide 16 and 6 bytes of data */
552LIBSPEC int
553UPNP_GetSpecificPortMappingEntry(const char * controlURL,
554                                 const char * servicetype,
555                                 const char * extPort,
556                                                             const char * proto,
557                                 char * intClient,
558                                 char * intPort)
559{
560        struct NameValueParserData pdata;
561        struct UPNParg * GetPortMappingArgs;
562        char buffer[4096];
563        int bufsize = 4096;
564        char * p;
565        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
566
567        if(!intPort || !intClient || !extPort || !proto)
568                return UPNPCOMMAND_INVALID_ARGS;
569
570        GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
571        GetPortMappingArgs[0].elt = "NewRemoteHost";
572        GetPortMappingArgs[1].elt = "NewExternalPort";
573        GetPortMappingArgs[1].val = extPort;
574        GetPortMappingArgs[2].elt = "NewProtocol";
575        GetPortMappingArgs[2].val = proto;
576        if(simpleUPnPcommand(-1, controlURL, servicetype,
577                             "GetSpecificPortMappingEntry",
578                             GetPortMappingArgs, buffer, &bufsize) < 0) {
579                free(GetPortMappingArgs);
580                return UPNPCOMMAND_HTTP_ERROR;
581        }
582        /*DisplayNameValueList(buffer, bufsize);*/
583        ParseNameValue(buffer, bufsize, &pdata);
584
585        p = GetValueFromNameValueList(&pdata, "NewInternalClient");
586        if(p) {
587                strncpy(intClient, p, 16);
588                intClient[15] = '\0';
589                ret = UPNPCOMMAND_SUCCESS;
590        } else
591                intClient[0] = '\0';
592
593        p = GetValueFromNameValueList(&pdata, "NewInternalPort");
594        if(p) {
595                strncpy(intPort, p, 6);
596                intPort[5] = '\0';
597        } else
598                intPort[0] = '\0';
599
600        p = GetValueFromNameValueList(&pdata, "errorCode");
601        if(p) {
602                ret = UPNPCOMMAND_UNKNOWN_ERROR;
603                sscanf(p, "%d", &ret);
604        }
605
606        ClearNameValueList(&pdata);
607        free(GetPortMappingArgs);
608        return ret;
609}
610
611
Note: See TracBrowser for help on using the repository browser.