(13 bits)
u_char ttl; // 存活时间(Time to live) u_char proto; // 协议(Protocol)
u_short crc; // 首部校验和(Header checksum) ip_address saddr; // 源地址(Source address) ip_address daddr; // 目的地址(Destination address) u_int op_pad; // 选项与填充(Option + Padding) } ip_header;
然后根据报头长度又可以计算出TCP或UDP的头部指针,根据TCP或UDP的头部信息可以获得源端口号和目的端口号等信息,一般TCP的头部长度为20bytes,UDP的头部长度为8bytes,TCP和UDP的报文格式如下所示:
图2.2.2.3 TCP报文格式
图2.2.2.4 UDP报文格式
TCP/UDP包头结构在程序中的表示:
/* TCP头部 */
typedef struct tcp_header {
u_short srcPort; // 源端口号 16bits u_short destPort; // 目的端口号 16bits
u_int seqNum; // 序号 32bits u_int ackNum;
// 确认号 32bits
u_short headLen_other; // 首部长度+保留未用+其他字段 16bits u_short windowSize; // 窗口大小 16bits u_short checkSum; // 检验和 16bits u_short pointer; // 紧急数据指针 16bits u_int option; } tcp_header;
/* UDP头部 */
typedef struct udp_header {
u_short srcPort; // 源端口号 16bits u_short destPort; // 目的端口号 16bits u_short udpLen; // udp长度 16bits u_short checkSum; // 检验和 16bits } udp_header;
最后就是应用层的数据了,根据上层的报文头部信息可以计算出应用层数据的头部指针,同时根据IP数据包的头部信息可以计算出应用层数据的长度,因此就可以通过程序将应用层的数据取出来,应用层又根据不同的协议取出实际有用的数据。应用层协议主要有FTP、HTTP、DNS等。
通过以上对数据包格式的了解,那么就可以很容易对捕获的数据包进行一层一层的解析了,一般捕获的数据包都是取得链路层的帧,然后再根据头部信息一层一层地剥离,具体的程序分析流程如下图所示:
// 选项 可选、不定长
图2.2.2.5 数据包分析流程
以下就是根据以上分析流程捕获到包并对其进行分析而得出的结果(一个TCP数据包):
-------------------------------------data-------------------------------------
------------------------------------frame------------------------------------
dest_mac: 0.26.c6.67.77.14 src_mac: c8.3a.35.32.41.28 protocal: 800
---------------------------------ip packet--------------------------------- version:4 head len:20 type of service: 0 total len: 121 identifi: 14155 flag: 2 offset: 0
time to live: 50 protocal: 6
check sum: 5bb
source addr: 125.39.205.67 dest addr: 192.168.0.102
------------------------------tcp datagram------------------------------ srcPort:80 destPort:1695 seqNum:396591251 ackNum:1797819109 headLen:20 windowSize:47386 checkSum:40441 pointer:0
---------------------------------app_data--------------------------------- 数据长度:81
.Q..Q....1.9Q...#[SkY#...d..qK\..]...
相关推荐: