2010-12-18 76 views
4

我正在研究Linux内核的TCP拥塞控制算法,这是我作为内核模块实现的。 在代码中,我想访问tcp头并使用以下函数来完成此操作。从tcp拥塞控制访问TCP头Linux内核模块

void get_hdr(struct sock *sk){ 
    struct sk_buff *skb; 
    skb = skb_peek_tail(&sk->sk_receive_queue); 
    if (skb != NULL) 
    printk(KERN_INFO "skb address: %p", skb); 
    struct tcphdr *tcp_header = tcp_hdr(skb); 
    if(tcp_header != 0) 
    printk(KERN_INFO "tcp_header address: %p", tcp_header); 
    else 
    printk(KERN_INFO "tcp_header is NULL"); 
} 

我认为这应该基本工作,因为它是做 here inside the kernel为好。

豪尔,看着我的kern.log我看到:

skb address: dbd94501 
tcp_header address is NULL 

显然调用tcp_hdr(skb)失败。

我不知道为什么应该这样。有没有人有一个鼓舞人心的提示,我应该看看,或者我必须改变以获得tcp标题?

干杯,

斯特凡

+0

你在'skb-> transport_header'中看到了什么?你怎么接入内核? Netfilter的? – eater 2010-12-18 14:03:13

+0

你好@eater感谢您的评论。我必须在实验室测试它。我发现我为sk提供的指针在第一个地方是错误的。然而,使用正确的我的skb_peek_tail调用返回null。我想我必须深入研究一下。不管怎么说,还是要谢谢你。顺便说一句,我不是在关注内核。它是直接作为内核代码运行的内核模块。 – Phi 2010-12-20 11:51:25

+2

通过挂钩内核,我所问的是你的内核模块如何被网络堆栈调用。例如,如果你的模块在'ip_input'之前被调用,那么'skb-> transport_header'可能还没有被设置。但这听起来像是别的什么是错的。顺便说一句,阅读评论,并确保你了解使用'skb_peek_tail()'的危险 – eater 2010-12-20 14:57:06

回答

1

在行

struct tcphdr *tcp_header = tcp_hdr(skb); 

你仍然可以拥有SKB == NULL。

为什么不把整个if部分放在大括号中?

void get_hdr(struct sock *sk){ 
struct sk_buff *skb; 
skb = skb_peek_tail(&sk->sk_receive_queue); 
if (skb != NULL) { 
    printk(KERN_INFO "skb address: %p", skb); 
    struct tcphdr *tcp_header = tcp_hdr(skb); 
    if(tcp_header != 0) 
     printk(KERN_INFO "tcp_header address: %p", tcp_header); 
    else 
     printk(KERN_INFO "tcp_header is NULL"); 
} 
} 
1

它可能是一个没有transport_header的数据包。