netinet/tcp.h中tcphdr的TCP偏移字段是th_off还是doff?
字段差异说明
- 你看到的
th_off和doff本质对应TCP头部同一个4bit的数据偏移字段,差异来自头文件的来源:- 你贴出的
<netinet/tcp.h>是glibc为用户态程序提供的标准头文件,这里定义的th_off就是该字段的官方命名,头文件已经帮你处理了大小端的位序适配,直接读取就能得到正确的偏移值,单位为4字节,乘以4即可得到TCP头部的总长度,你之前用th_off读取payload的逻辑是完全正确的,和发行版无关。 doff是Linux内核源码中<linux/tcp.h>头文件对同一个字段的命名,仅在内核模块开发场景下使用,和用户态的th_off指向完全相同的比特位,没有功能差异。
- 你贴出的
现有代码的可优化点
你当前定义的TCP_HLEN宏属于手动操作字节位掩码实现偏移提取,不如直接使用标准字段安全,可直接替换为:
#define TCP_HLEN(tcp) (tcp->th_off * 4)
另外注意你计算IP头部长度的逻辑有隐患:IP头部存在可选字段,长度不固定,不能直接用sizeof(struct iphdr)作为IP头长度,应该通过IP头的ihl字段计算:
// 正确的IP头长度计算,ihl单位也是4字节 #define IP_HLEN(ip) (ip->ihl *4)
对应payload的计算逻辑修改为:
char *payload_body = (char *)((uint8_t *)tcp + TCP_HLEN(tcp)); // 或者从ppd开始计算的写法: char *payload_body = (char *)((uint8_t*)ppd + ppd->tp_mac + IP_HLEN(ip) + TCP_HLEN(tcp));
其他相关字段说明
你当前用到的TCP头相关字段已经覆盖了payload提取的需求,没有遗漏的必要字段,唯一需要注意的就是不要混淆用户态和内核态的头文件命名即可。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

