当前位置: 技术问答>linux和unix
请问netfilter中tcp报文的信息什么时候更新?
来源: 互联网 发布时间:2016-07-06
本文导语: 本帖最后由 wryse 于 2009-09-30 17:19:46 编辑 我在NF_INET_PRE_ROUTING这个点挂载的钩子函数,现在能正常获取到数据包,检查内容时已经能判断出当前包是一个tcp报文了,但发现sk_buff结构中的transport_header的值和network_header的...
以下是部分关键代码,盼高手指点:
struct sk_buff *msg_buf = skb;
struct iphdr *msg_ip_hdr = NULL;
struct tcphdr *msg_tcp_hdr = NULL;
msg_ip_hdr = ip_hdr(msg_buf); //ip包包头,这个应该不会有问题,毕竟源目的地址以及长度都正确取到了
...... //一些取ip,长度的计算,结果正确,过程中没有改变过msg_buf和msg_ip_hdr的值
msg_tcp_hdr = tcp_hdr(msg_buf); //这个值取出来和前一段的值完全一样
//msg_tcp_hdr = (struct tcphdr*)(msg_buf->network_header); //直接取,虽然知道没有区别但还是试了一下,同样的结果
msg_tcp_hdr_len = tcp_hdrlen(msg_buf); //前面两个值一样,导致这行悲剧了
//msg_tcp_hdr_len = msg_tcp_hdr->doff * 4;
msg_tcp_payload_len = msg_ip_tot_len - msg_ip_hdr_len; //这里通过ip包的内容算出来的是正确的长度
//输出,第一行的输出里四个值全都相等,囧rz
printk("SKB transport header: %x, network header: %x, IP header pointer: %x, TCP header pointer: %xn",
msg_buf->transport_header, msg_buf->network_header,
msg_ip_hdr, msg_tcp_hdr);
printk("TCP total payload len: %u, TCP header len: %u. TCP res1: %un",
msg_tcp_payload_len, msg_tcp_hdr_len, msg_tcp_hdr->res1);
|
看了下kernel的code,当网卡收到数据包后交由softirq处理,在netif_receive_skb函数中同时调用了skb_reset_network_header和skb_reset_transport_header,这时network_header就和transport_header相等。
在netfilter的NF_INET_LOCAL_IN hook点之后会调用ip_local_deliver_finish, 在ip_local_deliver_finish中会重新计算transport_header。也就是在数据包从第三层(IP)进入第四层(TCP)之前设置transport_header。
在netfilter的NF_INET_LOCAL_IN hook点之后会调用ip_local_deliver_finish, 在ip_local_deliver_finish中会重新计算transport_header。也就是在数据包从第三层(IP)进入第四层(TCP)之前设置transport_header。
static int ip_local_deliver_finish(struct sk_buff* skb)
{
struct net *net = dev_net(skb->dev);
__skb_pull(skb, ip_hdrlen(skb));
/* Point into the IP datagram, just pass the header. */
skb_reset_transport_header(skb);
....
....
}