Annotation of embedaddon/miniupnpc/upnpcommands.c, revision 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>