2.6.30内核Netfilter的简单例子、八(simpNat)

2740阅读 0评论2015-03-17 keep_coding
分类:C/C++

Linux2.6内核Netfilter的简单例子、八(simpNat) 收藏

在openSuSE上搭建好实验环境之后,继续内核模块的实验。这次做的是一个简单的网络地址转换(NAT)。
在负载均衡器(LB)上,将目的地址是192.168.99.102的数据包(skb)的目的地址改为192.168.99.101。
没有做连接跟踪、没有将192.168.99.101返回的原地址改成192.168.99.102,一切从简!
只能拿ping做实验。
1、源代码:simpNat.c

#include
#include                   /* for tcphdr */
#include
#include                     /* for csum_tcpudp_magic */
#include
#include                    /* for icmp_send */
#include                   /* for ip_route_output */
#include
#include
#include
#include
#include

#include
MODULE_LICENSE("GPL");
/* This is the structure we shall use to register our function */
static struct nf_hook_ops nfho;
/* IP address we want to Nat*/
static unsigned char *nat_ip = "\xc0\xa8\x63\x65";   /* 192.168.99.101 */
static unsigned char *org_ip = "\xc0\xa8\x63\x66";   /* 192.168.99.102 */
/* This is the hook function itself */
unsigned int hook_func(unsigned int hooknum,
                           struct sk_buff *skb,
                           const struct net_device *in,
                           const struct net_device *out,
                           int (*okfn)(struct sk_buff *))
{
  struct sk_buff *sb = skb;
  struct iphdr *iph;
  if(!sb) return NF_ACCEPT;
  iph = ip_hdr(sb);
  if(!iph) return NF_ACCEPT;

 
  if (iph->daddr == *(unsigned int *)org_ip){
    iph->daddr= *(unsigned int *)nat_ip;
    ip_send_check(iph);
    skb->local_df = 1;

    printk("Nat: %d.%d.%d.%d To:%d.%d.%d.%d\n",
                *org_ip, *(org_ip + 1), *(org_ip + 2),*(org_ip + 3),
                *nat_ip, *(nat_ip + 1), *(nat_ip + 2),*(nat_ip + 3));
    return NF_ACCEPT;
  }else{
    printk("Not NAT this ip\n");
    return NF_ACCEPT;
  }
}
/* Initialisation routine */
int init_module()
{
  /* Fill in our hook structure */
  nfho.hook     = hook_func;         /* Handler function */
  nfho.hooknum  = NF_INET_PRE_ROUTING; /* First hook for IPv4 */
  nfho.pf       = PF_INET;
  nfho.priority = NF_IP_PRI_FIRST;   /* Make our function first */
  nf_register_hook(&nfho);
  pr_info("simpNat install into kernel!\n");
  return 0;
}
/* Cleanup routine */
void cleanup_module()
{
  nf_unregister_hook(&nfho);
  pr_info("simpNat removed from kernel!\n");
}


2、Makefile:

obj-m +=simpNat.o
all:
 make -C /lib/modules/`uname -r`/build M=`pwd`
clean:
 make -C /lib/modules/`uname -r`/build M=`pwd` clean
install:
 /sbin/insmod simpNat.ko
remove:
 /sbin/rmmod simpNat

上一篇:linux内核netfilter实现url重定向
下一篇:Netlink 内核和用户消息传送