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