Hi everyone,
I am trying a netfilter module in kernel 3.8.0.34 to filter NF_IP_LOCAL_OUT packets like below. The packets have not been touched but UDP checksum was recalculated using csum_tcpudp_magic(), However the returned checksum value is always different from original ip_header->check.
Am I missing something or the original checksum was calculated with different method ?
Output:
Code:
[252565.092326] recalculating udp checksum 38161
[252565.092327] recalculated udp checksum 27332
Code:
unsigned int out_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff*))
{
printk(KERN_INFO "Out_hook: entering function\n");
struct sk_buff *sock_buff;
struct iphdr *ip_header;
struct udphdr *udp_header;
struct tcphdr *tcp_header;
unsigned int udp_len;
unsigned int tcp_len;
if(!skb)
{
printk(KERN_INFO "skb is NULL\n");
return NF_ACCEPT;
}
if(!(skb->network_header))
{
printk(KERN_INFO "Error in nh\n");
return NF_ACCEPT;
}
sock_buff = skb;
printk(KERN_INFO "Getting ip_header\n");
/* Get ip header */
ip_header = ip_hdr(sock_buff);
/* Handle udp protocol */
if(ip_header->protocol == IPPROTO_UDP)
{
printk(KERN_INFO "Handling udp packet\n");
udp_header = udp_hdr(sock_buff);
/* udp length = sock_buff->len - ip_header length (should be 20 bytes) */
udp_len = sock_buff->len - (ip_header->ihl << 2);
/* If UDP checksum is enabled, need to re-calculate */
if(udp_header->check)
{
printk(KERN_INFO "recalculating udp checksum %u\n", udp_header->check);
udp_header->check = csum_tcpudp_magic(ip_header->saddr, ip_header->daddr, udp_len, IPPROTO_UDP, csum_partial(udp_header, udp_len ,0));
printk(KERN_INFO "recalculated udp checksum %u\n", udp_header->check);
}
return NF_ACCEPT;
}