windows row socket

#include <winsock2.h>
//#include <ws2tcpip.h> /* for IP_HDRINCL */
#include <mstcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")  /* WinSock使用的库函数 */

typedef struct _iphdr //定义IP首部 
{ 
	unsigned char h_verlen; //4位首部长度+4位IP版本号 
	unsigned char tos; //8位服务类型TOS 
	unsigned short total_len; //16位总长度(字节) 
	unsigned short ident; //16位标识 
	unsigned short frag_and_flags; //3位标志位 
	unsigned char ttl; //8位生存时间 TTL 
	unsigned char proto; //8位协议 (TCP, UDP 或其他) 
	unsigned short checksum; //16位IP首部校验和 
	unsigned int sourceIP; //32位源IP地址 
	unsigned int destIP; //32位目的IP地址 
}IP_HEADER; 


typedef struct _tcphdr //定义TCP首部 
{ 
	USHORT th_sport; //16位源端口 
	USHORT th_dport; //16位目的端口 
	unsigned int th_seq; //32位序列号 
	unsigned int th_ack; //32位确认号 
	unsigned char th_lenres;//4位首部长度/6位保留字 
	unsigned char th_flag; //6位标志位
	USHORT th_win; //16位窗口大小
	USHORT th_sum; //16位校验和
	USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER; 

char* GetProtocolTxt(int Protocol)
{
	switch (Protocol)
	{
	case IPPROTO_ICMP : //1 control message protocol 
		return "ICMP";
	case IPPROTO_TCP : //6 tcp */
		return "TCP";
	case IPPROTO_UDP : //17 user datagram protocol */
		return "UDP";
	default:
		return "UNKNOWN";
	}
}
void printIP(IP_HEADER *ip)
{
	printf("\nProtocol\t: %s(%u)\r\n",GetProtocolTxt(ip->proto),ip->proto);;
	printf( "ip version\t: %u\n",(ip->h_verlen&0xf0)>>4);
	printf( "ip header length\t: %u\n",(ip->h_verlen&0x0f)*4);
	printf( "ip inedtifier\t: %x\n",ip->ident);

	unsigned char* p = (unsigned char*)&ip->sourceIP;
	printf("Source IP\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]);
	p = (unsigned char*)&ip->destIP;
	printf("Destination IP\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]);
	printf("ip total length\t: %u\n", ntohs(ip->total_len));
}

void printTCP(TCP_HEADER *tcp)
{
	printf("\nTCP source Port\t: %u\r\n",ntohs(tcp->th_sport));
	printf("TCP dest Port\t: %u\r\n",ntohs(tcp->th_dport) );
	printf("seq number\t: %u\r\n",ntohl(tcp->th_seq));
	printf("ack number\t: %u\r\n",ntohl(tcp->th_ack));
	printf("TCP Header length\t: %u\r\n",((tcp->th_lenres&0xf0)>>4)*4);
	printf("FLAG\t: "); 
	unsigned char it = 0x20;
	for(unsigned int i=0;i<6;i++)
	{
		if(tcp->th_flag&it)
			putchar('1');
		else
			putchar('0');
		it >>= 1 ;
	}
	printf("(Binary)\r\n");
	printf("window size\t:%u\r\n",ntohs(tcp->th_win));
	printf("urg ptr\t:%u\r\n",ntohs(tcp->th_urp));
	//	char *p = (char *)tcp;
	//	printf("Data: \t%s\n\n", (char *)(p +((tcp->th_lenres&0xf0)>>4)*4 ));

}
int main(int argc, char **argv)
{
	WSADATA wsa_data;
	WSAStartup(WINSOCK_VERSION, &wsa_data); /* 初始化 WinSock 资源 */

	SOCKET raw_soc = 0;        /* socket 句柄 */
	int result;
	BOOL opt_val = TRUE;
	unsigned long local_addr;
	struct hostent *host_ent;
	char host[256];
	/* 创建 raw socket */
	raw_soc = socket( AF_INET, SOCK_RAW, IPPROTO_IP);
	if( raw_soc == INVALID_SOCKET )
	{
		printf("socket() error: %d\n",WSAGetLastError());
		return 0;
	}
	/* 得到本机的 IP 地址 */
	if (gethostname(host, sizeof(host)) == SOCKET_ERROR) 
	{
		printf("gethostname() error: %d\r\n", WSAGetLastError());
		return -1;
	}

	host_ent = gethostbyname(host);
	if (host_ent == 0) 
	{
		printf("gethostbyname() error: %d\r\n", WSAGetLastError());
		return -1 ;
	}

	memcpy(&local_addr, host_ent->h_addr, sizeof(struct in_addr));
	//绑定本地地址到SOCKET句柄
	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_addr.S_un.S_addr = local_addr; //IP
	addr.sin_port = 0;		//端口,IP层端口可随意填
	if( SOCKET_ERROR == bind( raw_soc, (sockaddr *)&addr, sizeof(addr) ) )
	{
		closesocket(raw_soc );
		printf("bind error: %d\n",WSAGetLastError());
		return 0;
	}
	//设置该SOCKET为接收所有流经绑定的IP的网卡的所有数据,包括接收和发送的数据包
	//该函数在mstcpip.h里面,详见MSDN帮助
	u_long sioarg = 1;
	DWORD wt=0;
	/*if( SOCKET_ERROR == WSAIoctl( raw_soc, SIO_RCVALL , &sioarg,sizeof(sioarg),NULL,0,&wt,NULL,NULL ) )
	{
	closesocket( raw_soc);
	printf("WSAIoctl error: %d\n",WSAGetLastError());
	return 0;
	}*/
	// 设置SOCK_RAW为SIO_RCVALL(混合模式),以便接收所有的IP包.
	DWORD dwValue = 1;
	ioctlsocket(raw_soc, SIO_RCVALL, &dwValue); // dwValue为1时执行,0时取消

	const int BUFFER_SIZE = 102400;
	char RecvBuf[BUFFER_SIZE];
	IP_HEADER* ip;
	printf("Waiting for incopming IP packet..\n");
	int len = 0;

	while (true)
	{
		// 接收原始数据包信息
		int ret = recv(raw_soc, RecvBuf, BUFFER_SIZE, 0);
		if (ret > 0)
		{
			RecvBuf[ret] = 0;
			// 对数据包进行分析,并输出分析结果
			ip = (IP_HEADER*)RecvBuf;
			
			if (ip->proto == IPPROTO_TCP)
			{
				//printf("TCP packet... \n");
				printIP(ip);
				TCP_HEADER* tcp = (TCP_HEADER*)(RecvBuf + (ip->h_verlen&0x0f)*4);
				printTCP(tcp);
				printf("-----------------\n");
			}
			else if (ip->proto == IPPROTO_UDP)
			{
				//printf("UDP packet...\n");
			//	printf("-----------------\n");
			}
			else if (ip->proto == IPPROTO_ICMP)
			{
				//printf("ICMP packet...\n");
			//	printf("-----------------\n");
			}
		}
	}
	return 0;
}

 

在win7上,需要管理员身份运行。

你可能感兴趣的:(windows row socket)