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

📄 upnpnat.cpp

📁 upnpForWindows by microsoft
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *   Copyright (C) 2006 by taofei   * *   gudu2005@126.com   * *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * *   This program is distributed in the hope that it will be useful,       * *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         * *   GNU General Public License for more details.                          * *                                                                         * *   You should have received a copy of the GNU General Public License     * *   along with this program; if not, write to the                         * *   Free Software Foundation, Inc.,                                       * *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * ***************************************************************************///#include <sys/types.h>//#include <sys/socket.h>//#include <arpa/inet.h>//#include <windows.h>//#include <wininet.h>#include <winsock2.h>#include <iostream>#include <string>#include "upnpnat.h"#include "utils.h"#include "xmlParser.h"#define MAX_BUFF_SIZE 102400/******************************************************************** Discovery Defines                                                 ********************************************************************/#define HTTPMU_HOST_ADDRESS "239.255.255.250"#define HTTPMU_HOST_PORT 1900//#define SEARCH_REQUEST_DEVICE "urn:schemas-upnp-org:service:%s"#define SEARCH_REQUEST_STRING "M-SEARCH * HTTP/1.1\r\n"            \                              "ST:UPnP:rootdevice\r\n"             \							  "MX: 3\r\n"  						   \							  "Man:\"ssdp:discover\"\r\n"          \                              "HOST: 239.255.255.250:1900\r\n"     \							  "\r\n"#define HTTP_OK "200 OK"#define DEFAULT_HTTP_PORT 80/******************************************************************** Device and Service  Defines                                                 ********************************************************************/#define DEVICE_TYPE_1 	"urn:schemas-upnp-org:device:InternetGatewayDevice:1"#define DEVICE_TYPE_2	"urn:schemas-upnp-org:device:WANDevice:1"#define DEVICE_TYPE_3	"urn:schemas-upnp-org:device:WANConnectionDevice:1"#define SERVICE_WANIP  "urn:schemas-upnp-org:service:WANIPConnection:1"#define SERVICE_WANPPP "urn:schemas-upnp-org:service:WANPPPConnection:1" /******************************************************************** Action Defines                                                 ********************************************************************/#define HTTP_HEADER_ACTION "POST %s HTTP/1.1\r\n"                         \                           "HOST: %s:%u\r\n"                                  \                           "SOAPACTION:\"%s#%s\"\r\n"                           \                           "CONTENT-TYPE: text/xml ; charset=\"utf-8\"\r\n"\                           "Content-Length: %d \r\n\r\n"#define SOAP_ACTION  "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"     \                     "<s:Envelope xmlns:s="                               \                     "\"http://schemas.xmlsoap.org/soap/envelope/\" "     \                     "s:encodingStyle="                                   \                     "\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" \                     "<s:Body>\r\n"                                       \                     "<u:%s xmlns:u=\"%s\">\r\n%s"         \                     "</u:%s>\r\n"                                        \                     "</s:Body>\r\n"                                      \                     "</s:Envelope>\r\n"#define PORT_MAPPING_LEASE_TIME "0"#define PORT_MAPPING_DESCRIPTION "UPNP PORT MAPPING TOOL"#define ADD_PORT_MAPPING_PARAMS "<NewRemoteHost></NewRemoteHost>\r\n"      \                                "<NewExternalPort>%u</NewExternalPort>\r\n"\                                "<NewProtocol>%s</NewProtocol>\r\n"        \                                "<NewInternalPort>%u</NewInternalPort>\r\n"\                                "<NewInternalClient>%s"                    \                                "</NewInternalClient>\r\n"                 \                                "<NewEnabled>1</NewEnabled>\r\n"           \                                "<NewPortMappingDescription>"              \                                PORT_MAPPING_DESCRIPTION                   \                                "</NewPortMappingDescription>\r\n"         \                                "<NewLeaseDuration>"                       \                                PORT_MAPPING_LEASE_TIME                    \                                "</NewLeaseDuration>\r\n"#define DEL_PORT_MAPPING_PARAMS "<NewRemoteHost></NewRemoteHost>\r\n" \                                   "<NewExternalPort>%u"                 \                                   "</NewExternalPort>\r\n"              \								   "<NewProtocol>%s</NewProtocol>\r\n"        \#define GET_GEN_PARAMS          "<NewPortMappingIndex>%i</NewPortMappingIndex>" \								"<NewRemoteHost></NewRemoteHost>\r\n"      \                                "<NewExternalPort></NewExternalPort>\r\n"\                                "<NewProtocol></NewProtocol>\r\n"        \                                "<NewInternalPort></NewInternalPort>\r\n"\                                "<NewInternalClient>"                    \                                "</NewInternalClient>\r\n"                 \                                "<NewEnabled>1</NewEnabled>\r\n"           \                                "<NewPortMappingDescription>"              \                                "</NewPortMappingDescription>\r\n"         \                                "<NewLeaseDuration>"                       \                                "</NewLeaseDuration>\r\n"#define ACTION_ADD	 "AddPortMapping"#define ACTION_DEL   "DeletePortMapping"#define ACTION_GET_SPE "GetSpecificPortMappingEntry"#define ACTION_GET_GEN "GetGenericPortMappingEntry"#define MAPPING_INFO "%s/%s[%s]-->%s:%s\r\n"//*********************************************************************************bool UPNPNAT::init(int time,int inter){	time_out=time;	interval=inter;	status=NAT_INIT;	WSADATA     WSAData ;        WSAStartup (MAKEWORD(2,2), &WSAData);	return true;}bool UPNPNAT::get_localIP(){	struct sockaddr_in addr;	int len = sizeof(addr);	getsockname(tcp_socket_fd,(struct sockaddr*)&addr, &len);	local_ip = inet_ntoa(addr.sin_addr);	return true;}bool UPNPNAT::tcp_connect(const char * _host,unsigned short int _port){	int ret,i;	tcp_socket_fd=socket(AF_INET,SOCK_STREAM,0);	struct sockaddr_in r_address;        r_address.sin_family = AF_INET;	r_address.sin_port=htons(_port);        r_address.sin_addr.s_addr=inet_addr(_host);//    if (ret<0)//    {//		status=NAT_ERROR;//		last_error="Fail to convert IP.\n";//		return false;//    }	for(i=1;i<=time_out;i++)	{			if(i>1);			//sleep(interval);				ret=connect(tcp_socket_fd,(const struct sockaddr *)&r_address,sizeof(struct sockaddr) );		if(ret==0)		{			status=NAT_TCP_CONNECTED;			return true;		}	}	status=NAT_ERROR;	char temp[100];	sprintf(temp,"Fail to connect to %s:%i (using TCP)\n",_host,_port);	last_error=temp;	return false;		}bool UPNPNAT::discovery(){    udp_socket_fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);    int i,ret;    std::string send_buff=SEARCH_REQUEST_STRING;    std::string recv_buff;    char buff[MAX_BUFF_SIZE+1]; //buff should be enough big       struct sockaddr_in r_address;    r_address.sin_family=AF_INET;    r_address.sin_port=htons(HTTPMU_HOST_PORT);    r_address.sin_addr.s_addr=inet_addr(HTTPMU_HOST_ADDRESS);//    if (ret<0)//    {//		status=NAT_ERROR;//		last_error="Fail to convert IP.\n";//		return false;//    }    bool bOptVal = true;    int bOptLen = sizeof(bool);    int iOptVal;    int iOptLen = sizeof(int);    ret=setsockopt(udp_socket_fd, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen); //    if (ret!=SOCKET_ERROR)//    {//    	std::cout<<"Set SO_BROADCAST: ON\n";//    }    ret=sendto(udp_socket_fd,send_buff.c_str(),send_buff.size(),0,(struct sockaddr*)&r_address,sizeof(struct sockaddr_in));//    for(i=1;i<=time_out;i++)//    { //	ret=sendto(udp_socket_fd,send_buff.c_str(),send_buff.size(),0,(struct sockaddr*)&r_address,sizeof(struct sockaddr_in));//    	if (ret!=SOCKET_ERROR)//			break;//	else//	{//		int error=WSAGetLastError();//		switch (error)//		{//		case WSANOTINITIALISED: std::cout<<"WSANOTINITIALISED";break;//		case WSAENOTSOCK:std::cout<<"WSAENOTSOCK";break;//		case WSAENETDOWN:std::cout<<"WSAENETDOWN";break;//		}//	}//    }	    for(i=1;i<=time_out;i++)    {//		if(i>1) ;		//	sleep(interval);	//std::string response;        ret=recvfrom(udp_socket_fd,buff,MAX_BUFF_SIZE,0,NULL,NULL);        if(ret==SOCKET_ERROR)            continue;        //buff[ret]=0;        //找出描述URL	recv_buff=buff;        ret=recv_buff.find(HTTP_OK);        if(ret==std::string::npos)		continue;                       //不是合法的回应        std::string::size_type begin=recv_buff.find("http://");        if(begin==std::string::npos)            continue;                       //不是合法的回应        std::string::size_type end=recv_buff.find("\r",begin);        if(end==std::string::npos)	    continue;                       //不是合法的回应	describe_url=describe_url.assign(recv_buff,begin,end-begin);        closesocket(udp_socket_fd);	status=NAT_FOUND;					//找到发现UPNP 设备 	return true ;    }	status=NAT_ERROR;	last_error="Fail to find an UPNP NAT.\n";        return false;                               //没有发现UPNP 设备 }bool UPNPNAT::get_description(){	std::string host,path;	unsigned short int port;	int ret=parseUrl(describe_url.c_str(),host,&port,path);	if(!ret)	{		status=NAT_ERROR;		last_error="Fail to parseURl: "+describe_url+"\n";		return false;	}		//connect 	ret=tcp_connect(host.c_str(),port);	if(!ret)		return false;		char request[200];	sprintf (request,"GET %s HTTP/1.1\r\nHost: %s:%d\r\n\r\n",path.c_str(),host.c_str(),port); 	std::string http_request=request;		//send request	ret=send(tcp_socket_fd,http_request.c_str(),http_request.size(),0);	//get description xml file	char buff[MAX_BUFF_SIZE+1]; 			//buff should be enough big		std::string response;		while ( ret=recv(tcp_socket_fd,buff,MAX_BUFF_SIZE,0) >0) 	{		//buff[ret+1]=0;		response+=buff;	}	//ptr+=ret;	//ret=recv(tcp_socket_fd,description,MAX_BUFF_SIZE,MSG_WAITALL);//MSG_WAITALL);//	if(ret<0)//	{//		status=NAT_ERROR;//		last_error="Fail to get device describe XML File from "+describe_url+"\n";//		return false;//	}	//*(ptr+ret)=0;	description_info=response;//	std::cout<<"description url:"<<describe_url<<std::endl;//	std::cout<<"description:"<<description<<std::endl;//	system("pause");	return true;}bool UPNPNAT::parser_description(){	XMLNode node=XMLNode::parseString(description_info.c_str(),"root");	if(node.isEmpty())	{		status=NAT_ERROR;		last_error="The device descripe XML file is not a valid XML file. Cann't find root element.\n";		return false;	}		XMLNode baseURL_node=node.getChildNode("URLBase",0);	if(!baseURL_node.getText())	{		std::string::size_type index=describe_url.find("/",7);		if(index==std::string::npos )		{			status=NAT_ERROR;			last_error="Fail to get base_URL from XMLNode \"URLBase\" or describe_url.\n";			return false;		}		base_url=base_url.assign(describe_url,0,index);	}	else		base_url=baseURL_node.getText();		/* get the serviceType child that has the service type as it's data */    /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1     and it's devicelist */	const char * deviceType;	int num,i;	XMLNode device_node,deviceList_node,deviceType_node;	num=node.nChildNode("device");	for(i=0;i<num;i++)	{		device_node=node.getChildNode("device",i);		if(device_node.isEmpty())			break;		deviceType_node=device_node.getChildNode("deviceType",0);		if(strcmp(deviceType_node.getText(),DEVICE_TYPE_1)==0)			break;	}	if(device_node.isEmpty())	{		status=NAT_ERROR;		last_error="Fail to find device \"urn:schemas-upnp-org:device:InternetGatewayDevice:1 \"\n";		return false;	}		deviceList_node=device_node.getChildNode("deviceList",0);	if(deviceList_node.isEmpty())	{		status=NAT_ERROR;		last_error=" Fail to find deviceList of device \"urn:schemas-upnp-org:device:InternetGatewayDevice:1 \"\n";		return false;	}	// get urn:schemas-upnp-org:device:WANDevice:1 and it's devicelist 	num=deviceList_node.nChildNode("device");	for(i=0;i<num;i++)	{		device_node=deviceList_node.getChildNode("device",i);		if(device_node.isEmpty())			break;		deviceType_node=device_node.getChildNode("deviceType",0);		if(strcmp(deviceType_node.getText(),DEVICE_TYPE_2)==0)

⌨️ 快捷键说明

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