Пример #1
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;
}
Пример #2
0
int test_igd_desc_parse(char * buffer, int len, FILE * f)
{
	int n;
	struct IGDdatas igd;
	struct xmlparser parser;
	struct UPNPUrls urls;

	memset(&igd, 0, sizeof(struct IGDdatas));
	memset(&parser, 0, sizeof(struct xmlparser));
	parser.xmlstart = buffer;
	parser.xmlsize = len;
	parser.data = &igd;
	parser.starteltfunc = IGDstartelt;
	parser.endeltfunc = IGDendelt;
	parser.datafunc = IGDdata;
	parsexml(&parser);
#ifdef DEBUG
	printIGD(&igd);
#endif /* DEBUG */
	GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml", 0);
	printf("ipcondescURL='%s'\n", urls.ipcondescURL);
	printf("controlURL='%s'\n", urls.controlURL);
	printf("controlURL_CIF='%s'\n", urls.controlURL_CIF);
	n = f ? compare_igd(&igd, f) : 0;
	FreeUPNPUrls(&urls);
	return n;
}
Пример #3
0
// 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;
}
Пример #4
0
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;
}
Пример #5
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"));
	}
}
Пример #6
0
/* UPNP_GetIGDFromUrl()
 * Used when skipping the discovery process.
 * return value :
 *   0 - Not ok
 *   1 - OK */
int
UPNP_GetIGDFromUrl(const char * rootdescurl,
                   struct UPNPUrls * urls,
                   struct IGDdatas * data,
                   char * lanaddr, int lanaddrlen)
{
	char * descXML;
	int descXMLsize = 0;
	descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
	   	                       lanaddr, lanaddrlen, 0);
	if(descXML) {
		memset(data, 0, sizeof(struct IGDdatas));
		memset(urls, 0, sizeof(struct UPNPUrls));
		parserootdesc(descXML, descXMLsize, data);
		free(descXML);
		descXML = NULL;
		GetUPNPUrls(urls, data, rootdescurl, 0);
		return 1;
	} else {
		return 0;
	}
}
Пример #7
0
int test_igd_desc_parse(char * buffer, int len)
{
	struct IGDdatas igd;
	struct xmlparser parser;
	struct UPNPUrls urls;
	memset(&igd, 0, sizeof(struct IGDdatas));
	memset(&parser, 0, sizeof(struct xmlparser));
	parser.xmlstart = buffer;
	parser.xmlsize = len;
	parser.data = &igd;
	parser.starteltfunc = IGDstartelt;
	parser.endeltfunc = IGDendelt;
	parser.datafunc = IGDdata;
	parsexml(&parser);
	printIGD(&igd);
	GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml", 0);
	printf("ipcondescURL='%s'\n", urls.ipcondescURL);
	printf("controlURL='%s'\n", urls.controlURL);
	printf("controlURL_CIF='%s'\n", urls.controlURL_CIF);
	FreeUPNPUrls(&urls);
	return 0;
}
Пример #8
0
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
}
Пример #9
0
/* UPNP_GetValidIGD() :
 * return values :
 *    -1 = Internal error
 *     0 = NO IGD found
 *     1 = A valid connected IGD has been found
 *     2 = A valid IGD has been found but it reported as
 *         not connected
 *     3 = an UPnP device has been found but was not recognized as an IGD
 *
 * In any non zero return case, the urls and data structures
 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
				 struct IGDdatas * data,
				 char * lanaddr, int lanaddrlen)
{
	struct xml_desc {
		char * xml;
		int size;
	} * desc = NULL;
	struct UPNPDev * dev;
	int ndev = 0;
	int i;
	int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
	if(!devlist)
	{
#ifdef DEBUG
		printf("Empty devlist\n");
#endif
		return 0;
	}
	for(dev = devlist; dev; dev = dev->pNext)
		ndev++;
	if(ndev > 0)
	{
		desc = calloc(ndev, sizeof(struct xml_desc));
		if(!desc)
			return -1; /* memory allocation error */
	}
	for(state = 1; state <= 3; state++)
	{
		for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
		{
			/* we should choose an internet gateway device.
		 	* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
			if(state == 1)
			{
				desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
				   	                           lanaddr, lanaddrlen,
				                               dev->scope_id);
#ifdef DEBUG
				if(!desc[i].xml)
				{
					printf("error getting XML description %s\n", dev->descURL);
				}
#endif
			}
			if(desc[i].xml)
			{
				memset(data, 0, sizeof(struct IGDdatas));
				memset(urls, 0, sizeof(struct UPNPUrls));
				parserootdesc(desc[i].xml, desc[i].size, data);
				if(0==strcmp(data->CIF.servicetype,
				   "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
				   || state >= 3 )
				{
				  GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);

#ifdef DEBUG
				  printf("UPNPIGD_IsConnected(%s) = %d\n",
				     urls->controlURL,
			         UPNPIGD_IsConnected(urls, data));
#endif
				  if((state >= 2) || UPNPIGD_IsConnected(urls, data))
					goto free_and_return;
				  FreeUPNPUrls(urls);
				  if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
				    printf("We tried %s, now we try %s !\n",
				           data->first.servicetype, data->second.servicetype);
#endif
				    /* swaping WANPPPConnection and WANIPConnection ! */
				    memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
				    memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
				    memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
				    GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
#ifdef DEBUG
				    printf("UPNPIGD_IsConnected(%s) = %d\n",
				       urls->controlURL,
			           UPNPIGD_IsConnected(urls, data));
#endif
				    if((state >= 2) || UPNPIGD_IsConnected(urls, data))
					  goto free_and_return;
				    FreeUPNPUrls(urls);
				  }
				}
				memset(data, 0, sizeof(struct IGDdatas));
			}
		}
	}
	state = 0;
free_and_return:
	if(desc) {
		for(i = 0; i < ndev; i++) {
			if(desc[i].xml) {
				free(desc[i].xml);
			}
		}
		free(desc);
	}
	return state;
}
Пример #10
0
/* UPNP_GetValidIGD() :
 * return values :
 *     0 = NO IGD found
 *     1 = A valid connected IGD has been found
 *     2 = A valid IGD has been found but it reported as
 *         not connected
 *     3 = an UPnP device has been found but was not recognized as an IGD
 *
 * In any non zero return case, the urls and data structures
 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
				 struct IGDdatas * data,
				 char * lanaddr, int lanaddrlen)
{
	char * descXML;
	int descXMLsize = 0;
	struct UPNPDev * dev;
	int ndev = 0;
	int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
	if(!devlist)
	{
#ifdef DEBUG
		printf("Empty devlist\n");
#endif
		return 0;
	}
	for(state = 1; state <= 3; state++)
	{
		for(dev = devlist; dev; dev = dev->pNext)
		{
			/* we should choose an internet gateway device.
		 	* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
			descXML = miniwget_getaddr(dev->descURL, &descXMLsize,
			   	                        lanaddr, lanaddrlen);
			if(descXML)
			{
				ndev++;
				memset(data, 0, sizeof(struct IGDdatas));
				memset(urls, 0, sizeof(struct UPNPUrls));
				parserootdesc(descXML, descXMLsize, data);
				free(descXML);
				descXML = NULL;
				if(0==strcmp(data->servicetype_CIF,
				   "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
				   || state >= 3 )
				{
				  GetUPNPUrls(urls, data, dev->descURL);

#ifdef DEBUG
				  printf("UPNPIGD_IsConnected(%s) = %d\n",
				     urls->controlURL,
			         UPNPIGD_IsConnected(urls, data));
#endif
				  if((state >= 2) || UPNPIGD_IsConnected(urls, data))
					return state;
				  FreeUPNPUrls(urls);
				}
				memset(data, 0, sizeof(struct IGDdatas));
			}
#ifdef DEBUG
			else
			{
				printf("error getting XML description %s\n", dev->descURL);
			}
#endif
		}
	}
	return 0;
}
Пример #11
0
/* UPNP_GetValidIGD() :
 * return values :
 *    -1 = Internal error
 *     0 = NO IGD found
 *     1 = A valid connected IGD has been found
 *     2 = A valid IGD has been found but it reported as
 *         not connected
 *     3 = an UPnP device has been found but was not recognized as an IGD
 *
 * In any positive non zero return case, the urls and data structures
 * passed as parameters are set. Don't forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
				 struct IGDdatas * data,
				 char * lanaddr, int lanaddrlen)
{
	struct xml_desc {
		char * xml;
		int size;
		int is_igd;
	} * desc = NULL;
	struct UPNPDev * dev;
	int ndev = 0;
	int i;
	int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
	char extIpAddr[16];
	char myLanAddr[40];
	int status_code = -1;

	if(!devlist)
	{
#ifdef DEBUG
		printf("Empty devlist\n");
#endif
		return 0;
	}
	/* counting total number of devices in the list */
	for(dev = devlist; dev; dev = dev->pNext)
		ndev++;
	/* ndev is always > 0 */
	desc = calloc(ndev, sizeof(struct xml_desc));
	if(!desc)
		return -1; /* memory allocation error */
	/* Step 1 : downloading descriptions and testing type */
	for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
	{
		/* we should choose an internet gateway device.
		 * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
		desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
		                               myLanAddr, sizeof(myLanAddr),
		                               dev->scope_id, &status_code);
#ifdef DEBUG
		if(!desc[i].xml)
		{
			printf("error getting XML description %s\n", dev->descURL);
		}
#endif
		if(desc[i].xml)
		{
			memset(data, 0, sizeof(struct IGDdatas));
			memset(urls, 0, sizeof(struct UPNPUrls));
			parserootdesc(desc[i].xml, desc[i].size, data);
			if(COMPARE(data->CIF.servicetype,
			           "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:"))
			{
				desc[i].is_igd = 1;
				if(lanaddr)
					strncpy(lanaddr, myLanAddr, lanaddrlen);
			}
		}
	}
	/* iterate the list to find a device depending on state */
	for(state = 1; state <= 3; state++)
	{
		for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
		{
			if(desc[i].xml)
			{
				memset(data, 0, sizeof(struct IGDdatas));
				memset(urls, 0, sizeof(struct UPNPUrls));
				parserootdesc(desc[i].xml, desc[i].size, data);
				if(desc[i].is_igd || state >= 3 )
				{
				  int is_connected;

				  GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);

				  /* in state 2 and 3 we don't test if device is connected ! */
				  if(state >= 2)
				    goto free_and_return;
				  is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
				  printf("UPNPIGD_IsConnected(%s) = %d\n",
				     urls->controlURL, is_connected);
#endif
				  /* checks that status is connected AND there is a external IP address assigned */
				  if(is_connected &&
				     (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0)) {
					if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
					   && (0 != strcmp(extIpAddr, "0.0.0.0")))
					  goto free_and_return;
				  }
				  FreeUPNPUrls(urls);
				  if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
				    printf("We tried %s, now we try %s !\n",
				           data->first.servicetype, data->second.servicetype);
#endif
				    /* swaping WANPPPConnection and WANIPConnection ! */
				    memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
				    memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
				    memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
				    GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
				    is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
				    printf("UPNPIGD_IsConnected(%s) = %d\n",
				       urls->controlURL, is_connected);
#endif
				    if(is_connected &&
				       (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0)) {
					  if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
					     && (0 != strcmp(extIpAddr, "0.0.0.0")))
					    goto free_and_return;
				    }
				    FreeUPNPUrls(urls);
				  }
				}
				memset(data, 0, sizeof(struct IGDdatas));
			}
		}
	}
	state = 0;
free_and_return:
	for(i = 0; i < ndev; i++)
		free(desc[i].xml);
	free(desc);
	return state;
}
Пример #12
0
/* UPNP_GetValidIGDe) :
 * return values :
 *    -1 = Internal error
 *     0 = NO IGD found
 *     1 = A valid connected IGD has been found
 *     2 = A valid IGD has been found but it reported as
 *         not connected
 *     3 = an UPnP device has been found but was not recognized as an IGD
 *
 * In any positive non zero return case, the urls and data structures
 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
                 struct IGDdatas * data,
                 char * lanaddr, int lanaddrlen)
{
    struct xml_desc {
        char * xml;
        int size;
        int is_igd;
    } * desc = NULL;
    struct UPNPDev * dev;
    int ndev = 0;
    int i;
    int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
    int n_igd = 0;
    char extIpAddr[16];
    struct UPNPDevInfo IGDInfo;
    char *dut_lanaddr;
    char IGDDescURL[256];

    if(!devlist)
    {
#ifdef DEBUG
        printf("Empty devlist\n");
#endif
        return 0;
    }
    /* counting total number of devices in the list */
    for(dev = devlist; dev; dev = dev->pNext)
        ndev++;
    if(ndev > 0)
    {
        desc = calloc(ndev, sizeof(struct xml_desc));
        if(!desc)
            return -1; /* memory allocation error */
    }

    dut_lanaddr = get_lan_ipaddr();

    /* Step 1 : downloading descriptions and testing type */
    for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
    {
        memset(&IGDInfo, 0, sizeof(struct UPNPDevInfo));
        /* we should choose an internet gateway device.
         * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
        strcpy(IGDDescURL, dev->descURL);
        desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
                                       lanaddr, lanaddrlen,
                                       dev->scope_id, &IGDInfo, dut_lanaddr);

#ifdef DEBUG
        if(!desc[i].xml)
        {
            printf("error getting XML description %s\n", dev->descURL);
        }
#endif
        if(desc[i].xml)
        {
            memset(data, 0, sizeof(struct IGDdatas));
            memset(urls, 0, sizeof(struct UPNPUrls));
            /* parserootdesc(desc[i].xml, desc[i].size, data); */

#ifdef DEBUG
            FILE *xml_fd;
            xml_fd = fopen("/tmp/upnpc_xml.log", "w");
            fprintf(xml_fd, "============= XML ==============\n");
            fprintf(xml_fd, "%s\n", desc[i].xml);
            parsedescxml(desc[i].xml, &IGDInfo.friendlyName, &IGDInfo.iconUrl);
            fprintf(xml_fd, "    HostName: %s\n", IGDInfo.hostname);
            fprintf(xml_fd, "    type:     %s\n", IGDInfo.type);
            fprintf(xml_fd, "    F Name:   %s\n", IGDInfo.friendlyName);
            fprintf(xml_fd, "    Icon URL: %s\n", IGDInfo.iconUrl);
            fprintf(xml_fd, "================================\n\n");
            syslog(LOG_NOTICE, "parse icon url: %s", IGDInfo.iconUrl);
#endif

            strcpy(dev->DevInfo.hostname, IGDInfo.hostname);
            strcpy(dev->DevInfo.type, IGDInfo.type);
            strcpy(dev->DevInfo.friendlyName, IGDInfo.friendlyName);
            strcpy(dev->DevInfo.iconUrl, IGDInfo.iconUrl);

#ifdef RTCONFIG_JFFS2USERICON
            if(strcmp(IGDInfo.iconUrl, "") != NULL) {
                char realIconUrl[158], iconFile[32], iconBuf[512];
                char *ico_head, *ico_end;
                char *icon, *p, *q;
                int  iconSize, i = 0, iconCheck = 0;
                FILE *ico_fd;

                memset(realIconUrl, 0, 158);
                if(strstr(IGDInfo.iconUrl, "http://")) {
                    strcpy(realIconUrl, IGDInfo.iconUrl);
                }
                else {
                    q = IGDDescURL;
                    while(q = strchr(q, '/')) {
                        i++;
                        if(i == 3) {
                            p = IGDDescURL;
                            i = 0;
                            while ( p < q ) {
                                realIconUrl[i++] = *p++;
                            }
                            strcat(realIconUrl, IGDInfo.iconUrl);
#ifdef DEBUG
                            printf("\n*** Real URL=%s=\n\n", realIconUrl);
#endif
                            break;
                        }
                        q++;
                    }
                }
get_icon:
#ifdef DEBUG
                syslog(LOG_NOTICE, "Real icon url: %s", realIconUrl);
                fprintf(xml_fd, "Real icon url: %s\n", realIconUrl);
#endif
                sprintf(iconFile, "/tmp/upnpicon/%s.ico", IGDInfo.hostname);

                icon = miniwget_getaddr(realIconUrl, &iconSize,
                                        lanaddr, lanaddrlen,
                                        0, &IGDInfo, dut_lanaddr);

                if( iconSize > 512 ) {
                    ico_fd = fopen(iconFile, "w");
                    if(ico_fd) {
                        fwrite(icon, sizeof(char), iconSize, ico_fd);
                        fclose(ico_fd);
                    }
                }
                else if(iconSize > 0) {
                    ico_head = strstr(icon, "<a href=");
                    if(ico_head) {
                        ico_head = ico_head+9;
                        ico_end = strstr(icon, "\">");
                        if(ico_end) {
                            *ico_end = '\0';
                            strcpy(realIconUrl, ico_head);
                            goto get_icon;
                        }
                    }
                }
            }
#endif

            if(COMPARE(data->CIF.servicetype,
                       "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:"))
            {
                desc[i].is_igd = 1;
                n_igd++;
            }
#ifdef DEBUG
            fclose(xml_fd);
#endif
        }
        else
            memset(dev->DevInfo.hostname, 0, 65);
    }

    /* iterate the list to find a device depending on state */
    for(state = 1; state <= 3; state++)
        /*if(0)*/
    {
        for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
        {
            if(desc[i].xml)
            {
                memset(data, 0, sizeof(struct IGDdatas));
                memset(urls, 0, sizeof(struct UPNPUrls));
                parserootdesc(desc[i].xml, desc[i].size, data);
                if(desc[i].is_igd || state >= 3 )
                {
                    GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);

                    /* in state 2 and 3 we dont test if device is connected ! */
                    if(state >= 2)
                        goto free_and_return;
#ifdef DEBUG
                    printf("UPNPIGD_IsConnected(%s) = %d\n",
                           urls->controlURL,
                           UPNPIGD_IsConnected(urls, data));
#endif
                    /* checks that status is connected AND there is a external IP address assigned */
                    if(UPNPIGD_IsConnected(urls, data)
                            && (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0))
                        goto free_and_return;
                    FreeUPNPUrls(urls);
                    if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
                        printf("We tried %s, now we try %s !\n",
                               data->first.servicetype, data->second.servicetype);
#endif
                        /* swaping WANPPPConnection and WANIPConnection ! */
                        memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
                        memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
                        memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
                        GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
#ifdef DEBUG
                        printf("UPNPIGD_IsConnected(%s) = %d\n",
                               urls->controlURL,
                               UPNPIGD_IsConnected(urls, data));
#endif
                        if(UPNPIGD_IsConnected(urls, data)
                                && (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0))
                            goto free_and_return;
                        FreeUPNPUrls(urls);
                    }
                }
                memset(data, 0, sizeof(struct IGDdatas));
            }
        }
    }
    state = 0;
free_and_return:
    if(desc) {
        for(i = 0; i < ndev; i++) {
            if(desc[i].xml) {
                free(desc[i].xml);
            }
        }
        free(desc);
    }
    return state;
}
Пример #13
0
// called from ---UPnP--- thread
// discovers the IGD
static bool InitUPnP()
{
  static bool s_inited = false;
  static bool s_error = false;

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

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

  s_urls = {};
  s_data = {};

  // Find all UPnP devices
  int upnperror = 0;
  std::unique_ptr<UPNPDev, decltype(&freeUPNPDevlist)> devlist(nullptr, freeUPNPDevlist);
#if MINIUPNPC_API_VERSION >= 14
  devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror));
#else
  devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, &upnperror));
#endif
  if (!devlist)
  {
    WARN_LOG(NETPLAY, "An error occurred trying to discover UPnP devices.");

    s_error = true;

    return false;
  }

  // Look for the IGD
  for (UPNPDev* dev = devlist.get(); dev; dev = dev->pNext)
  {
    if (!std::strstr(dev->st, "InternetGatewayDevice"))
      continue;

    int desc_xml_size = 0;
    std::unique_ptr<char, decltype(&std::free)> desc_xml(nullptr, std::free);
    int statusCode = 200;
#if MINIUPNPC_API_VERSION >= 16
    desc_xml.reset(
      static_cast<char*>(miniwget_getaddr(dev->descURL, &desc_xml_size, s_our_ip.data(),
        static_cast<int>(s_our_ip.size()), 0, &statusCode)));
#else
    desc_xml.reset(static_cast<char*>(miniwget_getaddr(
      dev->descURL, &desc_xml_size, s_our_ip.data(), static_cast<int>(s_our_ip.size()), 0)));
#endif
    if (desc_xml && statusCode == 200)
    {
      parserootdesc(desc_xml.get(), desc_xml_size, &s_data);
      GetUPNPUrls(&s_urls, &s_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);
    }
  }

  s_inited = true;

  return true;
}
Пример #14
0
void init_upnp (void)
{
	struct UPNPDev * devlist;
	struct UPNPDev * dev;
	char * descXML;
	int descXMLsize = 0;
    int res = 0;

    char IPAddress[40];
    int r;

    if (!sv_upnp)
        return;

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

	Printf(PRINT_HIGH, "UPnP: Discovering router (max 1 unit supported)\n");

	devlist = upnpDiscover(sv_upnp_discovertimeout.asInt(), NULL, NULL, 0, 0, &res);

	if (!devlist || res != UPNPDISCOVER_SUCCESS)
    {
		Printf(PRINT_HIGH, "UPnP: Router not found or timed out, error %d\n",
            res);

        is_upnp_ok = false;

        return;
    }

    dev = devlist;

    while (dev)
    {
        if (strstr (dev->st, "InternetGatewayDevice"))
            break;
        dev = dev->pNext;
    }

    if (!dev)
        dev = devlist; /* defaulting to first device */

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

    descXML = (char *)miniwget(dev->descURL, &descXMLsize, 0);

    if (descXML)
    {
        parserootdesc (descXML, descXMLsize, &data);
        free (descXML);
        descXML = NULL;
        GetUPNPUrls (&urls, &data, dev->descURL, 0);
    }

    freeUPNPDevlist(devlist);

    r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype,
            IPAddress);

    if (r != 0)
    {
        Printf(PRINT_HIGH,
            "UPnP: Router found but unable to get external IP address\n");

        is_upnp_ok = false;
    }
    else
    {
        Printf(PRINT_HIGH, "UPnP: Router found, external IP address is: %s\n",
            IPAddress);

        // Store ip address just in case admin wants it
        sv_upnp_externalip.ForceSet(IPAddress);

        is_upnp_ok = true;
    }
}