TCP checksum not transmited to the wire!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I am trying to use netfilter to program my own firewall. To make a forwarding test to the local machine, I made a test program that change a certain destination IP address in the PRE ROUTING HOOK to my local machine, I changed back the source IP address in the POST ROUTING hook to the old destination address. I computed TCP and IP checksums in this hook but I still have a bad TCP checksum on the receiver. I can see in the POST ROUTING hook that my checksum was changed! Below is my code

 

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/proc_fs.h>

#include <linux/list.h>

#include <asm/uaccess.h>

#include <linux/udp.h>

#include <linux/tcp.h>

#include <linux/skbuff.h>

#include <linux/ip.h>

#include <linux/netfilter.h>

#include <linux/netfilter_ipv4.h>

#include <net/ip.h>

 

static struct nf_hook_ops nfho;

static struct nf_hook_ops nfho_out;

 

 

unsigned int hook_func_in(unsigned int hooknum, struct sk_buff *skb,

          const struct net_device *in, const struct net_device *out,

          int (*okfn)(struct sk_buff *)) {

   

    u32 local = 1090627776; //my machine IP 192.168.1.65

    struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);

    struct tcphdr *tcp_header = (struct tcphdr *)skb_transport_header(skb);

    unsigned int src_port = (unsigned int)ntohs(tcp_header->source);

    ip_header->daddr = local;

    //printk(KERN_INFO "PRE: saddr: %pI4 %u, daddr: %pI4, %u", &ip_header->saddr, ip_header->saddr, &ip_header->daddr, ip_header->daddr);

    //printk("IN saddr: %pI4 daddr: %pI4 len: %u check: %x\n", &ip_header->saddr, &ip_header->daddr, src_port, tcp_header->check);      

    return NF_ACCEPT;               

 

}

 

 

 

  

unsigned int hook_func_out(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out,

          int (*okfn)(struct sk_buff *))

{

   

    struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);

   

    u32 dest = 388809389; //the old destination ip

    ip_header->saddr = dest;

   

    struct tcphdr *tcp_header = (struct tcphdr *)skb_transport_header(skb);

    tcp_header->check = 0;

  

    int len = skb->len-20;

    unsigned int src_port = (unsigned int)ntohs(tcp_header->source);

    tcp_header->check = csum_tcpudp_magic(ip_header->saddr, ip_header->daddr, len, IPPROTO_TCP, csum_partial((char *)tcp_header, len, 0));

    ip_header->check = 0;

    ip_send_check (ip_header);

    //to check changes

    printk( "saddr: %pI4 daddr: %pI4 check: %x\n", &ip_header->saddr, &ip_header->daddr,  tcp_header->check);

    int i;

    for (i=0; i<skb->len; i++)

        printk("%x", skb->data[i]);

    printk("\n");

 

    return NF_ACCEPT;           

  }

  

  

 

  /* Initialization routine */

  int init_module() {

 

    printk(KERN_INFO "initialize kernel module\n");

     

      /* Fill in the hook structure for incoming packet hook*/

      nfho.hook = hook_func_in;

      nfho.hooknum = NF_INET_PRE_ROUTING;

      nfho.pf = PF_INET;

      nfho.priority = NF_IP_PRI_FIRST;

      nf_register_hook(&nfho);         // Register the hook

      /* Fill in the hook structure for outgoing packet hook*/

      nfho_out.hook = hook_func_out;

      nfho_out.hooknum = NF_INET_POST_ROUTING;

      nfho_out.pf = PF_INET;

      nfho_out.priority = NF_IP_PRI_FIRST;

      nf_register_hook(&nfho_out);    // Register the hook

 

 

   

      return 0;

  }

  

  /* Cleanup routine */

  void cleanup_module() {

     

      nf_unregister_hook(&nfho);

      nf_unregister_hook(&nfho_out);

 

     

      printk(KERN_INFO "kernel module unloaded.\n");

  }

 

 

Would you please help me, I spent 10 days working on this issue and not solved yet.

Best,

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux