Annotation of embedaddon/miniupnpc/upnpc.c, revision 1.1.1.2

1.1.1.2 ! misho       1: /* $Id: upnpc.c,v 1.99 2013/02/06 12:56:41 nanard Exp $ */
1.1       misho       2: /* Project : miniupnp
                      3:  * Author : Thomas Bernard
1.1.1.2 ! misho       4:  * Copyright (c) 2005-2013 Thomas Bernard
1.1       misho       5:  * This software is subject to the conditions detailed in the
                      6:  * LICENCE file provided in this distribution. */
                      7: 
                      8: #include <stdio.h>
                      9: #include <stdlib.h>
                     10: #include <string.h>
                     11: #include <time.h>
1.1.1.2 ! misho      12: #ifdef _WIN32
1.1       misho      13: #include <winsock2.h>
                     14: #define snprintf _snprintf
1.1.1.2 ! misho      15: #else
        !            16: /* for IPPROTO_TCP / IPPROTO_UDP */
        !            17: #include <netinet/in.h>
1.1       misho      18: #endif
                     19: #include "miniwget.h"
                     20: #include "miniupnpc.h"
                     21: #include "upnpcommands.h"
                     22: #include "upnperrors.h"
                     23: 
1.1.1.2 ! misho      24: /* protofix() checks if protocol is "UDP" or "TCP"
1.1       misho      25:  * returns NULL if not */
                     26: const char * protofix(const char * proto)
                     27: {
                     28:        static const char proto_tcp[4] = { 'T', 'C', 'P', 0};
                     29:        static const char proto_udp[4] = { 'U', 'D', 'P', 0};
                     30:        int i, b;
                     31:        for(i=0, b=1; i<4; i++)
1.1.1.2 ! misho      32:                b = b && (   (proto[i] == proto_tcp[i])
1.1       misho      33:                          || (proto[i] == (proto_tcp[i] | 32)) );
                     34:        if(b)
                     35:                return proto_tcp;
                     36:        for(i=0, b=1; i<4; i++)
                     37:                b = b && (   (proto[i] == proto_udp[i])
                     38:                          || (proto[i] == (proto_udp[i] | 32)) );
                     39:        if(b)
                     40:                return proto_udp;
                     41:        return 0;
                     42: }
                     43: 
                     44: static void DisplayInfos(struct UPNPUrls * urls,
                     45:                          struct IGDdatas * data)
                     46: {
                     47:        char externalIPAddress[40];
                     48:        char connectionType[64];
                     49:        char status[64];
                     50:        char lastconnerr[64];
                     51:        unsigned int uptime;
                     52:        unsigned int brUp, brDown;
                     53:        time_t timenow, timestarted;
                     54:        int r;
1.1.1.2 ! misho      55:        if(UPNP_GetConnectionTypeInfo(urls->controlURL,
        !            56:                                      data->first.servicetype,
        !            57:                                      connectionType) != UPNPCOMMAND_SUCCESS)
        !            58:                printf("GetConnectionTypeInfo failed.\n");
        !            59:        else
1.1       misho      60:                printf("Connection Type : %s\n", connectionType);
1.1.1.2 ! misho      61:        if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
        !            62:                              status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS)
        !            63:                printf("GetStatusInfo failed.\n");
1.1       misho      64:        else
1.1.1.2 ! misho      65:                printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
        !            66:                       status, uptime, lastconnerr);
1.1       misho      67:        timenow = time(NULL);
                     68:        timestarted = timenow - uptime;
                     69:        printf("  Time started : %s", ctime(&timestarted));
1.1.1.2 ! misho      70:        if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
        !            71:                                        &brDown, &brUp) != UPNPCOMMAND_SUCCESS) {
        !            72:                printf("GetLinkLayerMaxBitRates failed.\n");
        !            73:        } else {
        !            74:                printf("MaxBitRateDown : %u bps", brDown);
        !            75:                if(brDown >= 1000000) {
        !            76:                        printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10);
        !            77:                } else if(brDown >= 1000) {
        !            78:                        printf(" (%u Kbps)", brDown / 1000);
        !            79:                }
        !            80:                printf("   MaxBitRateUp %u bps", brUp);
        !            81:                if(brUp >= 1000000) {
        !            82:                        printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10);
        !            83:                } else if(brUp >= 1000) {
        !            84:                        printf(" (%u Kbps)", brUp / 1000);
        !            85:                }
        !            86:                printf("\n");
1.1       misho      87:        }
                     88:        r = UPNP_GetExternalIPAddress(urls->controlURL,
                     89:                                  data->first.servicetype,
                     90:                                                          externalIPAddress);
1.1.1.2 ! misho      91:        if(r != UPNPCOMMAND_SUCCESS) {
        !            92:                printf("GetExternalIPAddress failed. (errorcode=%d)\n", r);
        !            93:        } else {
1.1       misho      94:                printf("ExternalIPAddress = %s\n", externalIPAddress);
1.1.1.2 ! misho      95:        }
1.1       misho      96: }
                     97: 
                     98: static void GetConnectionStatus(struct UPNPUrls * urls,
                     99:                                struct IGDdatas * data)
                    100: {
                    101:        unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
                    102:        DisplayInfos(urls, data);
                    103:        bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
                    104:        bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
                    105:        packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
                    106:        packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
                    107:        printf("Bytes:   Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
                    108:        printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
                    109: }
                    110: 
                    111: static void ListRedirections(struct UPNPUrls * urls,
                    112:                              struct IGDdatas * data)
                    113: {
                    114:        int r;
                    115:        int i = 0;
                    116:        char index[6];
                    117:        char intClient[40];
                    118:        char intPort[6];
                    119:        char extPort[6];
                    120:        char protocol[4];
                    121:        char desc[80];
                    122:        char enabled[6];
                    123:        char rHost[64];
                    124:        char duration[16];
                    125:        /*unsigned int num=0;
                    126:        UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
                    127:        printf("PortMappingNumberOfEntries : %u\n", num);*/
1.1.1.2 ! misho     128:        printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
1.1       misho     129:        do {
                    130:                snprintf(index, 6, "%d", i);
                    131:                rHost[0] = '\0'; enabled[0] = '\0';
                    132:                duration[0] = '\0'; desc[0] = '\0';
                    133:                extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
                    134:                r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
                    135:                                               data->first.servicetype,
                    136:                                               index,
                    137:                                               extPort, intClient, intPort,
                    138:                                                                           protocol, desc, enabled,
                    139:                                                                           rHost, duration);
                    140:                if(r==0)
                    141:                /*
                    142:                        printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n"
                    143:                               "     desc='%s' rHost='%s'\n",
                    144:                               i, protocol, extPort, intClient, intPort,
                    145:                                   enabled, duration,
                    146:                                   desc, rHost);
                    147:                                   */
                    148:                        printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",
                    149:                               i, protocol, extPort, intClient, intPort,
                    150:                               desc, rHost, duration);
                    151:                else
                    152:                        printf("GetGenericPortMappingEntry() returned %d (%s)\n",
                    153:                               r, strupnperror(r));
                    154:                i++;
                    155:        } while(r==0);
                    156: }
                    157: 
                    158: static void NewListRedirections(struct UPNPUrls * urls,
                    159:                                 struct IGDdatas * data)
                    160: {
                    161:        int r;
                    162:        int i = 0;
                    163:        struct PortMappingParserData pdata;
                    164:        struct PortMapping * pm;
                    165: 
                    166:        memset(&pdata, 0, sizeof(struct PortMappingParserData));
                    167:        r = UPNP_GetListOfPortMappings(urls->controlURL,
                    168:                                    data->first.servicetype,
                    169:                                       "0",
                    170:                                       "65535",
                    171:                                       "TCP",
                    172:                                       "1000",
                    173:                                       &pdata);
                    174:        if(r == UPNPCOMMAND_SUCCESS)
                    175:        {
1.1.1.2 ! misho     176:                printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
1.1       misho     177:                for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
                    178:                {
                    179:                        printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
                    180:                               i, pm->protocol, pm->externalPort, pm->internalClient,
                    181:                               pm->internalPort,
                    182:                               pm->description, pm->remoteHost,
                    183:                               (unsigned)pm->leaseTime);
                    184:                        i++;
                    185:                }
                    186:                FreePortListing(&pdata);
                    187:        }
                    188:        else
                    189:        {
                    190:                printf("GetListOfPortMappings() returned %d (%s)\n",
                    191:                       r, strupnperror(r));
                    192:        }
                    193:        r = UPNP_GetListOfPortMappings(urls->controlURL,
                    194:                                    data->first.servicetype,
                    195:                                       "0",
                    196:                                       "65535",
                    197:                                       "UDP",
                    198:                                       "1000",
                    199:                                       &pdata);
                    200:        if(r == UPNPCOMMAND_SUCCESS)
                    201:        {
                    202:                for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
                    203:                {
                    204:                        printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
                    205:                               i, pm->protocol, pm->externalPort, pm->internalClient,
                    206:                               pm->internalPort,
                    207:                               pm->description, pm->remoteHost,
                    208:                               (unsigned)pm->leaseTime);
                    209:                        i++;
                    210:                }
                    211:                FreePortListing(&pdata);
                    212:        }
                    213:        else
                    214:        {
                    215:                printf("GetListOfPortMappings() returned %d (%s)\n",
                    216:                       r, strupnperror(r));
                    217:        }
                    218: }
                    219: 
1.1.1.2 ! misho     220: /* Test function
1.1       misho     221:  * 1 - get connection type
                    222:  * 2 - get extenal ip address
                    223:  * 3 - Add port mapping
                    224:  * 4 - get this port mapping from the IGD */
                    225: static void SetRedirectAndTest(struct UPNPUrls * urls,
                    226:                                struct IGDdatas * data,
                    227:                                                           const char * iaddr,
                    228:                                                           const char * iport,
                    229:                                                           const char * eport,
                    230:                                const char * proto,
1.1.1.2 ! misho     231:                                const char * leaseDuration,
        !           232:                                const char * description)
1.1       misho     233: {
                    234:        char externalIPAddress[40];
                    235:        char intClient[40];
                    236:        char intPort[6];
                    237:        char duration[16];
                    238:        int r;
                    239: 
                    240:        if(!iaddr || !iport || !eport || !proto)
                    241:        {
                    242:                fprintf(stderr, "Wrong arguments\n");
                    243:                return;
                    244:        }
                    245:        proto = protofix(proto);
                    246:        if(!proto)
                    247:        {
                    248:                fprintf(stderr, "invalid protocol\n");
                    249:                return;
                    250:        }
1.1.1.2 ! misho     251: 
1.1       misho     252:        UPNP_GetExternalIPAddress(urls->controlURL,
                    253:                                  data->first.servicetype,
                    254:                                                          externalIPAddress);
                    255:        if(externalIPAddress[0])
                    256:                printf("ExternalIPAddress = %s\n", externalIPAddress);
                    257:        else
                    258:                printf("GetExternalIPAddress failed.\n");
1.1.1.2 ! misho     259: 
1.1       misho     260:        r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
1.1.1.2 ! misho     261:                                eport, iport, iaddr, description,
        !           262:                                proto, 0, leaseDuration);
1.1       misho     263:        if(r!=UPNPCOMMAND_SUCCESS)
                    264:                printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
                    265:                       eport, iport, iaddr, r, strupnperror(r));
                    266: 
                    267:        r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
                    268:                                         data->first.servicetype,
                    269:                                     eport, proto,
                    270:                                                                         intClient, intPort, NULL/*desc*/,
                    271:                                         NULL/*enabled*/, duration);
                    272:        if(r!=UPNPCOMMAND_SUCCESS)
                    273:                printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
                    274:                       r, strupnperror(r));
1.1.1.2 ! misho     275: 
1.1       misho     276:        if(intClient[0]) {
                    277:                printf("InternalIP:Port = %s:%s\n", intClient, intPort);
                    278:                printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n",
                    279:                       externalIPAddress, eport, proto, intClient, intPort, duration);
                    280:        }
                    281: }
                    282: 
                    283: static void
                    284: RemoveRedirect(struct UPNPUrls * urls,
                    285:                struct IGDdatas * data,
                    286:                           const char * eport,
                    287:                           const char * proto)
                    288: {
                    289:        int r;
                    290:        if(!proto || !eport)
                    291:        {
                    292:                fprintf(stderr, "invalid arguments\n");
                    293:                return;
                    294:        }
                    295:        proto = protofix(proto);
                    296:        if(!proto)
                    297:        {
                    298:                fprintf(stderr, "protocol invalid\n");
                    299:                return;
                    300:        }
                    301:        r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0);
                    302:        printf("UPNP_DeletePortMapping() returned : %d\n", r);
                    303: }
                    304: 
                    305: /* IGD:2, functions for service WANIPv6FirewallControl:1 */
                    306: static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
                    307: {
                    308:        unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
                    309:        int firewallEnabled = 0, inboundPinholeAllowed = 0;
                    310: 
                    311:        UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed);
                    312:        printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed);
                    313:        printf("GetFirewallStatus:\n   Firewall Enabled: %s\n   Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No");
1.1.1.2 ! misho     314: 
1.1       misho     315:        bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
                    316:        bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
                    317:        packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
                    318:        packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
                    319:        printf("Bytes:   Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
                    320:        printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
                    321: }
                    322: 
1.1.1.2 ! misho     323: /* Test function
1.1       misho     324:  * 1 - Add pinhole
                    325:  * 2 - Check if pinhole is working from the IGD side */
                    326: static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data,
                    327:                                        const char * remoteaddr, const char * eport,
                    328:                                        const char * intaddr, const char * iport,
                    329:                                        const char * proto, const char * lease_time)
                    330: {
                    331:        char uniqueID[8];
1.1.1.2 ! misho     332:        /*int isWorking = 0;*/
1.1       misho     333:        int r;
1.1.1.2 ! misho     334:        char proto_tmp[8];
1.1       misho     335: 
                    336:        if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time)
                    337:        {
                    338:                fprintf(stderr, "Wrong arguments\n");
                    339:                return;
                    340:        }
1.1.1.2 ! misho     341:        if(atoi(proto) == 0)
1.1       misho     342:        {
1.1.1.2 ! misho     343:                const char * protocol;
        !           344:                protocol = protofix(proto);
        !           345:                if(protocol && (strcmp("TCP", protocol) == 0))
        !           346:                {
        !           347:                        snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP);
        !           348:                        proto = proto_tmp;
        !           349:                }
        !           350:                else if(protocol && (strcmp("UDP", protocol) == 0))
        !           351:                {
        !           352:                        snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP);
        !           353:                        proto = proto_tmp;
        !           354:                }
        !           355:                else
        !           356:                {
        !           357:                        fprintf(stderr, "invalid protocol\n");
        !           358:                        return;
        !           359:                }
        !           360:        }
1.1       misho     361:        r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID);
                    362:        if(r!=UPNPCOMMAND_SUCCESS)
                    363:                printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
1.1.1.2 ! misho     364:                       remoteaddr, eport, intaddr, iport, r, strupnperror(r));
1.1       misho     365:        else
                    366:        {
1.1.1.2 ! misho     367:                printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n",
        !           368:                       remoteaddr, eport, intaddr, iport, uniqueID);
1.1       misho     369:                /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking);
                    370:                if(r!=UPNPCOMMAND_SUCCESS)
                    371:                        printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
                    372:                printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/
                    373:        }
                    374: }
                    375: 
                    376: /* Test function
                    377:  * 1 - Check if pinhole is working from the IGD side
                    378:  * 2 - Update pinhole */
                    379: static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data,
                    380:                                        const char * uniqueID, const char * lease_time)
                    381: {
                    382:        int isWorking = 0;
                    383:        int r;
                    384: 
                    385:        if(!uniqueID || !lease_time)
                    386:        {
                    387:                fprintf(stderr, "Wrong arguments\n");
                    388:                return;
                    389:        }
                    390:        r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
                    391:        printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
                    392:        if(r!=UPNPCOMMAND_SUCCESS)
                    393:                printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
                    394:        if(isWorking || r==709)
                    395:        {
                    396:                r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time);
                    397:                printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time);
                    398:                if(r!=UPNPCOMMAND_SUCCESS)
                    399:                        printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r));
                    400:        }
                    401: }
                    402: 
1.1.1.2 ! misho     403: /* Test function
1.1       misho     404:  * Get pinhole timeout
                    405:  */
                    406: static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data,
                    407:                                        const char * remoteaddr, const char * eport,
                    408:                                        const char * intaddr, const char * iport,
                    409:                                        const char * proto)
                    410: {
                    411:        int timeout = 0;
                    412:        int r;
                    413: 
                    414:        if(!intaddr || !remoteaddr || !iport || !eport || !proto)
                    415:        {
                    416:                fprintf(stderr, "Wrong arguments\n");
                    417:                return;
                    418:        }
                    419: 
                    420:        r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout);
                    421:        if(r!=UPNPCOMMAND_SUCCESS)
                    422:                printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
                    423:                       intaddr, iport, remoteaddr, eport, r, strupnperror(r));
                    424:        else
                    425:                printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout);
                    426: }
                    427: 
                    428: static void
                    429: GetPinholePackets(struct UPNPUrls * urls,
                    430:                struct IGDdatas * data, const char * uniqueID)
                    431: {
                    432:        int r, pinholePackets = 0;
                    433:        if(!uniqueID)
                    434:        {
                    435:                fprintf(stderr, "invalid arguments\n");
                    436:                return;
                    437:        }
                    438:        r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets);
                    439:        if(r!=UPNPCOMMAND_SUCCESS)
                    440:                printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r));
                    441:        else
                    442:                printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets);
                    443: }
                    444: 
                    445: static void
                    446: CheckPinhole(struct UPNPUrls * urls,
                    447:                struct IGDdatas * data, const char * uniqueID)
                    448: {
                    449:        int r, isWorking = 0;
                    450:        if(!uniqueID)
                    451:        {
                    452:                fprintf(stderr, "invalid arguments\n");
                    453:                return;
                    454:        }
                    455:        r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
                    456:        if(r!=UPNPCOMMAND_SUCCESS)
                    457:                printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
                    458:        else
                    459:                printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
                    460: }
                    461: 
                    462: static void
                    463: RemovePinhole(struct UPNPUrls * urls,
                    464:                struct IGDdatas * data, const char * uniqueID)
                    465: {
                    466:        int r;
                    467:        if(!uniqueID)
                    468:        {
                    469:                fprintf(stderr, "invalid arguments\n");
                    470:                return;
                    471:        }
                    472:        r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID);
                    473:        printf("UPNP_DeletePinhole() returned : %d\n", r);
                    474: }
                    475: 
                    476: 
                    477: /* sample upnp client program */
                    478: int main(int argc, char ** argv)
                    479: {
                    480:        char command = 0;
                    481:        char ** commandargv = 0;
                    482:        int commandargc = 0;
                    483:        struct UPNPDev * devlist = 0;
                    484:        char lanaddr[64];       /* my ip address on the LAN */
                    485:        int i;
                    486:        const char * rootdescurl = 0;
                    487:        const char * multicastif = 0;
                    488:        const char * minissdpdpath = 0;
                    489:        int retcode = 0;
                    490:        int error = 0;
                    491:        int ipv6 = 0;
1.1.1.2 ! misho     492:        const char * description = 0;
1.1       misho     493: 
1.1.1.2 ! misho     494: #ifdef _WIN32
1.1       misho     495:        WSADATA wsaData;
                    496:        int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
                    497:        if(nResult != NO_ERROR)
                    498:        {
                    499:                fprintf(stderr, "WSAStartup() failed.\n");
                    500:                return -1;
                    501:        }
                    502: #endif
1.1.1.2 ! misho     503:     printf("upnpc : miniupnpc library test client. (c) 2005-2013 Thomas Bernard\n");
1.1       misho     504:     printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
                    505:               "for more information.\n");
                    506:        /* command line processing */
                    507:        for(i=1; i<argc; i++)
                    508:        {
                    509:                if(argv[i][0] == '-')
                    510:                {
                    511:                        if(argv[i][1] == 'u')
                    512:                                rootdescurl = argv[++i];
                    513:                        else if(argv[i][1] == 'm')
                    514:                                multicastif = argv[++i];
                    515:                        else if(argv[i][1] == 'p')
                    516:                                minissdpdpath = argv[++i];
                    517:                        else if(argv[i][1] == '6')
                    518:                                ipv6 = 1;
1.1.1.2 ! misho     519:                        else if(argv[i][1] == 'e')
        !           520:                                description = argv[++i];
1.1       misho     521:                        else
                    522:                        {
                    523:                                command = argv[i][1];
                    524:                                i++;
                    525:                                commandargv = argv + i;
                    526:                                commandargc = argc - i;
                    527:                                break;
                    528:                        }
                    529:                }
                    530:                else
                    531:                {
                    532:                        fprintf(stderr, "option '%s' invalid\n", argv[i]);
                    533:                }
                    534:        }
                    535: 
                    536:        if(!command || (command == 'a' && commandargc<4)
                    537:           || (command == 'd' && argc<2)
                    538:           || (command == 'r' && argc<2)
                    539:           || (command == 'A' && commandargc<6)
                    540:           || (command == 'U' && commandargc<2)
                    541:           || (command == 'D' && commandargc<1))
                    542:        {
                    543:                fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]);
                    544:                fprintf(stderr, "       \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
                    545:                fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
                    546:                fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
                    547:                fprintf(stderr, "       \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings, IGD v2)\n", argv[0]);
                    548:                fprintf(stderr, "       \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
                    549:                fprintf(stderr, "       \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]);
                    550:                fprintf(stderr, "       \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
                    551:                fprintf(stderr, "       \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]);
                    552:                fprintf(stderr, "       \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]);
                    553:                fprintf(stderr, "       \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]);
                    554:                fprintf(stderr, "       \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]);
                    555:                fprintf(stderr, "       \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]);
                    556:                fprintf(stderr, "       \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]);
                    557:                fprintf(stderr, "\nprotocol is UDP or TCP\n");
                    558:                fprintf(stderr, "Options:\n");
1.1.1.2 ! misho     559:                fprintf(stderr, "  -e description : set description for port mapping.\n");
1.1       misho     560:                fprintf(stderr, "  -6 : use ip v6 instead of ip v4.\n");
                    561:                fprintf(stderr, "  -u url : bypass discovery process by providing the XML root description url.\n");
1.1.1.2 ! misho     562:                fprintf(stderr, "  -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n");
1.1       misho     563:                fprintf(stderr, "  -p path : use this path for MiniSSDPd socket.\n");
                    564:                return 1;
                    565:        }
                    566: 
                    567:        if( rootdescurl
                    568:          || (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
                    569:                                     0/*sameport*/, ipv6, &error)))
                    570:        {
                    571:                struct UPNPDev * device;
                    572:                struct UPNPUrls urls;
                    573:                struct IGDdatas data;
                    574:                if(devlist)
                    575:                {
                    576:                        printf("List of UPNP devices found on the network :\n");
                    577:                        for(device = devlist; device; device = device->pNext)
                    578:                        {
                    579:                                printf(" desc: %s\n st: %s\n\n",
                    580:                                           device->descURL, device->st);
                    581:                        }
                    582:                }
                    583:                else
                    584:                {
                    585:                        printf("upnpDiscover() error code=%d\n", error);
                    586:                }
                    587:                i = 1;
                    588:                if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
                    589:                  || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
                    590:                {
                    591:                        switch(i) {
                    592:                        case 1:
                    593:                                printf("Found valid IGD : %s\n", urls.controlURL);
                    594:                                break;
                    595:                        case 2:
                    596:                                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                    597:                                printf("Trying to continue anyway\n");
                    598:                                break;
                    599:                        case 3:
                    600:                                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                    601:                                printf("Trying to continue anyway\n");
                    602:                                break;
                    603:                        default:
                    604:                                printf("Found device (igd ?) : %s\n", urls.controlURL);
                    605:                                printf("Trying to continue anyway\n");
                    606:                        }
                    607:                        printf("Local LAN ip address : %s\n", lanaddr);
                    608:                        #if 0
                    609:                        printf("getting \"%s\"\n", urls.ipcondescURL);
                    610:                        descXML = miniwget(urls.ipcondescURL, &descXMLsize);
                    611:                        if(descXML)
                    612:                        {
                    613:                                /*fwrite(descXML, 1, descXMLsize, stdout);*/
                    614:                                free(descXML); descXML = NULL;
                    615:                        }
                    616:                        #endif
                    617: 
                    618:                        switch(command)
                    619:                        {
                    620:                        case 'l':
                    621:                                DisplayInfos(&urls, &data);
                    622:                                ListRedirections(&urls, &data);
                    623:                                break;
                    624:                        case 'L':
                    625:                                NewListRedirections(&urls, &data);
                    626:                                break;
                    627:                        case 'a':
                    628:                                SetRedirectAndTest(&urls, &data,
                    629:                                                   commandargv[0], commandargv[1],
                    630:                                                   commandargv[2], commandargv[3],
1.1.1.2 ! misho     631:                                                   (commandargc > 4)?commandargv[4]:"0",
        !           632:                                                   description);
1.1       misho     633:                                break;
                    634:                        case 'd':
                    635:                                for(i=0; i<commandargc; i+=2)
                    636:                                {
                    637:                                        RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
                    638:                                }
                    639:                                break;
                    640:                        case 's':
                    641:                                GetConnectionStatus(&urls, &data);
                    642:                                break;
                    643:                        case 'r':
                    644:                                for(i=0; i<commandargc; i+=2)
                    645:                                {
                    646:                                        /*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
                    647:                                        SetRedirectAndTest(&urls, &data,
                    648:                                                           lanaddr, commandargv[i],
1.1.1.2 ! misho     649:                                                                           commandargv[i], commandargv[i+1], "0",
        !           650:                                                           description);
1.1       misho     651:                                }
                    652:                                break;
                    653:                        case 'A':
                    654:                                SetPinholeAndTest(&urls, &data,
                    655:                                                  commandargv[0], commandargv[1],
                    656:                                                  commandargv[2], commandargv[3],
                    657:                                                  commandargv[4], commandargv[5]);
                    658:                                break;
                    659:                        case 'U':
                    660:                                GetPinholeAndUpdate(&urls, &data,
                    661:                                                   commandargv[0], commandargv[1]);
                    662:                                break;
                    663:                        case 'C':
                    664:                                for(i=0; i<commandargc; i++)
                    665:                                {
                    666:                                        CheckPinhole(&urls, &data, commandargv[i]);
                    667:                                }
                    668:                                break;
                    669:                        case 'K':
                    670:                                for(i=0; i<commandargc; i++)
                    671:                                {
                    672:                                        GetPinholePackets(&urls, &data, commandargv[i]);
                    673:                                }
                    674:                                break;
                    675:                        case 'D':
                    676:                                for(i=0; i<commandargc; i++)
                    677:                                {
                    678:                                        RemovePinhole(&urls, &data, commandargv[i]);
                    679:                                }
                    680:                                break;
                    681:                        case 'S':
                    682:                                GetFirewallStatus(&urls, &data);
                    683:                                break;
                    684:                        case 'G':
                    685:                                GetPinholeOutboundTimeout(&urls, &data,
                    686:                                                        commandargv[0], commandargv[1],
                    687:                                                        commandargv[2], commandargv[3],
                    688:                                                        commandargv[4]);
                    689:                                break;
                    690:                        case 'P':
                    691:                                printf("Presentation URL found:\n");
                    692:                                printf("            %s\n", data.presentationurl);
                    693:                                break;
                    694:                        default:
                    695:                                fprintf(stderr, "Unknown switch -%c\n", command);
                    696:                                retcode = 1;
                    697:                        }
                    698: 
                    699:                        FreeUPNPUrls(&urls);
                    700:                }
                    701:                else
                    702:                {
                    703:                        fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
                    704:                        retcode = 1;
                    705:                }
                    706:                freeUPNPDevlist(devlist); devlist = 0;
                    707:        }
                    708:        else
                    709:        {
                    710:                fprintf(stderr, "No IGD UPnP Device found on the network !\n");
                    711:                retcode = 1;
                    712:        }
                    713:        return retcode;
                    714: }
                    715: 

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