This article is a bit outdated. Text that you do not understand applies only to kernel versions below 3.11.
For new kernels (> = 3.11)
If you are sure that your code will only be used with kernels> = 3.11, you can use the following code for input and output :
udp_header = (struct udphdr *)skb_transport_header(skb);
Or more elegantly:
udp_header = udp_hdr(skb);
This is because the transport header is already configured for you in ip_rcv () :
skb->transport_header = skb->network_header + iph->ihl*4;
This change was caused by this commit .
For older kernels (<3.11)
Outgoing Packages ( NF_INET_POST_ROUTING)
.transport_header sk_buffer, (UDP/TCP). , :
udp_header = (struct udphdr *)skb_transport_header(skb);
( ):
udp_header = udp_hdr(skb);
(NF_INET_PRE_ROUTING)
.
.transport_header (UDP TCP) sk_buffer ( hook netfilter). .transport_header IP ( ).
, . IP (.. IP .transport_header). :
udp_header = (struct udphdr *)(skb_transport_header(skb) + 20);
, 20 IP.
:
struct iphdr *iph;
struct udphdr *udph;
iph = ip_hdr(skb);
if (skb_transport_header(skb) == (unsigned char *)iph)
udph = (unsigned char *)iph + (iph->ihl * 4);
else
udph = udp_hdr(skb);
IP ( iph->ihl * 4, ) 20.
- 17 :
if (ip_header->protocol == 17) {
IPPROTO_UDP 17:
#include <linux/udp.h>
if (ip_header->protocol == IPPROTO_UDP) {
/ Netfilter
netfilter, . .

:
[1]: GitHub
[2]: "Linux Kernel Networking: "
[3]: