NF_ARP_IN、NF_ARP_ OUT和 NF_ARP _FORWARD

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>


#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_arp.h>
#include <linux/if_arp.h>
#include <net/arp.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/icmp.h>
#include <linux/spinlock.h>


#include <linux/timer.h>
#include <linux/list.h>
#include <linux/jiffies.h>


#include <linux/proc_fs.h>
#include <linux/sched.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("kenthy@163.com");


#define   ARP_OUT     0
#define   ARP_IN      1


#define    ARP_EXIST         0
#define    ARP_NOT_EXIST     1
  
typedef struct o_arp
 {
         struct list_head list;
        u32 dip;
        u32 sip;
        u16 arpop;
        int type; // in or out
 }O_ARP;


static LIST_HEAD(arplist);


static spinlock_t wa_lock = SPIN_LOCK_UNLOCKED;


static void ip_add(O_ARP* node)
{
        unsigned long flags;
        
  spin_lock_irqsave(&wa_lock, flags);
  list_add(&node->list,&arplist);
        spin_unlock_irqrestore(&wa_lock, flags);
}


/*return 1--exist    0---not exist
 * if exist then update it
 */
static int ip_exist(u32 sip, u32 dip, int type)
{
  struct list_head *p,*n;
        unsigned long flags;
  
  O_ARP* node;
  int exists= ARP_NOT_EXIST;
  
  spin_lock_irqsave(&wa_lock, flags);
        list_for_each_safe(p,n,&arplist)
   {
     node=list_entry(p, O_ARP, list);
           if(node->sip==sip && node->dip==dip && node->type==type)
      {
       exists=ARP_EXIST;
           break;
            }
         }
  
  spin_unlock_irqrestore(&wa_lock, flags);
  return (exists);
}


void free_list(void)
{
  struct list_head *p,*n;
  O_ARP *node;
        unsigned long flags;
  
  spin_lock_irqsave(&wa_lock, flags);
        list_for_each_safe(p,n,&arplist)
        {
    node=list_entry(p, O_ARP,list);
          list_del(&(node->list));
    kfree(node);
         }
  spin_unlock_irqrestore(&wa_lock, flags);                


}        
        
        
void skb_fun(struct sk_buff* skb, int flag)
{
        struct arphdr *arp;
        struct net_device * dev;
        unsigned char * arp_ptr;
        u32 sip,dip;
        unsigned short arpop;
        O_ARP* node = NULL;
        
        dev= skb->dev;
         arp = skb->nh.arph;
        arp_ptr= (unsigned char *)(arp+1);
        arp_ptr += dev->addr_len;
        memcpy(&sip, arp_ptr, 4);
         arp_ptr += 4;
        arp_ptr += dev->addr_len;
        memcpy(&dip, arp_ptr, 4);


        arpop=ntohs(arp->ar_op);


  if(ip_exist(sip, dip, ARP_IN) == ARP_NOT_EXIST)
   {
    node = kmalloc(sizeof(O_ARP),GFP_ATOMIC);
    if(node == NULL)
    {
     printk("%s\n", "kmalloc node error");
     return;        
            }
    node->sip=sip;
    node->dip=dip;
    node->arpop = arpop;
      node->type=flag;
    ip_add(node);
         }
}
        
unsigned int arphook_rcv(unsigned int hooknum,
                         struct sk_buff **skb,
                         const struct net_device *in, 
                         const struct net_device * out,
                         int (*okfn)(struct sk_buff*))
{
        skb_fun(*skb, ARP_IN);
        return NF_ACCEPT;
}


unsigned int arphook_snd(unsigned int hooknum,
                         struct sk_buff **skb,
                         const struct net_device *in, 
                         const struct net_device *out,
                         int (*okfn)(struct sk_buff*))
{
        skb_fun(*skb, ARP_OUT);
        return NF_ACCEPT;
}


static int arp_read(char *page, char **start, off_t off,int count, int *eof, void *data) 
{
  int len = 0;
  struct list_head *p,*n;
  O_ARP *node;
        unsigned long flags;
  
  spin_lock_irqsave(&wa_lock, flags);
        list_for_each_safe(p,n,&arplist)
        {
    node=list_entry(p, O_ARP,list);
          len += sprintf(page+len,NIPQUAD_FMT" "NIPQUAD_FMT" %s %s %lu\n",
                       NIPQUAD(node->sip),NIPQUAD(node->dip),
                       node->arpop==ARPOP_REQUEST?"ARPOP_REQUEST ":"ARPOP_REPLY", 
                       node->type==ARP_OUT?"OUT":"IN",
                       node->time_stamp);
   }
         
  spin_unlock_irqrestore(&wa_lock, flags);                
      
  if (len <= off+count) *eof = 1;
  *start = page + off;
  len -= off;
  if (len>count) len = count;
  if (len<0) len = 0;
  
  return len;
}


static struct nf_hook_ops arp_ops[] = {
        {
                .hook                = arphook_rcv,
                .owner                = THIS_MODULE,
                .pf                = NF_ARP,
                .hooknum        = NF_ARP_IN,
        },
        {
                .hook                = arphook_snd,
                .owner                = THIS_MODULE,
                .pf                = NF_ARP,
                .hooknum        = NF_ARP_OUT,
        },
};


static int __init init(void)
{
    int ret;
    struct proc_dir_entry *entry;


    ret = nf_register_hooks(arp_ops, ARRAY_SIZE(arp_ops));
    if (ret < 0) {
        printk("http detect:can't register arp_ops hook!\n");
        return ret;
    }
  
    entry = create_proc_entry("o_arp", 0444, &proc_root);
    if(entry == 0)
    {
        printk(KERN_ERR "create_proc_entry failed!\n");
        return -1;
    }
    entry->mode = S_IFREG | 0444;
    entry->size = 0;
    entry->read_proc = arp_read;


    printk("insmod arp_ops module\n");
    return 0;
}


static void __exit fini(void)
{
    nf_unregister_hooks(arp_ops, ARRAY_SIZE(arp_ops));
    free_list();
    remove_proc_entry("o_arp", &proc_root);
    printk("remove arp_ops hook.\n");
}




module_init(init);
module_exit(fini);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值