在实现netfiler挂钩时,我一直在尝试读取数据包内容。
我可以正确地过滤IP字段或TCP字段,但是,出于好奇,我一直在努力进一步,并且还显示应用程序级别有效负载的内容,但失败了。
我知道“防火墙在3级运行”的原则,所以在某种程度上这是正常的。
我的问题是:在技术方面,为什么sock_buffer似乎停在TCP / UDP标头?
这将获得IP标头:
ip_header = (struct iphdr*)skb_network_header(sock_buff);
这将获得TCP标头:
tcp_header = (struct tcphdr*)((char*)ip_header + sizeof(struct iphdr));
但如果我这样做:
(char*) (tcp_header + 4*(tcp_header->doff)) //4*(tcp_header->doff) is size of tcp header
并显示,我看到基本测试(例如netcats发送'AAAA')它根本不显示这些字符。
我的第二个问题是:如何在Linux模块级别访问我的其余数据包?
编辑:
尝试了Joachim的建议,但也没有用!
print_payload(tcp_header + 4*(tcp_header->doff));
print_payload为:
void print_payload(void *s){
char *payload;
int i;
payload = s;
for(i=0;i<8;i++){
printk(KERN_INFO "%.2x|", payload[i]);
}
printk(KERN_INFO "\n");
}
它显示了奇怪的东西,如:
77 | 70 | 21 | ffffffc1 | 00 | 00 | 00 | 00 |
一旦我开始通过netcat发送'Z'字符......
答案 0 :(得分:1)
这是因为你应该(char*) tcp_header + 4*(tcp_header->doff)
(即删除附加的括号)。
上面的表达式将tcp_header
类型转换为char*
并添加4*(tcp_header->doff)
个字节的偏移量。
您的代码向指针添加4*(tcp_header->doff) * sizeof(*tcp_header)
字节的偏移量,然后将结果指针类型转换为char*
。