⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miniupnpc.c

📁 很小的linux下的upnp客户端代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		PRINT_SOCKET_ERROR("socket");		return NULL;	}    /* reception */    memset(&sockudp_r, 0, sizeof(struct sockaddr_in));    sockudp_r.sin_family = AF_INET;#ifdef TX_FROM_UPNP_PORT    sockudp_r.sin_port = htons(PORT);#endif    sockudp_r.sin_addr.s_addr = INADDR_ANY;    /* emission */    memset(&sockudp_w, 0, sizeof(struct sockaddr_in));    sockudp_w.sin_family = AF_INET;    sockudp_w.sin_port = htons(PORT);    sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);#ifdef WIN32	if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)#else	if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)#endif	{		PRINT_SOCKET_ERROR("setsockopt");		return NULL;	}	if(multicastif)	{		struct in_addr mc_if;		mc_if.s_addr = inet_addr(multicastif);    	sockudp_r.sin_addr.s_addr = mc_if.s_addr;		if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)		{			PRINT_SOCKET_ERROR("setsockopt");		}	}	/* Avant d'envoyer le paquet on bind pour recevoir la reponse */    if (bind(sudp, (struct sockaddr *)&sockudp_r, sizeof(struct sockaddr_in)) != 0)	{        PRINT_SOCKET_ERROR("bind");		closesocket(sudp);		return NULL;    }	/* receiving SSDP response packet */	for(n = 0;;)	{	if(n == 0)	{		/* sending the SSDP M-SEARCH packet */		n = snprintf(bufr, sizeof(bufr),		             MSearchMsgFmt, deviceList[deviceIndex++]);		/*printf("Sending %s", bufr);*/		n = sendto(sudp, bufr, n, 0,		           (struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));		if (n < 0) {			PRINT_SOCKET_ERROR("sendto");			closesocket(sudp);			return devlist;		}	}	/* Waiting for SSDP REPLY packet to M-SEARCH */	n = ReceiveData(sudp, bufr, sizeof(bufr), delay);	if (n < 0) {		/* error */		closesocket(sudp);		return devlist;	} else if (n == 0) {		/* no data or Time Out */		if (devlist || (deviceList[deviceIndex] == 0)) {			/* no more device type to look for... */			closesocket(sudp);			return devlist;		}	} else {		const char * descURL=NULL;		int urlsize=0;		const char * st=NULL;		int stsize=0;        /*printf("%d byte(s) :\n%s\n", n, bufr);*/ /* affichage du message */		parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize);		if(st&&descURL)		{			/*printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",			       stsize, st, urlsize, descURL); */			tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);			tmp->pNext = devlist;			tmp->descURL = tmp->buffer;			tmp->st = tmp->buffer + 1 + urlsize;			memcpy(tmp->buffer, descURL, urlsize);			tmp->buffer[urlsize] = '\0';			memcpy(tmp->buffer + urlsize + 1, st, stsize);			tmp->buffer[urlsize+1+stsize] = '\0';			devlist = tmp;		}	}	}}/* freeUPNPDevlist() should be used to * free the chained list returned by upnpDiscover() */void freeUPNPDevlist(struct UPNPDev * devlist){	struct UPNPDev * next;	while(devlist)	{		next = devlist->pNext;		free(devlist);		devlist = next;	}}static voidurl_cpy_or_cat(char * dst, const char * src, int n){	if(  (src[0] == 'h')	   &&(src[1] == 't')	   &&(src[2] == 't')	   &&(src[3] == 'p')	   &&(src[4] == ':')	   &&(src[5] == '/')	   &&(src[6] == '/'))	{		strncpy(dst, src, n);	}	else	{		int l = strlen(dst);		if(src[0] != '/')			dst[l++] = '/';		if(l<=n)			strncpy(dst + l, src, n - l);	}}/* Prepare the Urls for usage... */void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,                 const char * descURL){	char * p;	int n1, n2, n3;	n1 = strlen(data->urlbase);	if(n1==0)		n1 = strlen(descURL);	n1 += 2;	/* 1 byte more for Null terminator, 1 byte for '/' if needed */	n2 = n1; n3 = n1;	n1 += strlen(data->scpdurl);	n2 += strlen(data->controlurl);	n3 += strlen(data->controlurl_CIF);	urls->ipcondescURL = (char *)malloc(n1);	urls->controlURL = (char *)malloc(n2);	urls->controlURL_CIF = (char *)malloc(n3);	/* maintenant on chope la desc du WANIPConnection */	if(data->urlbase[0] != '\0')		strncpy(urls->ipcondescURL, data->urlbase, n1);	else		strncpy(urls->ipcondescURL, descURL, n1);	p = strchr(urls->ipcondescURL+7, '/');	if(p) p[0] = '\0';	strncpy(urls->controlURL, urls->ipcondescURL, n2);	strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);		url_cpy_or_cat(urls->ipcondescURL, data->scpdurl, n1);	url_cpy_or_cat(urls->controlURL, data->controlurl, n2);	url_cpy_or_cat(urls->controlURL_CIF, data->controlurl_CIF, n3);#ifdef DEBUG	printf("urls->ipcondescURL='%s' %d n1=%d\n", urls->ipcondescURL,	       strlen(urls->ipcondescURL), n1);	printf("urls->controlURL='%s' %d n2=%d\n", urls->controlURL,	       strlen(urls->controlURL), n2);	printf("urls->controlURL_CIF='%s' %d n3=%d\n", urls->controlURL_CIF,	       strlen(urls->controlURL_CIF), n3);#endif}voidFreeUPNPUrls(struct UPNPUrls * urls){	if(!urls)		return;	free(urls->controlURL);	urls->controlURL = 0;	free(urls->ipcondescURL);	urls->ipcondescURL = 0;	free(urls->controlURL_CIF);	urls->controlURL_CIF = 0;}int ReceiveData(int socket, char * data, int length, int timeout){    int n;#ifndef WIN32    struct pollfd fds[1]; /* for the poll */    fds[0].fd = socket;    fds[0].events = POLLIN;    n = poll(fds, 1, timeout);    if(n < 0)    {        PRINT_SOCKET_ERROR("poll");        return -1;    }    else if(n == 0)    {        return 0;    }#else    fd_set socketSet;    TIMEVAL timeval;    FD_ZERO(&socketSet);    FD_SET(socket, &socketSet);    timeval.tv_sec = timeout / 1000;    timeval.tv_usec = (timeout % 1000) * 1000;    n = select(0, &socketSet, NULL, NULL, &timeval);    if(n < 0)    {        PRINT_SOCKET_ERROR("select");        return -1;    }    else if(n == 0)    {        return 0;    }    #endif	n = recv(socket, data, length, 0);	if(n<0)	{		PRINT_SOCKET_ERROR("recv");	}	return n;}intUPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data){	char status[64];	unsigned int uptime;	status[0] = '\0';	UPNP_GetStatusInfo(urls->controlURL, data->servicetype, status, &uptime);	if(0 == strcmp("Connected", status))	{		return 1;	}	else		return 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. */intUPNP_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 */			if((state >= 3) || strstr(dev->st, "InternetGatewayDevice"))			{				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;					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;}/* UPNP_GetIGDFromUrl() * Used when skipping the discovery process. * return value : *   0 - Not ok *   1 - OK */intUPNP_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);	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);		return 1;	} else {		return 0;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -