我正在编写一个接收Linux 2.6.31以太网数据包的内核模块,我想从指向struct sk_buff
的指针中提取以太网数据包的内容,该指针传递给func
函数struct packet_type
,由dev_add_pack
注册。我应该参考哪个结构成员?当我发送一个46字节正文的以太网数据包时,skb->data - skb->head
为48,skb->len
为46,其中skb
是指向struct sk_buff
的指针。
答案 0 :(得分:0)
您可以使用netfilter挂钩功能。这是我的示例代码。
static unsigned int hook_func(unsigned int hooknum,
struct sk_buff *pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff*)) {
int ret = 110;
int x = 0;
struct net_device * dev;
struct ethhdr *neth_hdr = NULL;
if(strcmp(in->name,"lo0") == 0){
return NF_ACCEPT;
}
if(!pskb){
return NF_ACCEPT;
}
struct iphdr* iph = ip_hdr(pskb);
if(!(iph)){
return NF_ACCEPT;
}
if(iph->ttl == 0xFF){
return NF_ACCEPT;
}
if(iph->protocol == 6){
struct tcphdr *tcp = tcp_hdr(pskb);
if(tcp == NULL){
return NF_ACCEPT;
}
if(ntohs(tcp->dest) == 80){
if(tcp->syn == 1){
printk(KERN_DEBUG "Packet TCP SYN\n");
return NF_ACCEPT;
}
}
}
return NF_ACCEPT;
}
int init_module(void) {
nfho.hook = hook_func;
nfho.pf = PF_INET;
nfho.hooknum = NF_INET_PRE_ROUTING;
nfho.priority = NF_IP_PRI_FIRST;
thrqueue = create_workqueue(WQ_NAME1);
INIT_WORK(&thread, thread_function);
return nf_register_hook(&nfho);
}
void cleanup_module() {
nf_unregister_hook(&nfho);
}
答案 1 :(得分:-1)
您可以将sk_buff结构中的数据提取为...
char buff[1024];
int i=0;
//printk("******start of the data*******\n");
while(i<((skb->tail)-(skb->data)))
buff[i]=(char *)((skb->data)[i]);
缓冲区的大小可能不同,或者您可以根据需要定义它。
&安培;实际上,在此缓冲区中,您已使用标头或没有标头以及实际数据包负载复制数据。 这取决于你捕获sk_buff的位置(我的意思是在哪一层)。 因为当数据包从套接字转到NIC或从NIC到套接字时,sk_buff的相关字段会更新。