请大家帮帮忙,一个对我很重要的问题

minoriz 2004-11-21 07:57:07
我最近一直在做一个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.这个应该返回一个值的.
网上看了很多代码,都没有写这个的.我应该怎么改?
...全文
134 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
zdhzidy 2004-11-22
  • 打赏
  • 举报
回复
你打开文件的时候就会调用fw_open,
close的时候就会调用fw_release
你对设备发IOctl的时候就会调用fw_ioctl
fw_ioctl这个函数一般都是一些case语句,针对不同的IOCtl号来直接执行相应的控制功能。当然有些功能号是系统预先已经定义了的,最好不要和这些冲突。
zdhzidy 2004-11-22
  • 打赏
  • 举报
回复
建立设备文件可以到你要建立的目录下用mknode来创建设备文件。用法就自己man了:)
zdhzidy 2004-11-22
  • 打赏
  • 举报
回复
上面是处理错误的一些原则。
我看了一下你的代码,你的设备没有创建读函数。你用读的方式打开这个设备应该是打不开的,你试一试用O_NONBLOCK 标志来打开你的设备。

PS:这个问题你才给20分太小气了,瓦哈哈哈。
minoriz 2004-11-22
  • 打赏
  • 举报
回复
设备文件没有建立,我不知道下一步该怎么做
请大家指教
zdhzidy 2004-11-22
  • 打赏
  • 举报
回复
int f=open("/dev/fw",0);
这种编程习惯不好,最好用相应的宏来代替0这种magicnumber。

请检查:
1.你的设备文件创建了没有,是否有相应的操作权限。
2.你的设备是不是有相应的操作函数。
3.当你函数出错的时候请你,检查系统的错误代码,这样就可以知道返回-1的时候是什么具体的错误了。
沙沙的吹 2004-11-22
  • 打赏
  • 举报
回复
对防火墙不了解,只能帮你顶了
沙沙的吹 2004-11-22
  • 打赏
  • 举报
回复
file_operations 你没有给R/W函数,open的时候是不是可以用0来打开?
沙沙的吹 2004-11-22
  • 打赏
  • 举报
回复
dev/fw这个文件你建立了没有啊?
minoriz 2004-11-22
  • 打赏
  • 举报
回复
大家帮帮忙啊,着急中.........
minoriz 2004-11-22
  • 打赏
  • 举报
回复
希望你再教教我如何用mknode,我看了一些文章,脑子里面一片糊涂。
苦啊,要做那么多作业,还有图形学和数据库,啊……
minoriz 2004-11-22
  • 打赏
  • 举报
回复
我想说一下我现在对这个问题的理解,如果还有不对的地方,请zdhzidy指教。
我首先建立一个设备文件,把/dev/fw和我那个module里面的fw_ioctl联系起来,然后我在用户接口里面把f=open("/dev/fw",0)传给ioctl,系统就会自己去调用fw_ioctl?
大概是不是这样?

还有什么叫打开文件的时候fw_open,close的时候调用fw_release?在我这个程序里面它什么时候调用?当module被加载和卸载的时候?
minoriz 2004-11-21
  • 打赏
  • 举报
回复
给我一种感觉就是这个接口没有连接到fw_ioctl这个函数上面。
还有就是fw_open和fw_release什么时候被调用?fw_open这个函数好像根本就没有被调用过

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧