Example #1
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}