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

📄 upnpsoap.c

📁 miniupnpd可以在嵌入式linux中实现upnp功能
💻 C
📖 第 1 页 / 共 2 页
字号:
		"<NewInternalClient>%s</NewInternalClient>"		"<NewEnabled>1</NewEnabled>"		"<NewPortMappingDescription>%s</NewPortMappingDescription>"		"<NewLeaseDuration>0</NewLeaseDuration>"		"</u:%sResponse>";	char body[1024];	int bodylen;	struct NameValueParserData data;	const char * r_host, * ext_port, * protocol;	unsigned short eport, iport;	char int_ip[32];	char desc[64];	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);	r_host = GetValueFromNameValueList(&data, "NewRemoteHost");	ext_port = GetValueFromNameValueList(&data, "NewExternalPort");	protocol = GetValueFromNameValueList(&data, "NewProtocol");	if(!ext_port || !protocol)	{		ClearNameValueList(&data);		SoapError(h, 402, "Invalid Args");		return;	}	eport = (unsigned short)atoi(ext_port);	r = upnp_get_redirection_infos(eport, protocol, &iport,	                               int_ip, sizeof(int_ip),	                               desc, sizeof(desc));	if(r < 0)	{				SoapError(h, 714, "NoSuchEntryInArray");	}	else	{		syslog(LOG_INFO, "%s: rhost='%s' %s %s found => %s:%u desc='%s'",		       action,		       r_host, ext_port, protocol, int_ip, (unsigned int)iport, desc);		bodylen = snprintf(body, sizeof(body), resp,				action, "urn:schemas-upnp-org:service:WANIPConnection:1",				(unsigned int)iport, int_ip, desc,				action);		BuildSendAndCloseSoapResp(h, body, bodylen);	}	ClearNameValueList(&data);}static voidDeletePortMapping(struct upnphttp * h, const char * action){	int r;	static const char resp[] =		"<u:DeletePortMappingResponse "		"xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"		"</u:DeletePortMappingResponse>";	struct NameValueParserData data;	const char * r_host, * ext_port, * protocol;	unsigned short eport;	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);	r_host = GetValueFromNameValueList(&data, "NewRemoteHost");	ext_port = GetValueFromNameValueList(&data, "NewExternalPort");	protocol = GetValueFromNameValueList(&data, "NewProtocol");	if(!ext_port || !protocol)	{		ClearNameValueList(&data);		SoapError(h, 402, "Invalid Args");		return;	}	eport = (unsigned short)atoi(ext_port);	/* TODO : if in secure mode, check the IP */	syslog(LOG_INFO, "%s: external port: %hu, protocol: %s", 		action, eport, protocol);	r = upnp_delete_redirection(eport, protocol);	if(r < 0)	{			SoapError(h, 714, "NoSuchEntryInArray");	}	else	{		BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);	}	ClearNameValueList(&data);}static voidGetGenericPortMappingEntry(struct upnphttp * h, const char * action){	int r;		static const char resp[] =		"<u:%sResponse "		"xmlns:u=\"%s\">"		"<NewRemoteHost></NewRemoteHost>"		"<NewExternalPort>%u</NewExternalPort>"		"<NewProtocol>%s</NewProtocol>"		"<NewInternalPort>%u</NewInternalPort>"		"<NewInternalClient>%s</NewInternalClient>"		"<NewEnabled>1</NewEnabled>"		"<NewPortMappingDescription>%s</NewPortMappingDescription>"		"<NewLeaseDuration>0</NewLeaseDuration>"		"</u:%sResponse>";	int index = 0;	unsigned short eport, iport;	const char * m_index;	char protocol[4], iaddr[32];	char desc[64];	struct NameValueParserData data;	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);	m_index = GetValueFromNameValueList(&data, "NewPortMappingIndex");	if(!m_index)	{		ClearNameValueList(&data);		SoapError(h, 402, "Invalid Args");		return;	}		index = (int)atoi(m_index);	syslog(LOG_INFO, "%s: index=%d", action, index);	r = upnp_get_redirection_infos_by_index(index, &eport, protocol, &iport,                                            iaddr, sizeof(iaddr),	                                        desc, sizeof(desc));	if(r < 0)	{		SoapError(h, 713, "SpecifiedArrayIndexInvalid");	}	else	{		int bodylen;		char body[2048];		bodylen = snprintf(body, sizeof(body), resp,			action, "urn:schemas-upnp-org:service:WANIPConnection:1",			(unsigned int)eport, protocol, (unsigned int)iport, iaddr, desc,			action);		BuildSendAndCloseSoapResp(h, body, bodylen);	}	ClearNameValueList(&data);}#ifdef ENABLE_L3F_SERVICEstatic voidSetDefaultConnectionService(struct upnphttp * h, const char * action){	static const char resp[] =		"<u:SetDefaultConnectionServiceResponse "		"xmlns:u=\"urn:schemas-upnp-org:service:Layer3Forwarding:1\">"		"</u:SetDefaultConnectionServiceResponse>";	struct NameValueParserData data;	char * p;	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);	p = GetValueFromNameValueList(&data, "NewDefaultConnectionService");	if(p) {		syslog(LOG_INFO, "%s(%s) : Ignored", action, p);	}	ClearNameValueList(&data);	BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);}static voidGetDefaultConnectionService(struct upnphttp * h, const char * action){	static const char resp[] =		"<u:%sResponse "		"xmlns:u=\"urn:schemas-upnp-org:service:Layer3Forwarding:1\">"		"<NewDefaultConnectionService>%s:WANConnectionDevice:1,"		"urn:upnp-org:serviceId:WANIPConn1</NewDefaultConnectionService>"		"</u:%sResponse>";	/* example from UPnP_IGD_Layer3Forwarding 1.0.pdf :	 * uuid:44f5824f-c57d-418c-a131-f22b34e14111:WANConnectionDevice:1,	 * urn:upnp-org:serviceId:WANPPPConn1 */	char body[1024];	int bodylen;	bodylen = snprintf(body, sizeof(body), resp,	                   action, uuidvalue, action);	BuildSendAndCloseSoapResp(h, body, bodylen);}#endif/*If a control point calls QueryStateVariable on a state variable that is notbuffered in memory within (or otherwise available from) the service,the service must return a SOAP fault with an errorCode of 404 Invalid Var.QueryStateVariable remains useful as a limited test tool but may not bepart of some future versions of UPnP.*/static voidQueryStateVariable(struct upnphttp * h, const char * action){	static const char resp[] =        "<u:%sResponse "        "xmlns:u=\"%s\">"		"<return>%s</return>"        "</u:%sResponse>";	char body[512];	int bodylen;	struct NameValueParserData data;	const char * var_name;	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);	/*var_name = GetValueFromNameValueList(&data, "QueryStateVariable"); */	/*var_name = GetValueFromNameValueListIgnoreNS(&data, "varName");*/	var_name = GetValueFromNameValueList(&data, "varName");	/*syslog(LOG_INFO, "QueryStateVariable(%.40s)", var_name); */	if(!var_name)	{		SoapError(h, 402, "Invalid Args");	}	else if(strcmp(var_name, "ConnectionStatus") == 0)	{			bodylen = snprintf(body, sizeof(body), resp,                           action, "urn:schemas-upnp-org:control-1-0",		                   "Connected", action);		BuildSendAndCloseSoapResp(h, body, bodylen);	}#if 0	/* not usefull */	else if(strcmp(var_name, "ConnectionType") == 0)	{			bodylen = snprintf(body, sizeof(body), resp, "IP_Routed");		BuildSendAndCloseSoapResp(h, body, bodylen);	}	else if(strcmp(var_name, "LastConnectionError") == 0)	{			bodylen = snprintf(body, sizeof(body), resp, "ERROR_NONE");		BuildSendAndCloseSoapResp(h, body, bodylen);	}#endif	else if(strcmp(var_name, "PortMappingNumberOfEntries") == 0)	{		char strn[10];		snprintf(strn, sizeof(strn), "%i",		         upnp_get_portmapping_number_of_entries());		bodylen = snprintf(body, sizeof(body), resp,                           action, "urn:schemas-upnp-org:control-1-0",		                   strn, action);		BuildSendAndCloseSoapResp(h, body, bodylen);	}	else	{		syslog(LOG_NOTICE, "%s: Unknown: %s", action, var_name?var_name:"");		SoapError(h, 404, "Invalid Var");	}	ClearNameValueList(&data);	}/* Windows XP as client send the following requests : * GetConnectionTypeInfo * GetNATRSIPStatus * ? GetTotalBytesSent - WANCommonInterfaceConfig * ? GetTotalBytesReceived - idem * ? GetTotalPacketsSent - idem * ? GetTotalPacketsReceived - idem * GetCommonLinkProperties - idem * GetStatusInfo - WANIPConnection * GetExternalIPAddress * QueryStateVariable / ConnectionStatus! */static const struct {	const char * methodName; 	void (*methodImpl)(struct upnphttp *, const char *);}soapMethods[] ={	{ "GetConnectionTypeInfo", GetConnectionTypeInfo },	{ "GetNATRSIPStatus", GetNATRSIPStatus},	{ "GetExternalIPAddress", GetExternalIPAddress},	{ "AddPortMapping", AddPortMapping},	{ "DeletePortMapping", DeletePortMapping},	{ "GetGenericPortMappingEntry", GetGenericPortMappingEntry},	{ "GetSpecificPortMappingEntry", GetSpecificPortMappingEntry},	{ "QueryStateVariable", QueryStateVariable},	{ "GetTotalBytesSent", GetTotalBytesSent},	{ "GetTotalBytesReceived", GetTotalBytesReceived},	{ "GetTotalPacketsSent", GetTotalPacketsSent},	{ "GetTotalPacketsReceived", GetTotalPacketsReceived},	{ "GetCommonLinkProperties", GetCommonLinkProperties},	{ "GetStatusInfo", GetStatusInfo},#ifdef ENABLE_L3F_SERVICE	{ "SetDefaultConnectionService", SetDefaultConnectionService},	{ "GetDefaultConnectionService", GetDefaultConnectionService},#endif	{ 0, 0 }};voidExecuteSoapAction(struct upnphttp * h, const char * action, int n){	char * p;	char * p2;	int i, len, methodlen;	i = 0;	p = strchr(action, '#');	if(p)	{		p++;		p2 = strchr(p, '"');		if(p2)			methodlen = p2 - p;		else			methodlen = n - (p - action);		/*syslog(LOG_DEBUG, "SoapMethod: %.*s", methodlen, p);*/		while(soapMethods[i].methodName)		{			len = strlen(soapMethods[i].methodName);			if(strncmp(p, soapMethods[i].methodName, len) == 0)			{				soapMethods[i].methodImpl(h, soapMethods[i].methodName);				return;			}			i++;		}		syslog(LOG_NOTICE, "SoapMethod: Unknown: %.*s", methodlen, p);	}	SoapError(h, 401, "Invalid Action");}/* Standard Errors: * * errorCode errorDescription Description * --------	---------------- ----------- * 401 		Invalid Action 	No action by that name at this service. * 402 		Invalid Args 	Could be any of the following: not enough in args, * 							too many in args, no in arg by that name,  * 							one or more in args are of the wrong data type. * 403 		Out of Sync 	Out of synchronization. * 501 		Action Failed 	May be returned in current state of service * 							prevents invoking that action. * 600-699 	TBD 			Common action errors. Defined by UPnP Forum * 							Technical Committee. * 700-799 	TBD 			Action-specific errors for standard actions. * 							Defined by UPnP Forum working committee. * 800-899 	TBD 			Action-specific errors for non-standard actions.  * 							Defined by UPnP vendor.*/voidSoapError(struct upnphttp * h, int errCode, const char * errDesc){	static const char resp[] = 		"<s:Envelope "		"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "		"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"		"<s:Body>"		"<s:Fault>"		"<faultcode>s:Client</faultcode>"		"<faultstring>UPnPError</faultstring>"		"<detail>"		"<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">"		"<errorCode>%d</errorCode>"		"<errorDescription>%s</errorDescription>"		"</UPnPError>"		"</detail>"		"</s:Fault>"		"</s:Body>"		"</s:Envelope>";	char body[2048];	int bodylen;	syslog(LOG_INFO, "Returning UPnPError %d: %s", errCode, errDesc);	bodylen = snprintf(body, sizeof(body), resp, errCode, errDesc);	BuildResp2_upnphttp(h, 500, "Internal Server Error", body, bodylen);	SendResp_upnphttp(h);	CloseSocket_upnphttp(h);}

⌨️ 快捷键说明

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