I have a kernel module that captures outgoing Internet traffic(Netfilter hook: LOCAL_OUT) At this hook, there\'s still no Ethernet header.
I built the Ethernet header an
Wow, you don't do that. Don't mess with skb internal pointers directly. Just allocate an skb and copy the headers and payload to the new one.
Let's assume you want to add ICMP, IP and ethernet headers and copy payload from orig_skb
. Do it like this:
struct skbuff *skb = skb_alloc(full_len, GFP_KERNEL);
/* icmp_hlen, ip_hlen and payload_size should be known */
int header_size = icmp_hlen + ip_hlen;
/* reserve headroom */
skb_reserve(skb, header_size);
/* payload */
unsigned char *data = skb_put(skb, payload_size);
memcpy(data, orig_skb->data, payload_size);
struct icmphdr *icmph = skb_push(skb, icmp_hlen);
/* set up icmp header here */
struct iphdr *iph = skb_push(skb, ip_hlen);
/* set up ip header here */
/*
* This function sets up the ethernet header,
* destination address addr, source address myaddr
*/
dev_hard_header(skb, dev, ETH_P_IP, addr, myaddr, dev->addr_len);
You can push multiple headers if you want to add transport, network etc headers.