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