Network programming 在sk_buff中接收以太网数据包

Network programming 在sk_buff中接收以太网数据包,network-programming,linux-kernel,ethernet,Network Programming,Linux Kernel,Ethernet,我正在编写一个内核模块,用于接收Linux 2.6.31的以太网数据包,我想从指向struct sk_buff的指针中提取以太网数据包的内容,该指针被传递给struct packet_type的func函数,该函数由dev\u add_pack注册。我应该指结构中的哪一个成员?当我发送一个46字节的以太网数据包时,skb->data-skb->head是48,skb->len是46,其中skb是指向struct sk_buff的指针,您可以从sk_buff结构中提取数据,如下所示 char bu

我正在编写一个内核模块,用于接收Linux 2.6.31的以太网数据包,我想从指向
struct sk_buff
的指针中提取以太网数据包的内容,该指针被传递给
struct packet_type
func
函数,该函数由
dev\u add_pack
注册。我应该指结构中的哪一个成员?当我发送一个46字节的以太网数据包时,
skb->data-skb->head
是48,
skb->len
是46,其中
skb
是指向
struct sk_buff
的指针,您可以从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]);
charbuff[1024];
int i=0;
//printk(“******数据的开始部分******\n”);
while(itail)-(skb->data)))
buff[i]=(char*)((skb->data)[i]);
缓冲区的大小可能不同,或者您可以根据需要定义它

&在这个缓冲区中,实际上您已经复制了带有报头或不带报头的数据以及实际的数据包负载。 这取决于你在哪里捕捉sk_buff(我的意思是在哪一层)。
因为当数据包从套接字到NIC或从NIC到套接字时,sk_buff的相关字段会更新。

您可以使用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);
}