Ejemplo n.º 1
0
Archivo: UPnP.cpp Proyecto: l-n-s/i2pd
    void UPnP::Discover ()
    {
        int nerror = 0;
#if MINIUPNPC_API_VERSION >= 14
        m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
#else
        m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
#endif
		{
			// notify satrting thread			
			std::unique_lock<std::mutex> l(m_StartedMutex);
			m_Started.notify_all ();
		}	
		
        int r;
        r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
        if (r == 1)
        {
            r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
            if(r != UPNPCOMMAND_SUCCESS)
            {
                LogPrint (eLogError, "UPnP: UPNP_GetExternalIPAddress() returned ", r);
                return;
            }
            else
            {
                if (!m_externalIPAddress[0])
                {
                    LogPrint (eLogError, "UPnP: GetExternalIPAddress() failed.");
                    return;
                }
            }
        }
		else
		{
			 LogPrint (eLogError, "UPnP: GetValidIGD() failed.");
             return;
		}

		// UPnP discovered	
		LogPrint (eLogDebug, "UPnP: ExternalIPAddress is ", m_externalIPAddress);
        i2p::context.UpdateAddress (boost::asio::ip::address::from_string (m_externalIPAddress));
		// port mapping
		PortMapping ();
    }
Ejemplo n.º 2
0
int SetUp(void)
{
    int error = 0;
    g_devlist = upnpDiscover(1000, NULL, NULL, 0, 0, &error);

    if(!g_devlist)
    {
        printf("no upnp device list\n");
        return -1;
    }

    g_urls = (struct UPNPUrls*)malloc(sizeof(struct UPNPUrls));
    g_data = (struct IGDdatas*)malloc(sizeof(struct IGDdatas));
    if(!g_urls || !g_data)
    {
        printf("malloc failed\n");
        return -1;
    }
    memset(g_urls, 0, sizeof(struct UPNPUrls));
    memset(g_data, 0, sizeof(struct IGDdatas));

    int result = UPNP_GetValidIGD(g_devlist, g_urls, g_data, g_lanaddr, sizeof(g_lanaddr));

    if(result == 1)
    {
        printf("%d, %s\n", result, g_urls->controlURL);
    }
    else if(result == 2)
    {
        printf("%d, %s\n", result, g_urls->controlURL);
    }
    else if(result == 3)
    {
        printf("%d, %s\n", result, g_urls->controlURL);
    }
    else
    {
        printf("no valid IGD\n");
        return -1;
    }

    printf("local address: %s\n", g_lanaddr);

    return 0;
}
Ejemplo n.º 3
0
static gboolean
update_upnp_status (VinoUpnp *upnp)
{
  struct UPNPDev * devlist;
  int res;

  if (upnp->priv->have_igd)
    return TRUE;

  clean_upnp_data (upnp);

  dprintf (UPNP, "UPnP: Doing the discovery... ");
  devlist = upnpDiscover (2000, NULL, NULL, 0);
  if (!devlist)
    {
      dprintf (UPNP, "nothing found, aborting.");
      return FALSE;
    }
  dprintf (UPNP, "found.\n");
  dprintf (UPNP, "UPnP: Looking for a valid IGD... ");

  upnp->priv->urls = g_new0 (struct UPNPUrls, 1);
  upnp->priv->data = g_new0 (struct IGDdatas, 1);

  res = UPNP_GetValidIGD (devlist,
			  upnp->priv->urls,
			  upnp->priv->data,
                          upnp->priv->lanaddr,
                          sizeof (upnp->priv->lanaddr));

  if (res == 1 || res == 2)
    {
      dprintf (UPNP, "found: %s\n", upnp->priv->urls->controlURL);
      upnp->priv->have_igd = TRUE;
    }
  else
    {
      dprintf (UPNP, "none found, aborting.\n");
      upnp->priv->have_igd = FALSE;
    }

  freeUPNPDevlist (devlist);
  return upnp->priv->have_igd;
}
Ejemplo n.º 4
0
static inline void I_InitUPnP(void)
{
	struct UPNPDev * devlist = NULL;
	int upnp_error = -2;
	CONS_Printf(M_GetText("Looking for UPnP Internet Gateway Device\n"));
	devlist = upnpDiscover(2000, NULL, NULL, 0, false, &upnp_error);
	if (devlist)
	{
		struct UPNPDev *dev = devlist;
		char * descXML;
		int descXMLsize = 0;
		while (dev)
		{
			if (strstr (dev->st, "InternetGatewayDevice"))
				break;
			dev = dev->pNext;
		}
		if (!dev)
			dev = devlist; /* defaulting to first device */

		CONS_Printf(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
		           dev->descURL, dev->st);

		UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
		CONS_Printf(M_GetText("Local LAN IP address: %s\n"), lanaddr);
		descXML = miniwget(dev->descURL, &descXMLsize);
		if (descXML)
		{
			parserootdesc(descXML, descXMLsize, &data);
			free(descXML);
			descXML = NULL;
			memset(&urls, 0, sizeof(struct UPNPUrls));
			memset(&data, 0, sizeof(struct IGDdatas));
			GetUPNPUrls(&urls, &data, dev->descURL);
			I_AddExitFunc(I_ShutdownUPnP);
		}
		freeUPNPDevlist(devlist);
	}
	else if (upnp_error == UPNPDISCOVER_SOCKET_ERROR)
	{
		CONS_Printf(M_GetText("No UPnP devices discovered\n"));
	}
}
Ejemplo n.º 5
0
static PyObject *
UPnP_selectigd(UPnPObject *self)
{
	int r;
Py_BEGIN_ALLOW_THREADS
	r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data,
	                     self->lanaddr, sizeof(self->lanaddr));
Py_END_ALLOW_THREADS
	if(r)
	{
		return Py_BuildValue("s", self->urls.controlURL);
	}
	else
	{
		/* TODO: have our own exception type ! */
		PyErr_SetString(PyExc_Exception, "No UPnP device discovered");
		return NULL;
	}
}
Ejemplo n.º 6
0
/** Initialize the UPnP backend and store the results in
 * <b>backend_state</b>.*/
int
tor_upnp_init(tor_fw_options_t *options, void *backend_state)
{
  /*
    This leaks the user agent from the client to the router - perhaps we don't
    want to do that? eg:

    User-Agent: Ubuntu/10.04, UPnP/1.0, MiniUPnPc/1.4

  */
  miniupnpc_state_t *state = (miniupnpc_state_t *) backend_state;
  struct UPNPDev *devlist;
  int r;

  memset(&(state->urls), 0, sizeof(struct UPNPUrls));
  memset(&(state->data), 0, sizeof(struct IGDdatas));
  state->init = 0;

#ifdef MINIUPNPC15
  devlist = upnpDiscover(UPNP_DISCOVER_TIMEOUT, NULL, NULL, 0);
#else
  devlist = upnpDiscover(UPNP_DISCOVER_TIMEOUT, NULL, NULL, 0, 0, NULL);
#endif
  if (NULL == devlist) {
    fprintf(stderr, "E: upnpDiscover returned: NULL\n");
    return UPNP_ERR_NODEVICESFOUND;
  }

  assert(options);
  r = UPNP_GetValidIGD(devlist, &(state->urls), &(state->data),
                       state->lanaddr, UPNP_LANADDR_SZ);
  fprintf(stderr, "tor-fw-helper: UPnP GetValidIGD returned: %d (%s)\n", r,
          r==UPNP_SUCCESS?"SUCCESS":"FAILED");

  freeUPNPDevlist(devlist);

  if (r != 1 && r != 2)
    return UPNP_ERR_NOIGDFOUND;

  state->init = 1;
  return UPNP_ERR_SUCCESS;
}
Ejemplo n.º 7
0
	void threadMain()
		throw()
	{
		char lanaddr[4096];
		char externalip[4096]; // no range checking? so make these buffers larger than any UDP packet a uPnP server could send us as a precaution :P
		char inport[16];
		char outport[16];
		struct UPNPUrls urls;
		struct IGDdatas data;

#ifdef ZT_UPNP_TRACE
		fprintf(stderr,"UPNPClient: started for UDP port %d"ZT_EOL_S,localPort);
#endif

		unsigned int tryPortStart = 0;
		Utils::getSecureRandom(&tryPortStart,sizeof(tryPortStart));
		tryPortStart = (tryPortStart % (65535 - 1025)) + 1025;

		while (run) {
			{
				int upnpError = 0;
				UPNPDev *devlist = upnpDiscover(2000,(const char *)0,(const char *)0,0,0,0,&upnpError);
				if (devlist) {
#ifdef ZT_UPNP_TRACE
					{
						UPNPDev *dev = devlist;
						while (dev) {
							fprintf(stderr,"UPNPClient: found device at URL '%s': %s"ZT_EOL_S,dev->descURL,dev->st);
							dev = dev->pNext;
						}
					}
#endif

					memset(lanaddr,0,sizeof(lanaddr));
					memset(externalip,0,sizeof(externalip));
					memset(&urls,0,sizeof(urls));
					memset(&data,0,sizeof(data));
					Utils::snprintf(inport,sizeof(inport),"%d",localPort);

					if ((UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) {
#ifdef ZT_UPNP_TRACE
						fprintf(stderr,"UPNPClient: my LAN IP address: %s"ZT_EOL_S,lanaddr);
#endif
						if ((UPNP_GetExternalIPAddress(urls.controlURL,data.first.servicetype,externalip) == UPNPCOMMAND_SUCCESS)&&(externalip[0])) {
#ifdef ZT_UPNP_TRACE
							fprintf(stderr,"UPNPClient: my external IP address: %s"ZT_EOL_S,externalip);
#endif

							for(int tries=0;tries<64;++tries) {
								int tryPort = (int)tryPortStart + tries;
								if (tryPort >= 65535)
									tryPort = (tryPort - 65535) + 1025;
								Utils::snprintf(outport,sizeof(outport),"%u",tryPort);

								int mapResult = 0;
								if ((mapResult = UPNP_AddPortMapping(urls.controlURL,data.first.servicetype,outport,inport,lanaddr,"ZeroTier","UDP",(const char *)0,"0")) == UPNPCOMMAND_SUCCESS) {
	#ifdef ZT_UPNP_TRACE
									fprintf(stderr,"UPNPClient: reserved external port: %s"ZT_EOL_S,outport);
	#endif
									{
										Mutex::Lock sl(surface_l);
										surface.clear();
										InetAddress tmp(externalip);
										tmp.setPort(tryPort);
										surface.push_back(tmp);
									}
									break;
								} else {
	#ifdef ZT_UPNP_TRACE
									fprintf(stderr,"UPNPClient: UPNP_AddAnyPortMapping(%s) failed: %d"ZT_EOL_S,outport,mapResult);
	#endif
									Thread::sleep(1000);
								}
							}
						} else {
#ifdef ZT_UPNP_TRACE
							fprintf(stderr,"UPNPClient: UPNP_GetExternalIPAddress failed"ZT_EOL_S);
#endif
						}
					} else {
#ifdef ZT_UPNP_TRACE
						fprintf(stderr,"UPNPClient: UPNP_GetValidIGD failed"ZT_EOL_S);
#endif
					}

					freeUPNPDevlist(devlist);
				} else {
#ifdef ZT_UPNP_TRACE
					fprintf(stderr,"UPNPClient: upnpDiscover error code: %d"ZT_EOL_S,upnpError);
#endif
				}
			}

#ifdef ZT_UPNP_TRACE
			fprintf(stderr,"UPNPClient: rescanning in %d ms"ZT_EOL_S,ZT_UPNP_CLIENT_REFRESH_DELAY);
#endif
			Thread::sleep(ZT_UPNP_CLIENT_REFRESH_DELAY);
		}
		delete this;
	}
Ejemplo n.º 8
0
/* sample upnp client program */
int main(int argc, char ** argv)
{
	char command = 0;
	char ** commandargv = 0;
	int commandargc = 0;
	struct UPNPDev * devlist = 0;
	char lanaddr[64];	/* my ip address on the LAN */
	int i;
	const char * rootdescurl = 0;
	const char * multicastif = 0;
	const char * minissdpdpath = 0;
	int retcode = 0;
	int error = 0;
	int ipv6 = 0;
	const char * description = 0;

#ifdef _WIN32
	WSADATA wsaData;
	int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if(nResult != NO_ERROR)
	{
		fprintf(stderr, "WSAStartup() failed.\n");
		return -1;
	}
#endif
    printf("upnpc : miniupnpc library test client. (c) 2005-2014 Thomas Bernard\n");
    printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
	       "for more information.\n");
	/* command line processing */
	for(i=1; i<argc; i++)
	{
		if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h"))
		{
			command = 0;
			break;
		}
		if(argv[i][0] == '-')
		{
			if(argv[i][1] == 'u')
				rootdescurl = argv[++i];
			else if(argv[i][1] == 'm')
				multicastif = argv[++i];
			else if(argv[i][1] == 'p')
				minissdpdpath = argv[++i];
			else if(argv[i][1] == '6')
				ipv6 = 1;
			else if(argv[i][1] == 'e')
				description = argv[++i];
			else
			{
				command = argv[i][1];
				i++;
				commandargv = argv + i;
				commandargc = argc - i;
				break;
			}
		}
		else
		{
			fprintf(stderr, "option '%s' invalid\n", argv[i]);
		}
	}

	if(!command 
	   || (command == 'a' && commandargc<4)
	   || (command == 'd' && argc<2)
	   || (command == 'r' && argc<2)
	   || (command == 'A' && commandargc<6)
	   || (command == 'U' && commandargc<2)
	   || (command == 'D' && commandargc<1))
	{
		fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -d external_port protocol <remote host>\n\t\tDelete port redirection\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
		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]);
		fprintf(stderr, "       \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]);
		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]);
		fprintf(stderr, "       \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]);
		fprintf(stderr, "\nprotocol is UDP or TCP\n");
		fprintf(stderr, "Options:\n");
		fprintf(stderr, "  -e description : set description for port mapping.\n");
		fprintf(stderr, "  -6 : use ip v6 instead of ip v4.\n");
		fprintf(stderr, "  -u url : bypass discovery process by providing the XML root description url.\n");
		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");
		fprintf(stderr, "  -p path : use this path for MiniSSDPd socket.\n");
		return 1;
	}

	if( rootdescurl
	  || (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
	                             0/*sameport*/, ipv6, &error)))
	{
		struct UPNPDev * device;
		struct UPNPUrls urls;
		struct IGDdatas data;
		if(devlist)
		{
			printf("List of UPNP devices found on the network :\n");
			for(device = devlist; device; device = device->pNext)
			{
				printf(" desc: %s\n st: %s\n\n",
					   device->descURL, device->st);
			}
		}
		else if(!rootdescurl)
		{
			printf("upnpDiscover() error code=%d\n", error);
		}
		i = 1;
		if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
		  || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
		{
			switch(i) {
			case 1:
				printf("Found valid IGD : %s\n", urls.controlURL);
				break;
			case 2:
				printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
				printf("Trying to continue anyway\n");
				break;
			case 3:
				printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
				printf("Trying to continue anyway\n");
				break;
			default:
				printf("Found device (igd ?) : %s\n", urls.controlURL);
				printf("Trying to continue anyway\n");
			}
			printf("Local LAN ip address : %s\n", lanaddr);
			#if 0
			printf("getting \"%s\"\n", urls.ipcondescURL);
			descXML = miniwget(urls.ipcondescURL, &descXMLsize);
			if(descXML)
			{
				/*fwrite(descXML, 1, descXMLsize, stdout);*/
				free(descXML); descXML = NULL;
			}
			#endif

			switch(command)
			{
			case 'l':
				DisplayInfos(&urls, &data);
				ListRedirections(&urls, &data);
				break;
			case 'L':
				NewListRedirections(&urls, &data);
				break;
			case 'a':
				SetRedirectAndTest(&urls, &data,
						   commandargv[0], commandargv[1],
						   commandargv[2], commandargv[3],
						   (commandargc > 4)?commandargv[4]:"0",
						   description, 0);
				break;
			case 'd':
				RemoveRedirect(&urls, &data, commandargv[0], commandargv[1],
				               commandargc > 2 ? commandargv[2] : NULL);
				break;
			case 'n':	/* aNy */
				SetRedirectAndTest(&urls, &data,
						   commandargv[0], commandargv[1],
						   commandargv[2], commandargv[3],
						   (commandargc > 4)?commandargv[4]:"0",
						   description, 1);
				break;
			case 'N':
				if (commandargc < 3)
					fprintf(stderr, "too few arguments\n");

				RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2],
						    commandargc > 3 ? commandargv[3] : NULL);
				break;
			case 's':
				GetConnectionStatus(&urls, &data);
				break;
			case 'r':
				i=0;
				while(i<commandargc){
					if(!is_int(commandargv[i+1])){
						/* 2nd parameter not an integer, so format is '<port> <protocol>' */
						/* Note: no 2nd parameter is also not-an-integer, and will lead to a "Wrong arguments" */
						SetRedirectAndTest(&urls, &data,
								   lanaddr, commandargv[i],
								   commandargv[i], commandargv[i+1], "0",
								   description, 0);
						i+=2;	/* 2 parameters parsed */
					} else {
						/* 2nd parameter is an integer, so format is '<port> <external_port> <protocol>' */
						SetRedirectAndTest(&urls, &data,
								   lanaddr, commandargv[i],
								   commandargv[i+1], commandargv[i+2], "0",
								   description, 0);
						i+=3;	/* 3 parameters parsed */
					}
				}
				break;
			case 'A':
				SetPinholeAndTest(&urls, &data,
				                  commandargv[0], commandargv[1],
				                  commandargv[2], commandargv[3],
				                  commandargv[4], commandargv[5]);
				break;
			case 'U':
				GetPinholeAndUpdate(&urls, &data,
				                   commandargv[0], commandargv[1]);
				break;
			case 'C':
				for(i=0; i<commandargc; i++)
				{
					CheckPinhole(&urls, &data, commandargv[i]);
				}
				break;
			case 'K':
				for(i=0; i<commandargc; i++)
				{
					GetPinholePackets(&urls, &data, commandargv[i]);
				}
				break;
			case 'D':
				for(i=0; i<commandargc; i++)
				{
					RemovePinhole(&urls, &data, commandargv[i]);
				}
				break;
			case 'S':
				GetFirewallStatus(&urls, &data);
				break;
			case 'G':
				GetPinholeOutboundTimeout(&urls, &data,
							commandargv[0], commandargv[1],
							commandargv[2], commandargv[3],
							commandargv[4]);
				break;
			case 'P':
				printf("Presentation URL found:\n");
				printf("            %s\n", data.presentationurl);
				break;
			default:
				fprintf(stderr, "Unknown switch -%c\n", command);
				retcode = 1;
			}

			FreeUPNPUrls(&urls);
		}
		else
		{
			fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
			retcode = 1;
		}
		freeUPNPDevlist(devlist); devlist = 0;
	}
	else
	{
		fprintf(stderr, "No IGD UPnP Device found on the network !\n");
		retcode = 1;
	}
#ifdef _WIN32
	nResult = WSACleanup();
	if(nResult != NO_ERROR) {
		fprintf(stderr, "WSACleanup() failed.\n");
	}
#endif /* _WIN32 */
	return retcode;
}
Ejemplo n.º 9
0
/**
 *  Erstellt per UPnP ein Portforwarding.
 *
 *  @author FloSoft
 */
bool UPnP::OpenPort(const unsigned short& port)
{
    if(remote_port_ != 0)
        ClosePort();

    remote_port_ = port;

#ifdef _MSC_VER
    HRESULT hr;

    CoInitialize(NULL);

    IUPnPNAT* upnpnat;
    hr = CoCreateInstance (CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void**)&upnpnat);
    if(FAILED(hr) || !upnpnat)
    {
        if(!upnpnat)
            hr = E_NOINTERFACE;
        SetLastError(hr);
        return false;
    }

    IStaticPortMappingCollection* upnpspmc = NULL;
    hr = upnpnat->get_StaticPortMappingCollection(&upnpspmc);
    if(FAILED(hr) || !upnpspmc)
    {
        if(!upnpspmc)
            hr = E_NOINTERFACE;
        SetLastError(hr);
        return false;
    }

    std::string local_address;
    std::vector<std::string> addresses = GetAllv4Addresses();

    // if we have multiple addresses, search the private one
    if(addresses.size() > 1)
    {
        for(std::vector<std::string>::iterator addr = addresses.begin(); addr != addresses.end(); ++addr)
        {
            std::string ss = *addr;
            std::stringstream s, sc;
            s << ss;
            std::getline(s, ss, '.');
            sc << ss << " ";
            std::getline(s, ss, '.');
            sc << ss << " ";

            int a, b;
            sc >> a;
            sc >> b;

            int ab = (a << 24) | (b << 16);

            if( (ab & 0xff000000) == 0x0a000000 || // 10.0.0.0/8
                    (ab & 0xff000000) == 0x7f000000 || // 127.0.0.0/8
                    (ab & 0xfff00000) == 0xac100000 || // 172.16.0.0/12
                    (ab & 0xffff0000) == 0xc0a80000 )  // 192.168.0.0/16
                local_address = *addr;
        }
    }

    // otherwise use the first one
    if(local_address == "" && !addresses.empty())
        local_address = addresses.front();

    // I hope we found one ...
    if(local_address == "")
    {
        SetLastError(E_FAIL);
        return false;
    }

    BSTR bstrProtocol = A2BSTR("TCP");
    BSTR bstrLocalAddress = A2BSTR(local_address.c_str());
    BSTR bstrDescription = A2BSTR("Return To The Roots");

    IStaticPortMapping* upnpspm = NULL;
    hr = upnpspmc->Add(port, bstrProtocol, port, bstrLocalAddress, VARIANT_TRUE, bstrDescription, &upnpspm);

    SysFreeString(bstrProtocol);
    SysFreeString(bstrLocalAddress);
    SysFreeString(bstrDescription);

    if(SUCCEEDED(hr) && !upnpspm)
        hr = E_NOINTERFACE;

    SetLastError(hr);

    if(SUCCEEDED(hr) && upnpspm)
        return true;
#else
    int hr;
    UPNPDev* devicelist = NULL;
#ifdef UPNPDISCOVER_SUCCESS
    int upnperror = 0;
    devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror);
#else
    devicelist = upnpDiscover(2000, NULL, NULL, 0);
#endif
    if(!devicelist)
        return false;

    UPNPUrls urls;
    IGDdatas data;
    char lanAddr[64];
    hr = UPNP_GetValidIGD(devicelist, &urls, &data, lanAddr, sizeof(lanAddr));

    if(hr == 1 || hr == 2)
    {
        std::stringstream p;
        p << port;

#ifdef UPNPDISCOVER_SUCCESS
        hr = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), p.str().c_str(), lanAddr, "Return To The Roots", "TCP", NULL, NULL);
#else
        hr = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), p.str().c_str(), lanAddr, "Return To The Roots", "TCP", NULL);
#endif
    }

    freeUPNPDevlist(devicelist);

    if(hr == 0)
        return true;
#endif
    return false;
}
Ejemplo n.º 10
0
void UPnP::ClosePort()
{
    if(remote_port_ == 0)
        return;

#ifdef _MSC_VER
    HRESULT hr;

    IUPnPNAT* upnpnat;
    hr = CoCreateInstance (CLSID_UPnPNAT, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPNAT, (void**)&upnpnat);
    if(FAILED(hr) || !upnpnat)
        return;

    IStaticPortMappingCollection* upnpspmc = NULL;
    hr = upnpnat->get_StaticPortMappingCollection(&upnpspmc);
    if(FAILED(hr) || !upnpspmc)
        return;

    BSTR bstrProtocol = A2BSTR("TCP");

    hr = upnpspmc->Remove(remote_port_, bstrProtocol);

    if(FAILED(hr))
        LOG.writeLastError("Automatisches Entfernen des Portforwardings mit UPnP fehlgeschlagen\nFehler");

    SysFreeString(bstrProtocol);

    if(FAILED(hr))
        return;
#else
    int hr;
    UPNPDev* devicelist = NULL;
#ifdef UPNPDISCOVER_SUCCESS
    int upnperror = 0;
#if (MINIUPNPC_API_VERSION >= 14) /* miniUPnPc API version 14 adds TTL parameter */
    devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, 2, &upnperror);
#else
    devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror);
#endif
#else
    devicelist = upnpDiscover(2000, NULL, NULL, 0);
#endif
    if(!devicelist)
        return;

    UPNPUrls urls;
    IGDdatas data;
    hr = UPNP_GetValidIGD(devicelist, &urls, &data, NULL, 0);
    if(hr == 1 || hr == 2)
    {
        std::stringstream p;
        p << remote_port_;
        hr = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, p.str().c_str(), "TCP", NULL);
    }

    freeUPNPDevlist(devicelist);

    if(hr != 0)
        return;
#endif

    remote_port_ = 0;
}
Ejemplo n.º 11
0
/// RakNet stuff
void CDemo::UpdateRakNet(void)
{
	RakNet::SystemAddress facilitatorSystemAddress(DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_IP, DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_PORT);
	RakNet::Packet *packet;
	RakNet::TimeMS curTime = RakNet::GetTimeMS();
	RakNet::RakString targetName;
	for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive())
	{
		if (strcmp(packet->systemAddress.ToString(false),DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_IP)==0)
		{
			targetName="NATPunchthroughServer";
		}
		else
		{
			targetName=packet->systemAddress.ToString(true);
		}

		switch (packet->data[0])
		{
		case ID_IP_RECENTLY_CONNECTED:
			{
				PushMessage(RakNet::RakString("This IP address recently connected from ") + targetName + RakNet::RakString("."));
				if (packet->systemAddress==facilitatorSystemAddress)
					PushMessage("Multiplayer will not work without the NAT punchthrough server!");
			}
			break;
		case ID_INCOMPATIBLE_PROTOCOL_VERSION:
			{
				PushMessage(RakNet::RakString("Incompatible protocol version from ") + targetName + RakNet::RakString("."));
				if (packet->systemAddress==facilitatorSystemAddress)
					PushMessage("Multiplayer will not work without the NAT punchthrough server!");
			}
			break;
		case ID_DISCONNECTION_NOTIFICATION:
			{
				PushMessage(RakNet::RakString("Disconnected from ") + targetName + RakNet::RakString("."));
				if (packet->systemAddress==facilitatorSystemAddress)
					isConnectedToNATPunchthroughServer=false;
			}
			break;
		case ID_CONNECTION_LOST:
			{
				PushMessage(RakNet::RakString("Connection to ") + targetName + RakNet::RakString(" lost."));
				if (packet->systemAddress==facilitatorSystemAddress)
					isConnectedToNATPunchthroughServer=false;
			}
			break;
		case ID_NO_FREE_INCOMING_CONNECTIONS:
			{
				PushMessage(RakNet::RakString("No free incoming connections to ") + targetName + RakNet::RakString("."));
				if (packet->systemAddress==facilitatorSystemAddress)
					PushMessage("Multiplayer will not work without the NAT punchthrough server!");
			}
			break;
		case ID_NEW_INCOMING_CONNECTION:
			{
				if (fullyConnectedMesh2->IsHostSystem())
				{
					PushMessage(RakNet::RakString("Sending player list to new connection"));
					fullyConnectedMesh2->StartVerifiedJoin(packet->guid);
				}
			}
			break;
		case ID_FCM2_VERIFIED_JOIN_START:
			{
				DataStructures::List<RakNet::SystemAddress> addresses;
				DataStructures::List<RakNet::RakNetGUID> guids;
				fullyConnectedMesh2->GetVerifiedJoinRequiredProcessingList(packet->guid, addresses, guids);
				for (unsigned int i=0; i < guids.Size(); i++)
					natPunchthroughClient->OpenNAT(guids[i], facilitatorSystemAddress);
			}
			break;
		case ID_FCM2_VERIFIED_JOIN_FAILED:
			{
				PushMessage(RakNet::RakString("Failed to join game session"));
			}
			break;
		case ID_FCM2_VERIFIED_JOIN_CAPABLE:
			{
				fullyConnectedMesh2->RespondOnVerifiedJoinCapable(packet, true, 0);
			}
			break;
		case ID_FCM2_VERIFIED_JOIN_ACCEPTED:
			{
				DataStructures::List<RakNet::RakNetGUID> systemsAccepted;
				bool thisSystemAccepted;
				fullyConnectedMesh2->GetVerifiedJoinAcceptedAdditionalData(packet, &thisSystemAccepted, systemsAccepted, 0);
				if (thisSystemAccepted)
					PushMessage("Game join request accepted\n");
				else
					PushMessage(RakNet::RakString("System %s joined the mesh\n", systemsAccepted[0].ToString()));
				
				// DataStructures::List<RakNetGUID> participantList;
				// fullyConnectedMesh2->GetParticipantList(participantList);

				for (unsigned int i=0; i < systemsAccepted.Size(); i++)
					replicaManager3->PushConnection(replicaManager3->AllocConnection(rakPeer->GetSystemAddressFromGuid(systemsAccepted[i]), systemsAccepted[i]));
			}
			break;
		case ID_CONNECTION_REQUEST_ACCEPTED:
			{
				PushMessage(RakNet::RakString("Connection request to ") + targetName + RakNet::RakString(" accepted."));
				if (packet->systemAddress==facilitatorSystemAddress)
				{
					isConnectedToNATPunchthroughServer=true;

					// Open UPNP.
					struct UPNPDev * devlist = 0;
					devlist = upnpDiscover(1000, 0, 0, 0);
					if (devlist)
					{
						char lanaddr[64];	/* my ip address on the LAN */
						struct UPNPUrls urls;
						struct IGDdatas data;
						if (UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))==1)
						{
							// External port is the port people will be connecting to us on. This is our port as seen by the directory server
							// Internal port is the port RakNet was internally started on
							char eport[32], iport[32];
							natPunchthroughClient->GetUPNPPortMappings(eport, iport, facilitatorSystemAddress);

							int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
								eport, iport, lanaddr, 0, "UDP", 0);

							if(r==UPNPCOMMAND_SUCCESS)
							{
								// UPNP done
							}

						}
					}
					
					// Query cloud for other running game instances
					RakNet::CloudQuery cloudQuery;
					cloudQuery.keys.Push(RakNet::CloudKey("IrrlichtDemo",0),_FILE_AND_LINE_);
					cloudClient->Get(&cloudQuery, packet->guid);
				}
			}
			break;
		case ID_FCM2_NEW_HOST:
			{
				if (packet->guid==rakPeer->GetMyGUID())
				{
					// Original host dropped. I am the new session host. Upload to the cloud so new players join this system.
					RakNet::CloudKey cloudKey("IrrlichtDemo",0);
					cloudClient->Post(&cloudKey, 0, 0, rakPeer->GetGuidFromSystemAddress(facilitatorSystemAddress));
				}
			}
			break;
		case ID_CLOUD_GET_RESPONSE:
			{
				RakNet::CloudQueryResult cloudQueryResult;
				cloudClient->OnGetReponse(&cloudQueryResult, packet);
				if (cloudQueryResult.rowsReturned.Size()>0)
				{	
					PushMessage(RakNet::RakString("NAT punch to existing game instance"));
					natPunchthroughClient->OpenNAT(cloudQueryResult.rowsReturned[0]->clientGUID, facilitatorSystemAddress);
				}
				else
				{
					PushMessage(RakNet::RakString("Publishing new game instance"));

					// Start as a new game instance because no other games are running
					RakNet::CloudKey cloudKey("IrrlichtDemo",0);
					cloudClient->Post(&cloudKey, 0, 0, packet->guid);
				}

				cloudClient->DeallocateWithDefaultAllocator(&cloudQueryResult);
			}
			break;
		case ID_CONNECTION_ATTEMPT_FAILED:
			{
				PushMessage(RakNet::RakString("Connection attempt to ") + targetName + RakNet::RakString(" failed."));
				if (packet->systemAddress==facilitatorSystemAddress)
					PushMessage("Multiplayer will not work without the NAT punchthrough server!");
			}
			break;
		case ID_NAT_TARGET_NOT_CONNECTED:
			{
				RakNet::RakNetGUID recipientGuid;
				RakNet::BitStream bs(packet->data,packet->length,false);
				bs.IgnoreBytes(sizeof(RakNet::MessageID));
				bs.Read(recipientGuid);
				targetName=recipientGuid.ToString();
				PushMessage(RakNet::RakString("NAT target ") + targetName + RakNet::RakString(" not connected."));
			}
			break;
		case ID_NAT_TARGET_UNRESPONSIVE:
			{
				RakNet::RakNetGUID recipientGuid;
				RakNet::BitStream bs(packet->data,packet->length,false);
				bs.IgnoreBytes(sizeof(RakNet::MessageID));
				bs.Read(recipientGuid);
				targetName=recipientGuid.ToString();
				PushMessage(RakNet::RakString("NAT target ") + targetName + RakNet::RakString(" unresponsive."));
			}
			break;
		case ID_NAT_CONNECTION_TO_TARGET_LOST:
			{
				RakNet::RakNetGUID recipientGuid;
				RakNet::BitStream bs(packet->data,packet->length,false);
				bs.IgnoreBytes(sizeof(RakNet::MessageID));
				bs.Read(recipientGuid);
				targetName=recipientGuid.ToString();
				PushMessage(RakNet::RakString("NAT target connection to ") + targetName + RakNet::RakString(" lost."));
			}
			break;
		case ID_NAT_ALREADY_IN_PROGRESS:
			{
				RakNet::RakNetGUID recipientGuid;
				RakNet::BitStream bs(packet->data,packet->length,false);
				bs.IgnoreBytes(sizeof(RakNet::MessageID));
				bs.Read(recipientGuid);
				targetName=recipientGuid.ToString();
				PushMessage(RakNet::RakString("NAT punchthrough to ") + targetName + RakNet::RakString(" in progress (skipping)."));
			}
			break;

		case ID_NAT_PUNCHTHROUGH_SUCCEEDED:
			{
				if (packet->data[1]==1)
				{
					PushMessage(RakNet::RakString("Connecting to existing game instance"));
					RakNet::ConnectionAttemptResult car = rakPeer->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), 0, 0);
					RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED);
				}
			}
			break;

		case ID_ADVERTISE_SYSTEM:
			if (packet->guid!=rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS))
			{
				char hostIP[32];
				packet->systemAddress.ToString(false,hostIP);
				RakNet::ConnectionAttemptResult car = rakPeer->Connect(hostIP,packet->systemAddress.GetPort(),0,0);
				RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED);
			}
			break;
		}
	}

	// Call the Update function for networked game objects added to BaseIrrlichtReplica once the game is ready
	if (currentScene>=1)
	{
		unsigned int idx;
		for (idx=0; idx < replicaManager3->GetReplicaCount(); idx++)
			((BaseIrrlichtReplica*)(replicaManager3->GetReplicaAtIndex(idx)))->Update(curTime);;
	}	
}
Ejemplo n.º 12
0
void upnp_service::map_port( uint16_t local_port )
{
  std::string port = fc::variant(local_port).as_string();

  my->map_port_complete = my->upnp_thread.async( [=]() {
      const char * multicastif = 0;
      const char * minissdpdpath = 0;
      struct UPNPDev * devlist = 0;
      char lanaddr[64];
      
      /* miniupnpc 1.6 */
      int error = 0;
      devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);

      struct UPNPUrls urls;
      memset( &urls, 0, sizeof(urls) );
      struct IGDdatas data;
      memset( &data, 0, sizeof(data) );
      int r;
      
      r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));

      bool port_mapping_added = false;
      bool port_mapping_added_successfully = false;

       if (r == 1)
       {
           if (true) //  TODO  config this ?  fDiscover) 
           {
               char externalIPAddress[40];
               r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
               if(r != UPNPCOMMAND_SUCCESS)
                   wlog("UPnP: GetExternalIPAddress() returned ${code}", ("code", r));
               else
               {
                   if(externalIPAddress[0])
                   {
                       ulog("UPnP: ExternalIPAddress = ${address}", ("address", externalIPAddress));
                       my->external_ip = fc::ip::address( std::string(externalIPAddress) );
                       // AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
                   }
                   else
                       wlog("UPnP: GetExternalIPAddress failed.");
               }
           }
       
           std::string strDesc = "BitShares 0.0"; // TODO  + FormatFullVersion();
       
     //      try 
           {
               while(!my->done)  // TODO provide way to exit cleanly
               {
                   /* miniupnpc 1.6 */
                   r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
                                       port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
       
                   port_mapping_added = true;
                   if(r!=UPNPCOMMAND_SUCCESS)
                       wlog("AddPortMapping(${port}, ${port}, ${addr}) failed with code ${code} (${string})",
                            ("port", port)("addr", lanaddr)("code", r)("string", strupnperror(r)));
                   else
                   {
                       if (!port_mapping_added_successfully)
                         ulog("UPnP Port Mapping successful");
                       port_mapping_added_successfully = true;

                       my->mapped_port = local_port;
                   }
       
                   fc::usleep( fc::seconds(60*20) ); // Refresh every 20 minutes
               }
           }
     //      catch (boost::thread_interrupted)
           {
               if( port_mapping_added )
               {
                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
                 ilog("UPNP_DeletePortMapping() returned : ${r}", ("r",r));
                 freeUPNPDevlist(devlist); devlist = 0;
                 FreeUPNPUrls(&urls);
               }
      //         throw;
           }
       } else {
           //printf("No valid UPnP IGDs found\n");
           wlog("No valid UPnP IGDs found");
           freeUPNPDevlist(devlist); devlist = 0;
           if (r != 0)
           {
               FreeUPNPUrls(&urls);
           }
       }
  }, "upnp::map_port" );
}
Ejemplo n.º 13
0
int CUPnPImplMiniLib::CStartDiscoveryThread::Run()
{
	DbgSetThreadName("CUPnPImplMiniLib::CStartDiscoveryThread");
	if ( !m_pOwner )
		return 0;

	CSingleLock sLock(&m_pOwner->m_mutBusy);
	if (!sLock.Lock(0)){
		DebugLogWarning(_T("CUPnPImplMiniLib::CStartDiscoveryThread::Run, failed to acquire Lock, another Mapping try might be running already"));
		return 0;
	}

	if (m_pOwner->m_bAbortDiscovery) // requesting to abort ASAP?
		return 0;

	UPNPDev* structDeviceList = upnpDiscover(2000, NULL, NULL);
	if (structDeviceList == NULL){
		DebugLog(_T("UPNP: No Internet Gateway Devices found, aborting"));
		m_pOwner->m_bUPnPPortsForwarded = TRIS_FALSE;
		m_pOwner->SendResultMessage();
		return 0;
	}

	if (m_pOwner->m_bAbortDiscovery){ // requesting to abort ASAP?
		freeUPNPDevlist(structDeviceList);
		return 0;
	}

	DebugLog(_T("List of UPNP devices found on the network:"));
	for(UPNPDev* pDevice = structDeviceList; pDevice != NULL; pDevice = pDevice->pNext)
	{
		DebugLog(_T("Desc: %S, st: %S"), pDevice->descURL, pDevice->st);
	}
	m_pOwner->m_pURLs = new UPNPUrls;
	ZeroMemory(m_pOwner->m_pURLs, sizeof(UPNPUrls));
	m_pOwner->m_pIGDData = new IGDdatas;
	ZeroMemory(m_pOwner->m_pIGDData, sizeof(IGDdatas));
	char achLanIP[16];
	achLanIP[0] = 0;

	int iResult = UPNP_GetValidIGD(structDeviceList, m_pOwner->m_pURLs, m_pOwner->m_pIGDData, achLanIP, sizeof(achLanIP));
	switch (iResult){
		case 1:
			DebugLog(_T("Found valid IGD : %S"), m_pOwner->m_pURLs->controlURL);
			break;
		case 2:
			DebugLog(_T("Found a (not connected?) IGD : %S - Trying to continue anyway"), m_pOwner->m_pURLs->controlURL);
			break;
		case 3:
			DebugLog(_T("UPnP device found. Is it an IGD ? : %S - Trying to continue anyway"), m_pOwner->m_pURLs->controlURL);
			break;
		default:
			DebugLog(_T("Found device (igd ?) : %S - Trying to continue anyway"), m_pOwner->m_pURLs->controlURL);
	}
	freeUPNPDevlist(structDeviceList);
	DebugLog(_T("Our LAN IP: %S"), achLanIP);

	if (m_pOwner->m_bAbortDiscovery) // requesting to abort ASAP?
		return 0;

	// do we still have old mappings? Remove them first
	m_pOwner->DeletePorts(true);
	
	bool bSucceeded = OpenPort(m_pOwner->m_nTCPPort, true, achLanIP);
	if (bSucceeded && m_pOwner->m_nUDPPort != 0)
		bSucceeded = OpenPort(m_pOwner->m_nUDPPort, false, achLanIP);

	if (!m_pOwner->m_bAbortDiscovery){ // dont send a result on a abort request
		m_pOwner->m_bUPnPPortsForwarded = bSucceeded ? TRIS_TRUE : TRIS_FALSE;
		m_pOwner->SendResultMessage();
	}
	return 0;
}
Ejemplo n.º 14
0
// redirect port on external upnp enabled router to port on *this* host
int upnpredirect(const char* eport, const char* iport, const char* proto, const char* description)
{
    
    //  Discovery parameters
    struct UPNPDev * devlist = 0;
    struct UPNPUrls urls;
    struct IGDdatas data;
    int i;
    char lanaddr[64];	// my ip address on the LAN
    const char* leaseDuration="0";
    
    //  Redirect & test parameters
    char intClient[40];
    char intPort[6];
    char externalIPAddress[40];
    char duration[16];
    int error=0;
    
    //  Find UPNP devices on the network
    if ((devlist=upnpDiscover(2000, 0, 0,0, 0, &error))) {
        struct UPNPDev * device = 0;
        printf("UPNP INIALISED: List of UPNP devices found on the network.\n");
        for(device = devlist; device; device = device->pNext) {
            printf("UPNP INFO: dev [%s] \n\t st [%s]\n",
                   device->descURL, device->st);
        }
    } else {
        printf("UPNP ERROR: no device found - MANUAL PORTMAP REQUIRED\n");
        return 0;
    }
    
    //  Output whether we found a good one or not.
    if((error = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) {
        switch(error) {
            case 1:
                printf("UPNP OK: Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("UPNP WARN: Found a (not connected?) IGD : %s\n", urls.controlURL);
                break;
            case 3:
                printf("UPNP WARN: UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                break;
            default:
                printf("UPNP WARN: Found device (igd ?) : %s\n", urls.controlURL);
        }
        printf("UPNP OK: Local LAN ip address : %s\n", lanaddr);
    } else {
        printf("UPNP ERROR: no device found - MANUAL PORTMAP REQUIRED\n");
        return 0;
    }
    
    //  Get the external IP address (just because we can really...)
    if(UPNP_GetExternalIPAddress(urls.controlURL,
                                 data.first.servicetype,
                                 externalIPAddress)!=UPNPCOMMAND_SUCCESS)
        printf("UPNP WARN: GetExternalIPAddress failed.\n");
    else
        printf("UPNP OK: ExternalIPAddress = %s\n", externalIPAddress);
    
    //  Check for existing supernet mapping - from this host and another host
    //  In theory I can adapt this so multiple nodes can exist on same lan and choose a different portmap
    //  for each one :)
    //  At the moment just delete a conflicting portmap and override with the one requested.
    i=0;
    error=0;
    do {
        char index[6];
        char extPort[6];
        char desc[80];
        char enabled[6];
        char rHost[64];
        char protocol[4];
        
        snprintf(index, 6, "%d", i++);
        
        if(!(error=UPNP_GetGenericPortMappingEntry(urls.controlURL,
                                                   data.first.servicetype,
                                                   index,
                                                   extPort, intClient, intPort,
                                                   protocol, desc, enabled,
                                                   rHost, duration))) {
            // printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",i, protocol, extPort, intClient, intPort,desc, rHost, duration);
            
            // check for an existing supernet mapping on this host
            if(!strcmp(lanaddr, intClient)) { // same host
                if(!strcmp(protocol,proto)) { //same protocol
                    if(!strcmp(intPort,iport)) { // same port
                        printf("UPNP WARN: existing mapping found (%s:%s)\n",lanaddr,iport);
                        if(!strcmp(extPort,eport)) {
                            printf("UPNP OK: exact mapping already in place (%s:%s->%s)\n", lanaddr, iport, eport);
                            FreeUPNPUrls(&urls);
                            freeUPNPDevlist(devlist);
                            return 1;
                            
                        } else { // delete old mapping
                            printf("UPNP WARN: deleting existing mapping (%s:%s->%s)\n",lanaddr, iport, extPort);
                            if(UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, extPort, proto, rHost))
                                printf("UPNP WARN: error deleting old mapping (%s:%s->%s) continuing\n", lanaddr, iport, extPort);
                            else printf("UPNP OK: old mapping deleted (%s:%s->%s)\n",lanaddr, iport, extPort);
                        }
                    }
                }
            } else { // ipaddr different - check to see if requested port is already mapped
                if(!strcmp(protocol,proto)) {
                    if(!strcmp(extPort,eport)) {
                        printf("UPNP WARN: EXT port conflict mapped to another ip (%s-> %s vs %s)\n", extPort, lanaddr, intClient);
                        if(UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, extPort, proto, rHost))
                            printf("UPNP WARN: error deleting conflict mapping (%s:%s) continuing\n", intClient, extPort);
                        else printf("UPNP OK: conflict mapping deleted (%s:%s)\n",intClient, extPort);
                    }
                }
            }
        } else
            printf("UPNP OK: GetGenericPortMappingEntry() End-of-List (%d entries) \n", i);
    } while(error==0);
    
    //  Set the requested port mapping
    if((i=UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
                              eport, iport, lanaddr, description,
                              proto, 0, leaseDuration))!=UPNPCOMMAND_SUCCESS) {
        printf("UPNP ERROR: AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
               eport, iport, lanaddr, i, strupnperror(i));
        
        FreeUPNPUrls(&urls);
        freeUPNPDevlist(devlist);
        return 0; //error - adding the port map primary failure
    }
    
    if((i=UPNP_GetSpecificPortMappingEntry(urls.controlURL,
                                           data.first.servicetype,
                                           eport, proto, NULL/*remoteHost*/,
                                           intClient, intPort, NULL/*desc*/,
                                           NULL/*enabled*/, duration))!=UPNPCOMMAND_SUCCESS) {
        printf("UPNP ERROR: GetSpecificPortMappingEntry(%s, %s, %s) failed with code %d (%s)\n", eport, iport, lanaddr,
               i, strupnperror(i));
        FreeUPNPUrls(&urls);
        freeUPNPDevlist(devlist);
        return 0; //error - port map wasnt returned by query so likely failed.
    }
    else printf("UPNP OK: EXT (%s:%s) %s redirected to INT (%s:%s) (duration=%s)\n",externalIPAddress, eport, proto, intClient, intPort, duration);
    FreeUPNPUrls(&urls);
    freeUPNPDevlist(devlist);
    return 1; //ok - we are mapped:)
}
Ejemplo n.º 15
0
static int
upnpPulse( ml_upnpmp_t * map )
{
    int ret;

    if( map->enabled && ( map->upnpState == ML_UPNP_DISCOVER ) )
    {
        struct UPNPDev * devlist;
        errno = 0;
        devlist = upnpDiscover( 2000, NULL, NULL, 0, 0, 0 );
        if( devlist == NULL )
        {
            dbg_printf( "upnpDiscover failed (errno %d - %s)\n", errno,  str_errno( errno ) );
        }
        errno = 0;
        if( UPNP_IGD_VALID_CONNECTED == UPNP_GetValidIGD( devlist, &map->upnpUrls, &map->upnpData,
        		map->lanaddr, sizeof( map->lanaddr ) ) )
        {
            dbg_printf( "Found Internet Gateway Device \"%s\" \n", map->upnpUrls.controlURL );
            dbg_printf( "Local Address is \"%s\" \n", map->lanaddr );
            map->upnpState = ML_UPNP_IDLE;
            map->upnpDiscovered = 1;
        }
        else
        {
            map->upnpState = ML_UPNP_ERR;
            dbg_printf( "UPNP_GetValidIGD failed (errno %d - %s)\n", errno, str_errno( errno ) );
            dbg_printf( "If your router supports UPnP, please make sure UPnP is enabled!\n" );
        }
        freeUPNPDevlist( devlist );
    }

    if( map->upnpState == ML_UPNP_IDLE )
    {
        if( map->upnpMapped && ( !map->enabled ) )
        	map->upnpState = ML_UPNP_UNMAP;
    }

    if( map->enabled && map->upnpMapped && map->doPortCheck )
    {
        char portStr[8];
        char intPort[8];
        char intClient[16];
        char type[8];
        int i;

        snprintf( portStr, sizeof( portStr ), "%d", map->extPort );
        snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) );
        i = UPNP_GetSpecificPortMappingEntry( map->upnpUrls.controlURL,
                                              map->upnpData.first.servicetype, portStr,
                                              type,
#if MINIUPNPC_API_VERSION >= 10
                                              NULL, /* remoteHost */
#endif
                                              intClient, intPort, NULL, NULL, NULL );
        if( i != UPNPCOMMAND_SUCCESS )
        {
            dbg_printf( "Port %d isn't forwarded\n", map->extPort );
            map->upnpMapped = 0;
        }
        map->doPortCheck = 0;
    }

    if( map->upnpState == ML_UPNP_UNMAP )
    {
        char portStr[16];
        char type[8];
        snprintf( portStr, sizeof( portStr ), "%d", map->extPort );
        snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) );
        UPNP_DeletePortMapping( map->upnpUrls.controlURL,
                                map->upnpData.first.servicetype,
                                portStr, type, NULL );
        dbg_printf( "Stopping port forwarding through \"%s\", service \"%s\"\n", map->upnpUrls.controlURL, map->upnpData.first.servicetype );
        map->upnpMapped = 0;
        map->upnpState = ML_UPNP_IDLE;
        map->extPort = 0;
    }

    if( map->upnpState == ML_UPNP_IDLE )
    {
        if( map->enabled && !map->upnpMapped )
            map->upnpState = ML_UPNP_MAP;
    }

    if( map->upnpState == ML_UPNP_MAP )
    {
        int  err = -1;
        errno = 0;

        if( !map->upnpUrls.controlURL || !map->upnpData.first.servicetype )
            map->upnpMapped = 0;
        else
        {
            char intPortStr[16];
            char extPortStr[16];
            char desc[64];
            char type[8];
            snprintf( intPortStr, sizeof( intPortStr ), "%d", map->intPort );
            snprintf( extPortStr, sizeof( extPortStr ), "%d", map->extPort );
            snprintf( desc, sizeof( desc ), "%s", map->notes );
            snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) );
            err = UPNP_AddPortMapping( map->upnpUrls.controlURL,
                                       map->upnpData.first.servicetype,
                                       extPortStr, intPortStr, map->lanaddr,
                                       desc, type, NULL, "0" );
            map->upnpMapped = !err;
        }
        dbg_printf( "Port forwarding through \"%s\", service \"%s\". (local address[%s:%d])\n", map->upnpUrls.controlURL, map->upnpData.first.servicetype, map->lanaddr, map->intPort );
        if( map->upnpMapped )
        {
            dbg_printf( "Port forwarding successful!\n" );
            //handle->port = port;
            map->upnpState = ML_UPNP_IDLE;
        }
        else
        {
            dbg_printf( "Port forwarding failed with error %d (errno %d - %s)\n", err, errno, str_errno( errno ) );
            dbg_printf( "If your router supports UPnP, please make sure UPnP is enabled!\n" );
            //handle->port = -1;
            map->upnpState = ML_UPNP_ERR;
        }
    }

    switch( map->upnpState )
    {
        case ML_UPNP_DISCOVER:
            ret = ML_PORT_UNMAPPED; break;

        case ML_UPNP_MAP:
            ret = ML_PORT_MAPPING; break;

        case ML_UPNP_UNMAP:
            ret = ML_PORT_UNMAPPING; break;

        case ML_UPNP_IDLE:
            ret = map->upnpMapped ? ML_PORT_MAPPED
                  : ML_PORT_UNMAPPED; break;

        default:
            ret = ML_PORT_ERROR; break;
    }

    return ret;
}
Ejemplo n.º 16
0
int xshl5_redirect_remove(const char* ext_port_and_protocols[], int num,
                    int ipv6, const char* interface_or_ipaddr)
{
    int retcode = -1;

    struct UPNPDev * devlist = 0;
    const char * multicastif = interface_or_ipaddr;
    const char * minissdpdpath = 0;
    char lanaddr[64];	/* my ip address on the LAN */

    int error = 0, i = 0;
    if(num <= 0)
        return retcode;

    if( (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
                                 0/*sameport*/, ipv6, &error)))
    {
        struct UPNPDev * device;
        struct UPNPUrls urls;
        struct IGDdatas data;
        if(devlist)
        {
            printf("List of UPNP devices found on the network :\n");
            for(device = devlist; device; device = device->pNext)
            {
                printf(" desc: %s\n st: %s\n\n",
                       device->descURL, device->st);
            }
        }
        else
        {
            printf("upnpDiscover() error code=%d\n", error);
        }
        i = 1;
        if( (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))) )
        {
            switch(i) {
            case 1:
                printf("Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            case 3:
                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            default:
                printf("Found device (igd ?) : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
            }
            printf("Local LAN ip address : %s\n", lanaddr);

            for(i=0; i<num; i+=2)
            {
                if(ext_port_and_protocols[i] == NULL || ext_port_and_protocols[i+1] == NULL)
                {
                    retcode = -2;
                    break;
                }

                RemoveRedirect(&urls, &data, ext_port_and_protocols[i],
                        strcmp(ext_port_and_protocols[i+1], "udp")==0? "udp": "tcp");
            }
            retcode = 0;

            FreeUPNPUrls(&urls);
        }
        else
        {
            fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
            retcode = 1;
        }
        freeUPNPDevlist(devlist); devlist = 0;
    }
    else
    {
        fprintf(stderr, "No IGD UPnP Device found on the network !\n");
        retcode = 1;
    }

    return retcode;
}
Ejemplo n.º 17
0
int xshl5_redirect(unsigned short pri_port, unsigned short ext_port,
                   const char* pri_ip, const char* protocol, int ipv6,
                   const char* interface_or_ipaddr, const char* description,
                   /*out*/char* ext_ipaddr)
{
    int retcode = -1;

    struct UPNPDev * devlist = 0;
    const char * multicastif = interface_or_ipaddr;
    const char * minissdpdpath = 0;
    char lanaddr[64];	/* my ip address on the LAN */

    int error = 0, i = 0;

    char used_protocol[16] = "tcp";
    char used_ipaddr[32] = {0};
    char used_pri_port[8] = {0};
    char used_ext_port[8] = {0};

    // used_pri_port
    sprintf(used_pri_port, "%u", pri_port);
    // used_ext_port
    if(ext_port == 0)
        sprintf(used_ext_port, "%u", pri_port);
    else
        sprintf(used_ext_port, "%u", ext_port);
    // used_protocol
    if(protocol != NULL && (protocol[0]=='u'&&protocol[1]=='d'&&protocol[2]=='p') )
    {
        strncpy(used_protocol, protocol, 3);
    }

    if( (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
                                 0/*sameport*/, ipv6, &error)))
    {
        struct UPNPDev * device;
        struct UPNPUrls urls;
        struct IGDdatas data;
        if(devlist)
        {
            printf("List of UPNP devices found on the network :\n");
            for(device = devlist; device; device = device->pNext)
            {
                printf(" desc: %s\n st: %s\n\n",
                       device->descURL, device->st);
            }
        }
        else
        {
            printf("upnpDiscover() error code=%d\n", error);
        }
        i = 1;
        if( (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))) )
        {
            switch(i) {
            case 1:
                printf("Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            case 3:
                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            default:
                printf("Found device (igd ?) : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
            }
            printf("Local LAN ip address : %s\n", lanaddr);

            // used_ipaddr
            if(pri_ip == NULL)
                strcpy(used_ipaddr, lanaddr);
            else
                strcpy(used_ipaddr, pri_ip);

            SetRedirectAndTest(&urls, &data,
                       used_ipaddr, used_pri_port,
                       used_ext_port, used_protocol,
                       "0",
                       description, 0, ext_ipaddr);
            retcode = 0;
/*
            case 'a':
                SetRedirectAndTest(&urls, &data,
                           commandargv[0], commandargv[1],
                           commandargv[2], commandargv[3],
                           (commandargc > 4)?commandargv[4]:"0",
                           description, 0);
                break;
            case 'd':
                for(i=0; i<commandargc; i+=2)
                {
                    RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
                }
                break;
*/
            FreeUPNPUrls(&urls);
        }
        else
        {
            fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
            retcode = 1;
        }
        freeUPNPDevlist(devlist); devlist = 0;
    }
    else
    {
        fprintf(stderr, "No IGD UPnP Device found on the network !\n");
        retcode = 1;
    }

    return retcode;
}
Ejemplo n.º 18
0
bool UPnP::start()
{
    int error = 0;

    UPNPDev *devlist = ::upnpDiscover(2000, NULL, NULL, FALSE, FALSE, &error);
    UPNPDev *devlistBegin = devlist;

    // get interface list
    /*foreach(interface, interfaces) {
        newdevlist = ::upnpDiscover(2000, interface, NULL, FALSE, FALSE, &error);

        // go to end of list and append
    }*/

    while (devlist)
    {
        UPNPUrls urls;
        IGDdatas data;
        char lanaddr[64];
        UPnPHash resultHash;

        int code = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));

        if (code > 0)   // TODO maybe distinguish between the return codes (1,2,3) to add information what happend to the result
        {
            resultHash.insert(LanIpAddress, QLatin1String(lanaddr));

            char externalIP[40];

            if (UPNPCOMMAND_SUCCESS == UPNP_GetExternalIPAddress(urls.controlURL,
                                                                 data.first.servicetype,
                                                                 externalIP))
            {
                resultHash.insert(ExternalIpAddress, QLatin1String(externalIP));
            }

            char connectionType[64];

            if (UPNPCOMMAND_SUCCESS == UPNP_GetConnectionTypeInfo(urls.controlURL,
                                                                  data.first.servicetype,
                                                                  connectionType))
            {
                resultHash.insert(ConnectionType, QLatin1String(connectionType));
            }

            quint32 uplink, downlink;

            if (UPNPCOMMAND_SUCCESS == UPNP_GetLinkLayerMaxBitRates(urls.controlURL_CIF,
                                                                    data.CIF.servicetype,
                                                                    &downlink, &uplink))
            {
                resultHash.insert(LinkLayerMaxDownload, downlink);
                resultHash.insert(LinkLayerMaxUpload, uplink);
            }

            quint32 bytesSent, bytesReceived, packetsSent, packetsReceived;

            bytesSent = UPNP_GetTotalBytesSent(urls.controlURL_CIF,
                                               data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != bytesSent)
            {
                resultHash.insert(TotalBytesSent, bytesSent);
            }

            bytesReceived = UPNP_GetTotalBytesReceived(urls.controlURL_CIF,
                                                       data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != bytesReceived)
            {
                resultHash.insert(TotalBytesReceived, bytesReceived);
            }

            packetsSent = UPNP_GetTotalPacketsSent(urls.controlURL_CIF,
                                                   data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != packetsSent)
            {
                resultHash.insert(TotalPacketsSent, packetsSent);
            }


            packetsReceived = UPNP_GetTotalPacketsReceived(urls.controlURL_CIF,
                                                           data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != packetsReceived)
            {
                resultHash.insert(TotalPacketsReceived, packetsReceived);
            }


            char status[100];
            unsigned int uptime = 0;
            char lastConnectionError[128];

            if (UPNPCOMMAND_SUCCESS == UPNP_GetStatusInfo(urls.controlURL,
                                                          data.first.servicetype,
                                                          status,
                                                          &uptime,
                                                          lastConnectionError))
            {
                resultHash.insert(Status, status);
                resultHash.insert(Uptime, uptime);
                resultHash.insert(LastConnectionError, lastConnectionError);
            }

            quint32 num;

            if (UPNPCOMMAND_SUCCESS == UPNP_GetPortMappingNumberOfEntries(urls.controlURL,
                                                                          data.first.servicetype,
                                                                          &num))
            {
                resultHash.insert(NumberOfPortMappings, num);
            }

            // TODO GetListOfPortMappings do we need this?

            int firewallEnabled, inboundPinholeAllowed;

            if (UPNPCOMMAND_SUCCESS == UPNP_GetFirewallStatus(urls.controlURL,
                                                              data.first.servicetype,
                                                              &firewallEnabled,
                                                              &inboundPinholeAllowed))
            {
                resultHash.insert(FirewallEnabled, firewallEnabled);
                resultHash.insert(InboundPinholeAllowed, inboundPinholeAllowed);
            }

            int bufferSize = 0;

            if (char *buffer = (char *)miniwget(urls.rootdescURL, &bufferSize, 0))
            {
                NameValueParserData pdata;
                ParseNameValue(buffer, bufferSize, &pdata);
                free(buffer);
                buffer = NULL;

                QStringList modelName = GetValuesFromNameValueList(&pdata, "modelName");

                if (!modelName.isEmpty())
                {
                    resultHash.insert(ModelName, modelName.last());
                }

                QStringList manufacturer = GetValuesFromNameValueList(&pdata, "manufacturer");

                if (!manufacturer.isEmpty())
                {
                    resultHash.insert(Manufacturer, manufacturer.last());
                }

                QStringList friendlyName = GetValuesFromNameValueList(&pdata, "friendlyName");

                if (!friendlyName.isEmpty())
                {
                    resultHash.insert(FriendlyName, friendlyName.last());
                }

                ClearNameValueList(&pdata);
            }
        }

        FreeUPNPUrls(&urls);

        results.append(resultHash);
        devlist = devlist->pNext;
    }

    freeUPNPDevlist(devlistBegin);

    emit finished();
    return true; // TODO return false if something went wrong or if there are no results
}
Ejemplo n.º 19
0
int upnpPulse(upnp * handle, int port, int proto, char isEnabled, int doPortCheck, const char* name)
{
    if(isEnabled && (handle->state == UPNP_DISCOVER))
    {
        struct UPNPDev * devlist;
        devlist = upnpDiscover(200, NULL, NULL, 0);
        if(UPNP_GetValidIGD(devlist, &handle->urls, &handle->data,
                             handle->lanaddr, sizeof(handle->lanaddr )) == UPNP_IGD_VALID_CONNECTED)
        {
			//qDebug() << QString("Found Internet Gateway Device \"%1\"").arg(QString(handle->urls.controlURL));
			//qDebug() << QString("Local Address is \"%1\"").arg(QString(handle->lanaddr));

            handle->state = UPNP_IDLE;
            handle->hasDiscovered = 1;
        }
        else
        {
            handle->state = UPNP_ERR;
			//qDebug() << QString("UPNP_GetValidIGD failed");
        }
        freeUPNPDevlist(devlist);
    }

    if(handle->state == UPNP_IDLE)
    {
        if(handle->isMapped && (!isEnabled || handle->port != port))
            handle->state = UPNP_UNMAP;
    }

	char* protoStr = "";
	switch(proto)
	{
	case PORT_TCP: protoStr = "TCP"; break;
	case PORT_UDP: protoStr = "UDP"; break;
	}

    if(isEnabled && handle->isMapped && doPortCheck)
    {
        char portStr[8];
        char intPort[8];
        char intClient[16];

        snprintf(portStr, sizeof(portStr), "%d", handle->port);
        if(UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, protoStr, intClient, intPort ) != UPNPCOMMAND_SUCCESS)
        {
			//qDebug() << QString("Port %1 isn't forwarded").arg(handle->port);
            handle->isMapped = 0;
        }
    }

    if( handle->state == UPNP_UNMAP )
    {
        char portStr[16];
        snprintf(portStr, sizeof(portStr), "%d", handle->port);
        UPNP_DeletePortMapping(handle->urls.controlURL, handle->data.first.servicetype, portStr, protoStr, NULL);

		//qDebug() << QString("Stopping port forwarding through \"%1\", service \"%1\"").arg(QString(handle->urls.controlURL)).arg(QString(handle->data.first.servicetype));

        handle->isMapped = 0;
        handle->state = UPNP_IDLE;
        handle->port = -1;
    }

    if(handle->state == UPNP_IDLE)
    {
        if(isEnabled && !handle->isMapped)
            handle->state = UPNP_MAP;
    }

    if(handle->state == UPNP_MAP)
    {
        int  err = -1;

        if(!handle->urls.controlURL || !handle->data.first.servicetype)
            handle->isMapped = 0;
        else
        {
            char portStr[16];
            char desc[64];
            snprintf(portStr, sizeof(portStr), "%d", port);
            snprintf(desc, sizeof(desc), "%s at %d", name, port);

            err = UPNP_AddPortMapping(handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, protoStr, NULL);
			//if(err)
			//	qDebug() << QString("%1 Port forwarding failed with error %2").arg(QString(protoStr)).arg(err);
            
            handle->isMapped = !err;
        }
		//qDebug() << QString("Port forwarding through \"%1\", service \"%2\". (local address: %3:%4)")
		//		.arg(QString(handle->urls.controlURL)).arg(QString(handle->data.first.servicetype)).arg(QString(handle->lanaddr)).arg(port);

        if(handle->isMapped)
        {
			//qDebug() << QString("Port forwarding successful!");
            handle->port = port;
            handle->state = UPNP_IDLE;
        }
        else
        {
			//qDebug() << QString("If your router supports UPnP, please make sure UPnP is enabled!");
            handle->port = -1;
            handle->state = UPNP_ERR;
        }
    }

    switch( handle->state )
    {
    case UPNP_DISCOVER:	return PORT_UNMAPPED;
	case UPNP_MAP:		return PORT_MAPPING;
	case UPNP_UNMAP:	return PORT_UNMAPPING;
	case UPNP_IDLE:		return handle->isMapped ? PORT_MAPPED : PORT_UNMAPPED;
	default:			return PORT_ERROR;
    }
}
Ejemplo n.º 20
0
int
tr_upnpPulse( tr_upnp * handle,
              int       port,
              int       isEnabled,
              int       doPortCheck )
{
    int ret;

    if( isEnabled && ( handle->state == TR_UPNP_DISCOVER ) )
    {
        struct UPNPDev * devlist;
        errno = 0;
        devlist = upnpDiscover( 2000, NULL, NULL, 0 );
        if( devlist == NULL )
        {
            tr_ndbg(
                 getKey( ), "upnpDiscover failed (errno %d - %s)", errno,
                tr_strerror( errno ) );
        }
        errno = 0;
        if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data,
                             handle->lanaddr, sizeof( handle->lanaddr ) ) == UPNP_IGD_VALID_CONNECTED )
        {
            tr_ninf( getKey( ), _(
                         "Found Internet Gateway Device \"%s\"" ),
                     handle->urls.controlURL );
            tr_ninf( getKey( ), _(
                         "Local Address is \"%s\"" ), handle->lanaddr );
            handle->state = TR_UPNP_IDLE;
            handle->hasDiscovered = 1;
        }
        else
        {
            handle->state = TR_UPNP_ERR;
            tr_ndbg(
                 getKey( ), "UPNP_GetValidIGD failed (errno %d - %s)",
                errno,
                tr_strerror( errno ) );
            tr_ndbg(
                getKey( ),
                "If your router supports UPnP, please make sure UPnP is enabled!" );
        }
        freeUPNPDevlist( devlist );
    }

    if( handle->state == TR_UPNP_IDLE )
    {
        if( handle->isMapped && ( !isEnabled || ( handle->port != port ) ) )
            handle->state = TR_UPNP_UNMAP;
    }

    if( isEnabled && handle->isMapped && doPortCheck )
    {
        char portStr[8];
        char intPort[8];
        char intClient[16];

        tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port );
        if( UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, 
            portStr, "TCP", intClient, intPort ) != UPNPCOMMAND_SUCCESS  ||
            UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, 
            portStr, "UDP", intClient, intPort ) != UPNPCOMMAND_SUCCESS )
        {
            tr_ninf( getKey( ), _( "Port %d isn't forwarded" ), handle->port );
            handle->isMapped = FALSE;
        }
    }

    if( handle->state == TR_UPNP_UNMAP )
    {
        char portStr[16];
        tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port );
        UPNP_DeletePortMapping( handle->urls.controlURL,
                                handle->data.first.servicetype,
                                portStr, "TCP", NULL );
        UPNP_DeletePortMapping( handle->urls.controlURL,
                                handle->data.first.servicetype,
                                portStr, "UDP", NULL );
        tr_ninf( getKey( ),
                 _(
                     "Stopping port forwarding through \"%s\", service \"%s\"" ),
                 handle->urls.controlURL, handle->data.first.servicetype );
        handle->isMapped = 0;
        handle->state = TR_UPNP_IDLE;
        handle->port = -1;
    }

    if( handle->state == TR_UPNP_IDLE )
    {
        if( isEnabled && !handle->isMapped )
            handle->state = TR_UPNP_MAP;
    }

    if( handle->state == TR_UPNP_MAP )
    {
        int  err_tcp = -1;
        int  err_udp = -1;
        errno = 0;

        if( !handle->urls.controlURL || !handle->data.first.servicetype )
            handle->isMapped = 0;
        else
        {
            char portStr[16];
            char desc[64];
            const int prev_errno = errno;
            tr_snprintf( portStr, sizeof( portStr ), "%d", port );
            tr_snprintf( desc, sizeof( desc ), "%s at %d", TR_NAME, port );

            errno = 0;
            err_tcp = UPNP_AddPortMapping( handle->urls.controlURL,
                                       handle->data.first.servicetype,
                                       portStr, portStr, handle->lanaddr,
                                       desc, "TCP", NULL );
            if( err_tcp )
                tr_ndbg( getKey( ), "TCP Port forwarding failed with error %d (errno %d - %s)",
                         err_tcp, errno, tr_strerror( errno ) );

            errno = 0;
            err_udp = UPNP_AddPortMapping( handle->urls.controlURL,
                                       handle->data.first.servicetype,
                                       portStr, portStr, handle->lanaddr,
                                       desc, "UDP", NULL );
            if( err_udp )
                tr_ndbg( getKey( ), "UDP Port forwarding failed with error %d (errno %d - %s)",
                         err_udp, errno, tr_strerror( errno ) );

            errno = prev_errno;
            handle->isMapped = !err_tcp | !err_udp;
        }
        tr_ninf( getKey( ),
                 _( "Port forwarding through \"%s\", service \"%s\". (local address: %s:%d)" ),
                 handle->urls.controlURL, handle->data.first.servicetype,
                 handle->lanaddr, port );
        if( handle->isMapped )
        {
            tr_ninf( getKey( ), "%s", _( "Port forwarding successful!" ) );
            handle->port = port;
            handle->state = TR_UPNP_IDLE;
        }
        else
        {
            tr_ndbg( getKey( ), "If your router supports UPnP, please make sure UPnP is enabled!" );
            handle->port = -1;
            handle->state = TR_UPNP_ERR;
        }
    }

    switch( handle->state )
    {
        case TR_UPNP_DISCOVER:
            ret = TR_PORT_UNMAPPED; break;

        case TR_UPNP_MAP:
            ret = TR_PORT_MAPPING; break;

        case TR_UPNP_UNMAP:
            ret = TR_PORT_UNMAPPING; break;

        case TR_UPNP_IDLE:
            ret = handle->isMapped ? TR_PORT_MAPPED
                  : TR_PORT_UNMAPPED; break;

        default:
            ret = TR_PORT_ERROR; break;
    }

    return ret;
}
Ejemplo n.º 21
0
void* CNetServerWorker::SetupUPnP(void*)
{
	// Values we want to set.
	char psPort[6];
	sprintf_s(psPort, ARRAY_SIZE(psPort), "%d", PS_DEFAULT_PORT);
	const char* leaseDuration = "0"; // Indefinite/permanent lease duration.
	const char* description = "0AD Multiplayer";
	const char* protocall = "UDP";
	char internalIPAddress[64];
	char externalIPAddress[40];
	// Variables to hold the values that actually get set.
	char intClient[40];
	char intPort[6];
	char duration[16];
	// Intermediate variables.
	struct UPNPUrls urls;
	struct IGDdatas data;
	struct UPNPDev* devlist = NULL;

	// Cached root descriptor URL.
	std::string rootDescURL;
	CFG_GET_VAL("network.upnprootdescurl", rootDescURL);
	if (!rootDescURL.empty())
		LOGMESSAGE("Net server: attempting to use cached root descriptor URL: %s", rootDescURL.c_str());

	int ret = 0;
	bool allocatedUrls = false;

	// Try a cached URL first
	if (!rootDescURL.empty() && UPNP_GetIGDFromUrl(rootDescURL.c_str(), &urls, &data, internalIPAddress, sizeof(internalIPAddress)))
	{
		LOGMESSAGE("Net server: using cached IGD = %s", urls.controlURL);
		ret = 1;
	}
	// No cached URL, or it did not respond. Try getting a valid UPnP device for 10 seconds.
	else if ((devlist = upnpDiscover(10000, 0, 0, 0, 0, 0)) != NULL)
	{
		ret = UPNP_GetValidIGD(devlist, &urls, &data, internalIPAddress, sizeof(internalIPAddress));
		allocatedUrls = ret != 0; // urls is allocated on non-zero return values
	}
	else
	{
		LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL.");
		return NULL;
	}

	switch (ret)
	{
	case 0:
		LOGMESSAGE("Net server: No IGD found");
		break;
	case 1:
		LOGMESSAGE("Net server: found valid IGD = %s", urls.controlURL);
		break;
	case 2:
		LOGMESSAGE("Net server: found a valid, not connected IGD = %s, will try to continue anyway", urls.controlURL);
		break;
	case 3:
		LOGMESSAGE("Net server: found a UPnP device unrecognized as IGD = %s, will try to continue anyway", urls.controlURL);
		break;
	default:
		debug_warn(L"Unrecognized return value from UPNP_GetValidIGD");
	}

	// Try getting our external/internet facing IP. TODO: Display this on the game-setup page for conviniance.
	ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
	if (ret != UPNPCOMMAND_SUCCESS)
	{
		LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret));
		return NULL;
	}
	LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress);

	// Try to setup port forwarding.
	ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, psPort, psPort,
							internalIPAddress, description, protocall, 0, leaseDuration);
	if (ret != UPNPCOMMAND_SUCCESS)
	{
		LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)",
			   psPort, psPort, internalIPAddress, ret, strupnperror(ret));
		return NULL;
	}

	// Check that the port was actually forwarded.
	ret = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
									 data.first.servicetype,
									 psPort, protocall,
#if defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 10
									 NULL/*remoteHost*/,
#endif
									 intClient, intPort, NULL/*desc*/,
									 NULL/*enabled*/, duration);

	if (ret != UPNPCOMMAND_SUCCESS)
	{
		LOGMESSAGE("Net server: GetSpecificPortMappingEntry() failed with code %d (%s)", ret, strupnperror(ret));
		return NULL;
	}

	LOGMESSAGE("Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)",
				   externalIPAddress, psPort, protocall, intClient, intPort, duration);

	// Cache root descriptor URL to try to avoid discovery next time.
	g_ConfigDB.SetValueString(CFG_USER, "network.upnprootdescurl", urls.controlURL);
	g_ConfigDB.WriteFile(CFG_USER);
	LOGMESSAGE("Net server: cached UPnP root descriptor URL as %s", urls.controlURL);

	// Make sure everything is properly freed.
	if (allocatedUrls)
		FreeUPNPUrls(&urls);
    
	freeUPNPDevlist(devlist);

	return NULL;
}
Ejemplo n.º 22
0
int CUPnPImplMiniLib::CStartDiscoveryThread::Run()
{
	DbgSetThreadName("CUPnPImplMiniLib::CStartDiscoveryThread");
	if ( !m_pOwner )
		return 0;

	CSingleLock sLock(&m_pOwner->m_mutBusy);
	if (!sLock.Lock(0)){
		DebugLogWarning(_T("CUPnPImplMiniLib::CStartDiscoveryThread::Run, failed to acquire Lock, another Mapping try might be running already"));
		return 0;
	}

	if (m_pOwner->m_bAbortDiscovery) // requesting to abort ASAP?
		return 0;

	bool bSucceeded = false;
#if !(defined(_DEBUG) || defined(_BETA))
	try
#endif
	{
		if (!m_pOwner->m_bCheckAndRefresh)
		{
			UPNPDev* structDeviceList = upnpDiscover(2000, NULL, NULL, NULL);
			if (structDeviceList == NULL){
				DebugLog(_T("UPNP: No Internet Gateway Devices found, aborting"));
				m_pOwner->m_bUPnPPortsForwarded = TRIS_FALSE;
				m_pOwner->SendResultMessage();
				return 0;
			}

			if (m_pOwner->m_bAbortDiscovery){ // requesting to abort ASAP?
				freeUPNPDevlist(structDeviceList);
				return 0;
			}

			DebugLog(_T("List of UPNP devices found on the network:"));
			for(UPNPDev* pDevice = structDeviceList; pDevice != NULL; pDevice = pDevice->pNext)
			{
				DebugLog(_T("Desc: %S, st: %S"), pDevice->descURL, pDevice->st);
			}
			m_pOwner->m_pURLs = new UPNPUrls;
			ZeroMemory(m_pOwner->m_pURLs, sizeof(UPNPUrls));
			m_pOwner->m_pIGDData = new IGDdatas;
			ZeroMemory(m_pOwner->m_pIGDData, sizeof(IGDdatas));
			
			m_pOwner->m_achLanIP[0] = 0;
			int iResult = UPNP_GetValidIGD(structDeviceList, m_pOwner->m_pURLs, m_pOwner->m_pIGDData, m_pOwner->m_achLanIP, sizeof(m_pOwner->m_achLanIP));
			freeUPNPDevlist(structDeviceList);
			bool bNotFound = false;
			switch (iResult){
				case 1:
					DebugLog(_T("Found valid IGD : %S"), m_pOwner->m_pURLs->controlURL);
					break;
				case 2:
					DebugLog(_T("Found a (not connected?) IGD : %S - Trying to continue anyway"), m_pOwner->m_pURLs->controlURL);
					break;
				case 3:
					DebugLog(_T("UPnP device found. Is it an IGD ? : %S - Trying to continue anyway"), m_pOwner->m_pURLs->controlURL);
					break;
				default:
					DebugLog(_T("Found device (igd ?) : %S - Aborting"), m_pOwner->m_pURLs->controlURL != NULL ? m_pOwner->m_pURLs->controlURL : "(none)");
					bNotFound = true;
			}
			if (bNotFound || m_pOwner->m_pURLs->controlURL == NULL)
			{
				m_pOwner->m_bUPnPPortsForwarded = TRIS_FALSE;
				m_pOwner->SendResultMessage();
				return 0;
			}
			DebugLog(_T("Our LAN IP: %S"), m_pOwner->m_achLanIP);

			if (m_pOwner->m_bAbortDiscovery) // requesting to abort ASAP?
				return 0;

			// do we still have old mappings? Remove them first
			m_pOwner->DeletePorts(true);
		}
		
		bSucceeded = OpenPort(m_pOwner->m_nTCPPort, true, m_pOwner->m_achLanIP, m_pOwner->m_bCheckAndRefresh);
		if (bSucceeded && m_pOwner->m_nUDPPort != 0)
			bSucceeded = OpenPort(m_pOwner->m_nUDPPort, false, m_pOwner->m_achLanIP, m_pOwner->m_bCheckAndRefresh);
		if (bSucceeded && m_pOwner->m_nTCPWebPort != 0)
			OpenPort(m_pOwner->m_nTCPWebPort, true, m_pOwner->m_achLanIP, m_pOwner->m_bCheckAndRefresh); // don't fail if only the webinterface port fails for some reason
	}
#if !(defined(_DEBUG) || defined(_BETA))
	catch(...)
	{
		DebugLogError(_T("Unknown Exception in CUPnPImplMiniLib::CStartDiscoveryThread::Run()"));
	}
#endif
	if (!m_pOwner->m_bAbortDiscovery){ // dont send a result on a abort request
		m_pOwner->m_bUPnPPortsForwarded = bSucceeded ? TRIS_TRUE : TRIS_FALSE;
		m_pOwner->m_bSucceededOnce |= bSucceeded;
		m_pOwner->SendResultMessage();
	}
	return 0;
}
Ejemplo n.º 23
0
int upnp_handler( struct upnp_handle_t *handle, unsigned short port, time_t lifespan, time_t now ) {
	struct UPNPDev * devlist;

	/* Retry later if we want to wait longer */
	if( handle->retry > now ) {
		return PF_RETRY;
	}

#ifdef DEBUG
	log_debug( "UPnP: Handle port: %hu, lifespan: %ld, state: %s", port, lifespan, upnp_statestr( handle->state ) );
#endif

	/* Get gateway address */
	if( handle->state == UPNP_STATE_DISCOVER_GATEWAY ) {
#if (MINIUPNPC_API_VERSION <= 5)
		devlist = upnpDiscover( 1000, NULL, NULL, 0 );
		if( devlist == NULL ) {
#else
		int err = UPNPDISCOVER_SUCCESS;
		devlist = upnpDiscover( 1000, NULL, NULL, 0, 0, &err );
		if( err != UPNPDISCOVER_SUCCESS ) {
#endif
			log_debug( "UPnP: Method upnpDiscover failed." );
			handle->retry = now + (10 * 60);
			handle->state = UPNP_STATE_DISCOVER_GATEWAY;
			return PF_RETRY;
		} else if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data,
				handle->addr, sizeof(handle->addr) ) == 1 ) {
			freeUPNPDevlist( devlist );
			log_info( "UPnP: Found gateway device \"%s\".", handle->urls.controlURL );
			handle->state = UPNP_STATE_GET_PORTMAPPING;
			return PF_RETRY;
		} else {
			freeUPNPDevlist( devlist );
			goto error;
		}
	}

	if( handle->state == UPNP_STATE_GET_PORTMAPPING ) {
		if( lifespan == 0 ) {
			/* Remove port forwarding */
			int rc_tcp = upnpDeletePortMapping( handle, "TCP", port );
			int rc_udp = upnpDeletePortMapping( handle, "UDP", port );

			if( rc_tcp == UPNPCOMMAND_SUCCESS && rc_udp == UPNPCOMMAND_SUCCESS ) {
				log_debug( "UPnP: Removed port forwarding for local port %d through \"%s\".", port, handle->urls.controlURL );
				handle->state = UPNP_STATE_GET_PORTMAPPING;
				return PF_DONE;
			} else {
				log_debug( "UPnP: Removing port mapping failed." );
				goto error;
			}
		} else {
			/* Check port forwarding */
			int rc_tcp = upnpGetSpecificPortMappingEntry( handle, "TCP", port );
			int rc_udp = upnpGetSpecificPortMappingEntry( handle, "UDP", port );

			if( rc_tcp == UPNPCOMMAND_SUCCESS && rc_udp == UPNPCOMMAND_SUCCESS ) {
				log_debug( "UPnP: Port forwarding for local port %d already exists.", port );
				handle->state = UPNP_STATE_GET_PORTMAPPING;
				return PF_DONE;
			} else {
				log_debug( "UPnP: Port %d isn't forwarded.", port );
				handle->state = UPNP_STATE_ADD_PORTMAPPING;
				return PF_RETRY;
			}
		}
	}

	/* Add port forwarding */
	if( handle->state == UPNP_STATE_ADD_PORTMAPPING ) {
		if ( handle->urls.controlURL && handle->data.first.servicetype ) {
			int rc_tcp = upnpAddPortMapping( handle, "TCP", port );
			int rc_udp = upnpAddPortMapping( handle, "UDP", port );

			if( rc_tcp == UPNPCOMMAND_SUCCESS && rc_udp == UPNPCOMMAND_SUCCESS ) {
				log_info( "UPnP: Port %d through \"%s\" forwarded to local address %s:%d.",
					port, handle->urls.controlURL, handle->addr, port );
				handle->state = UPNP_STATE_GET_PORTMAPPING;
				return PF_DONE;
			} else {
				log_debug( "UPnP: Port forwarding of port %d failed.", port );
				goto error;
			}
		} else {
			goto error;
		}
	}

	error:;

	handle->retry = now + 60;
	handle->state = UPNP_STATE_ERROR;
	return PF_ERROR;
}
Ejemplo n.º 24
0
/* sample upnp client program */
int main(int argc, char ** argv)
{
    char command = 0;
    char ** commandargv = 0;
    int commandargc = 0;
    struct UPNPDev * devlist = 0;
    char lanaddr[64];	/* my ip address on the LAN */
    int i;
    const char * rootdescurl = 0;
    const char * multicastif = 0;
    const char * minissdpdpath = 0;
    int retcode = 0;

#ifdef WIN32
    WSADATA wsaData;
    int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if(nResult != NO_ERROR)
    {
        fprintf(stderr, "WSAStartup() failed.\n");
        return -1;
    }
#endif
    printf("upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard\n");
    printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
           "for more information.\n");
    /* command line processing */
    for(i=1; i<argc; i++)
    {
        if(argv[i][0] == '-')
        {
            if(argv[i][1] == 'u')
                rootdescurl = argv[++i];
            else if(argv[i][1] == 'm')
                multicastif = argv[++i];
            else if(argv[i][1] == 'p')
                minissdpdpath = argv[++i];
            else
            {
                command = argv[i][1];
                i++;
                commandargv = argv + i;
                commandargc = argc - i;
                break;
            }
        }
        else
        {
            fprintf(stderr, "option '%s' invalid\n", argv[i]);
        }
    }

    if(!command || (command == 'a' && commandargc<4)
            || (command == 'd' && argc<2)
            || (command == 'r' && argc<2))
    {
        fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol\n\t\tAdd port redirection\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
        fprintf(stderr, "\nprotocol is UDP or TCP\n");
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -u url : bypass discovery process by providing the XML root description url.\n");
        fprintf(stderr, "  -m address : provide ip address of the interface to use for sending SSDP multicast packets.\n");
        fprintf(stderr, "  -p path : use this path for MiniSSDPd socket.\n");
        return 1;
    }

    if( rootdescurl
            || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0)))
    {
        struct UPNPDev * device;
        struct UPNPUrls urls;
        struct IGDdatas data;
        if(devlist)
        {
            printf("List of UPNP devices found on the network :\n");
            for(device = devlist; device; device = device->pNext)
            {
                printf(" desc: %s\n st: %s\n\n",
                       device->descURL, device->st);
            }
        }
        i = 1;
        if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
                || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
        {
            switch(i) {
            case 1:
                printf("Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            case 3:
                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            default:
                printf("Found device (igd ?) : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
            }
            printf("Local LAN ip address : %s\n", lanaddr);
#if 0
            printf("getting \"%s\"\n", urls.ipcondescURL);
            descXML = miniwget(urls.ipcondescURL, &descXMLsize);
            if(descXML)
            {
                /*fwrite(descXML, 1, descXMLsize, stdout);*/
                free(descXML);
                descXML = NULL;
            }
#endif

            switch(command)
            {
            case 'l':
                DisplayInfos(&urls, &data);
                ListRedirections(&urls, &data);
                break;
            case 'a':
                SetRedirectAndTest(&urls, &data,
                                   commandargv[0], commandargv[1],
                                   commandargv[2], commandargv[3]);
                break;
            case 'd':
                for(i=0; i<commandargc; i+=2)
                {
                    RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
                }
                break;
            case 's':
                GetConnectionStatus(&urls, &data);
                break;
            case 'r':
                for(i=0; i<commandargc; i+=2)
                {
                    /*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
                    SetRedirectAndTest(&urls, &data,
                                       lanaddr, commandargv[i],
                                       commandargv[i], commandargv[i+1]);
                }
                break;
            default:
                fprintf(stderr, "Unknown switch -%c\n", command);
                retcode = 1;
            }

            FreeUPNPUrls(&urls);
        }
        else
        {
            fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
            retcode = 1;
        }
        freeUPNPDevlist(devlist);
        devlist = 0;
    }
    else
    {
        fprintf(stderr, "No IGD UPnP Device found on the network !\n");
        retcode = 1;
    }
    return retcode;
}