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

Last change on this file since 5094 was 5094, checked in by charles, 15 years ago

update to miniupnpc-1.0

File size: 15.7 KB
Line 
1/* $Id: upnpcommands.c,v 1.19 2008/02/18 13:27:23 nanard Exp $ */
2/* Project : miniupnp
3 * Author : Thomas Bernard
4 * Copyright (c) 2005 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{
308        struct UPNParg * AddPortMappingArgs;
309        char buffer[4096];
310        int bufsize = 4096;
311        struct NameValueParserData pdata;
312        const char * resVal;
313        int ret;
314
315        if(!inPort || !inClient || !proto || !extPort)
316                return UPNPCOMMAND_INVALID_ARGS;
317
318        AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
319        AddPortMappingArgs[0].elt = "NewRemoteHost";
320        AddPortMappingArgs[1].elt = "NewExternalPort";
321        AddPortMappingArgs[1].val = extPort;
322        AddPortMappingArgs[2].elt = "NewProtocol";
323        AddPortMappingArgs[2].val = proto;
324        AddPortMappingArgs[3].elt = "NewInternalPort";
325        AddPortMappingArgs[3].val = inPort;
326        AddPortMappingArgs[4].elt = "NewInternalClient";
327        AddPortMappingArgs[4].val = inClient;
328        AddPortMappingArgs[5].elt = "NewEnabled";
329        AddPortMappingArgs[5].val = "1";
330        AddPortMappingArgs[6].elt = "NewPortMappingDescription";
331        AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
332        AddPortMappingArgs[7].elt = "NewLeaseDuration";
333        AddPortMappingArgs[7].val = "0";
334        simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize);
335        /*DisplayNameValueList(buffer, bufsize);*/
336        /*buffer[bufsize] = '\0';*/
337        /*puts(buffer);*/
338        ParseNameValue(buffer, bufsize, &pdata);
339        resVal = GetValueFromNameValueList(&pdata, "errorCode");
340        if(resVal) {
341                /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
342                ret = UPNPCOMMAND_UNKNOWN_ERROR;
343                sscanf(resVal, "%d", &ret);
344        } else {
345                ret = UPNPCOMMAND_SUCCESS;
346        }
347        ClearNameValueList(&pdata);
348        free(AddPortMappingArgs);
349        return ret;
350}
351
352int
353UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
354                       const char * extPort, const char * proto)
355{
356        /*struct NameValueParserData pdata;*/
357        struct UPNParg * DeletePortMappingArgs;
358        char buffer[4096];
359        int bufsize = 4096;
360        struct NameValueParserData pdata;
361        const char * resVal;
362        int ret;
363
364        if(!extPort || !proto)
365                return UPNPCOMMAND_INVALID_ARGS;
366
367        DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
368        DeletePortMappingArgs[0].elt = "NewRemoteHost";
369        DeletePortMappingArgs[1].elt = "NewExternalPort";
370        DeletePortMappingArgs[1].val = extPort;
371        DeletePortMappingArgs[2].elt = "NewProtocol";
372        DeletePortMappingArgs[2].val = proto;
373        simpleUPnPcommand(-1, controlURL, servicetype,
374                          "DeletePortMapping",
375                                          DeletePortMappingArgs, buffer, &bufsize);
376        /*DisplayNameValueList(buffer, bufsize);*/
377        ParseNameValue(buffer, bufsize, &pdata);
378        resVal = GetValueFromNameValueList(&pdata, "errorCode");
379        if(resVal) {
380                ret = UPNPCOMMAND_UNKNOWN_ERROR;
381                sscanf(resVal, "%d", &ret);
382        } else {
383                ret = UPNPCOMMAND_SUCCESS;
384        }
385        ClearNameValueList(&pdata);
386        free(DeletePortMappingArgs);
387        return ret;
388}
389
390int UPNP_GetGenericPortMappingEntry(const char * controlURL,
391                                     const char * servicetype,
392                                                                         const char * index,
393                                                                         char * extPort,
394                                                                         char * intClient,
395                                                                         char * intPort,
396                                                                         char * protocol,
397                                                                         char * desc,
398                                                                         char * enabled,
399                                                                         char * rHost,
400                                                                         char * duration)
401{
402        struct NameValueParserData pdata;
403        struct UPNParg * GetPortMappingArgs;
404        char buffer[4096];
405        int bufsize = 4096;
406        char * p;
407        int r = UPNPCOMMAND_UNKNOWN_ERROR;
408        if(!index)
409                return UPNPCOMMAND_INVALID_ARGS;
410        intClient[0] = '\0';
411        intPort[0] = '\0';
412        GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
413        GetPortMappingArgs[0].elt = "NewPortMappingIndex";
414        GetPortMappingArgs[0].val = index;
415        simpleUPnPcommand(-1, controlURL, servicetype,
416                          "GetGenericPortMappingEntry",
417                                          GetPortMappingArgs, buffer, &bufsize);
418        ParseNameValue(buffer, bufsize, &pdata);
419        p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
420        if(p && rHost)
421        {
422                strncpy(rHost, p, 64);
423                rHost[63] = '\0';
424        }
425        p = GetValueFromNameValueList(&pdata, "NewExternalPort");
426        if(p && extPort)
427        {
428                strncpy(extPort, p, 6);
429                extPort[5] = '\0';
430                r = UPNPCOMMAND_SUCCESS;
431        }
432        p = GetValueFromNameValueList(&pdata, "NewProtocol");
433        if(p && protocol)
434        {
435                strncpy(protocol, p, 4);
436                protocol[3] = '\0';
437        }
438        p = GetValueFromNameValueList(&pdata, "NewInternalClient");
439        if(p && intClient)
440        {
441                strncpy(intClient, p, 16);
442                intClient[15] = '\0';
443                r = 0;
444        }
445        p = GetValueFromNameValueList(&pdata, "NewInternalPort");
446        if(p && intPort)
447        {
448                strncpy(intPort, p, 6);
449                intPort[5] = '\0';
450        }
451        p = GetValueFromNameValueList(&pdata, "NewEnabled");
452        if(p && enabled)
453        {
454                strncpy(enabled, p, 4);
455                enabled[3] = '\0';
456        }
457        p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
458        if(p && desc)
459        {
460                strncpy(desc, p, 80);
461                desc[79] = '\0';
462        }
463        p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
464        if(p && duration)
465        {
466                strncpy(duration, p, 16);
467                duration[15] = '\0';
468        }
469        p = GetValueFromNameValueList(&pdata, "errorCode");
470        if(p) {
471                r = UPNPCOMMAND_UNKNOWN_ERROR;
472                sscanf(p, "%d", &r);
473        }
474        ClearNameValueList(&pdata);
475        free(GetPortMappingArgs);
476        return r;
477}
478
479int UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries)
480{
481        struct NameValueParserData pdata;
482        char buffer[4096];
483        int bufsize = 4096;
484        char* p;
485        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
486        simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize);
487#ifndef NDEBUG
488        DisplayNameValueList(buffer, bufsize);
489#endif
490        ParseNameValue(buffer, bufsize, &pdata);
491
492        p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
493        if(numEntries && p) {
494                *numEntries = 0;
495                sscanf(p, "%u", numEntries);
496                ret = UPNPCOMMAND_SUCCESS;
497        }
498
499        p = GetValueFromNameValueList(&pdata, "errorCode");
500        if(p) {
501                ret = UPNPCOMMAND_UNKNOWN_ERROR;
502                sscanf(p, "%d", &ret);
503        }
504
505        ClearNameValueList(&pdata);
506        return ret;
507}
508
509/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
510 * the result is returned in the intClient and intPort strings
511 * please provide 16 and 6 bytes of data */
512int
513UPNP_GetSpecificPortMappingEntry(const char * controlURL,
514                                 const char * servicetype,
515                                 const char * extPort,
516                                                             const char * proto,
517                                 char * intClient,
518                                 char * intPort)
519{
520        struct NameValueParserData pdata;
521        struct UPNParg * GetPortMappingArgs;
522        char buffer[4096];
523        int bufsize = 4096;
524        char * p;
525        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
526
527        if(!intPort || !intClient || !extPort || !proto)
528                return UPNPCOMMAND_INVALID_ARGS;
529
530        GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
531        GetPortMappingArgs[0].elt = "NewRemoteHost";
532        GetPortMappingArgs[1].elt = "NewExternalPort";
533        GetPortMappingArgs[1].val = extPort;
534        GetPortMappingArgs[2].elt = "NewProtocol";
535        GetPortMappingArgs[2].val = proto;
536        simpleUPnPcommand(-1, controlURL, servicetype,
537                          "GetSpecificPortMappingEntry",
538                                          GetPortMappingArgs, buffer, &bufsize);
539        /*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */
540        /*DisplayNameValueList(buffer, bufsize);*/
541        ParseNameValue(buffer, bufsize, &pdata);
542
543        p = GetValueFromNameValueList(&pdata, "NewInternalClient");
544        if(p) {
545                strncpy(intClient, p, 16);
546                intClient[15] = '\0';
547                ret = UPNPCOMMAND_SUCCESS;
548        } else
549                intClient[0] = '\0';
550
551        p = GetValueFromNameValueList(&pdata, "NewInternalPort");
552        if(p) {
553                strncpy(intPort, p, 6);
554                intPort[5] = '\0';
555        } else
556                intPort[0] = '\0';
557
558        p = GetValueFromNameValueList(&pdata, "errorCode");
559        if(p) {
560                ret = UPNPCOMMAND_UNKNOWN_ERROR;
561                sscanf(p, "%d", &ret);
562        }
563
564        ClearNameValueList(&pdata);
565        free(GetPortMappingArgs);
566        return ret;
567}
568
569
Note: See TracBrowser for help on using the repository browser.