<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>
<p class="MsoNormal">Hello,<o:p></o:p></p>

<p class="MsoNormal">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<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">#include &lt;linux/module.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/kernel.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/proc_fs.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/list.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;asm/uaccess.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/udp.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/tcp.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/skbuff.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/ip.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/netfilter.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;linux/netfilter_ipv4.h&gt;<o:p></o:p></p>

<p class="MsoNormal">#include &lt;net/ip.h&gt;<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">static struct nf_hook_ops nfho;<o:p></o:p></p>

<p class="MsoNormal">static struct nf_hook_ops nfho_out;<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">&nbsp; <o:p></o:p></p>

<p class="MsoNormal">unsigned int hook_func_in(unsigned int hooknum, struct
sk_buff *skb, <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct
net_device *in, const struct net_device *out,<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*okfn)(struct
sk_buff *)) {<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; u32 local =
1090627776; //my machine IP 192.168.1.65<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; struct iphdr
*ip_header = (struct iphdr *)skb_network_header(skb);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; struct tcphdr
*tcp_header = (struct tcphdr *)skb_transport_header(skb);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; unsigned int src_port
= (unsigned int)ntohs(tcp_header-&gt;source);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;
ip_header-&gt;daddr = local;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; //printk(KERN_INFO
"PRE: saddr: %pI4 %u, daddr: %pI4, %u", &amp;ip_header-&gt;saddr,
ip_header-&gt;saddr, &amp;ip_header-&gt;daddr, ip_header-&gt;daddr);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; //printk("IN
saddr: %pI4 daddr: %pI4 len: %u check: %x\n", &amp;ip_header-&gt;saddr,
&amp;ip_header-&gt;daddr, src_port, tcp_header-&gt;check);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; return
NF_ACCEPT;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp; <o:p></o:p></p>

<p class="MsoNormal">}<o:p></o:p></p>

<p class="MsoNormal">&nbsp;<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">unsigned int hook_func_out(unsigned int hooknum, struct
sk_buff *skb, const struct net_device *in, const struct net_device *out,<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int
(*okfn)(struct sk_buff *)) <o:p></o:p></p>

<p class="MsoNormal">{<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; struct iphdr
*ip_header = (struct iphdr *)skb_network_header(skb);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; u32 dest =
388809389; //the old destination ip<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; ip_header-&gt;saddr
= dest;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; struct tcphdr
*tcp_header = (struct tcphdr *)skb_transport_header(skb);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;
tcp_header-&gt;check = 0;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; int len =
skb-&gt;len-20;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; unsigned int
src_port = (unsigned int)ntohs(tcp_header-&gt;source);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;
tcp_header-&gt;check = csum_tcpudp_magic(ip_header-&gt;saddr,
ip_header-&gt;daddr, len, IPPROTO_TCP, csum_partial((char *)tcp_header, len,
0));<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;
ip_header-&gt;check = 0;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; ip_send_check
(ip_header);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; //to check changes<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; printk(
"saddr: %pI4 daddr: %pI4 check: %x\n", &amp;ip_header-&gt;saddr,
&amp;ip_header-&gt;daddr,&nbsp;
tcp_header-&gt;check);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; int i;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; for (i=0;
i&lt;skb-&gt;len; i++)<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
printk("%x", skb-&gt;data[i]);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;
printk("\n");<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; return
NF_ACCEPT;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp; }<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp; /* Initialization
routine */<o:p></o:p></p>

<p class="MsoNormal">&nbsp; int init_module() {<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; printk(KERN_INFO
"initialize kernel module\n");<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Fill in the
hook structure for incoming packet hook*/<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho.hook =
hook_func_in;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho.hooknum =
NF_INET_PRE_ROUTING;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho.pf =
PF_INET;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho.priority =
NF_IP_PRI_FIRST;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nf_register_hook(&amp;nfho);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// Register the hook<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Fill in the
hook structure for outgoing packet hook*/<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho_out.hook =
hook_func_out;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho_out.hooknum
= NF_INET_POST_ROUTING;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho_out.pf =
PF_INET;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nfho_out.priority
= NF_IP_PRI_FIRST;<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nf_register_hook(&amp;nfho_out);&nbsp;&nbsp;&nbsp;
// Register the hook<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<o:p></o:p></p>

<p class="MsoNormal">&nbsp; }<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp; /* Cleanup routine
*/<o:p></o:p></p>

<p class="MsoNormal">&nbsp; void
cleanup_module() {<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nf_unregister_hook(&amp;nfho);<o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nf_unregister_hook(&amp;nfho_out);<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></p>

<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO
"kernel module unloaded.\n");<o:p></o:p></p>

<p class="MsoNormal">&nbsp; }<o:p></o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal"><o:p>&nbsp;</o:p></p>

<p class="MsoNormal">Would you please help me, I spent 10 days working on this
issue and not solved yet.<o:p></o:p></p>

<p class="MsoNormal">Best,<o:p></o:p></p>                                               </div></body>
</html>