File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpc / upnpc.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 00:36:10 2013 UTC (10 years, 10 months ago) by misho
Branches: miniupnpc, elwix, MAIN
CVS tags: v1_8p0, v1_8, HEAD
1.8

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

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