0

I'm trying to implement a netfilter module, while processing sk_buff I found two possible ways to retrieve TCP header:

struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);
struct tcphdr *tcp_header = (struct tcphdr *)skb_transport_header(skb);

And

struct iphdr *ip_header = skb_header_pointer(skb, 0, sizeof(struct iphdr), &_iph)
struct tcphdr *tcp_header = skb_header_pointer(skb, ip_header->ihl * 4, sizeof(struct tcphdr), &_tcph);

Which one should I use?

red0ct
  • 4,840
  • 3
  • 17
  • 44
daisy
  • 22,498
  • 29
  • 129
  • 265

1 Answers1

2

You should use ip_hdr() from /include/linux/ip.h and tcp_hdr() from /include/linux/tcp.h in case you know that there cannot be paged-skb here:

struct iphdr *ip_header = ip_hdr(skb);
if (ip_header->protocol == IPPROTO_TCP) {
    struct tcphdr *tcp_header = tcp_hdr(skb);
    //...

skb_header_pointer() should be used in case the appearance of paged-skb is possible. Examples: IP, TCP, ICMP, etc.
So if the header is in paged data (fully or partially) - skb_header_pointer() will correctly handle it.
Also remember to check the return value of skb_header_pointer(), it can return NULL.

Useful links: 1, 2

red0ct
  • 4,840
  • 3
  • 17
  • 44