我该怎么从netfilter勾出来的报文里读取数据?
我使用这个钩子函数,读取netfilter架构勾出来的网络报文对应的skbuff结构体的内容,并打印到日志中.
unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
//这个函数是钩子函数.
//抓到包时会执行该函数.
//sk_buff是抓到的数据包.
//接受了3个参数,只有中间那个用到了.
{
struct iphdr*p=ip_hdr(skb);
if(p->protocol==6)
{
printk(KERN_INFO"TCP packet!");
printk(KERN_INFO"---len=%d",skb->len);
struct tcphdr*t=(struct tcphdr*)(skb->data+p->ihl*4);
u16 srcport=ntohs(t->source),dstport=ntohs(t->dest);
printk(KERN_INFO"---srcport=%hu,dstport=%hu",srcport,dstport);
unsigned char *c=skb->data;
unsigned char *end=skb->head+skb->tail;
if(srcport==12345)
for(int i=0;c+i<end;i++)
printk(KERN_INFO"%c %c %c %c %c %c",c[i*6],c[i*6+1],c[i*6+2],c[i*6+3],c[i*6+4],c[i*6+5]);
}
return NF_ACCEPT; // accept the packet
//这里,钩子函数判定,接受该包.
}
之后,我在本地的12345端口,使用两个终端的netcat指令进行通信,内容为ABCDE.
然后我截取到类似如此的内容.
[24394.700504] ---srcport=12345,dstport=36050
[24394.700507] E \x00 \x00 ; : ]
[24394.700509] @ \x00 @ \x06 \x02 ^
[24394.700511] \x7f \x00 \x00 \x01 \x7f \x00
[24394.700513] \x00 \x01 0 9 \x8c \xd2
[24394.700514] \xc6 \x98 { \xa9 _ \xf8
[24394.700516] F \xe6 \x80 \x18 \x02 \x00
[24394.700518] \xfe / \x00 \x00 \x01 \x01
[24394.700519] \x08
\x9e \xa1 \xfc d
[24394.700521] \x9e \xa1 \xe1 \xf4 \x00 \x00
[24394.700523] \x00 \x00 \x00 \x00 \x00 \x00
[24394.700524] \x00 \x00 \x00 \x00 \x00 \x00
[24394.700526] \x00 \x00 \x00 \x00 \x00 \x00
差不多是这么个样子.如果它的网络报文中包含A,B这些英文字符,那为什么我使用printk打印不出来?
现在我发现一个问题,那就是这个钩子函数截取的只有网络报文的头部,和在wireshark打印的样子一模一样.
报文内部的内容是完全没有的.
netfilter没法获取报文内部的应用层数据吗?我看说明说可以啊.
这个包打印的没啥问题,应该是你打错包了。 TCP协议是有三次握手的,有syn、ack、fin、rst这些控制报文,所以你判断源端口是不是12345,并不能说明这个包一定就是你想要的带着ABC数据的报文。通过打印结果来看,这就是一个ACK的空包。
综上,打印没啥问题,应该是打印错包了。另外你计算end的那行我猜你的本意应该是找到报文结束吧?代码写错了,head和tail这俩是指针,指针相加不是代表报文结束,所以你这个printk打印了后面的一堆的0, 如果不考虑非线性数据: