libipq动态防火墙的入门实验

实验要求如下:
 
   1.配置自己的网络,让虚拟机和主机能相互ping通,我使用的网络是,主机Vmnet8的ip为192.168.48.1,也就是windows的网络地址。因为我使用的是nat网络,vmware自动把本地连接映射成vmnet8,相当于路由器,然后虚拟机里的ip被自动分配为192.168.48.129,网络是通的。
    
   2.设置iptables过滤规则为:所有从主机发出的icmp包全部到自己编写的应用程序。
 
   3.编写应用程序,功能如下
        允许从主机出发,目的地址为192.168.48.129的包
        丢弃其他任何的icmp包
        出错时要进行错误处理,能够清理占用资源,退出程序
 
 
实验步骤如下:
    安装软件iptables,iptables-dev开发包,安装libnet1,libnetl-dev,其中iptables为linux下的早期防火墙,而libnet则是linux下构造数据包的工具,文档比较齐全,使用比较方便,linux下的的捕获数据包用libpcap,本实验中没有用到,建议真正想在linux下网络编程的人要使用libnet和libpcap。
    安装好工具后,就开时编程序了。

设置过滤环境

加载过滤需要的内核模块

          # modprobe iptable_filter

          # modprobe ip_queue

设置过滤规则

         iptables -A OUTPUT -p icmp -j QUEUE

编写应用程序:

程序框架

ipq_create_handle()

->ipq_set_mode()

->包过滤处理循环while(1){

->ipq_read()

->分析包ipq_message_type() ipq_get_packet()

->包处理ipq_set_verdict()

}

->ipq_destroy()

 

 

实验代码如下:

//test.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <linux/netfilter.h>
#include <libipq/libipq.h>

#include <libnet.h>
#define BUFSIZE 2048

static void die(struct ipq_handle *h)
{
 ipq_perror("passer");
 ipq_destroy_handle(h);
 exit(1);
}

int main(int argc, char **argv)
{
 int status;
 unsigned char buf[BUFSIZE];
 struct ipq_handle *h;
 char *ip_dst_s="192.168.48.1";
 h = ipq_create_handle(0, PF_INET);
 if (!h)
  die(h);
               
 status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
 if (status < 0)
  die(h);
               
 do{
  status = ipq_read(h, buf, BUFSIZE, 0);
  if (status < 0)
   die(h);
                       
  switch (ipq_message_type(buf)) {
   case NLMSG_ERROR:
    fprintf(stderr, "Received error message %d\n",
      ipq_get_msgerr(buf));
    break;
                               
   case IPQM_PACKET: {
    ipq_packet_msg_t *m = ipq_get_packet(buf);
    struct libnet_ipv4_hdr* iph;
    iph=(struct libnet_ipv4_hdr*)m->payload;
    if(m->data_len<20){
     fprintf(stderr, "ip header is too short\n");
     die(h);
    }

    char *dst = libnet_addr2name4(iph->ip_dst.s_addr, LIBNET_DONT_RESOLVE);
    
    if(!strcmp(dst, ip_dst_s)){
      status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
     printf("dst ip:%s state: accept\n", dst);
    }
    else{
     status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL);
     printf("dst ip:%s state: drop\n", dst);
    }
 
    if (status < 0)
     die(h);
    break;
   }
   default:
    fprintf(stderr, "Unknown message type!\n");
    break;
  }
 } while (1);

 ipq_destroy_handle(h);
 return 0;
}

 

至于实验结果就不帖了,读者想知道就自己编译一下测试测试

编译方法是:

gcc test.c -lipq -lnet

实验体会:

    很多软件都定义了一些相同的数据结构,但是名字不同,感觉这是一大缺陷,比如ip header,实验手册中给的是linux/ip.h 中的struct iphdrlibnetlibnet-headers.hstruct libnet_ipv4_hdrstruct libnet_ipv6_hdr,分析snort源码时,snort也定义了一个自己的typedef struct _IPHdr{…} IPHdr;,对同一数据结构进行了多次的不同的定义,明显感觉有的复用性没有达到,我选择了libnet_ipv4_hdr,因为手头有libnet的手册,查询比较方便。就应该开发一套通用的放到c语言规范里,这样可以避免大量的重复劳动,而且程序员也不需要有太大的负担

<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
阅读(740) | 评论(0) | 转发(0) |
0

上一篇:链表

下一篇:IO模式的选择

给主人留下些什么吧!~~
评论热议
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值