Linux防火墙程序设计(2)

  下面给出一个简单防火墙程序。在这里假设读者对以太协议、IP协议、TCP协议等常用协议有一定的了解。用命令行"gcc -Wall -O2 -c MyFirewall.c"进行编译,再用insmod命令加载程序后,系统将只响应外部网络用TCP协议的80端口所进行的访问。要让系统恢复原有功能,则可用rmmod命令卸载该程序,源代码见网站上的同名文章。

  // MyFirewall.c 2000年3月7日编写

  #ifndef __KERNEL__

  # define __KERNEL__ //按内核模块编译

  #endif

  #ifndef MODULE

  # define MODULE //按设备驱动程序模块编译

  #endif

  #include <linux/module.h> //最基本的内核模块头文件

  #include <linux/sched.h>

  #include <linux/kernel.h> //最基本的内核模块头文件

  #include <linux/netdevice.h>

  #include <linux/ip.h>

  #include <linux/tcp.h>

  #include <linux/skbuff.h>

  #include <linux/proc_fs.h>

  #include <linux/if.h>

  #include <linux/in.h>

  #include <linux/firewall.h>

  #define SOL_ICMP 1

  #define PERMIT_PORT 80 //只允许访问TCP的80端口

  int zzl_input(struct firewall_ops *this,int pf,struct device *dev,

  void *phdr,void *arg,struct sk_buff **pskb)

  {//每当收到一个网络报时,此函数将被内核调用

  struct tcphdr *tcph; //TCP的头指针

  struct iphdr *iph; //IP头指针

  struct sk_buff *skb=*pskb;

  if (skb->protocol==htons(ETH_P_ARP)){

  printk(" Permit a ARP Packet");

  return FW_ACCEPT;//允许地址解析协议报

  }

  if(skb->protocol==htons(ETH_P_RARP)){

  printk(" Permit a RARP Packet");

  return FW_ACCEPT;//允许反向地址解析协议报

  }

  if(skb->protocol==htons(ETH_P_IP))

  {

  iph=skb->nh.iph;

  if (iph->protocol==SOL_ICMP)

  {

  printk(" Permit a ICMP Packet");

  return FW_ACCEPT;//允许网络控制报

  }

  if(iph->protocol==SOL_TCP){

  tcph=skb->h.th;

  if(tcph->dest==PERMIT_PORT){

  printk(" Permit a valid access");

  return FW_ACCEPT;//允许对TCP端口80的访问

  }

  }

  }

  return FW_REJECT;//禁止对本计算机的所有其它访问

  }

  int zzl_output(struct firewall_ops *this,int pf,struct device *dev,

  void *phdr,void *arg,struct sk_buff **pskb)

  {//程序编写方法同zzl_input函数模块

  printk(" zzl_output is called ");

  return FW_SKIP;

  }

  int zzl_foreward(struct firewall_ops *this,int pf,struct device *dev,

  void *phdr,void *arg,struct sk_buff **pskb)

  {//程序编写方法同zzl_input函数模块

  printk(" zzl_foreward is called ");

  return FW_SKIP;

  }

  struct firewall_ops zzl_ops=

  {

  NULL,

  zzl_foreward,

  zzl_input,

  zzl_output,

  PF_INET,

  01

  };

  int init_module(void)

  {

  if(register_firewall(PF_INET,&zzl_ops)!=0)

  {

  printk(" unable register firewall");

  return -1;

  }

  printk(" zzl_ops=%p",&zzl_ops);

  return 0;

  }

  void cleanup_module(void)

  {

  printk("unload ");

  unregister_firewall(PF_INET,&zzl_ops);

  }

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzwysf.html