?? firewall.c
字號(hào):
/* 基于netfilter包過(guò)濾防火墻 *//* 作者: 胡辛遙 *//* 作者: 胡辛遙 *//* Data: 2004.11.23 *//* Version: 1.01 *//* Email: MontagueHu@Hotmail .com */ #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");#endifconst int DEV_NUMBER=100; /* 設(shè)備號(hào), 用來(lái)mknod */const int FTP_PORT=5376; /* 設(shè)默認(rèn)端口號(hào)碼為21 */static int in_use=0;static int major=0; /*用來(lái)判定注冊(cè)設(shè)備是否成功 */static unsigned int defaultFTPPort; /* 用戶設(shè)置的FTP端口, 默認(rèn)21 */static unsigned int deny_ip[1000]; /* 被拒絕的IP列表 */static unsigned int deny_port[1000]; /* 被拒絕的port列表 */static unsigned int deny_ftp_ip[1000]; /* 被FTP拒絕的IP列表 */unsigned int current_deny_ip=0; /* 當(dāng)前有多少個(gè)被拒絕的IP列表 */unsigned int current_deny_port=0; /* 當(dāng)前有多少個(gè)被拒絕的port列表 */unsigned int current_deny_ftp_ip=0; /* 當(dāng)前有多少個(gè)被FTP拒絕的IP列表 *//* IP */static int add_ip(unsigned int ip); /* 增加一個(gè)IP到列表 */ static int release_ip(unsigned int ip); /* 取消列表中的一個(gè)IP */static int check_ip(struct sk_buff* sb); /* 檢查IP的函數(shù) */static void show_current_ip_list(); /* 顯示當(dāng)前的IP列表 *//* port */static int add_port(unsigned int port); /* 增加一個(gè)port到列表 */static int release_port(unsigned int port); /* 取消列表中的一個(gè)port */static int check_port(struct sk_buff* sb); /* 檢查port的函數(shù) */static void show_current_port_list(); /* 顯示當(dāng)前的port列表 *//* ftp */static int add_ftp_ip(unsigned int ip); /* 增加一個(gè)IP到FTP列表 */static int release_ftp_ip(unsigned int ip); /* 取消FTP列表中的一個(gè)IP */static int check_ftp_ip(struct sk_buff* sb); /* 檢查FTP的函數(shù) */static void show_current_ftp_ip_list(); /* 顯示當(dāng)前的FTP拒絕列表 */static void show_current_ftp_port(); /* 顯示當(dāng)前的FTP端口 */static void set_ftp_port(unsigned int port); /* 改變默認(rèn)的FTP端口 *//* 其他 */static int fw_ioctl(struct inode*,struct file* file, /* 給外部調(diào)用的函數(shù) */ unsigned int cmd,unsigned long arg);static int fw_open(struct inode* inode,struct file* file); /* 設(shè)備開啟時(shí)調(diào)用的函數(shù) */static int fw_release(struct inode* inode,struct file* file); /* 設(shè)備關(guān)閉時(shí)調(diào)用的函數(shù) */unsigned int hook_func(unsigned int hooknum, /* 鉤子函數(shù),核心函數(shù) */ struct sk_buff** skb, const struct net_device* in, const struct net_device* out, int(*okfn)(struct sk_buff*));/* 用于注冊(cè)我們的函數(shù)的數(shù)據(jù)結(jié)構(gòu) */static struct nf_hook_ops nfho;/* 設(shè)備驅(qū)動(dòng)接口 file_operations */struct file_operations fw_fops={ NULL, NULL, NULL, NULL, NULL, NULL, fw_ioctl, NULL, fw_open, NULL, fw_release, NULL};/* 增加一個(gè)IP到列表 */static int add_ip(unsigned int ip){ printk("----------------------\n"); int i; for (i=0;i<current_deny_ip;++i) { if (ip==deny_ip[i]) { printk("This ip is already in the ip list\n"); return 0; } } deny_ip[current_deny_ip++]=ip; printk("Add ip %d.%d.%d.%d to the ip list successfully\n",ip&0x000000FF, (ip&0x0000FF00)>>8,(ip&0x00FF0000)>>16,(ip&0xFF000000)>>24); return 1;}/* 取消列表中的一個(gè)IP */static int release_ip(unsigned int ip){ printk("----------------------\n"); int i; for (i=0;i<current_deny_ip;++i) { if (ip==deny_ip[i]) { printk("Remove ip %d.%d.%d.%d from the ip list successfully\n",ip&0x000000FF, (ip&0x0000FF00)>>8,(ip&0x00FF0000)>>16, (ip&0xFF000000)>>24); deny_ip[i]=deny_ip[--current_deny_ip]; return 1; } } printk("This ip is not in the ip list\n"); return 0;}/* 顯示當(dāng)前的IP列表 */static void show_current_ip_list(){ printk("----------------------\n"); int i; printk("Here are the deny_ips!\nPlease check them!\n"); for (i=0;i<current_deny_ip;++i) { printk("%d: %d.%d.%d.%d\n",i+1, deny_ip[i]&0x000000FF,(deny_ip[i]&0x0000FF00)>>8, (deny_ip[i]&0x00FF0000)>>16,(deny_ip[i]&0xFF000000)>>24); }} /* 檢查IP的函數(shù) */static int check_ip(struct sk_buff* sb){ if(!sb) return NF_ACCEPT; if(!(sb->nh.iph)) return NF_ACCEPT; int i; for (i=0;i<current_deny_ip;++i) { if (sb->nh.iph->saddr==deny_ip[i]) { printk("Firewall: Dropped packet from IP: %d.%d.%d.%d\n", deny_ip[i]&0x000000FF,(deny_ip[i]&0x0000FF00)>>8, (deny_ip[i]&0x00FF0000)>>16,(deny_ip[i]&0xFF000000)>>24); return NF_DROP; } } return NF_ACCEPT;}/* 增加一個(gè)port到列表 */static int add_port(unsigned int port){ printk("----------------------\n"); int i; for (i=0;i<current_deny_port;++i) { if (port==deny_port[i]) { printk("This port is already in the port list\n"); return 0; } } printk("Add port %d to the port list successfully\n",((port&0xFF00)>>8|(port&0x00FF)<<8)); deny_port[current_deny_port++]=port; return 1;}/* 取消列表中的一個(gè)port */static int release_port(unsigned int port){ printk("----------------------\n"); int i; for (i=0;i<current_deny_port;++i) { if (port==deny_port[i]) { printk("Remove port %d from the port list successfully\n",((port&0xFF00)>>8|(port&0x00FF)<<8)); deny_port[i]=deny_port[--current_deny_port]; return 1; } } printk("This port is not in the port list\n"); return 0;}/* 顯示當(dāng)前的port列表 */static void show_current_port_list(){ printk("----------------------\n"); printk("Here are the deny_ports!\nPlease check them!\n"); int i; for (i=0;i<current_deny_port;++i) { printk("%d: %d\n",i+1, ((deny_port[i]&0xFF00)>>8|(deny_port[i]&0x00FF)<<8)); }}/* 檢查port的函數(shù) */static int check_port(struct sk_buff* sb){ if(!sb) return NF_ACCEPT; if(!(sb->nh.iph)) return NF_ACCEPT; struct tcphdr* thread=(struct tcphdr*)(sb->data+(sb->nh.iph->ihl*4)); int i; for (i=0;i<current_deny_port;++i) { if (thread->dest==deny_port[i]) { printk("Firewall: Dropped packet from TCP port: %d\n", ((deny_port[i]&0xFF00)>>8|(deny_port[i]&0x00FF)<<8)); return NF_DROP; } } return NF_ACCEPT;}/* 增加一個(gè)IP到FTP列表 */static int add_ftp_ip(unsigned int ip){ printk("----------------------\n"); int i; for (i=0;i<current_deny_ftp_ip;++i) { if (ip==deny_ftp_ip[i]) { printk("This ip is already in the ftp ip list\n"); return 0; } } deny_ftp_ip[current_deny_ftp_ip++]=ip; printk("Add ip %d.%d.%d.%d to the ftp ip list successfully\n",ip&0x000000FF, (ip&0x0000FF00)>>8,(ip&0x00FF0000)>>16,(ip&0xFF000000)>>24); return 1;}/* 取消FTP列表中的一個(gè)IP */static int release_ftp_ip(unsigned int ip){ printk("----------------------\n"); int i; for (i=0;i<current_deny_ftp_ip;++i) { if (ip==deny_ftp_ip[i]) { printk("Remove ip %d.%d.%d.%d from the ftp ip list successfully\n",ip&0x000000FF, (ip&0x0000FF00)>>8,(ip&0x00FF0000)>>16, (ip&0xFF000000)>>24); deny_ftp_ip[i]=deny_ftp_ip[--current_deny_ftp_ip]; return 1; } } printk("This ip is not in the ftp ip list\n"); return 0;}/* 檢查FTP的函數(shù) */static int check_ftp_ip(struct sk_buff* sb){ if(!sb) return NF_ACCEPT; if(!(sb->nh.iph)) return NF_ACCEPT; struct tcphdr* thread=(struct tcphdr*)(sb->data+(sb->nh.iph->ihl*4)); int i; for (i=0;i<current_deny_ftp_ip;++i) { if (thread->dest==defaultFTPPort && sb->nh.iph->saddr==deny_ftp_ip[i]) { printk("Firewall: Dropped packet from IP: %d.%d.%d.%d\n", deny_ftp_ip[i]&0x000000FF,(deny_ftp_ip[i]&0x0000FF00)>>8, (deny_ftp_ip[i]&0x00FF0000)>>16,(deny_ftp_ip[i]&0xFF000000)>>24); return NF_DROP; } } return NF_ACCEPT;}/* 顯示當(dāng)前的FTP拒絕列表 */static void show_current_ftp_ip_list(){ printk("----------------------\n"); int i; printk("Here are the deny_ftp_ips!\nPlease check them!\n"); for (i=0;i<current_deny_ftp_ip;++i) { printk("%d: %d.%d.%d.%d\n",i+1, deny_ftp_ip[i]&0x000000FF,(deny_ftp_ip[i]&0x0000FF00)>>8, (deny_ftp_ip[i]&0x00FF0000)>>16,(deny_ftp_ip[i]&0xFF000000)>>24); }}/* 改變默認(rèn)的FTP端口 */static void set_ftp_port(unsigned int port){ defaultFTPPort=port;}/* 顯示當(dāng)前的FTP端口 */static void show_current_ftp_port(){ printk("----------------------\n"); printk("The current ftp port is %d\n",((defaultFTPPort&0xFF00)>>8|(defaultFTPPort&0x00FF)<<8));}/* 設(shè)備開啟打開的函數(shù) */static int fw_open(struct inode* inode,struct file* file){ if (in_use) { return -EBUSY; } else { MOD_INC_USE_COUNT; ++in_use; } return 0;}/* 設(shè)備關(guān)閉打開的函數(shù) */static int fw_release(struct inode* inode,struct file* file){ in_use^=in_use; MOD_DEC_USE_COUNT; return 0;}/* 給外部調(diào)用的函數(shù),開給外部的接口 */static int fw_ioctl(struct inode* inode,struct file* file, unsigned int cmd,unsigned long arg){ int ret=0; switch(cmd) { case 1: { /* 增加一個(gè)IP到屏蔽列表 */ add_ip((unsigned int)arg); break; } case 2: { /* 釋放屏蔽列表中的一個(gè)IP */ release_ip((unsigned int)arg); break; } case 3: { /* 顯示當(dāng)前被屏蔽的IP列表 */ show_current_ip_list(); break; } case 4: { /* 增加一個(gè)端口到屏蔽列表 */ add_port((unsigned short)arg); break; } case 5: { /* 釋放屏蔽列表中的一個(gè)端口 */ release_port((unsigned short)arg); break; } case 6: { /* 顯示當(dāng)前被屏蔽的服務(wù)端的端口 */ show_current_port_list(); break; } case 7: { /* 增加一個(gè)IP到FTP屏蔽列表 */ add_ftp_ip((unsigned int)arg); break; } case 8: { /* 釋放FTP屏蔽列表中的一個(gè)IP */ release_ftp_ip((unsigned int)arg); break; } case 9: { /* 顯示FTP屏蔽列表 */ show_current_ftp_ip_list(); break; } case 10: { /* 顯示當(dāng)前設(shè)置的FTP端口 */ show_current_ftp_port(); break; } case 11: { /* 設(shè)置當(dāng)前的FTP端口, 默認(rèn)21 */ set_ftp_port((unsigned short)arg); break; } default: ret=-EBADRQC; } return ret;}/* 注冊(cè)的hook函數(shù)的實(shí)現(xiàn) */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; /* 檢查 ip */ if (check_ip(sb)==NF_DROP) { return NF_DROP; } else { /* 檢查 port */ if (check_port(sb)==NF_DROP) { return NF_DROP; } else { /* 檢查被FTP拒絕的IP列表 */ if (check_ftp_ip(sb)==NF_DROP) { return NF_DROP; } } } return NF_ACCEPT;}int init_module(){ SET_MODULE_OWNER(&fw_fops); /* 注冊(cè)這個(gè)設(shè)備 */ printk("----------------------\n"); if ((major=register_chrdev(DEV_NUMBER,"firewall",&fw_fops))<0) { /* 注冊(cè)設(shè)備失敗, 打印錯(cuò)誤消息, 返回 */ printk("Firewall: Failed registering control device!\n"); printk("Firewall: Module installation aborted\n"); return 0; } /* 注冊(cè)成功 */ in_use^=in_use; printk("Firewall: Control device successfully registered.\n"); printk("Author: MontagueHu.\n"); /* 填充我們的hook數(shù)據(jù)結(jié)構(gòu) */ nfho.hook=hook_func; /* 處理函數(shù) */ nfho.hooknum=NF_IP_PRE_ROUTING; /* 使用IPV4的第一個(gè)hook */ nfho.pf=PF_INET; /*IPV4*/ nfho.priority=NF_IP_PRI_FIRST; /* 讓我們的函數(shù)首先執(zhí)行 */ nf_register_hook(&nfho); /* 注冊(cè) */ /* 初始化FTP的端口 */ defaultFTPPort=FTP_PORT; return 0;}void cleanup_module(){ nf_unregister_hook(&nfho); /* 注消 */ int ret; printk("----------------------\n"); /* 注消設(shè)備 */ if((ret=unregister_chrdev(DEV_NUMBER,"firewall"))!=0) { /* 注消設(shè)備失敗 */ printk("Firewall: Removal of module failed!\n"); } /* 注消設(shè)備成功 */ printk("Firewall: Removal of module successfule\n");}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -