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

Last change on this file since 7837 was 7837, checked in by charles, 13 years ago

(trunk libT) update to the newest versions of miniupnp and libnatpmp

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