请大家帮帮忙,一个对我很重要的问题
我最近一直在做一个netfilter的防火墙,下面是代码
firewall.c:
#include <linux/kernel.h>
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/tcp.h>
#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,4,9)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX@hotmail.com");
#endif
static int in_use=0;
static int major=0;
static unsigned int deny_ip[1000]; /* 被拒绝的IP列表 */
static unsigned int deny_port[1000]; /* 被拒绝的port列表 */
unsigned int current_deny_ip=0; /* 当前有多少个被拒绝的IP列表 */
unsigned int current_deny_port=0; /* 当前有多少个被拒绝的port列表 */
static int add_ip(unsigned int ip); /* 增加一个IP到列表 */
static int release_ip(unsigned int ip); /* 取消列表中的一个IP */
static void list_current_deny_ip(); /* 打印当前被拒绝的IP列表 */
static int check_ip(struct sk_buff* sb); /* 检查IP的函数 */
static int add_port(unsigned int port); /* 增加一个port到列表 */
static int release_port(unsigned int port); /* 取消列表中的一个port */
static void list_current_deny_port(); /* 打印当前被拒绝的port列表 */
static int check_port(struct sk_buff* sb); /* 检查port的函数 */
static int fw_ioctl(struct inode*,struct file* file, /* 给fw_fops调用的函数 */
unsigned int cmd,unsigned long arg);
static int fw_open(struct inode* inode,struct file* file); /* 设备开启时调用的函数 */
static int fw_release(struct inode* inode,struct file* file); /* 设备关闭时调用的函数 */
unsigned int hook_func(unsigned int hooknum, /* hook_func,核心函数 */
struct sk_buff** skb,
const struct net_device* in,
const struct net_device* out,
int(*okfn)(struct sk_buff*));
/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;
/* 设备驱动接口 file_operations */
struct file_operations fw_fops={
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
fw_ioctl,
NULL,
fw_open,
NULL,
fw_release,
NULL
};
/* 增加一个IP到列表 */
static int add_ip(unsigned int ip)
{
int i;
for (i=0;i<current_deny_ip;++i)
{
if (ip==deny_ip[i])
{
return 0;
}
}
deny_ip[current_deny_ip++]=ip;
return 1;
}
/* 取消列表中的一个IP */
static int release_ip(unsigned int ip)
{
int i;
for (i=0;i<current_deny_ip;++i)
{
if (ip==deny_ip[i])
{
deny_ip[i]=deny_ip[--current_deny_ip];
return 1;
}
}
return 0;
}
/* 打印当前被拒绝的IP列表 */
static void list_current_deny_ip()
{
int i;
for (i=0;i<current_deny_ip;++i)
{
printk("Here are all of the deny ips\n");
printk("%d: %d.%d.%d.%d",i,deny_ip[i]&0x000000FF,
(deny_ip[i]&0x0000FF00)>>8,
(deny_ip[i]&0x00FF0000)>>16,
(deny_ip[i]&0xFF000000)>>24);
}
}
/* 检查IP的函数 */
static int check_ip(struct sk_buff* sb)
{
if(!sb) return NF_ACCEPT;
if(!(sb->nh.iph)) return NF_ACCEPT;
int i=0;
for (i=0;i<=current_deny_ip;++i)
{
if (sb->nh.iph->saddr==deny_ip[i])
{
return NF_DROP;
}
}
return NF_ACCEPT;
}
static int fw_open(struct inode* inode,struct file* file)
{
printk("open\n");
if (in_use)
{
return -EBUSY;
}
else
{
MOD_INC_USE_COUNT;
++in_use;
return 0;
}
return 0;
}
static int fw_release(struct inode* inode,struct file* file)
{
printk("release!\n");
in_use^=in_use;
MOD_DEC_USE_COUNT;
return 0;
}
static int fw_ioctl(struct inode* inode,struct file* file,
unsigned int cmd,unsigned long arg)
{
int ret=0;
printk("ioctl\n");
switch(cmd)
{
case 1:
{
add_ip((unsigned int)arg);
break;
}
case 2:
{
release_ip((unsigned int)arg);
break;
}
default:
ret=-EBADRQC;
}
return ret;
}
/* 注册的hook函数的实现 */
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;
/* check ip */
if (check_ip(sb)==NF_DROP)
{
return NF_DROP;
}
else
{
return NF_ACCEPT;
}
}
int init_module()
{
SET_MODULE_OWNER(&fw_fops);
if ((major=register_chrdev(241,"Firewall",&fw_fops))<0)
{
printk("\nFirewall: Failed registering control device!\n");
printk("Firewall: Module installation aborted\n");
return 0;
}
in_use^=in_use;
printk("\nFirewall: Control device successfully registered.\n");
/* 填充我们的hook数据结构 */
nfho.hook=hook_func; /* 处理函数 */
nfho.hooknum=NF_IP_PRE_ROUTING; /* 使用IPV4的第一个hook */
nfho.pf=PF_INET; /*IPV4*/
nfho.priority=NF_IP_PRI_FIRST; /* 让我们的函数首先执行 */
nf_register_hook(&nfho); /* 注册 */
return 0;
}
void cleanup_module()
{
nf_unregister_hook(&nfho); /* 注消 */
int ret;
if((ret=unregister_chrdev(241,"Firewall"))!=0)
{
printk("Firewall: Removal of module failed!\n");
}
printk("Firewall: Removal of module successfule\n");
}
第二个文件
用户接口
fwct.c
#include <asm/types.h>
#include <linux/netfilter.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/fs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
int main(int argc, char* argv[])
{
int f=open("/dev/fw",0);
argv++;
if (!strcmp(*argv,"addip"))
{
argv++;
ioctl(f,1,inet_addr(*argv));
}
if (!strcmp(*argv,"releaseip"))
{
argv++;
ioctl(f,2,inet_addr(*argv));
}
return 0;
}
现在问题是int f=open("/dev/fw",0);这行每次都返回-1.这个应该返回一个值的.
网上看了很多代码,都没有写这个的.我应该怎么改?