コード例 #1
0
void C4Network2UPnPP::Init()
{
	int error, status;

#if MINIUPNPC_API_VERSION == 10
	// Distributed with Debian jessie.
	if ((devlist = upnpDiscover(2000, NULL, NULL, 0, 0, &error)))
#else
	if ((devlist = upnpDiscover(2000, NULL, NULL, UPNP_LOCAL_PORT_ANY, 0, 2, &error)))
#endif
	{
		if ((status = UPNP_GetValidIGD(devlist, &upnp_urls, &igd_data, lanaddr, sizeof(lanaddr))))
		{
			ThreadLogS("UPnP: Found IGD %s (status %d)", upnp_urls.controlURL, status);
			initialized = true;
		}
		else
		{
			ThreadLog("UPnP: No IGD found.");
		}
	}
	else
	{
		ThreadLog("UPnP: No UPnP device found on the network.");
	}

}
コード例 #2
0
ファイル: UPnP.cpp プロジェクト: Flamefire/libutil
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.getlasterror("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;
    devicelist = upnpDiscover(2000, NULL, NULL, 0, 0 /* ipv6 */, &upnperror);
#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;
}
コード例 #3
0
bool Mapper_MiniUPnPc::init() {
	if(!url.empty())
		return true;

#if MINIUPNPC_API_VERSION < 14
	UPNPDev* devices = upnpDiscover(2000, localIp.empty() ? nullptr : localIp.c_str(), 0, 0, v6, 0);
#else
  UPNPDev* devices = upnpDiscover(2000, localIp.empty() ? nullptr : localIp.c_str(), 0, 0, v6, 2, 0);
#endif
	if(!devices)
		return false;

	UPNPUrls urls;
	IGDdatas data;

	auto ret = UPNP_GetValidIGD(devices, &urls, &data, 0, 0);

	bool ok = ret == 1;
	if(ok) {
		if (localIp.empty()) {
			// We have no bind address configured in settings
			// Try to avoid choosing a random adapter for port mapping

			// Parse router IP from the control URL address
			auto controlUrl = string(string(data.urlbase).empty() ? urls.controlURL : data.urlbase);

			string routerIp, portTmp, protoTmp, pathTmp, queryTmp, fragmentTmp;
			Util::decodeUrl(controlUrl, protoTmp, routerIp, portTmp, pathTmp, queryTmp, fragmentTmp);

			routerIp = Socket::resolve(routerIp, v6 ? AF_INET6 : AF_INET);
			if (!routerIp.empty()) {
				auto adapters = AirUtil::getNetworkAdapters(v6);

				// Find a local IP that is within the same subnet
				auto p = boost::find_if(adapters, [&routerIp, this](const AirUtil::AdapterInfo& aInfo) { return isIPInRange(aInfo.ip, routerIp, aInfo.prefix, v6); });
				if (p != adapters.end()) {
					localIp = p->ip;
				}
			}
		}

		url = urls.controlURL;
		service = data.first.servicetype;

#ifdef _WIN32
		device = data.CIF.friendlyName;
#else
		// Doesn't work on Linux
		device = "Generic";
#endif
	}

	if(ret) {
		FreeUPNPUrls(&urls);
		freeUPNPDevlist(devices);
	}

	return ok;
}
コード例 #4
0
bool Mapper_MiniUPnPc::init() {
	if(!url.empty())
		return true;

#ifdef HAVE_OLD_MINIUPNPC
	UPNPDev* devices = upnpDiscover(2000, localIp.empty() ? nullptr : localIp.c_str(), 0, 0);
#else
	UPNPDev* devices = upnpDiscover(2000, localIp.empty() ? nullptr : localIp.c_str(), 0, 0, v6, 0);
#endif
	if(!devices)
		return false;

	UPNPUrls urls;
	IGDdatas data;

	auto ret = UPNP_GetValidIGD(devices, &urls, &data, 0, 0);

	bool ok = ret == 1;
	if(ok) {
		if (localIp.empty()) {
			AirUtil::IpList addresses;
			AirUtil::getIpAddresses(addresses, v6);
	
			auto remoteIP = string(string(data.urlbase).empty() ?  urls.controlURL : data.urlbase);
			auto start = remoteIP.find("//");
			if (start != string::npos) {
				start = start+2;
				auto end = remoteIP.find(":", start);
				if (end != string::npos) {
					remoteIP = Socket::resolve(remoteIP.substr(start, end-start), v6 ? AF_INET6 : AF_INET);
					if (!remoteIP.empty()) {
						auto p = boost::find_if(addresses, [&remoteIP, this](const AirUtil::AddressInfo& aInfo) { return isIPInRange(aInfo.ip, remoteIP, aInfo.prefix, v6); });
						if (p != addresses.end()) {
							localIp = p->ip;
						}
					}
				}
			}
		}

		url = urls.controlURL;
		service = data.first.servicetype;

#ifdef _WIN32
		device = data.CIF.friendlyName;
#else
		// Doesn't work on Linux
		device = "Generic";
#endif
	}

	if(ret) {
		FreeUPNPUrls(&urls);
		freeUPNPDevlist(devices);
	}

	return ok;
}
コード例 #5
0
static int init_upnp(void)
{
	struct UPNPDev *devlist;
	struct UPNPDev *dev = NULL;
	struct UPNPDev *trydev = NULL;
	char *descXML;
	int descXMLsize = 0;
	const char *multicastif = 0;
	const char *minissdpdpath = 0;

	memset(&nat_globals.urls, 0, sizeof(struct UPNPUrls));
	memset(&nat_globals.data, 0, sizeof(struct IGDdatas));
	devlist = upnpDiscover(3000, multicastif, minissdpdpath, 0);

	if (devlist) {
		dev = devlist;
		while (dev) {
			if (strstr(dev->st, "InternetGatewayDevice")) {
				break;
			}
			if (!trydev && !switch_stristr("printer", dev->descURL)) {
				trydev = dev;
			}

			dev = dev->pNext;
		}

	}

	if (!dev && trydev) {
		dev = trydev; /* defaulting to first device */
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No InternetGatewayDevice, using first entry as default (%s).\n", dev->descURL);
	} else if (devlist && !dev && !trydev) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No InternetGatewayDevice found and I am NOT going to try your printer because printers should not route to the internet, that would be DAFT\n");
	}
	
	if (dev) {
		descXML = miniwget(dev->descURL, &descXMLsize);

		nat_globals.descURL = strdup(dev->descURL);

		if (descXML) {
			parserootdesc(descXML, descXMLsize, &nat_globals.data);
			free(descXML);
			descXML = 0;
			GetUPNPUrls(&nat_globals.urls, &nat_globals.data, dev->descURL);
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unable to retrieve device description XML (%s).\n", dev->descURL);
		}

		freeUPNPDevlist(devlist);
	}

	if (get_upnp_pubaddr(nat_globals.pub_addr) == SWITCH_STATUS_SUCCESS) {
		nat_globals.nat_type = SWITCH_NAT_TYPE_UPNP;
		return 0;
	}

	return -2;
}
コード例 #6
0
bool Mapper_MiniUPnPc::init() {
	if(!url.empty())
		return true;

	UPNPDev* devices = upnpDiscover(2000, localIp.empty() ? nullptr : localIp.c_str(), 0, 0, 0, 0);
	if(!devices)
		return false;

	UPNPUrls urls;
	IGDdatas data;

	auto ret = UPNP_GetValidIGD(devices, &urls, &data, 0, 0);

	bool ok = ret == 1;
	if(ok) {
		url = urls.controlURL;
		service = data.first.servicetype;
		device = data.CIF.friendlyName;
	}

	if(ret) {
		FreeUPNPUrls(&urls);
		freeUPNPDevlist(devices);
	}

	return ok;
}
コード例 #7
0
// MiniUPNP
bool UPNPCheckDlg::MiniUPnPc_init(string& url, string& service, string& device)
{
	bool initialized  = false;
	
	UPNPDev* devices = upnpDiscover(2000,
	                                SettingsManager::getInstance()->isDefault(SettingsManager::BIND_ADDRESS) ? nullptr : SETTING(BIND_ADDRESS).c_str(),
	                                0, 0, 0, 0);
	if (!devices)
		return false;
		
	UPNPUrls urls = {0};
	IGDdatas data = {0};
	
	auto res = UPNP_GetValidIGD(devices, &urls, &data, 0, 0);
	
	initialized = res == 1;
	if (initialized)
	{
		url = urls.controlURL;
		service = data.first.servicetype;
		device = data.CIF.friendlyName;
		device += '(' + data.CIF.modelDescription + ')'; // [+]PPA TODO - fix cope-paste
	}
	
	if (res)
	{
		FreeUPNPUrls(&urls);
		freeUPNPDevlist(devices);
	}
	return initialized;
}
コード例 #8
0
ファイル: NetPlayServer.cpp プロジェクト: Bigorneau/dolphin
// called from ---UPnP--- thread
// discovers the IGD
bool NetPlayServer::initUPnP()
{
	UPNPDev *devlist;
	std::vector<UPNPDev *> igds;
	int descXMLsize = 0, upnperror = 0;
	char *descXML;

	// Don't init if already inited
	if (m_upnp_inited)
		return true;

	// Don't init if it failed before
	if (m_upnp_error)
		return false;

	memset(&m_upnp_urls, 0, sizeof(UPNPUrls));
	memset(&m_upnp_data, 0, sizeof(IGDdatas));

	// Find all UPnP devices
	devlist = upnpDiscover(2000, NULL, NULL, 0, 0, &upnperror);
	if (!devlist)
	{
		WARN_LOG(NETPLAY, "An error occured trying to discover UPnP devices.");

		m_upnp_error = true;
		m_upnp_inited = false;

		return false;
	}

	// Look for the IGD
	for (UPNPDev* dev = devlist; dev; dev = dev->pNext)
	{
		if (strstr(dev->st, "InternetGatewayDevice"))
			igds.push_back(dev);
	}

	for (const UPNPDev* dev : igds)
	{
		descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0);
		if (descXML)
		{
			parserootdesc(descXML, descXMLsize, &m_upnp_data);
			free(descXML);
			descXML = 0;
			GetUPNPUrls(&m_upnp_urls, &m_upnp_data, dev->descURL, 0);

			NOTICE_LOG(NETPLAY, "Got info from IGD at %s.", dev->descURL);
			break;
		}
		else
		{
			WARN_LOG(NETPLAY, "Error getting info from IGD at %s.", dev->descURL);
		}
	}

	freeUPNPDevlist(devlist);

	return true;
}
コード例 #9
0
static PyObject *
UPnP_discover(UPnPObject *self)
{
	struct UPNPDev * dev;
	int i;
	PyObject *res = NULL;
	if(self->devlist)
	{
		freeUPNPDevlist(self->devlist);
		self->devlist = 0;
	}
	Py_BEGIN_ALLOW_THREADS
	self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
	                             0/* multicast if*/,
	                             0/*minissdpd socket*/,
								 0/*sameport flag*/,
	                             0/*ip v6*/,
	                             0/*error */);
	Py_END_ALLOW_THREADS
	/* Py_RETURN_NONE ??? */
	for(dev = self->devlist, i = 0; dev; dev = dev->pNext)
		i++;
	res = Py_BuildValue("i", i);
	return res;
}
コード例 #10
0
ファイル: ModuleUPnP.cpp プロジェクト: ElDewrito/ElDorito
	ModuleUPnP::ModuleUPnP() : ModuleBase("UPnP")
	{
		upnpDevice = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &upnpDiscoverError);

		VarUPnPEnabled = AddVariableInt("Enabled", "upnp_enabled", "Enables UPnP to automatically port forward when hosting a game.", eCommandFlagsArchived, 1);
		VarUPnPEnabled->ValueIntMin = 0;
		VarUPnPEnabled->ValueIntMax = 1;
	}
コード例 #11
0
ファイル: UPnP.cpp プロジェクト: 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 ();
    }
コード例 #12
0
DeviceManager::DeviceError DevicePluginWemo::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
    Q_UNUSED(params);
    if (deviceClassId != wemoSwitchDeviceClassId) {
        return DeviceManager::DeviceErrorDeviceClassNotFound;
    }
    upnpDiscover("upnp:rootdevice");
    return DeviceManager::DeviceErrorAsync;
}
コード例 #13
0
ファイル: portfwd.cpp プロジェクト: RJ/conjist
bool
Portfwd::init(unsigned int timeout)
{
#ifdef WIN32
    WSADATA wsaData;
    int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if(nResult != NO_ERROR)
    {
        fprintf(stderr, "WSAStartup() failed.\n");
        return -1;
    }
#endif
   struct UPNPDev * devlist;
   struct UPNPDev * dev;
   char * descXML;
   int descXMLsize = 0;
   printf("Portfwd::init()\n");
   urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls));
   data = (IGDdatas*)malloc(sizeof(struct IGDdatas));
   memset(urls, 0, sizeof(struct UPNPUrls));
   memset(data, 0, sizeof(struct IGDdatas));
   devlist = upnpDiscover(timeout, NULL, NULL, 0);
   if (devlist)
   {
       dev = devlist;
       while (dev)
       {
           if (strstr (dev->st, "InternetGatewayDevice"))
               break;
           dev = dev->pNext;
       }
       if (!dev)
           dev = devlist; /* defaulting to first device */

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

       descXML = (char*)miniwget(dev->descURL, &descXMLsize);
       if (descXML)
       {
           parserootdesc (descXML, descXMLsize, data);
           free (descXML); descXML = 0;
           GetUPNPUrls (urls, data, dev->descURL);
       }
       // get lan IP:
       char lanaddr[16];
       int i;
       i = UPNP_GetValidIGD(devlist, urls, data, (char*)&lanaddr, 16);
       m_lanip = std::string(lanaddr);
       
       freeUPNPDevlist(devlist);
       get_status();
       return true;
   }
   return false;
}
コード例 #14
0
static struct UPNPDev *
tr_upnpDiscover (int msec)
{
    struct UPNPDev * ret = NULL;

#if defined (HAVE_MINIUPNP_16)
    int err = UPNPDISCOVER_SUCCESS;
    ret = upnpDiscover (msec, NULL, NULL, 0, 0, &err);
    if (err != UPNPDISCOVER_SUCCESS)
#elif defined (HAVE_MINIUPNP_15)
    ret = upnpDiscover (msec, NULL, NULL, 0);
    if (ret == NULL)
#endif

        tr_logAddNamedDbg (getKey (), "upnpDiscover failed (errno %d - %s)", errno, tr_strerror (errno));

    return ret;
}
コード例 #15
0
ファイル: tor-fw-helper-upnp.c プロジェクト: AllardJ/Tomato
/** 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;
}
コード例 #16
0
ファイル: upnp.c プロジェクト: jparyani/Transmission
static struct UPNPDev *
tr_upnpDiscover (int msec)
{
  struct UPNPDev * ret;
  bool have_err;

#if (MINIUPNPC_API_VERSION >= 8) /* adds ipv6 and error args */
  int err = UPNPDISCOVER_SUCCESS;
  ret = upnpDiscover (msec, NULL, NULL, 0, 0, &err);
  have_err = err != UPNPDISCOVER_SUCCESS;
#else
  ret = upnpDiscover (msec, NULL, NULL, 0);
  have_err = ret == NULL;
#endif

  if (have_err)
    tr_logAddNamedDbg (getKey (), "upnpDiscover failed (errno %d - %s)", errno, tr_strerror (errno));

  return ret;
}
コード例 #17
0
MiniUPnPInterface::MiniUPnPInterface() : p(boost::make_shared<Private>()) {
	p->isValid = false;
	int error = 0;
	p->deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
	if (!p->deviceList) {
		return;
	}

	char lanAddress[64];
	if (!UPNP_GetValidIGD(p->deviceList, &p->urls, &p->data, lanAddress, sizeof(lanAddress))) {
		return;
	}
	p->localAddress = std::string(lanAddress);
	p->isValid = true;
}
コード例 #18
0
ファイル: Gateway.cpp プロジェクト: 119/IPCamGenius
bool Gateway::_getGatewayInfo()
{
	int error;
	bool ret = true;
	char lanaddr[64];
	struct UPNPDev *devlist = NULL;

	devlist = upnpDiscover(2000, 0, 0, 0, 0, &error);
	if (devlist == NULL) ret = false;
	else if (UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)) != 1) {
		ret = false;
	}

	freeUPNPDevlist(devlist);

	return ret;
}
コード例 #19
0
ファイル: upnptest.c プロジェクト: sylcrq/study
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;
}
コード例 #20
0
ファイル: vino-upnp.c プロジェクト: cctsao1008/vino
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;
}
コード例 #21
0
ファイル: i_tcp.c プロジェクト: RedEnchilada/SRB2
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"));
	}
}
コード例 #22
0
ファイル: net_natt.c プロジェクト: DoctorGoat/RetroArch_LibNX
void natt_init(void)
{
#ifndef HAVE_SOCKET_LEGACY
#if HAVE_MINIUPNPC
   struct UPNPDev * devlist;
   struct UPNPDev * dev;
   char * descXML;
   int descXMLsize = 0;
   int upnperror = 0;
   memset(&urls, 0, sizeof(struct UPNPUrls));
   memset(&data, 0, sizeof(struct IGDdatas));
   devlist = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &upnperror);
   if (devlist)
   {
      dev = devlist;
      while (dev)
      {
         if (strstr (dev->st, "InternetGatewayDevice"))
            break;
         dev = dev->pNext;
      }
      if (!dev)
         dev = devlist;

      descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0, NULL);
      if (descXML)
      {
         parserootdesc(descXML, descXMLsize, &data);
         free (descXML);
         descXML = 0;
         GetUPNPUrls (&urls, &data, dev->descURL, 0);
      }
      freeUPNPDevlist(devlist);
   }
#endif
#endif
}
コード例 #23
0
ファイル: NetServer.cpp プロジェクト: UnitecProgra3/0ad
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;
}
コード例 #24
0
ファイル: upnpc.c プロジェクト: jpbarraca/MiniUPnP-Client
int main(int argc, char ** argv)
{
	char * descURL = NULL;
	int option_index = 0;
	int c;
	int devid = -1;
	char arguments[1025]; arguments[0]='\0';
	char action[129]; action[0]='\0';
	char verbose = 0;

	unsigned int operation = OP_NONE;

	if(argc == 1)
	{
		printUsage(argv[0]);
		return -1;
	}

	while(1){
		c = getopt_long(argc,argv,"dlva:p:",long_options,&option_index);

		if(c == -1)
			break;

		switch(c){
		case 'd': operation = OP_DISCOVER; break;
		case 'l': operation = OP_LIST; break;
		case 'a': operation = OP_CALLOP; if(optarg) strncpy(action,optarg,128); break;
		case 'p': if(optarg) strncpy(arguments,optarg,1024); break;
		case 'v': verbose = 1; break;
		default: printUsage(argv[0]); return 0;
		}
	}
	
	if(verbose) printf("Universal Plug and Play IGD Tool v0.1\n  João Paulo Barraca <*****@*****.**>\n\n");
	if(operation == OP_NONE)
		return 0;

	descURL = upnpDiscover(5000);	// timeout = 5secs

	if(descURL)
	{
		struct IGDdatas *data = (struct IGDdatas*) malloc(sizeof(struct IGDdatas));
		struct UPNPUrls urls;

		memset(data, 0, sizeof(struct IGDdatas));
		memset(&urls, 0, sizeof(struct UPNPUrls));

		char * descXML;
		int descXMLsize = 0;
		descXML = miniwget(descURL, &descXMLsize);

		parserootdesc(descXML, descXMLsize, data);

		if(descXML)
		{

			switch(operation)
			{
			case OP_CALLOP:
				callUPNPVariable(data,action,arguments, verbose);
				break;
			case OP_LIST:
				listServices(data,devid,verbose); 
				break;
			case OP_DISCOVER:
				listDevices(data);		
				break;
			default: printf("Error: Action not implemented (yet)!\n"); break;
			}
			free(descXML);
		}
		else
		{
			printf("Error: Cannot get XML description of the device.\n");
		}
		freeIGD(data);
		free(descURL);
	}
	else
	{
		fprintf(stderr, "Error: No IGD UPnP Device found on the network !\n");
	}
	return 0;
}
コード例 #25
0
ファイル: upnp.c プロジェクト: ACEZLY/KadNode
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;
}
コード例 #26
0
ファイル: upnp.cpp プロジェクト: 371061198/bitshares_toolkit
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" );
}
コード例 #27
0
ファイル: upnp.c プロジェクト: marltu/transmission
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;
}
コード例 #28
0
ファイル: UPNPClient.cpp プロジェクト: bonki/ZeroTierOne
	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;
	}
コード例 #29
0
ファイル: upnpc.c プロジェクト: sanderjo/miniupnp
/* 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;
}
コード例 #30
0
ファイル: UPnP.cpp プロジェクト: Flamefire/libutil
/**
 *  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;
}