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

📄 upnpsoap.c

📁 很小的linux下的upnp服务器端代码适合嵌入式系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	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, "GetSpecificPortMappingEntry: rhost='%s' %s %s found => %s:%u desc='%s'",		       r_host, ext_port, protocol, int_ip, (unsigned int)iport, desc);		bodylen = snprintf(body, sizeof(body), resp, (unsigned int)iport, int_ip, desc);		BuildSendAndCloseSoapResp(h, body, bodylen);	}	ClearNameValueList(&data);}static voidDeletePortMapping(struct upnphttp * h){	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);	syslog(LOG_INFO, "DeletePortMapping: external port: %hu, protocol: %s", 		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){	int r;		static const char resp[] =		"<u:GetGenericPortMappingEntryResponse "		"xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"		"<NewRemoteHost></NewRemoteHost>"		"<NewExternalPort>%u</NewExternalPort>"		"<NewProtocol>%s</NewProtocol>"		"<NewInternalPort>%u</NewInternalPort>"		"<NewInternalClient>%s</NewInternalClient>"		"<NewEnabled>1</NewEnabled>"		"<NewPortMappingDescription>%s</NewPortMappingDescription>"		"<NewLeaseDuration>0</NewLeaseDuration>"		"</u:GetGenericPortMappingEntryResponse>";	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, "GetGenericPortMappingEntry: index=%d", 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, (unsigned int)eport,			protocol, (unsigned int)iport, iaddr, desc);		BuildSendAndCloseSoapResp(h, body, bodylen);	}	ClearNameValueList(&data);}/*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){	static const char resp[] =        "<u:QueryStateVariableResponse "        "xmlns:u=\"urn:schemas-upnp-org:control-1-0\">"		"<return>%s</return>"        "</u:QueryStateVariableResponse>";	char body[2048];	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, "Connected");		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)	{		int r = 0, index = 0;		unsigned short eport, iport;		char protocol[4], iaddr[32], desc[64];		char strindex[10];		do		{			protocol[0] = '\0'; iaddr[0] = '\0'; desc[0] = '\0';			r = upnp_get_redirection_infos_by_index(index, &eport, protocol, &iport,													iaddr, sizeof(iaddr),													desc, sizeof(desc));			index++;		}		while(r==0);		snprintf(strindex, sizeof(strindex), "%i", index - 1);		bodylen = snprintf(body, sizeof(body), resp, strindex);		BuildSendAndCloseSoapResp(h, body, bodylen);	}	else	{		syslog(LOG_NOTICE, "QueryStateVariable: Unknown: %s", 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 *);}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},	{ 0, 0 }};voidExecuteSoapAction(struct upnphttp * h, const char * action, int n){	char * p;	char method[2048];	int i, len, methodlen;	i = 0;	p = strchr(action, '#');	methodlen = strchr(p, '"') - p - 1;	if(p)	{		p++;		while(soapMethods[i].methodName)		{			len = strlen(soapMethods[i].methodName);			if(strncmp(p, soapMethods[i].methodName, len) == 0)			{				soapMethods[i].methodImpl(h);				return;			}			i++;		}		memset(method, 0, 2048);		memcpy(method, p, methodlen);		syslog(LOG_NOTICE, "SoapMethod: Unknown: %s", method);	}	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 + -