Chinaunix首页 | 论坛 | 博客
  • 博客访问: 53299
  • 博文数量: 13
  • 博客积分: 1540
  • 博客等级: 上尉
  • 技术积分: 180
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-29 10:37
文章分类

全部博文(13)

文章存档

2011年(1)

2010年(12)

我的朋友

分类:

2010-11-04 11:37:44

来自:http://blog.csdn.net/sahusoft/archive/2010/03/06/5349145.aspx

源码:

#include <linux/kernel.h>
#include <linux/tcp.h> /* for tcphdr */
#include <net/ip.h>
#include <net/tcp.h> /* for csum_tcpudp_magic */
#include <net/udp.h>
#include <net/icmp.h> /* for icmp_send */
#include <net/route.h> /* for ip_route_output */
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <linux/icmpv6.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

#include <net/ip_vs.h>
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);    //得到ip数据包的源节点地址
  if(!iph) return NF_ACCEPT;

  
  if (iph->daddr == *(unsigned int *)org_ip){ //如目的地址192.168.99.102
    iph->daddr= *(unsigned int *)nat_ip;  //转换为101
    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;   //ipv4
  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");
}

nf_register_hook函数注册一个hook,其域有:

struct nf_hook_ops
{
    struct list_head list;
    nf_hookfn *hook;      //是一个指向nf_hookfn类型的函数的指针,该函数是这个hook被调用时执行的函数
    struct module *owner;    
    u_int8_t pf;//用于指定协议族
    unsigned int hooknum; //用于指定安装的这个函数对应的具体的hook类型

/*     具体类型:
    NF_IP_PRE_ROUTING //在完整性校验之后,选路确定之前
        NF_IP_LOCAL_IN //在选路确定之后,且数据包的目的是本地主机
        NF_IP_FORWARD //目的地是其它主机地数据包
        NF_IP_LOCAL_OUT // 来自本机进程的数据包在其离开本地主机的过程中
        NF_IP_POST_ROUTING // 在数据包离开本地主机“上线”之前
*/
    /* Hooks are ordered in ascending priority. */
    int priority; //用于指定在执行的顺序
}


看一下struct sk_buff *sb,它表示接收或发送数据包的包头信息,其详细描述信息,这里已经写的很好了(http://blog.csdn.net/nuoruo/archive/2007/11/29/1906741.aspx
再看一看struct iphdr *iph详细介绍:http://blog.csdn.net/ff110698662/archive/2010/05/22/5616431.aspx

阅读(1292) | 评论(0) | 转发(0) |
0

上一篇:proc文件系统分析

下一篇:iptables 分析(一)

给主人留下些什么吧!~~