1,设置套接字为混杂模式
设置为混杂模式接受所有网络包。
ioctlsocket(raw_sock, SIO_RCVALL, &arg)
2,解析协议
以TCP协议为例,首先协议是封层的,如下图:
+---------------------+
| TCP |
+---------------------+
| internet protocol |
+---------------------+
所以为解析TCP,首先要先解析IP协议,然后在解析TCP协议。
以下为IP Header:
typedef struct ip_header_s {
unsigned v : 4;
unsigned ihl : 4;
unsigned tos : 8; //Type of Service
unsigned total_len : 16;
unsigned id : 16;
unsigned flags : 3;
unsigned frag_offset : 13;
unsigned ttl : 8;
unsigned proto : 8;
unsigned checksum : 16;
unsigned src_ip : 32;
unsigned dst_ip : 32;
}ip_header_t;
以下为TCP Header:
typedef struct tcp_header_s {
unsigned src_port : 16;
unsigned dst_port : 16;
unsigned seq_num : 32;
unsigned ack_num : 32;
unsigned data_offset : 4;
unsigned reserved : 6;
unsigned ctrl_bits : 6;
unsigned window : 16;
unsigned checksum : 16;
unsigned urg_pointer : 16;
}tcp_header_t;
3,解析IP头
以下为解析IP头的代码片段:
ip_header_t *ip_hdr = (ip_header_t*)packet;
in_addr source, dest;
char src_ip[32], dst_ip[32];
source.S_un.S_addr = ip_hdr->src_ip;
dest.S_un.S_addr = ip_hdr->dst_ip;
strcpy(src_ip, ::inet_ntoa(source));
strcpy(dst_ip, ::inet_ntoa(dest));
int hdr_len = ip_hdr->ihl;
int proto = ip_hdr->proto;
//printf(" %s -> %s proto(%d)\n", source_ip, dest_ip, proto);
switch(proto)
{
case IPPROTO_IPV4:
break;
case IPPROTO_TCP: // TCP
decode_tcp_packet(packet + hdr_len, src_ip, dst_ip);
break;
case IPPROTO_UDP:
break;
case IPPROTO_ICMP:
break;
}