Annotation of embedaddon/miniupnpd/miniupnpc/src/upnpcommands.c, revision 1.1

1.1     ! misho       1: /* $Id: upnpcommands.c,v 1.51 2019/04/23 11:45:15 nanard Exp $ */
        !             2: /* vim: tabstop=4 shiftwidth=4 noexpandtab
        !             3:  * Project : miniupnp
        !             4:  * Author : Thomas Bernard
        !             5:  * Copyright (c) 2005-2018 Thomas Bernard
        !             6:  * This software is subject to the conditions detailed in the
        !             7:  * LICENCE file provided in this distribution.
        !             8:  * */
        !             9: #include <stdlib.h>
        !            10: #include <stdio.h>
        !            11: #include <string.h>
        !            12: #include "upnpcommands.h"
        !            13: #include "miniupnpc.h"
        !            14: #include "portlistingparse.h"
        !            15: #include "upnpreplyparse.h"
        !            16: 
        !            17: static UNSIGNED_INTEGER
        !            18: my_atoui(const char * s)
        !            19: {
        !            20:    return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
        !            21: }
        !            22: 
        !            23: /*
        !            24:  * */
        !            25: MINIUPNP_LIBSPEC UNSIGNED_INTEGER
        !            26: UPNP_GetTotalBytesSent(const char * controlURL,
        !            27:                    const char * servicetype)
        !            28: {
        !            29:    struct NameValueParserData pdata;
        !            30:    char * buffer;
        !            31:    int bufsize;
        !            32:    unsigned int r = 0;
        !            33:    char * p;
        !            34:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !            35:                                    "GetTotalBytesSent", 0, &bufsize))) {
        !            36:        return (UNSIGNED_INTEGER)UPNPCOMMAND_HTTP_ERROR;
        !            37:    }
        !            38:    ParseNameValue(buffer, bufsize, &pdata);
        !            39:    /*DisplayNameValueList(buffer, bufsize);*/
        !            40:    free(buffer);
        !            41:    p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
        !            42:    r = my_atoui(p);
        !            43:    ClearNameValueList(&pdata);
        !            44:    return r;
        !            45: }
        !            46: 
        !            47: /*
        !            48:  * */
        !            49: MINIUPNP_LIBSPEC UNSIGNED_INTEGER
        !            50: UPNP_GetTotalBytesReceived(const char * controlURL,
        !            51:                        const char * servicetype)
        !            52: {
        !            53:    struct NameValueParserData pdata;
        !            54:    char * buffer;
        !            55:    int bufsize;
        !            56:    unsigned int r = 0;
        !            57:    char * p;
        !            58:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !            59:                                    "GetTotalBytesReceived", 0, &bufsize))) {
        !            60:        return (UNSIGNED_INTEGER)UPNPCOMMAND_HTTP_ERROR;
        !            61:    }
        !            62:    ParseNameValue(buffer, bufsize, &pdata);
        !            63:    /*DisplayNameValueList(buffer, bufsize);*/
        !            64:    free(buffer);
        !            65:    p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
        !            66:    r = my_atoui(p);
        !            67:    ClearNameValueList(&pdata);
        !            68:    return r;
        !            69: }
        !            70: 
        !            71: /*
        !            72:  * */
        !            73: MINIUPNP_LIBSPEC UNSIGNED_INTEGER
        !            74: UPNP_GetTotalPacketsSent(const char * controlURL,
        !            75:                        const char * servicetype)
        !            76: {
        !            77:    struct NameValueParserData pdata;
        !            78:    char * buffer;
        !            79:    int bufsize;
        !            80:    unsigned int r = 0;
        !            81:    char * p;
        !            82:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !            83:                                    "GetTotalPacketsSent", 0, &bufsize))) {
        !            84:        return (UNSIGNED_INTEGER)UPNPCOMMAND_HTTP_ERROR;
        !            85:    }
        !            86:    ParseNameValue(buffer, bufsize, &pdata);
        !            87:    /*DisplayNameValueList(buffer, bufsize);*/
        !            88:    free(buffer);
        !            89:    p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
        !            90:    r = my_atoui(p);
        !            91:    ClearNameValueList(&pdata);
        !            92:    return r;
        !            93: }
        !            94: 
        !            95: /*
        !            96:  * */
        !            97: MINIUPNP_LIBSPEC UNSIGNED_INTEGER
        !            98: UPNP_GetTotalPacketsReceived(const char * controlURL,
        !            99:                        const char * servicetype)
        !           100: {
        !           101:    struct NameValueParserData pdata;
        !           102:    char * buffer;
        !           103:    int bufsize;
        !           104:    unsigned int r = 0;
        !           105:    char * p;
        !           106:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           107:                                    "GetTotalPacketsReceived", 0, &bufsize))) {
        !           108:        return (UNSIGNED_INTEGER)UPNPCOMMAND_HTTP_ERROR;
        !           109:    }
        !           110:    ParseNameValue(buffer, bufsize, &pdata);
        !           111:    /*DisplayNameValueList(buffer, bufsize);*/
        !           112:    free(buffer);
        !           113:    p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
        !           114:    r = my_atoui(p);
        !           115:    ClearNameValueList(&pdata);
        !           116:    return r;
        !           117: }
        !           118: 
        !           119: /* UPNP_GetStatusInfo() call the corresponding UPNP method
        !           120:  * returns the current status and uptime */
        !           121: MINIUPNP_LIBSPEC int
        !           122: UPNP_GetStatusInfo(const char * controlURL,
        !           123:                const char * servicetype,
        !           124:                char * status,
        !           125:                unsigned int * uptime,
        !           126:                char * lastconnerror)
        !           127: {
        !           128:    struct NameValueParserData pdata;
        !           129:    char * buffer;
        !           130:    int bufsize;
        !           131:    char * p;
        !           132:    char * up;
        !           133:    char * err;
        !           134:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           135: 
        !           136:    if(!status && !uptime)
        !           137:        return UPNPCOMMAND_INVALID_ARGS;
        !           138: 
        !           139:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           140:                                    "GetStatusInfo", 0, &bufsize))) {
        !           141:        return UPNPCOMMAND_HTTP_ERROR;
        !           142:    }
        !           143:    ParseNameValue(buffer, bufsize, &pdata);
        !           144:    /*DisplayNameValueList(buffer, bufsize);*/
        !           145:    free(buffer);
        !           146:    up = GetValueFromNameValueList(&pdata, "NewUptime");
        !           147:    p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
        !           148:    err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
        !           149:    if(p && up)
        !           150:      ret = UPNPCOMMAND_SUCCESS;
        !           151: 
        !           152:    if(status) {
        !           153:        if(p){
        !           154:            strncpy(status, p, 64 );
        !           155:            status[63] = '\0';
        !           156:        }else
        !           157:            status[0]= '\0';
        !           158:    }
        !           159: 
        !           160:    if(uptime) {
        !           161:        if(up)
        !           162:            sscanf(up,"%u",uptime);
        !           163:        else
        !           164:            *uptime = 0;
        !           165:    }
        !           166: 
        !           167:    if(lastconnerror) {
        !           168:        if(err) {
        !           169:            strncpy(lastconnerror, err, 64 );
        !           170:            lastconnerror[63] = '\0';
        !           171:        } else
        !           172:            lastconnerror[0] = '\0';
        !           173:    }
        !           174: 
        !           175:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           176:    if(p) {
        !           177:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           178:        sscanf(p, "%d", &ret);
        !           179:    }
        !           180:    ClearNameValueList(&pdata);
        !           181:    return ret;
        !           182: }
        !           183: 
        !           184: /* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
        !           185:  * returns the connection type */
        !           186: MINIUPNP_LIBSPEC int
        !           187: UPNP_GetConnectionTypeInfo(const char * controlURL,
        !           188:                            const char * servicetype,
        !           189:                            char * connectionType)
        !           190: {
        !           191:    struct NameValueParserData pdata;
        !           192:    char * buffer;
        !           193:    int bufsize;
        !           194:    char * p;
        !           195:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           196: 
        !           197:    if(!connectionType)
        !           198:        return UPNPCOMMAND_INVALID_ARGS;
        !           199: 
        !           200:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           201:                                    "GetConnectionTypeInfo", 0, &bufsize))) {
        !           202:        return UPNPCOMMAND_HTTP_ERROR;
        !           203:    }
        !           204:    ParseNameValue(buffer, bufsize, &pdata);
        !           205:    free(buffer);
        !           206:    p = GetValueFromNameValueList(&pdata, "NewConnectionType");
        !           207:    /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
        !           208:    /* PossibleConnectionTypes will have several values.... */
        !           209:    if(p) {
        !           210:        strncpy(connectionType, p, 64 );
        !           211:        connectionType[63] = '\0';
        !           212:        ret = UPNPCOMMAND_SUCCESS;
        !           213:    } else
        !           214:        connectionType[0] = '\0';
        !           215:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           216:    if(p) {
        !           217:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           218:        sscanf(p, "%d", &ret);
        !           219:    }
        !           220:    ClearNameValueList(&pdata);
        !           221:    return ret;
        !           222: }
        !           223: 
        !           224: /* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
        !           225:  * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
        !           226:  * One of the values can be null
        !           227:  * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
        !           228:  * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
        !           229: MINIUPNP_LIBSPEC int
        !           230: UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
        !           231:                              const char * servicetype,
        !           232:                              unsigned int * bitrateDown,
        !           233:                              unsigned int * bitrateUp)
        !           234: {
        !           235:    struct NameValueParserData pdata;
        !           236:    char * buffer;
        !           237:    int bufsize;
        !           238:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           239:    char * down;
        !           240:    char * up;
        !           241:    char * p;
        !           242: 
        !           243:    if(!bitrateDown && !bitrateUp)
        !           244:        return UPNPCOMMAND_INVALID_ARGS;
        !           245: 
        !           246:    /* shouldn't we use GetCommonLinkProperties ? */
        !           247:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           248:                                    "GetCommonLinkProperties", 0, &bufsize))) {
        !           249:                                  /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
        !           250:        return UPNPCOMMAND_HTTP_ERROR;
        !           251:    }
        !           252:    /*DisplayNameValueList(buffer, bufsize);*/
        !           253:    ParseNameValue(buffer, bufsize, &pdata);
        !           254:    free(buffer);
        !           255:    /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
        !           256:    /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
        !           257:    down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
        !           258:    up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
        !           259:    /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
        !           260:    /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
        !           261:    if(down && up)
        !           262:        ret = UPNPCOMMAND_SUCCESS;
        !           263: 
        !           264:    if(bitrateDown) {
        !           265:        if(down)
        !           266:            sscanf(down,"%u",bitrateDown);
        !           267:        else
        !           268:            *bitrateDown = 0;
        !           269:    }
        !           270: 
        !           271:    if(bitrateUp) {
        !           272:        if(up)
        !           273:            sscanf(up,"%u",bitrateUp);
        !           274:        else
        !           275:            *bitrateUp = 0;
        !           276:    }
        !           277:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           278:    if(p) {
        !           279:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           280:        sscanf(p, "%d", &ret);
        !           281:    }
        !           282:    ClearNameValueList(&pdata);
        !           283:    return ret;
        !           284: }
        !           285: 
        !           286: 
        !           287: /* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
        !           288:  * if the third arg is not null the value is copied to it.
        !           289:  * at least 16 bytes must be available
        !           290:  *
        !           291:  * Return values :
        !           292:  * 0 : SUCCESS
        !           293:  * NON ZERO : ERROR Either an UPnP error code or an unknown error.
        !           294:  *
        !           295:  * 402 Invalid Args - See UPnP Device Architecture section on Control.
        !           296:  * 501 Action Failed - See UPnP Device Architecture section on Control.
        !           297:  */
        !           298: MINIUPNP_LIBSPEC int
        !           299: UPNP_GetExternalIPAddress(const char * controlURL,
        !           300:                           const char * servicetype,
        !           301:                           char * extIpAdd)
        !           302: {
        !           303:    struct NameValueParserData pdata;
        !           304:    char * buffer;
        !           305:    int bufsize;
        !           306:    char * p;
        !           307:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           308: 
        !           309:    if(!extIpAdd || !controlURL || !servicetype)
        !           310:        return UPNPCOMMAND_INVALID_ARGS;
        !           311: 
        !           312:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           313:                                    "GetExternalIPAddress", 0, &bufsize))) {
        !           314:        return UPNPCOMMAND_HTTP_ERROR;
        !           315:    }
        !           316:    /*DisplayNameValueList(buffer, bufsize);*/
        !           317:    ParseNameValue(buffer, bufsize, &pdata);
        !           318:    free(buffer);
        !           319:    /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
        !           320:    p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
        !           321:    if(p) {
        !           322:        strncpy(extIpAdd, p, 16 );
        !           323:        extIpAdd[15] = '\0';
        !           324:        ret = UPNPCOMMAND_SUCCESS;
        !           325:    } else
        !           326:        extIpAdd[0] = '\0';
        !           327: 
        !           328:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           329:    if(p) {
        !           330:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           331:        sscanf(p, "%d", &ret);
        !           332:    }
        !           333: 
        !           334:    ClearNameValueList(&pdata);
        !           335:    return ret;
        !           336: }
        !           337: 
        !           338: MINIUPNP_LIBSPEC int
        !           339: UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
        !           340:            const char * extPort,
        !           341:            const char * inPort,
        !           342:            const char * inClient,
        !           343:            const char * desc,
        !           344:            const char * proto,
        !           345:            const char * remoteHost,
        !           346:            const char * leaseDuration)
        !           347: {
        !           348:    struct UPNParg * AddPortMappingArgs;
        !           349:    char * buffer;
        !           350:    int bufsize;
        !           351:    struct NameValueParserData pdata;
        !           352:    const char * resVal;
        !           353:    int ret;
        !           354: 
        !           355:    if(!inPort || !inClient || !proto || !extPort)
        !           356:        return UPNPCOMMAND_INVALID_ARGS;
        !           357: 
        !           358:    AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
        !           359:    if(AddPortMappingArgs == NULL)
        !           360:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           361:    AddPortMappingArgs[0].elt = "NewRemoteHost";
        !           362:    AddPortMappingArgs[0].val = remoteHost;
        !           363:    AddPortMappingArgs[1].elt = "NewExternalPort";
        !           364:    AddPortMappingArgs[1].val = extPort;
        !           365:    AddPortMappingArgs[2].elt = "NewProtocol";
        !           366:    AddPortMappingArgs[2].val = proto;
        !           367:    AddPortMappingArgs[3].elt = "NewInternalPort";
        !           368:    AddPortMappingArgs[3].val = inPort;
        !           369:    AddPortMappingArgs[4].elt = "NewInternalClient";
        !           370:    AddPortMappingArgs[4].val = inClient;
        !           371:    AddPortMappingArgs[5].elt = "NewEnabled";
        !           372:    AddPortMappingArgs[5].val = "1";
        !           373:    AddPortMappingArgs[6].elt = "NewPortMappingDescription";
        !           374:    AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
        !           375:    AddPortMappingArgs[7].elt = "NewLeaseDuration";
        !           376:    AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
        !           377:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           378:                               "AddPortMapping", AddPortMappingArgs,
        !           379:                               &bufsize);
        !           380:    free(AddPortMappingArgs);
        !           381:    if(!buffer) {
        !           382:        return UPNPCOMMAND_HTTP_ERROR;
        !           383:    }
        !           384:    /*DisplayNameValueList(buffer, bufsize);*/
        !           385:    /*buffer[bufsize] = '\0';*/
        !           386:    /*puts(buffer);*/
        !           387:    ParseNameValue(buffer, bufsize, &pdata);
        !           388:    free(buffer);
        !           389:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !           390:    if(resVal) {
        !           391:        /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
        !           392:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           393:        sscanf(resVal, "%d", &ret);
        !           394:    } else {
        !           395:        ret = UPNPCOMMAND_SUCCESS;
        !           396:    }
        !           397:    ClearNameValueList(&pdata);
        !           398:    return ret;
        !           399: }
        !           400: 
        !           401: MINIUPNP_LIBSPEC int
        !           402: UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
        !           403:               const char * extPort,
        !           404:               const char * inPort,
        !           405:               const char * inClient,
        !           406:               const char * desc,
        !           407:               const char * proto,
        !           408:               const char * remoteHost,
        !           409:               const char * leaseDuration,
        !           410:               char * reservedPort)
        !           411: {
        !           412:    struct UPNParg * AddPortMappingArgs;
        !           413:    char * buffer;
        !           414:    int bufsize;
        !           415:    struct NameValueParserData pdata;
        !           416:    const char * resVal;
        !           417:    int ret;
        !           418: 
        !           419:    if(!inPort || !inClient || !proto || !extPort)
        !           420:        return UPNPCOMMAND_INVALID_ARGS;
        !           421: 
        !           422:    AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
        !           423:    if(AddPortMappingArgs == NULL)
        !           424:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           425:    AddPortMappingArgs[0].elt = "NewRemoteHost";
        !           426:    AddPortMappingArgs[0].val = remoteHost;
        !           427:    AddPortMappingArgs[1].elt = "NewExternalPort";
        !           428:    AddPortMappingArgs[1].val = extPort;
        !           429:    AddPortMappingArgs[2].elt = "NewProtocol";
        !           430:    AddPortMappingArgs[2].val = proto;
        !           431:    AddPortMappingArgs[3].elt = "NewInternalPort";
        !           432:    AddPortMappingArgs[3].val = inPort;
        !           433:    AddPortMappingArgs[4].elt = "NewInternalClient";
        !           434:    AddPortMappingArgs[4].val = inClient;
        !           435:    AddPortMappingArgs[5].elt = "NewEnabled";
        !           436:    AddPortMappingArgs[5].val = "1";
        !           437:    AddPortMappingArgs[6].elt = "NewPortMappingDescription";
        !           438:    AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
        !           439:    AddPortMappingArgs[7].elt = "NewLeaseDuration";
        !           440:    AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
        !           441:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           442:                               "AddAnyPortMapping", AddPortMappingArgs,
        !           443:                               &bufsize);
        !           444:    free(AddPortMappingArgs);
        !           445:    if(!buffer) {
        !           446:        return UPNPCOMMAND_HTTP_ERROR;
        !           447:    }
        !           448:    ParseNameValue(buffer, bufsize, &pdata);
        !           449:    free(buffer);
        !           450:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !           451:    if(resVal) {
        !           452:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           453:        sscanf(resVal, "%d", &ret);
        !           454:    } else {
        !           455:        char *p;
        !           456: 
        !           457:        p = GetValueFromNameValueList(&pdata, "NewReservedPort");
        !           458:        if(p) {
        !           459:            strncpy(reservedPort, p, 6);
        !           460:            reservedPort[5] = '\0';
        !           461:            ret = UPNPCOMMAND_SUCCESS;
        !           462:        } else {
        !           463:            ret = UPNPCOMMAND_INVALID_RESPONSE;
        !           464:        }
        !           465:    }
        !           466:    ClearNameValueList(&pdata);
        !           467:    return ret;
        !           468: }
        !           469: 
        !           470: MINIUPNP_LIBSPEC int
        !           471: UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
        !           472:                        const char * extPort, const char * proto,
        !           473:                        const char * remoteHost)
        !           474: {
        !           475:    /*struct NameValueParserData pdata;*/
        !           476:    struct UPNParg * DeletePortMappingArgs;
        !           477:    char * buffer;
        !           478:    int bufsize;
        !           479:    struct NameValueParserData pdata;
        !           480:    const char * resVal;
        !           481:    int ret;
        !           482: 
        !           483:    if(!extPort || !proto)
        !           484:        return UPNPCOMMAND_INVALID_ARGS;
        !           485: 
        !           486:    DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
        !           487:    if(DeletePortMappingArgs == NULL)
        !           488:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           489:    DeletePortMappingArgs[0].elt = "NewRemoteHost";
        !           490:    DeletePortMappingArgs[0].val = remoteHost;
        !           491:    DeletePortMappingArgs[1].elt = "NewExternalPort";
        !           492:    DeletePortMappingArgs[1].val = extPort;
        !           493:    DeletePortMappingArgs[2].elt = "NewProtocol";
        !           494:    DeletePortMappingArgs[2].val = proto;
        !           495:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           496:                              "DeletePortMapping",
        !           497:                              DeletePortMappingArgs, &bufsize);
        !           498:    free(DeletePortMappingArgs);
        !           499:    if(!buffer) {
        !           500:        return UPNPCOMMAND_HTTP_ERROR;
        !           501:    }
        !           502:    /*DisplayNameValueList(buffer, bufsize);*/
        !           503:    ParseNameValue(buffer, bufsize, &pdata);
        !           504:    free(buffer);
        !           505:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !           506:    if(resVal) {
        !           507:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           508:        sscanf(resVal, "%d", &ret);
        !           509:    } else {
        !           510:        ret = UPNPCOMMAND_SUCCESS;
        !           511:    }
        !           512:    ClearNameValueList(&pdata);
        !           513:    return ret;
        !           514: }
        !           515: 
        !           516: MINIUPNP_LIBSPEC int
        !           517: UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
        !           518:                    const char * extPortStart, const char * extPortEnd,
        !           519:                    const char * proto,
        !           520:                const char * manage)
        !           521: {
        !           522:    struct UPNParg * DeletePortMappingArgs;
        !           523:    char * buffer;
        !           524:    int bufsize;
        !           525:    struct NameValueParserData pdata;
        !           526:    const char * resVal;
        !           527:    int ret;
        !           528: 
        !           529:    if(!extPortStart || !extPortEnd || !proto || !manage)
        !           530:        return UPNPCOMMAND_INVALID_ARGS;
        !           531: 
        !           532:    DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg));
        !           533:    if(DeletePortMappingArgs == NULL)
        !           534:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           535:    DeletePortMappingArgs[0].elt = "NewStartPort";
        !           536:    DeletePortMappingArgs[0].val = extPortStart;
        !           537:    DeletePortMappingArgs[1].elt = "NewEndPort";
        !           538:    DeletePortMappingArgs[1].val = extPortEnd;
        !           539:    DeletePortMappingArgs[2].elt = "NewProtocol";
        !           540:    DeletePortMappingArgs[2].val = proto;
        !           541:    DeletePortMappingArgs[3].elt = "NewManage";
        !           542:    DeletePortMappingArgs[3].val = manage;
        !           543: 
        !           544:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           545:                               "DeletePortMappingRange",
        !           546:                               DeletePortMappingArgs, &bufsize);
        !           547:    free(DeletePortMappingArgs);
        !           548:    if(!buffer) {
        !           549:        return UPNPCOMMAND_HTTP_ERROR;
        !           550:    }
        !           551:    ParseNameValue(buffer, bufsize, &pdata);
        !           552:    free(buffer);
        !           553:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !           554:    if(resVal) {
        !           555:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           556:        sscanf(resVal, "%d", &ret);
        !           557:    } else {
        !           558:        ret = UPNPCOMMAND_SUCCESS;
        !           559:    }
        !           560:    ClearNameValueList(&pdata);
        !           561:    return ret;
        !           562: }
        !           563: 
        !           564: MINIUPNP_LIBSPEC int
        !           565: UPNP_GetGenericPortMappingEntry(const char * controlURL,
        !           566:                                 const char * servicetype,
        !           567:                             const char * index,
        !           568:                             char * extPort,
        !           569:                             char * intClient,
        !           570:                             char * intPort,
        !           571:                             char * protocol,
        !           572:                             char * desc,
        !           573:                             char * enabled,
        !           574:                             char * rHost,
        !           575:                             char * duration)
        !           576: {
        !           577:    struct NameValueParserData pdata;
        !           578:    struct UPNParg * GetPortMappingArgs;
        !           579:    char * buffer;
        !           580:    int bufsize;
        !           581:    char * p;
        !           582:    int r = UPNPCOMMAND_UNKNOWN_ERROR;
        !           583:    if(!index)
        !           584:        return UPNPCOMMAND_INVALID_ARGS;
        !           585:    intClient[0] = '\0';
        !           586:    intPort[0] = '\0';
        !           587:    GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
        !           588:    if(GetPortMappingArgs == NULL)
        !           589:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           590:    GetPortMappingArgs[0].elt = "NewPortMappingIndex";
        !           591:    GetPortMappingArgs[0].val = index;
        !           592:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           593:                               "GetGenericPortMappingEntry",
        !           594:                               GetPortMappingArgs, &bufsize);
        !           595:    free(GetPortMappingArgs);
        !           596:    if(!buffer) {
        !           597:        return UPNPCOMMAND_HTTP_ERROR;
        !           598:    }
        !           599:    ParseNameValue(buffer, bufsize, &pdata);
        !           600:    free(buffer);
        !           601: 
        !           602:    p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
        !           603:    if(p && rHost)
        !           604:    {
        !           605:        strncpy(rHost, p, 64);
        !           606:        rHost[63] = '\0';
        !           607:    }
        !           608:    p = GetValueFromNameValueList(&pdata, "NewExternalPort");
        !           609:    if(p && extPort)
        !           610:    {
        !           611:        strncpy(extPort, p, 6);
        !           612:        extPort[5] = '\0';
        !           613:        r = UPNPCOMMAND_SUCCESS;
        !           614:    }
        !           615:    p = GetValueFromNameValueList(&pdata, "NewProtocol");
        !           616:    if(p && protocol)
        !           617:    {
        !           618:        strncpy(protocol, p, 4);
        !           619:        protocol[3] = '\0';
        !           620:    }
        !           621:    p = GetValueFromNameValueList(&pdata, "NewInternalClient");
        !           622:    if(p)
        !           623:    {
        !           624:        strncpy(intClient, p, 16);
        !           625:        intClient[15] = '\0';
        !           626:        r = 0;
        !           627:    }
        !           628:    p = GetValueFromNameValueList(&pdata, "NewInternalPort");
        !           629:    if(p)
        !           630:    {
        !           631:        strncpy(intPort, p, 6);
        !           632:        intPort[5] = '\0';
        !           633:    }
        !           634:    p = GetValueFromNameValueList(&pdata, "NewEnabled");
        !           635:    if(p && enabled)
        !           636:    {
        !           637:        strncpy(enabled, p, 4);
        !           638:        enabled[3] = '\0';
        !           639:    }
        !           640:    p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
        !           641:    if(p && desc)
        !           642:    {
        !           643:        strncpy(desc, p, 80);
        !           644:        desc[79] = '\0';
        !           645:    }
        !           646:    p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
        !           647:    if(p && duration)
        !           648:    {
        !           649:        strncpy(duration, p, 16);
        !           650:        duration[15] = '\0';
        !           651:    }
        !           652:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           653:    if(p) {
        !           654:        r = UPNPCOMMAND_UNKNOWN_ERROR;
        !           655:        sscanf(p, "%d", &r);
        !           656:    }
        !           657:    ClearNameValueList(&pdata);
        !           658:    return r;
        !           659: }
        !           660: 
        !           661: MINIUPNP_LIBSPEC int
        !           662: UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
        !           663:                                    const char * servicetype,
        !           664:                                    unsigned int * numEntries)
        !           665: {
        !           666:    struct NameValueParserData pdata;
        !           667:    char * buffer;
        !           668:    int bufsize;
        !           669:    char* p;
        !           670:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           671:    if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           672:                                    "GetPortMappingNumberOfEntries", 0,
        !           673:                                    &bufsize))) {
        !           674:        return UPNPCOMMAND_HTTP_ERROR;
        !           675:    }
        !           676: #ifdef DEBUG
        !           677:    DisplayNameValueList(buffer, bufsize);
        !           678: #endif
        !           679:    ParseNameValue(buffer, bufsize, &pdata);
        !           680:    free(buffer);
        !           681: 
        !           682:    p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
        !           683:    if(numEntries && p) {
        !           684:        *numEntries = 0;
        !           685:        sscanf(p, "%u", numEntries);
        !           686:        ret = UPNPCOMMAND_SUCCESS;
        !           687:    }
        !           688: 
        !           689:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           690:    if(p) {
        !           691:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           692:        sscanf(p, "%d", &ret);
        !           693:    }
        !           694: 
        !           695:    ClearNameValueList(&pdata);
        !           696:    return ret;
        !           697: }
        !           698: 
        !           699: /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
        !           700:  * the result is returned in the intClient and intPort strings
        !           701:  * please provide 16 and 6 bytes of data */
        !           702: MINIUPNP_LIBSPEC int
        !           703: UPNP_GetSpecificPortMappingEntry(const char * controlURL,
        !           704:                                  const char * servicetype,
        !           705:                                  const char * extPort,
        !           706:                                  const char * proto,
        !           707:                                  const char * remoteHost,
        !           708:                                  char * intClient,
        !           709:                                  char * intPort,
        !           710:                                  char * desc,
        !           711:                                  char * enabled,
        !           712:                                  char * leaseDuration)
        !           713: {
        !           714:    struct NameValueParserData pdata;
        !           715:    struct UPNParg * GetPortMappingArgs;
        !           716:    char * buffer;
        !           717:    int bufsize;
        !           718:    char * p;
        !           719:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           720: 
        !           721:    if(!intPort || !intClient || !extPort || !proto)
        !           722:        return UPNPCOMMAND_INVALID_ARGS;
        !           723: 
        !           724:    GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
        !           725:    if(GetPortMappingArgs == NULL)
        !           726:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           727:    GetPortMappingArgs[0].elt = "NewRemoteHost";
        !           728:    GetPortMappingArgs[0].val = remoteHost;
        !           729:    GetPortMappingArgs[1].elt = "NewExternalPort";
        !           730:    GetPortMappingArgs[1].val = extPort;
        !           731:    GetPortMappingArgs[2].elt = "NewProtocol";
        !           732:    GetPortMappingArgs[2].val = proto;
        !           733:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           734:                               "GetSpecificPortMappingEntry",
        !           735:                               GetPortMappingArgs, &bufsize);
        !           736:    free(GetPortMappingArgs);
        !           737:    if(!buffer) {
        !           738:        return UPNPCOMMAND_HTTP_ERROR;
        !           739:    }
        !           740:    /*DisplayNameValueList(buffer, bufsize);*/
        !           741:    ParseNameValue(buffer, bufsize, &pdata);
        !           742:    free(buffer);
        !           743: 
        !           744:    p = GetValueFromNameValueList(&pdata, "NewInternalClient");
        !           745:    if(p) {
        !           746:        strncpy(intClient, p, 16);
        !           747:        intClient[15] = '\0';
        !           748:        ret = UPNPCOMMAND_SUCCESS;
        !           749:    } else
        !           750:        intClient[0] = '\0';
        !           751: 
        !           752:    p = GetValueFromNameValueList(&pdata, "NewInternalPort");
        !           753:    if(p) {
        !           754:        strncpy(intPort, p, 6);
        !           755:        intPort[5] = '\0';
        !           756:    } else
        !           757:        intPort[0] = '\0';
        !           758: 
        !           759:    p = GetValueFromNameValueList(&pdata, "NewEnabled");
        !           760:    if(p && enabled) {
        !           761:        strncpy(enabled, p, 4);
        !           762:        enabled[3] = '\0';
        !           763:    }
        !           764: 
        !           765:    p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
        !           766:    if(p && desc) {
        !           767:        strncpy(desc, p, 80);
        !           768:        desc[79] = '\0';
        !           769:    }
        !           770: 
        !           771:    p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
        !           772:    if(p && leaseDuration)
        !           773:    {
        !           774:        strncpy(leaseDuration, p, 16);
        !           775:        leaseDuration[15] = '\0';
        !           776:    }
        !           777: 
        !           778:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           779:    if(p) {
        !           780:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           781:        sscanf(p, "%d", &ret);
        !           782:    }
        !           783: 
        !           784:    ClearNameValueList(&pdata);
        !           785:    return ret;
        !           786: }
        !           787: 
        !           788: /* UPNP_GetListOfPortMappings()
        !           789:  *
        !           790:  * Possible UPNP Error codes :
        !           791:  * 606 Action not Authorized
        !           792:  * 730 PortMappingNotFound - no port mapping is found in the specified range.
        !           793:  * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
        !           794:  *                              consistent.
        !           795:  */
        !           796: MINIUPNP_LIBSPEC int
        !           797: UPNP_GetListOfPortMappings(const char * controlURL,
        !           798:                            const char * servicetype,
        !           799:                            const char * startPort,
        !           800:                            const char * endPort,
        !           801:                            const char * protocol,
        !           802:                            const char * numberOfPorts,
        !           803:                            struct PortMappingParserData * data)
        !           804: {
        !           805:    struct NameValueParserData pdata;
        !           806:    struct UPNParg * GetListOfPortMappingsArgs;
        !           807:    const char * p;
        !           808:    char * buffer;
        !           809:    int bufsize;
        !           810:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           811: 
        !           812:    if(!startPort || !endPort || !protocol)
        !           813:        return UPNPCOMMAND_INVALID_ARGS;
        !           814: 
        !           815:    GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
        !           816:    if(GetListOfPortMappingsArgs == NULL)
        !           817:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           818:    GetListOfPortMappingsArgs[0].elt = "NewStartPort";
        !           819:    GetListOfPortMappingsArgs[0].val = startPort;
        !           820:    GetListOfPortMappingsArgs[1].elt = "NewEndPort";
        !           821:    GetListOfPortMappingsArgs[1].val = endPort;
        !           822:    GetListOfPortMappingsArgs[2].elt = "NewProtocol";
        !           823:    GetListOfPortMappingsArgs[2].val = protocol;
        !           824:    GetListOfPortMappingsArgs[3].elt = "NewManage";
        !           825:    GetListOfPortMappingsArgs[3].val = "1";
        !           826:    GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
        !           827:    GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
        !           828: 
        !           829:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           830:                               "GetListOfPortMappings",
        !           831:                               GetListOfPortMappingsArgs, &bufsize);
        !           832:    free(GetListOfPortMappingsArgs);
        !           833:    if(!buffer) {
        !           834:        return UPNPCOMMAND_HTTP_ERROR;
        !           835:    }
        !           836: 
        !           837:    /*DisplayNameValueList(buffer, bufsize);*/
        !           838:    ParseNameValue(buffer, bufsize, &pdata);
        !           839:    free(buffer);
        !           840: 
        !           841:    /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
        !           842:    /*if(p) {
        !           843:        printf("NewPortListing : %s\n", p);
        !           844:    }*/
        !           845:    /*printf("NewPortListing(%d chars) : %s\n",
        !           846:           pdata.portListingLength, pdata.portListing);*/
        !           847:    if(pdata.portListing)
        !           848:    {
        !           849:        /*struct PortMapping * pm;
        !           850:        int i = 0;*/
        !           851:        ParsePortListing(pdata.portListing, pdata.portListingLength,
        !           852:                         data);
        !           853:        ret = UPNPCOMMAND_SUCCESS;
        !           854:        /*
        !           855:        for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
        !           856:        {
        !           857:            printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
        !           858:                   i, pm->protocol, pm->externalPort, pm->internalClient,
        !           859:                   pm->internalPort,
        !           860:                   pm->description, pm->remoteHost);
        !           861:            i++;
        !           862:        }
        !           863:        */
        !           864:        /*FreePortListing(&data);*/
        !           865:    }
        !           866: 
        !           867:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           868:    if(p) {
        !           869:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           870:        sscanf(p, "%d", &ret);
        !           871:    }
        !           872:    ClearNameValueList(&pdata);
        !           873: 
        !           874:    /*printf("%.*s", bufsize, buffer);*/
        !           875: 
        !           876:    return ret;
        !           877: }
        !           878: 
        !           879: /* IGD:2, functions for service WANIPv6FirewallControl:1 */
        !           880: MINIUPNP_LIBSPEC int
        !           881: UPNP_GetFirewallStatus(const char * controlURL,
        !           882:                const char * servicetype,
        !           883:                int * firewallEnabled,
        !           884:                int * inboundPinholeAllowed)
        !           885: {
        !           886:    struct NameValueParserData pdata;
        !           887:    char * buffer;
        !           888:    int bufsize;
        !           889:    char * fe, *ipa, *p;
        !           890:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           891: 
        !           892:    if(!firewallEnabled || !inboundPinholeAllowed)
        !           893:        return UPNPCOMMAND_INVALID_ARGS;
        !           894: 
        !           895:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           896:                               "GetFirewallStatus", 0, &bufsize);
        !           897:    if(!buffer) {
        !           898:        return UPNPCOMMAND_HTTP_ERROR;
        !           899:    }
        !           900:    ParseNameValue(buffer, bufsize, &pdata);
        !           901:    free(buffer);
        !           902:    fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
        !           903:    ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
        !           904:    if(ipa && fe)
        !           905:        ret = UPNPCOMMAND_SUCCESS;
        !           906:    if(fe)
        !           907:        *firewallEnabled = my_atoui(fe);
        !           908:    /*else
        !           909:        *firewallEnabled = 0;*/
        !           910:    if(ipa)
        !           911:        *inboundPinholeAllowed = my_atoui(ipa);
        !           912:    /*else
        !           913:        *inboundPinholeAllowed = 0;*/
        !           914:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !           915:    if(p)
        !           916:    {
        !           917:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           918:        sscanf(p, "%d", &ret);
        !           919:    }
        !           920:    ClearNameValueList(&pdata);
        !           921:    return ret;
        !           922: }
        !           923: 
        !           924: MINIUPNP_LIBSPEC int
        !           925: UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
        !           926:                     const char * remoteHost,
        !           927:                     const char * remotePort,
        !           928:                     const char * intClient,
        !           929:                     const char * intPort,
        !           930:                     const char * proto,
        !           931:                     int * opTimeout)
        !           932: {
        !           933:    struct UPNParg * GetOutboundPinholeTimeoutArgs;
        !           934:    char * buffer;
        !           935:    int bufsize;
        !           936:    struct NameValueParserData pdata;
        !           937:    const char * resVal;
        !           938:    int ret;
        !           939: 
        !           940:    if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
        !           941:        return UPNPCOMMAND_INVALID_ARGS;
        !           942: 
        !           943:    GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
        !           944:    if(GetOutboundPinholeTimeoutArgs == NULL)
        !           945:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !           946:    GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
        !           947:    GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
        !           948:    GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
        !           949:    GetOutboundPinholeTimeoutArgs[1].val = remotePort;
        !           950:    GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
        !           951:    GetOutboundPinholeTimeoutArgs[2].val = proto;
        !           952:    GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
        !           953:    GetOutboundPinholeTimeoutArgs[3].val = intPort;
        !           954:    GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
        !           955:    GetOutboundPinholeTimeoutArgs[4].val = intClient;
        !           956:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !           957:                               "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
        !           958:    free(GetOutboundPinholeTimeoutArgs);
        !           959:    if(!buffer)
        !           960:        return UPNPCOMMAND_HTTP_ERROR;
        !           961:    ParseNameValue(buffer, bufsize, &pdata);
        !           962:    free(buffer);
        !           963:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !           964:    if(resVal)
        !           965:    {
        !           966:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !           967:        sscanf(resVal, "%d", &ret);
        !           968:    }
        !           969:    else
        !           970:    {
        !           971:        const char * p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
        !           972:        if(p)
        !           973:            *opTimeout = my_atoui(p);
        !           974:        ret = UPNPCOMMAND_SUCCESS;
        !           975:    }
        !           976:    ClearNameValueList(&pdata);
        !           977:    return ret;
        !           978: }
        !           979: 
        !           980: MINIUPNP_LIBSPEC int
        !           981: UPNP_AddPinhole(const char * controlURL, const char * servicetype,
        !           982:                     const char * remoteHost,
        !           983:                     const char * remotePort,
        !           984:                     const char * intClient,
        !           985:                     const char * intPort,
        !           986:                     const char * proto,
        !           987:                     const char * leaseTime,
        !           988:                     char * uniqueID)
        !           989: {
        !           990:    struct UPNParg * AddPinholeArgs;
        !           991:    char * buffer;
        !           992:    int bufsize;
        !           993:    struct NameValueParserData pdata;
        !           994:    const char * resVal;
        !           995:    char * p;
        !           996:    int ret;
        !           997: 
        !           998:    if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
        !           999:        return UPNPCOMMAND_INVALID_ARGS;
        !          1000: 
        !          1001:    AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
        !          1002:    if(AddPinholeArgs == NULL)
        !          1003:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !          1004:    /* RemoteHost can be wilcarded */
        !          1005:    if(strncmp(remoteHost, "empty", 5)==0)
        !          1006:    {
        !          1007:        AddPinholeArgs[0].elt = "RemoteHost";
        !          1008:        AddPinholeArgs[0].val = "";
        !          1009:    }
        !          1010:    else
        !          1011:    {
        !          1012:        AddPinholeArgs[0].elt = "RemoteHost";
        !          1013:        AddPinholeArgs[0].val = remoteHost;
        !          1014:    }
        !          1015:    AddPinholeArgs[1].elt = "RemotePort";
        !          1016:    AddPinholeArgs[1].val = remotePort;
        !          1017:    AddPinholeArgs[2].elt = "Protocol";
        !          1018:    AddPinholeArgs[2].val = proto;
        !          1019:    AddPinholeArgs[3].elt = "InternalPort";
        !          1020:    AddPinholeArgs[3].val = intPort;
        !          1021:    if(strncmp(intClient, "empty", 5)==0)
        !          1022:    {
        !          1023:        AddPinholeArgs[4].elt = "InternalClient";
        !          1024:        AddPinholeArgs[4].val = "";
        !          1025:    }
        !          1026:    else
        !          1027:    {
        !          1028:        AddPinholeArgs[4].elt = "InternalClient";
        !          1029:        AddPinholeArgs[4].val = intClient;
        !          1030:    }
        !          1031:    AddPinholeArgs[5].elt = "LeaseTime";
        !          1032:    AddPinholeArgs[5].val = leaseTime;
        !          1033:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !          1034:                               "AddPinhole", AddPinholeArgs, &bufsize);
        !          1035:    free(AddPinholeArgs);
        !          1036:    if(!buffer)
        !          1037:        return UPNPCOMMAND_HTTP_ERROR;
        !          1038:    ParseNameValue(buffer, bufsize, &pdata);
        !          1039:    free(buffer);
        !          1040:    p = GetValueFromNameValueList(&pdata, "UniqueID");
        !          1041:    if(p)
        !          1042:    {
        !          1043:        strncpy(uniqueID, p, 8);
        !          1044:        uniqueID[7] = '\0';
        !          1045:    }
        !          1046:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !          1047:    if(resVal)
        !          1048:    {
        !          1049:        /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
        !          1050:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1051:        sscanf(resVal, "%d", &ret);
        !          1052:    }
        !          1053:    else
        !          1054:    {
        !          1055:        ret = UPNPCOMMAND_SUCCESS;
        !          1056:    }
        !          1057:    ClearNameValueList(&pdata);
        !          1058:    return ret;
        !          1059: }
        !          1060: 
        !          1061: MINIUPNP_LIBSPEC int
        !          1062: UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
        !          1063:                     const char * uniqueID,
        !          1064:                     const char * leaseTime)
        !          1065: {
        !          1066:    struct UPNParg * UpdatePinholeArgs;
        !          1067:    char * buffer;
        !          1068:    int bufsize;
        !          1069:    struct NameValueParserData pdata;
        !          1070:    const char * resVal;
        !          1071:    int ret;
        !          1072: 
        !          1073:    if(!uniqueID || !leaseTime)
        !          1074:        return UPNPCOMMAND_INVALID_ARGS;
        !          1075: 
        !          1076:    UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
        !          1077:    if(UpdatePinholeArgs == NULL)
        !          1078:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !          1079:    UpdatePinholeArgs[0].elt = "UniqueID";
        !          1080:    UpdatePinholeArgs[0].val = uniqueID;
        !          1081:    UpdatePinholeArgs[1].elt = "NewLeaseTime";
        !          1082:    UpdatePinholeArgs[1].val = leaseTime;
        !          1083:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !          1084:                               "UpdatePinhole", UpdatePinholeArgs, &bufsize);
        !          1085:    free(UpdatePinholeArgs);
        !          1086:    if(!buffer)
        !          1087:        return UPNPCOMMAND_HTTP_ERROR;
        !          1088:    ParseNameValue(buffer, bufsize, &pdata);
        !          1089:    free(buffer);
        !          1090:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !          1091:    if(resVal)
        !          1092:    {
        !          1093:        /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
        !          1094:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1095:        sscanf(resVal, "%d", &ret);
        !          1096:    }
        !          1097:    else
        !          1098:    {
        !          1099:        ret = UPNPCOMMAND_SUCCESS;
        !          1100:    }
        !          1101:    ClearNameValueList(&pdata);
        !          1102:    return ret;
        !          1103: }
        !          1104: 
        !          1105: MINIUPNP_LIBSPEC int
        !          1106: UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
        !          1107: {
        !          1108:    /*struct NameValueParserData pdata;*/
        !          1109:    struct UPNParg * DeletePinholeArgs;
        !          1110:    char * buffer;
        !          1111:    int bufsize;
        !          1112:    struct NameValueParserData pdata;
        !          1113:    const char * resVal;
        !          1114:    int ret;
        !          1115: 
        !          1116:    if(!uniqueID)
        !          1117:        return UPNPCOMMAND_INVALID_ARGS;
        !          1118: 
        !          1119:    DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
        !          1120:    if(DeletePinholeArgs == NULL)
        !          1121:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !          1122:    DeletePinholeArgs[0].elt = "UniqueID";
        !          1123:    DeletePinholeArgs[0].val = uniqueID;
        !          1124:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !          1125:                               "DeletePinhole", DeletePinholeArgs, &bufsize);
        !          1126:    free(DeletePinholeArgs);
        !          1127:    if(!buffer)
        !          1128:        return UPNPCOMMAND_HTTP_ERROR;
        !          1129:    /*DisplayNameValueList(buffer, bufsize);*/
        !          1130:    ParseNameValue(buffer, bufsize, &pdata);
        !          1131:    free(buffer);
        !          1132:    resVal = GetValueFromNameValueList(&pdata, "errorCode");
        !          1133:    if(resVal)
        !          1134:    {
        !          1135:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1136:        sscanf(resVal, "%d", &ret);
        !          1137:    }
        !          1138:    else
        !          1139:    {
        !          1140:        ret = UPNPCOMMAND_SUCCESS;
        !          1141:    }
        !          1142:    ClearNameValueList(&pdata);
        !          1143:    return ret;
        !          1144: }
        !          1145: 
        !          1146: MINIUPNP_LIBSPEC int
        !          1147: UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
        !          1148:                                  const char * uniqueID, int * isWorking)
        !          1149: {
        !          1150:    struct NameValueParserData pdata;
        !          1151:    struct UPNParg * CheckPinholeWorkingArgs;
        !          1152:    char * buffer;
        !          1153:    int bufsize;
        !          1154:    char * p;
        !          1155:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1156: 
        !          1157:    if(!uniqueID)
        !          1158:        return UPNPCOMMAND_INVALID_ARGS;
        !          1159: 
        !          1160:    CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
        !          1161:    if(CheckPinholeWorkingArgs == NULL)
        !          1162:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !          1163:    CheckPinholeWorkingArgs[0].elt = "UniqueID";
        !          1164:    CheckPinholeWorkingArgs[0].val = uniqueID;
        !          1165:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !          1166:                               "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
        !          1167:    free(CheckPinholeWorkingArgs);
        !          1168:    if(!buffer)
        !          1169:    {
        !          1170:        return UPNPCOMMAND_HTTP_ERROR;
        !          1171:    }
        !          1172:    ParseNameValue(buffer, bufsize, &pdata);
        !          1173:    free(buffer);
        !          1174: 
        !          1175:    p = GetValueFromNameValueList(&pdata, "IsWorking");
        !          1176:    if(p)
        !          1177:    {
        !          1178:        *isWorking=my_atoui(p);
        !          1179:        ret = UPNPCOMMAND_SUCCESS;
        !          1180:    }
        !          1181:    else
        !          1182:        *isWorking = 0;
        !          1183: 
        !          1184:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !          1185:    if(p)
        !          1186:    {
        !          1187:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1188:        sscanf(p, "%d", &ret);
        !          1189:    }
        !          1190: 
        !          1191:    ClearNameValueList(&pdata);
        !          1192:    return ret;
        !          1193: }
        !          1194: 
        !          1195: MINIUPNP_LIBSPEC int
        !          1196: UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
        !          1197:                                  const char * uniqueID, int * packets)
        !          1198: {
        !          1199:    struct NameValueParserData pdata;
        !          1200:    struct UPNParg * GetPinholePacketsArgs;
        !          1201:    char * buffer;
        !          1202:    int bufsize;
        !          1203:    char * p;
        !          1204:    int ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1205: 
        !          1206:    if(!uniqueID)
        !          1207:        return UPNPCOMMAND_INVALID_ARGS;
        !          1208: 
        !          1209:    GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
        !          1210:    if(GetPinholePacketsArgs == NULL)
        !          1211:        return UPNPCOMMAND_MEM_ALLOC_ERROR;
        !          1212:    GetPinholePacketsArgs[0].elt = "UniqueID";
        !          1213:    GetPinholePacketsArgs[0].val = uniqueID;
        !          1214:    buffer = simpleUPnPcommand(-1, controlURL, servicetype,
        !          1215:                               "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
        !          1216:    free(GetPinholePacketsArgs);
        !          1217:    if(!buffer)
        !          1218:        return UPNPCOMMAND_HTTP_ERROR;
        !          1219:    ParseNameValue(buffer, bufsize, &pdata);
        !          1220:    free(buffer);
        !          1221: 
        !          1222:    p = GetValueFromNameValueList(&pdata, "PinholePackets");
        !          1223:    if(p)
        !          1224:    {
        !          1225:        *packets=my_atoui(p);
        !          1226:        ret = UPNPCOMMAND_SUCCESS;
        !          1227:    }
        !          1228: 
        !          1229:    p = GetValueFromNameValueList(&pdata, "errorCode");
        !          1230:    if(p)
        !          1231:    {
        !          1232:        ret = UPNPCOMMAND_UNKNOWN_ERROR;
        !          1233:        sscanf(p, "%d", &ret);
        !          1234:    }
        !          1235: 
        !          1236:    ClearNameValueList(&pdata);
        !          1237:    return ret;
        !          1238: }

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