Annotation of embedaddon/miniupnpc/upnpcommands.c, revision 1.1.1.1

1.1       misho       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: 
                     15: static UNSIGNED_INTEGER
                     16: my_atoui(const char * s)
                     17: {
                     18:        return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
                     19: }
                     20: 
                     21: /*
                     22:  * */
                     23: LIBSPEC UNSIGNED_INTEGER
                     24: UPNP_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:  * */
                     47: LIBSPEC UNSIGNED_INTEGER
                     48: UPNP_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:  * */
                     71: LIBSPEC UNSIGNED_INTEGER
                     72: UPNP_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:  * */
                     95: LIBSPEC UNSIGNED_INTEGER
                     96: UPNP_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 */
                    119: LIBSPEC int
                    120: UPNP_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 */
                    184: LIBSPEC int
                    185: UPNP_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 */
                    227: LIBSPEC int
                    228: UPNP_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:  */
                    296: LIBSPEC int
                    297: UPNP_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: 
                    336: LIBSPEC int
                    337: UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
                    338:                     const char * extPort,
                    339:                                        const char * inPort,
                    340:                                        const char * inClient,
                    341:                                        const char * desc,
                    342:                                        const char * proto,
                    343:                     const char * remoteHost,
                    344:                     const char * leaseDuration)
                    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: 
                    397: LIBSPEC int
                    398: UPNP_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: 
                    441: LIBSPEC int
                    442: UPNP_GetGenericPortMappingEntry(const char * controlURL,
                    443:                                 const char * servicetype,
                    444:                                                         const char * index,
                    445:                                                         char * extPort,
                    446:                                                         char * intClient,
                    447:                                                         char * intPort,
                    448:                                                         char * protocol,
                    449:                                                         char * desc,
                    450:                                                         char * enabled,
                    451:                                                         char * rHost,
                    452:                                                         char * duration)
                    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: 
                    536: LIBSPEC int
                    537: UPNP_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 */
                    577: LIBSPEC int
                    578: UPNP_GetSpecificPortMappingEntry(const char * controlURL,
                    579:                                  const char * servicetype,
                    580:                                  const char * extPort,
                    581:                                                             const char * proto,
                    582:                                  char * intClient,
                    583:                                  char * intPort,
                    584:                                  char * desc,
                    585:                                  char * enabled,
                    586:                                  char * leaseDuration)
                    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:  */
                    668: LIBSPEC int
                    669: UPNP_GetListOfPortMappings(const char * controlURL,
                    670:                            const char * servicetype,
                    671:                            const char * startPort,
                    672:                            const char * endPort,
                    673:                            const char * protocol,
                    674:                            const char * numberOfPorts,
                    675:                            struct PortMappingParserData * data)
                    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 */ 
                    750: LIBSPEC int
                    751: UPNP_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: 
                    794: LIBSPEC int
                    795: UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
                    796:                     const char * remoteHost,
                    797:                     const char * remotePort,
                    798:                     const char * intClient,
                    799:                     const char * intPort,
                    800:                     const char * proto,
                    801:                     int * opTimeout)
                    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: 
                    849: LIBSPEC int
                    850: UPNP_AddPinhole(const char * controlURL, const char * servicetype,
                    851:                     const char * remoteHost,
                    852:                     const char * remotePort,
                    853:                     const char * intClient,
                    854:                     const char * intPort,
                    855:                     const char * proto,
                    856:                     const char * leaseTime,
                    857:                     char * uniqueID)
                    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: 
                    928: LIBSPEC int
                    929: UPNP_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: 
                    970: LIBSPEC int
                    971: UPNP_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: 
                   1009: LIBSPEC int
                   1010: UPNP_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: 
                   1054: LIBSPEC int
                   1055: UPNP_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: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>