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

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

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