zoukankan      html  css  js  c++  java
  • VC++实现防火墙过滤


    所谓防火墙指的是一个由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共网之间的界面上构造的保护屏障.是一种获取安全性方法的形象说法,它是一种计算机硬件和软件的结合,使Internet与Intranet之间建立起一个安全网关(Security Gateway),从而保护内部网免受非法用户的侵入,防火墙主要由服务访问规则、验证工具、包过滤和应用网关4个部分组成,防火墙就是一个位于计算机和它所连接的网络之间的软件或硬件。该计算机流入流出的所有网络通信和数据包均要经过此防火墙。
      在网络中,所谓“防火墙”,是指一种将内部网和公众访问网(如Internet)分开的方法,它实际上是一种隔离技术。防火墙是在两个网络通讯时执行的一种访问控制尺度,它能允许你“同意”的人和数据进入你的网络,同时将你“不同意”的人和数据拒之门外,最大限度地阻止网络中的黑客来访问你的网络。换句话说,如果不通过防火墙,公司内部的人就无法访问Internet,Internet上的人也无法和公司内部的人进行通信。
     网络层防火墙
      网络层防火墙可视为一种 IP 封包过滤器,运作在底层的 TCP/IP 协议堆栈上。我们可以以枚举的方式,只允许符合特定规则的封包通过,其余的一概禁止穿越防火墙(病毒除外,防火墙不能防止病毒侵入)。这些规则通常可以经由管理员定义或修改,不过某些防火墙设备可能只能套用内置的规则。
      我们也能以另一种较宽松的角度来制定防火墙规则,只要封包不符合任何一项“否定规则”就予以放行。现在的操作系统及网络设备大多已内置防火墙功能。
      较新的防火墙能利用封包的多样属性来进行过滤,例如:来源 IP 地址、来源端口号、目的 IP 地址或端口号、服务类型(如 WWW 或是 FTP)。也能经由通信协议、TTL 值、来源的网域名称或网段...等属性来进行过滤。
      应用层防火墙
      应用层防火墙是在 TCP/IP 堆栈的“应用层”上运作,您使用浏览器时所产生的数据流或是使用 FTP 时的数据流都是属于这一层。应用层防火墙可以拦截进出某应用程序的所有封包,并且封锁其他的封包(通常是直接将封包丢弃)。理论上,这一类的防火墙可以完全阻绝外部的数据流进到受保护的机器里。
      防火墙借由监测所有的封包并找出不符规则的内容,可以防范电脑蠕虫或是木马程序的快速蔓延。不过就实现而言,这个方法既烦且杂(软件有千千百百种啊),所以大部分的防火墙都不会考虑以这种方法设计。
      XML 防火墙是一种新型态的应用层防火墙。
      根据侧重不同,可分为:包过滤型防火墙、应用层网关型防火墙、服务器型防火墙。
    我们来简单实现一个数据包防火墙,请见代码!




    #include "pcap.h"   
    /*  
    -----------------------------------------------------------------------------------------------------------------------  
    下面是以太网协议格式  
    -----------------------------------------------------------------------------------------------------------------------  
     */   
    struct ether_header   
    {   
        u_int8_t ether_dhost[6];   
        /* 目的以太网地址 */   
        u_int8_t ether_shost[6];   
        /* 源以太网地址 */   
        u_int16_t ether_type;   
        /* 以太网类型 */   
    };   
    /* 下面是IP地址格式 */   
    typedef u_int32_t in_addr_t;   
    struct in_addr   
    {   
        in_addr_t s_addr; /* 存放IP地址 */   
    };   
    /*  
    -----------------------------------------------------------------------------------------------------------------------  
    下面是ARP协议格式  
    -----------------------------------------------------------------------------------------------------------------------  
     */   
    struct arp_header   
    {   
        u_int16_t arp_hardware_type;   
        /* 硬件地址类型 */   
        u_int16_t arp_protocol_type;   
        /* 协议地址类型 */   
        u_int8_t arp_hardware_length;   
        /* 硬件地址长度 */   
        u_int8_t arp_protocol_length;   
        /* 协议地址长度 */   
        u_int16_t arp_operation_code;   
        /* 操作类型 */   
        u_int8_t arp_source_ethernet_address[6];   
        /* 源以太网地址 */   
        u_int8_t arp_source_ip_address[4];   
        /* 源IP地址 */   
        u_int8_t arp_destination_ethernet_address[6];   
        /* 目的以太网地址 */   
        u_int8_t arp_destination_ip_address[4];   
        /* 目的IP地址 */   
    };   
    /*  
    =======================================================================================================================  
    下面是实现ARP协议分析的函数定义  
    =======================================================================================================================  
     */   
    void arp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)   
    {   
        struct arp_header *arp_protocol;   
        /* ARP协议变量 */   
        u_short protocol_type;   
        /* 协议类型 */   
        u_short hardware_type;   
        /* 硬件类型 */   
        u_short operation_code;   
        /* 操作类型 */   
        u_char *mac_string;   
        /* 以太网地址 */   
        struct in_addr source_ip_address;   
        /* 源IP地址 */   
        struct in_addr destination_ip_address;   
        /* 目的IP地址 */   
        u_char hardware_length;   
        /* 硬件地址长度 */   
        u_char protocol_length;   
        /* 协议地址长度 */   
        printf("--------   ARP Protocol (Network Layer)    --------\n");   
        arp_protocol = (struct arp_header*)(packet_content + 14);   
        /*  
         * 获得ARP协议数据。注意在这里要跳过以太网数据部分,它的长度刚好是14,所以在这里加上14,是指针跳过14个字节  
         */   
        hardware_type = ntohs(arp_protocol->arp_hardware_type);   
        /* 获得硬件类型 */   
        protocol_type = ntohs(arp_protocol->arp_protocol_type);   
        /* 获得协议类型 */   
        operation_code = ntohs(arp_protocol->arp_operation_code);   
        /* 获得操作码 */   
        hardware_length = arp_protocol->arp_hardware_length;   
        /* 获得硬件地址长度 */   
        protocol_length = arp_protocol->arp_protocol_length;   
        /* 获得协议地址长度 */   
        printf("ARP Hardware Type:%d\n", hardware_type);   
        printf("ARP Protocol Type:%d\n", protocol_type);   
        printf("ARP Hardware Length:%d\n", hardware_length);   
        printf("ARP Protocol Length:%d\n", protocol_length);   
        printf("ARP Operation:%d\n", operation_code);   
        switch (operation_code) /* 根据操作码进行判断是ARP什么类型协议 */   
        {   
            case 1:   
                printf("ARP Request Protocol\n");   
                break;   
                /* 是ARP查询协议 */   
            case 2:   
                printf("ARP Reply Protocol\n");   
                break;   
                /* 是ARP应答协议 */   
            case 3:   
                printf("RARP Request Protocol\n");   
                break;   
                /* 是RARP查询协议 */   
            case 4:   
                printf("RARP Reply Protocol\n");   
                break;   
                /* 是RARP应答协议 */   
            default:   
                break;   
        }   
        printf("Ethernet Source Address is : \n");   
        mac_string = arp_protocol->arp_source_ethernet_address;   
        printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));   
        /* 获得源以太网地址 */   
        memcpy((void*) &source_ip_address, (void*) &arp_protocol->arp_source_ip_address, sizeof(struct in_addr));   
        printf("Source IP Address:%s\n", inet_ntoa(source_ip_address));   
        /* 获得源IP地址 */   
        printf("Ethernet Destination Address is : \n");   
        mac_string = arp_protocol->arp_destination_ethernet_address;   
        printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));   
        /* 获得目的以太网地址 */   
        memcpy((void*) &destination_ip_address, (void*) &arp_protocol->arp_destination_ip_address, sizeof(struct in_addr));   
        printf("Destination IP Address:%s\n", inet_ntoa(destination_ip_address));   
        /* 获得目的IP地址 */   
    }   
    /*  
    =======================================================================================================================  
    下面是回调函数,实现以太网协议分析  
    =======================================================================================================================  
     */   
    void ethernet_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)   
    {   
        u_short ethernet_type;   
        /* 以太网类型 */   
        struct ether_header *ethernet_protocol;   
        /* 以太网协议变量 */   
        u_char *mac_string;   
        /* 以太网地址 */   
        static int packet_number = 1;   
        printf("**************************************************\n");   
        printf("The %d  ARP  packet is captured.\n", packet_number);   
        printf("--------   Ehternet Protocol (Link Layer)    --------\n");   
        ethernet_protocol = (struct ether_header*)packet_content;   
        /* 获得以太网协议数据 */   
        printf("Ethernet type is :\n");   
        ethernet_type = ntohs(ethernet_protocol->ether_type);   
        /* 获得以太网类型 */   
        printf("%04x\n", ethernet_type);   
        switch (ethernet_type) /* 根据以太网类型判断上层协议类型 */   
        {   
            case 0x0800:   
                printf("The network layer is IP protocol\n");   
                break;   
            case 0x0806:   
                printf("The network layer is ARP protocol\n");   
                break;   
            case 0x8035:   
                printf("The network layer is RARP protocol\n");   
                break;   
            default:   
                break;   
        }   
        printf("Mac Source Address is : \n");   
        mac_string = ethernet_protocol->ether_shost;   
        printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));   
        /* 获得源以太网地址 */   
        printf("Mac Destination Address is : \n");   
        mac_string = ethernet_protocol->ether_dhost;   
        printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));   
        /* 获得目的以太网地址 */   
        switch (ethernet_type)   
        {   
            case 0x0806:   
                arp_protocol_packet_callback(argument, packet_header, packet_content);   
                break;   
                /*  
                 * 如果以太网类型是0x0806,表示上层协议是ARP协议,应该调用分析ARP协议的函数。注意此时的参数传递,全部是回调函数的参数,它代表的是同一个网络数据包,所以在这里,既分析此数据包的以太网协议部分,又分析来了此数据包的ARP协议部分。  
                 */   
            default:   
                break;   
        }   
        printf("**************************************************\n");   
        packet_number++;   
    }   
    void main()   
    {   
        pcap_t *pcap_handle;   
        /* Libpcap句柄 */   
        char error_content[PCAP_ERRBUF_SIZE];   
        /* 错误信息 */   
        char *net_interface;   
        /* 网路接口 */   
        struct bpf_program bpf_filter;   
        /* bpf过滤规则 */   
        char bpf_filter_string[] = "arp";   
        /* 过滤规则字符串,这里表示本程序只是捕获所有ARP协议的网络数据包 */   
        bpf_u_int32 net_mask;   
        /* 网络掩码 */   
        bpf_u_int32 net_ip;   
        /* 网络地址 */   
        net_interface = pcap_lookupdev(error_content);   
        /* 获得网络接口 */   
        pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);   
        /* 获得网络地址和网络掩码 */   
        pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);   
        /* 打开网路接口 */   
        pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);   
        /* 编译过滤规则 */   
        pcap_setfilter(pcap_handle, &bpf_filter);   
        /* 设置过滤规则 */   
        if (pcap_datalink(pcap_handle) != DLT_EN10MB)   
            return ;   
        pcap_loop(pcap_handle,  - 1, ethernet_protocol_packet_callback, NULL);   
        /* 注册回到函数,循环捕获数据包 */   
        pcap_close(pcap_handle);   
        /* 关闭Libpcap操作 */   
    }   


  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/new0801/p/6177680.html
Copyright © 2011-2022 走看看