Chinaunix首页 | 论坛 | 博客
  • 博客访问: 85489
  • 博文数量: 14
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 153
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-13 11:26
文章分类

全部博文(14)

文章存档

2015年(2)

2014年(7)

2013年(5)

我的朋友

分类: LINUX

2015-08-01 23:29:05

/* Light-weight Fire Wall. Simple firewall utility based on
* Netfilter for 2.4. Designed for educational purposes.
*  
* Written by bioforge  -  March 2003.
*/
 
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
 
#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/slab.h>
#include <linux/cdev.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/errno.h>
#include <asm/uaccess.h>
#include "lwfw.h"
/* 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);
 
static int major = 0;               /* Control device major number */
 
/* 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
*/
static struct cdev lwfwcdev;
struct file_operations  lwfw_fops = {
     .ioctl = lwfw_ioctl,
     .open = lwfw_open,
     .release = lwfw_release,
     NULL                   /* Will be NULL'ed from here... */
};
MODULE_AUTHOR("bioforge");
MODULE_DESCRIPTION("Light-Weight Firewall for Linux 2.6.32");
/*
* 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;
    
   /* If LWFW is not currently active, immediately return ACCEPT */
   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)  
   {
      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)
{
   long retval;
   NULL_CHECK(statbuff);
   retval = copy_to_user(statbuff, &lwfw_statistics,
        sizeof(struct lwfw_stats));   
   printk("copy stats success!\n");
   return 0;
}
 
/* Function that compares a received TCP packet's destination port
* with the port specified in the Port Deny Rule. If a processing
* error occurs, NF_ACCEPT will be returned so that the packet is
* not lost. */
static int check_tcp_packet(struct sk_buff *skb)
{
   /* Seperately defined pointers to header structures are used
    * to access the TCP fields because it seems that the so-called
    * transport header from skb is the same as its network header TCP packets.
    * If you don't believe me then print the addresses of skb->nh.iph
    * and skb->h.th.  
    * It would have been nicer if the network header only was IP and
    * the transport header was TCP but what can you do? */
   struct tcphdr *thead;
   struct iphdr *iph;
    
   /* We don't want any NULL pointers in the chain to the TCP header. */
   if (!skb ) return NF_ACCEPT;
   iph = ip_hdr(skb);
   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->source) == deny_port) {
      /* Update statistics */
      lwfw_statistics.total_dropped++;
      lwfw_statistics.tcp_dropped++;  
      return NF_DROP;
   }
   return NF_ACCEPT;
}
/* Function that compares a received IPv4 packet's source address
* with the address specified in the IP Deny Rule. If a processing
* error occurs, NF_ACCEPT will be returned so that the packet is
* not lost. */
static int check_ip_packet(struct sk_buff *skb)
{
    struct iphdr *iph;
   /* We don't want any NULL pointers in the chain to the IP header. */
   if (!skb ) return NF_ACCEPT;
   iph = ip_hdr(skb);
   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;
   }
   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 {
      try_module_get(lwfwcdev.owner);
      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;
   module_put(lwfwcdev.owner);
   return 0;
}
/*********************************************/
/*
* Module initialisation and cleanup follow...
*/
int init_module()
{
    int retval;
    dev_t dev = 0;
    dev = MKDEV(LWFW_MAJOR, 0);
    retval = register_chrdev_region(dev, 1, LWFW_NAME);
    if (retval) return retval;
 
    cdev_init(&lwfwcdev, &lwfw_fops);
    retval = cdev_add(&lwfwcdev, dev, 1);
    if (retval) return retval;
 
    printk("register char device with (%d,%d)\n",major, LWFW_MAJOR);  
   /* Make sure the usage marker for the control device is cleared */
   lwfw_ctrl_in_use ^= lwfw_ctrl_in_use;
   printk("\nLWFW: Control device successfully registered.\n");  
   /* Now register the network hooks */
   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 */
   /* And register... */
   nf_register_hook(&nfkiller);
   printk("LWFW: Network hooks successfully installed.\n");
   printk("LWFW: Module installation successful.\n");
   return 0;
}
void cleanup_module()
{
   dev_t devno;
   /* Remove IPV4 hook */
   nf_unregister_hook(&nfkiller);
 
   /* Now unregister control device */
    devno = MKDEV(LWFW_MAJOR, 0);
    cdev_del(&lwfwcdev);   
    unregister_chrdev_region(devno, 1);
 
   /* 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_LICENSE("GPL");



######################################################################################################
/*
lwfw.h
* Include file for the Light-weight Fire Wall LKM.
*  
* A very simple Netfilter module that drops backets based on either
* their incoming interface or source IP address.
*  
* Written by bioforge  -  March 2003
* Commented by duanjigang - jule 2006
*/
#ifndef __LWFW_INCLUDE__
# define __LWFW_INCLUDE__
/* NOTE: The LWFW_MAJOR symbol is only made available for kernel code.
* Userspace code has no business knowing about it. */
# define LWFW_NAME        "lwfw"  
/* Version of LWFW */
# define LWFW_VERS        0x0001       /* 0.1 */
/* Definition of the LWFW_TALKATIVE symbol controls whether LWFW will
* print anything with printk(). This is included for debugging purposes.
*/
#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
/* Statistics structure for LWFW.
* Note that whenever a rule's condition is changed the related
* xxx_dropped field is reset.
*/
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       100   /* 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

########################################################################################################
obj-m := lwfw.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean


############################################################################################################
/*
Name: test.c
Author: duanjigang<duanjigang1983@gmail.com>
Date: 2006-5-15
*/
#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"
main()
{
        int fd;
        int i;
        struct lwfw_stats data;
        int retval;
        char msg[128];
        char * deny_ip = "123.125.114.144";
        char *ifcfg = "eth0";
        unsigned char *  port = "\x00\x50";
        fd = open("/dev/lwfw", O_RDWR);
        if(fd == -1)
    {
          perror("open fail!");
          exit(-1);
        }
        if( ioctl(fd,LWFW_ACTIVATE,0) == -1 )
        {
             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);
         }
while (1) {
        sleep(1);
        if( ioctl(fd, LWFW_GET_STATS,(unsigned long)&data) == -1)
         {
            printf("iotcl LWFW_GET_STATS fail!\n");
            exit(-1);
         }
        /*
       if(ioctl(fd, LWFW_DENY_IF, (unsigned*)ifcfg) == -1)
         {
               printf("ioctl LWFW_DENY_IF fail!\n");
               exit(-1);
         }
         */
         printf("ip dropped : %d\n", data.ip_dropped);
         printf("if dropped : %d\n", data.if_dropped);
         printf("tcp dropped : %d\n", data.tcp_dropped);
         printf("total dropped : %d\n", data.total_dropped);
         printf("total seen: %d\n", data.total_seen);
}
        close(fd);
}

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

上一篇:ffmpeg 和 libav的故事

下一篇:ubuntu 14.04 setup

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