daisy
daisy

Reputation: 23501

Difference between skb_header_pointer and skb_transport_header?

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?

Upvotes: 0

Views: 974

Answers (1)

red0ct
red0ct

Reputation: 5055

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

Upvotes: 2

Related Questions