改lwfw轻量级防火墙,2.6.28上运行

原创 2011年01月18日 09:32:00

lwfw轻量级防火墙(改),kernel 2.6.28

    lwfw基本思想:注册设备驱动文件,实例化设备文件的相关操作,主要通过ioctl来控制用户传的ip,tcp,源接口名,实现从内核态匹配规则,达到filter功能。

/* lwfw.c */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>

#include <asm/uaccess.h>
#include <asm/errno.h>

#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/device.h>
#include "lwfw.h"

static struct cdev *cdev;
static dev_t devno;
struct class *my_class;
/* Local function prototypes */
static int set_if_rule(char *name);
static int set_ip_rule(unsigned int ip);
static int set_port_rule(unsigned short port);
static int check_ip_packet(struct sk_buff *skb);
static int check_tcp_packet(struct sk_buff *skb);
static int copy_stats(struct lwfw_stats *statbuff);

/* Some function prototypes to be used by lwfw_fops below. */
static int lwfw_ioctl(struct inode *inode, struct file *file,
              unsigned int cmd, unsigned long arg);
static int lwfw_open(struct inode *inode, struct file *file);
static int lwfw_release(struct inode *inode, struct file *file);

/* Various flags used by the module */
/* This flag makes sure that only one instance of the lwfw device
* can be in use at any one time. */

static int lwfw_ctrl_in_use = 0;
/* This flag marks whether LWFW should actually attempt rule checking.
* If this is zero then LWFW automatically allows all packets. */

static int active = 0;
  

/* Specifies options for the LWFW module */
static unsigned int lwfw_options = (LWFW_IF_DENY_ACTIVE
                    | LWFW_IP_DENY_ACTIVE
                    | LWFW_PORT_DENY_ACTIVE);

/* This struct will describe our hook procedure. */
struct nf_hook_ops nfkiller;

/* Module statistics structure */
static struct lwfw_stats lwfw_statistics = {0, 0, 0, 0, 0};

/* Actual rule 'definitions'. */
/* TODO: One day LWFW might actually support many simultaneous rules.
* Just as soon as I figure out the list_head mechanism... */

static char *deny_if = NULL; /* Interface to deny */
static unsigned int deny_ip = 0x00000000; /* IP address to deny */
static unsigned short deny_port = 0x0000; /* TCP port to deny */

/* 
* This is the interface device's file_operations structure
*/

struct file_operations lwfw_fops = {
  
     .ioctl=lwfw_ioctl,

     .open=lwfw_open,

     .release=lwfw_release,
                     
};



/*
* This is the function that will be called by the hook
*/

unsigned int lwfw_hookfn(unsigned int hooknum,
               struct sk_buff *skb,
               const struct net_device *in,
               const struct net_device *out,
               int (*okfn)(struct sk_buff *))
{
   unsigned int ret = NF_ACCEPT;
   printk("%x/n",deny_ip);
   if (!active)
     return NF_ACCEPT;
   
   lwfw_statistics.total_seen++;
   /* Check the interface rule first */
   if (deny_if && DENY_IF_ACTIVE) {
      if (strcmp(in->name, deny_if) == 0) { /* Deny this interface */
     lwfw_statistics.if_dropped++;
     lwfw_statistics.total_dropped++;
     return NF_DROP;
      }
   }
   
   /* Check the IP address rule */
   if (deny_ip && DENY_IP_ACTIVE) {
      printk("ip run../n");
      ret = check_ip_packet(skb);
      if (ret != NF_ACCEPT) return ret;
   }
   
   /* Finally, check the TCP port rule */
   if (deny_port && DENY_PORT_ACTIVE) {
      ret = check_tcp_packet(skb);
      if (ret != NF_ACCEPT) return ret;
   }
   
   return NF_ACCEPT; /* We are happy to keep the packet */
}

/* Function to copy the LWFW statistics to a userspace buffer */
static int copy_stats(struct lwfw_stats *statbuff)
{
   NULL_CHECK(statbuff);

// copy_to_user(statbuff, &lwfw_statistics,sizeof(struct lwfw_stats));

   
   return 0;
}


static int check_tcp_packet(struct sk_buff *skb)
{
   
   struct tcphdr *thead;
   struct iphdr *iph;

   iph = ip_hdr(skb);
   if (!skb ) return NF_ACCEPT;
   if (!(iph)) return NF_ACCEPT;

   /* Be sure this is a TCP packet first */
   if (iph->protocol != IPPROTO_TCP) {
      return NF_ACCEPT;
   }

   thead = (struct tcphdr *)(skb->data + (iph->ihl * 4));
   
   /* Now check the destination port */
   if ((thead->dest) == deny_port) {
      /* Update statistics */
      lwfw_statistics.total_dropped++;
      lwfw_statistics.tcp_dropped++;
      
      return NF_DROP;
   }
   
   return NF_ACCEPT;
}


static int check_ip_packet(struct sk_buff *skb)
{
   struct iphdr *iph;
   struct sk_buff *sb = skb;

   iph = ip_hdr(sb);
   /* We don't want any NULL pointers in the chain to the IP header. */
   if (!sb ) return NF_ACCEPT;
   if (!(iph)) return NF_ACCEPT;
   
   if (iph->saddr == deny_ip) {/* Matches the address. Barf. */
      lwfw_statistics.ip_dropped++; /* Update the statistics */
      lwfw_statistics.total_dropped++;
      return NF_DROP;
   }else
       return NF_ACCEPT;
}

static int set_if_rule(char *name)
{
   int ret = 0;
   char *if_dup; /* Duplicate interface */
   
   /* Make sure the name is non-null */
   NULL_CHECK(name);
   
   /* Free any previously saved interface name */
   if (deny_if) {
      kfree(deny_if);
      deny_if = NULL;
   }
   
   if ((if_dup = kmalloc(strlen((char *)name) + 1, GFP_KERNEL))
        == NULL) {
      ret = -ENOMEM;
   } else {
      memset(if_dup, 0x00, strlen((char *)name) + 1);
      memcpy(if_dup, (char *)name, strlen((char *)name));
   }

   deny_if = if_dup;
   lwfw_statistics.if_dropped = 0; /* Reset drop count for IF rule */
   printk("LWFW: Set to deny from interface: %s/n", deny_if);
   
   return ret;
}

static int set_ip_rule(unsigned int ip)
{
   deny_ip = ip;
   lwfw_statistics.ip_dropped = 0; /* Reset drop count for IP rule */
   
   printk("LWFW: Set to deny from IP address: %d.%d.%d.%d/n",
      ip & 0x000000FF, (ip & 0x0000FF00) >> 8,
      (ip & 0x00FF0000) >> 16, (ip & 0xFF000000) >> 24);
   
   return 0;
}

static int set_port_rule(unsigned short port)
{
   deny_port = port;
   lwfw_statistics.tcp_dropped = 0; /* Reset drop count for TCP rule */
   
   printk("LWFW: Set to deny for TCP port: %d/n",
      ((port & 0xFF00) >> 8 | (port & 0x00FF) << 8));
      
   return 0;
}

/*********************************************/
/* 
* File operations functions for control device
*/

static int lwfw_ioctl(struct inode *inode, struct file *file,
              unsigned int cmd, unsigned long arg)
{
   int ret = 0;
   
   switch (cmd) {
    case LWFW_GET_VERS:
      return LWFW_VERS;
    case LWFW_ACTIVATE: {
       active = 1;
       printk("LWFW: Activated./n");
       if (!deny_if && !deny_ip && !deny_port) {
      printk("LWFW: No deny options set./n");
       }
       break;
    }
    case LWFW_DEACTIVATE: {
       active ^= active;
       printk("LWFW: Deactivated./n");
       break;
    }
    case LWFW_GET_STATS: {
       ret = copy_stats((struct lwfw_stats *)arg);
       break;
    }
    case LWFW_DENY_IF: {
       ret = set_if_rule((char *)arg);
       break;
    }
    case LWFW_DENY_IP: {
       ret = set_ip_rule((unsigned int)arg);
       break;
    }
    case LWFW_DENY_PORT: {
       ret = set_port_rule((unsigned short)arg);
       break;
    }
    default:
      ret = -EBADRQC;
   };
   
   return ret;
}

/* Called whenever open() is called on the device file */
static int lwfw_open(struct inode *inode, struct file *file)
{
   if (lwfw_ctrl_in_use) {
      return -EBUSY;
   } else {
   // MOD_INC_USE_COUNT;

      lwfw_ctrl_in_use++;
      return 0;
   }
   return 0;
}

/* Called whenever close() is called on the device file */
static int lwfw_release(struct inode *inode, struct file *file)
{
   lwfw_ctrl_in_use ^= lwfw_ctrl_in_use;
 // MOD_DEC_USE_COUNT;

   return 0;
}

/*********************************************/
/*
* Module initialisation and cleanup follow...
*/

int lwfw_init(void)
{
   /* 注册设备 /dev/lwfw */

    cdev = cdev_alloc();    
    if(cdev == NULL)
        return -1;
    if(alloc_chrdev_region(&devno,0,10,"lwfw")){
    printk("register char dev error/n");
    return -1;
    }
    cdev_init(cdev,&lwfw_fops);
    if(cdev_add(cdev,devno,1))
    {
        printk("add the cedev error/n");
    }
    my_class = class_create(THIS_MODULE,"xmimx_class");
    if(IS_ERR(my_class))
    {
        printk("Err:failed in creating class./n");
        return -1;
    }
    device_create(my_class,NULL,devno,NULL,"lwfw"); 
   
   /* Make sure the usage marker for the control device is cleared */
   lwfw_ctrl_in_use ^= lwfw_ctrl_in_use;

//注册hook
   printk("LWFW: Control device successfully registered./n");
   nfkiller.hook = lwfw_hookfn; 
   nfkiller.hooknum = NF_INET_PRE_ROUTING; /* First stage hook */
   nfkiller.pf = PF_INET; /* IPV4 protocol hook */
   nfkiller.priority = NF_IP_PRI_FIRST; /* Hook to come first */
   
   nf_register_hook(&nfkiller);
   
// printk("LWFW: Network hooks successfully installed./n");

   
   printk("LWFW: Module installation successful./n");
   return 0;
}

void lwfw_exit(void)
{
   
   nf_unregister_hook(&nfkiller);

  unregister_chrdev_region(devno, 1);
  cdev_del(cdev);
  device_destroy(my_class,devno);
  class_destroy(my_class);
  printk("LWFW: Removal of module failed!/n");
   

   /* If anything was allocated for the deny rules, free it here */
   if (deny_if)
     kfree(deny_if);
   
   printk("LWFW: Removal of module successful./n");
}
module_init(lwfw_init);
module_exit(lwfw_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Linux 2.6.28");

  

/* lwfw.h */

#ifndef __LWFW_INCLUDE__
# define __LWFW_INCLUDE__

/* Version of LWFW */
# define LWFW_VERS 0x0002 /* 0.2 */

#define LWFW_TALKATIVE

/* These are the IOCTL codes used for the control device */
#define LWFW_CTRL_SET 0xFEED0000 /* The 0xFEED... prefix is arbitrary */
#define LWFW_GET_VERS 0xFEED0001 /* Get the version of LWFM */
#define LWFW_ACTIVATE 0xFEED0002
#define LWFW_DEACTIVATE 0xFEED0003
#define LWFW_GET_STATS 0xFEED0004
#define LWFW_DENY_IF 0xFEED0005
#define LWFW_DENY_IP 0xFEED0006
#define LWFW_DENY_PORT 0xFEED0007

/* Control flags/Options */
#define LWFW_IF_DENY_ACTIVE 0x00000001
#define LWFW_IP_DENY_ACTIVE 0x00000002
#define LWFW_PORT_DENY_ACTIVE 0x00000004

struct lwfw_stats {
   unsigned int if_dropped; /* Packets dropped by interface rule */
   unsigned int ip_dropped; /* Packets dropped by IP addr. rule */
   unsigned int tcp_dropped; /* Packets dropped by TCP port rule */
   unsigned long total_dropped; /* Total packets dropped */
   unsigned long total_seen; /* Total packets seen by filter */
};

/* 
* From here on is used solely for the actual kernel module
*/

#ifdef __KERNEL__
# define LWFW_MAJOR 241 /* This exists in the experimental range */

/* This macro is used to prevent dereferencing of NULL pointers. If
* a pointer argument is NULL, this will return -EINVAL */

#define NULL_CHECK(ptr) /
   if ((ptr) == NULL) return -EINVAL

/* Macros for accessing options */
#define DENY_IF_ACTIVE (lwfw_options & LWFW_IF_DENY_ACTIVE)
#define DENY_IP_ACTIVE (lwfw_options & LWFW_IP_DENY_ACTIVE)
#define DENY_PORT_ACTIVE (lwfw_options & LWFW_PORT_DENY_ACTIVE)

#endif /* __KERNEL__ */
#endif


用户空间测试程序:

/* test */

#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<linux/rtc.h>
#include<linux/ioctl.h>
#include "lwfw.h"

int main(int argc,char *argv[])
{
        int fd,i,retval;
        struct lwfw_stats data;
        char msg[128];

char * deny_ip = "192.168.10.10";
char *ifcfg = "eth1";
unsigned char * port = "/x00/x16"; //22


fd = open("/dev/lwfw", O_RDONLY);
if(fd == -1)
{
          perror("open fail!");
          exit(-1);
}
if( ioctl(fd,LWFW_ACTIVATE,0) == -)
{
             perror("ioctl LWFW_ACTIVATE fail!/n");
             exit(-1);
}
if( ioctl(fd, LWFW_DENY_IP, inet_addr(deny_ip)) == -1)
         {
            printf("ioctl LWFW_DENY_IP fail/n"); 
            exit(-1); 
         }
if(ioctl(fd, LWFW_DENY_PORT, *(unsigned short *)port) == -1)
         {
           printf("ioctl LWFW_DENY_PORT fail!/n");
           exit(-1);
         }
if(ioctl(fd, LWFW_DENY_IF, (unsigned*)ifcfg) == -1)
         {
               printf("ioctl LWFW_DENY_IF fail!/n");
               exit(-1);
         }
 printf("set saddr,port,ifcfg seting ok./n");
         
         close(fd);
}


 

 

/*内核输出信息*/

root@sunxiuli-desktop:/home/oy/lwfw# dmesg 

[38114.824087] LWFW: Control device successfully registered.

[38114.838818] LWFW: Module installation successful.

[38118.281950] LWFW: Activated.

[38118.282013] LWFW: No deny options set.

[38118.282306] LWFW: Set to deny from IP address: 192.168.10.10

[38118.282361] LWFW: Set to deny for TCP port: 22

[38118.282560] LWFW: Set to deny from interface: eth1

[38191.276148] LWFW: Removal of module failed!

[38191.276239] LWFW: Removal of module successful.



 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

网络地址转换组件(Ipnat.sys)被使用 windows防火墙无法运行

网络地址转换组件(Ipnat.sys)被使用 windows防火墙无法运行 网络地址转换组件(Ipnat.sys)被使用 windows防火墙无法运行,我刚在服务器上装了window2003标准版,...

关闭SELinux及防火墙,设定运行级别

版本 Centos6.6 x86_641.关闭SELinuxSELinux是美国国家安全局对于强制访问控制的实现。[root@muban ~]# cat /etc/selinux/config 3个...

使用Mono打造轻量级的.NET程序运行时

在使用Mono让.NET程序跨平台运行这篇文章中,我们已经对Mono以及.NET程序的运行机制有了初步的理解。今天我想来谈谈”使用Mono打造轻量级的.NET运行时”这样一个话题。为什么我会有这样一种...

Flex:无缝安装AIR运行时在公司内网(防火墙)报下载失败的问题。

场景:       公司内网防火墙内,防火墙禁止了HTTPS,POST提交操作,允许GET提交,。现象:      按照之前的文章 【Flex:AIR程序加上自动更新功能 AIR项...

解决由于升级的Win10周年版本后Oracle VM VirtualBox无法运行导致的eNSP V390里面的路由器和防火墙等设备无法启动的问题(错误代码40)

解决由于升级的Win10周年版本后Oracle VM VirtualBox无法运行导致的eNSP V390里面的路由器和防火墙等设备无法启动的问题(错误代码40) 前言:        由于本人更...

Windows 防火墙无法运行 "由于另一个程序或正在运行的服务可能正在使用网络地址转换组件"

今天客户的服务器,客户自己安装了个u-mail 邮件服务器软件.重启系统后.就远程不了服务器.也ping不通了.手动重启系统也没用.只好机房.本地登陆进去..右击网上邻居--属性---窗口打开后.什么...

linux-2.6.28-AT45db081 驱动

Linux内核 2.6.28 和 2.6.29 版本中的新特性

介绍 2.6.28 和 2.6.29 版本中的新特性。生命的必然不仅包括死亡和纳税,还包括 GNU/Linux® 操作系统的发展,最新的两个内核发布的确没有让人失望。2.6.28 和 2.6.29 版...

linux-2.6.28 内核

  • 2013-05-06 20:29
  • 51.17MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)