0

I'm writing a kernel module that receives Ethernet packets for Linux 2.6.31 and I'd like to extract contents of Ethernet packets from a pointer to struct sk_buff that is passed to func function of struct packet_type, which is registered by dev_add_pack. Which member of the structure should I refer to? When I sent an Ethernet packet with 46-byte body, skb->data - skb->head was 48 and skb->len was 46, where skb is a pointer to struct sk_buff.

Pteromys
  • 1,441
  • 2
  • 12
  • 29

2 Answers2

0

You can use netfilter hooking features. This is my sample code.

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);
}
Avinash
  • 4,115
  • 2
  • 22
  • 41
StxApp
  • 35
  • 1
  • 8
-1

you can extract the data from the sk_buff structure as...

char buff[1024];    
int i=0;
//printk("******start of the data*******\n");
while(i<((skb->tail)-(skb->data)))
buff[i]=(char *)((skb->data)[i]);

the size of buffer may differ or you can define it as u wish.

& in this buffer actually you have copied the data with the header or without header plus actual packet payload. It depends on where you are capturing the sk_buff( i mean at which layer). because as the packet goes from socket to NIC or from NIC to socket sk_buff's related fields are updated.

akp
  • 1,753
  • 3
  • 18
  • 26