您的位置:首页 > 理论基础 > 计算机网络

用libpcap解析TCP/UDP

2014-02-18 15:24 741 查看
解析TCP/UDP

1.定义结构体以太网、IP、TCP、UDP包头的信息

2.利用pcap_lookupdev()函数得到网络接口的名字

3.利用pcap_lookupnet()得到网络地址和网络掩码

4.利用pcap_open_live()来捕获一个网络包

5.利用pcap_compile()编译过滤规则

6.利用pcap_setfilter()来设置过滤规则

7.利用pcap_loop()循环补包,同时调用回调函数

8.回调函数ethernet_protocol_packet_callback

①(u_char*argument,const struct pcap_pkthdr*packet_header,const u_char*packet_conent)里如定义以太网类型变量struct ether_header
*ethernet_protocol,以太网的类型u_short ethernet_type;

②把数据包头packet_conent强制转换成以太网类型ethernet_protocol = (struct ether_header*)packet_conent;

③转成以太网类型后,取出以太网的类型号(ntohs将本机字节序列转换为网络字节序列,ntohs是32位,如本机字节序列式0x1234转成网络之后是0x3412,注意在得到源目的地址之前都需要转换成网络顺序)ethernet_type
= ntohs(ethernet_protocol->ether_type);

④判断ethernet_type值,如果是0x0800,代表上层协议为IP协议,如果是0x0806,代表上层协议为ARP,如果是0x0835,代表上层协议为RARP,否则上层没有相应的协议;

⑤如果上层是IP协议,使用packet_conent +14可以得到IP的数据包头的地址,(注意每次得到相应头指针时都需要转换成相应的层的相应地址,14表示以太网的数据包头的长度)如:ip_protocol = (struct ip_header*)(packet_conent + 14);//ip_protocol是自己定义的ip类型的变量

⑥利用ip_protocol->ip_protocol来判断上层的协议,如果该值是1则表示上层ICMP协议,如果该值为2,则表示IGMP协议,如果该值是6则表示TCP协议,如果该值是17,则表示UDP协议,否则,提示没有相应的上层协议与之相匹配

⑦如果该值6,则表示上层协议为TCP协议,定义TCP类型的变量struct tcp_header *tcp_protocol,还有目的端口变量u_short tcp_destination_port;//16位目的端口(这里的变量名都是顺便起的,但尽量起的有含义,让大家一看变量名就知道它是用来干什么的)。用ip的头+ip_protocol->等于TCP的数据包的头首地址(因为Ip的数据包头一般是20个字节,但不固定,最短是20个字节,最长为60个字节)。

tcp_protocol=(structtcp_header*)(packet_conent+14+ip_protocol->ip_header_length*4+);

tcp_destination_port = ntohs(tcp_protocol->tcp_destination_port);

tcp_flags =tcp_protocol->tcp_flags,

(1)注意:如果(tcp_flags&0x01)!= 0则表示标记位表示FIN;如果(tcp_flags&0x02)!= 0则表示标记位表示SYN;如果(tcp_flags&0x04)!= 0则表示标记位表示RST;如果(tcp_flags&0x08)!= 0则表示标记位表示PSH;如果(tcp_flags&0x10)!= 0则表示标记位表示ACK;如果(tcp_flags&0x20)!=
0则表示标记位表示URG;

(2)判断目的端口tcp_destination_port的值,如果该值为21,则表示上层的协议为FTP;如果该值为23,则表示上层的协议为Telnet;如果该值为69,则表示上层的协议为TFTP;否则提示没有相匹配的协议;

⑧如果的到的协议的是UDP,用ip的头+ ip_protocol->ip_header_length*4等于UDP的数据包的头首地址(因为Ip的数据包头一般是20个字节,但不固定,最短是20个字节,最长为60个字节)。定义udp类型的指针变量dup_protocol

dup_protocol=(structudp_header*)(packet_conent+14+ip_protocol->ip_header_length*4);

udp_destination_port = ntohs(udp_protocol->udp_destination_port);

判断udp_destination_port的值,如果该值为138,则表示上层是NetBIOS数据报服务;如果该值为137,则表示上层是NetBIOS名字服务;如果该值为139,则表示上层是NetBIOS会话服务;如果该值为58,则表示上层是域名服务;

注意:

1.ip/tcp包头不是固定,ip/tcp数据包头中4位首部长度(假设为ss)负责计算出ip/tcp首都数据报的个数

2.ss*4就是ip/tcp首部实际长度,因为它是以4个字节为单位的。

3.需要转换为网络字节序,因为IP字节的位数从左到右是0-7bit,8-15bit,16-23bi,24-31bit,而TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序输出,故必须在传输数据之前把首部转换成网络字节序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: