网络数据包过滤_04_Z_应用层驱动层

1、驱动层:

  1.1、netfilter_hook.c

/**
 * @file netfilter_hook.c
 */

#include <linux/module.h>
#include <linux/kernel.h>

#include <linux/ip.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_arp.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("yuuyuu");
MODULE_DESCRIPTION("netfilter");
MODULE_VERSION("1.0");


#define printk_ip(info, be32_addr) \
    printk("%s %d.%d.%d.%d\n", \
    info, \
    ((unsigned char *)&(be32_addr))[0], \
    ((unsigned char *)&(be32_addr))[1], \
    ((unsigned char *)&(be32_addr))[2], \
    ((unsigned char *)&(be32_addr))[3])

int filter_ip(__be32 addr)
{
    unsigned char net_num = ((unsigned char *)&addr)[0];
    unsigned char host_num = ((unsigned char *)&addr)[3];
    if (net_num == 10 || host_num == 1 || host_num == 2)
        return 1;
    return 0;
}

int filter_src_dst_ip(__be32 s_addr, __be32 d_addr)
{
    int i = filter_ip(s_addr) && filter_ip(d_addr);
    return i;
}

unsigned int g_uiPktCntLow = 0;
unsigned int g_uiPktCntHigh = 0;
unsigned int g_uiPktLenLow = 0;
unsigned int g_uiPktLenHigh = 0;

/* NF_INET_PRE_ROUTING */
unsigned int pre_routing_hook(unsigned int hooknum, struct sk_buff *skb,
                                const struct net_device *in, const struct net_device *out,
                                int (*okfn)(struct sk_buff *))
{
//    unsigned char *puc = skb->head + skb->mac_header;
//    unsigned char *puc = &skb->head[(int)skb->mac_header];
//                 skb->head + skb->mac_header;

    unsigned char *pucMacHdr = skb_mac_header(skb);
    unsigned int ui12 = pucMacHdr[12];
    unsigned int ui13 = pucMacHdr[13];
    unsigned int ui14 = pucMacHdr[14];
    unsigned int uiVersion = (ui14 >> 4) & 0xF;
    unsigned int uiIpHdrLen = ui14 & 0xF;
    unsigned int uiOnePktLen = skb->len + skb->mac_len; // ZC: Bacause we filter ip packet,so the len is calculated from IpHeader??

    struct iphdr *ip_header;

    unsigned int uiPktCnt = g_uiPktCntLow;
    unsigned int uiPktLen = g_uiPktLenLow;
    g_uiPktCntLow ++;
    if (g_uiPktCntLow < uiPktCnt)
        g_uiPktCntHigh ++;
    g_uiPktLenLow += uiOnePktLen;
    if (g_uiPktLenLow < uiPktLen)
        g_uiPktLenHigh ++;

    ip_header = ip_hdr(skb);
//    if (filter_src_dst_ip(ip_header->saddr, ip_header->daddr))
    {
        unsigned char * pucIpSour = (unsigned char *)&ip_header->saddr;
        unsigned char * pucIpDest = (unsigned char *)&ip_header->daddr;

        //printk("pre_routing_hook()==================================\n");
        printk("%d-%d, %d-%d, (%d), [%02X, %02X], [%X, %X], [%d.%d.%d.%d --> %d.%d.%d.%d]\n",
            g_uiPktCntHigh, g_uiPktCntLow, g_uiPktLenHigh, g_uiPktLenLow, uiOnePktLen, ui12, ui13,
            uiVersion, uiIpHdrLen,
            pucIpSour[0],pucIpSour[1],pucIpSour[2],pucIpSour[3], pucIpDest[0],pucIpDest[1],pucIpDest[2],pucIpDest[3]);
    }
//*/
    return NF_ACCEPT;
}

struct nf_hook_ops pre_routing_ops =
{
    .hook = pre_routing_hook,
    .pf = PF_INET,
    .hooknum = NF_INET_PRE_ROUTING,
    .priority = NF_IP_PRI_FIRST
};



static int hook_init(void)
{
    printk("hook_init()======================\n");
    nf_register_hook(&pre_routing_ops);
//    nf_register_hook(&post_routing_ops);

    return 0;
}

static void hook_exit(void)
{
    printk("hook_exit()=====================\n");
    nf_unregister_hook(&pre_routing_ops);
//    nf_unregister_hook(&post_routing_ops);
}

module_init(hook_init);
module_exit(hook_exit);

  1.2、Makefile :

KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

obj-m := netfilter_hook.o

default:
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

 

2、应用层:

  2.1、main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>

#include <net/if.h>
#include <string.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

//#include <linux/ip.h>
#include <linux/sockios.h>

int main(int argc, char **argv)
{
    int sock, n;
    char buffer[2048];
    struct ethhdr *eth;
    struct iphdr *iph;

    if (0>(sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))))
    //if (0>(sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))))
    {
        perror("socket");
        exit(1);
    }

        struct ifreq ethreq;

        strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);
        if(-1 == ioctl(sock, SIOCGIFFLAGS, &ethreq))
        {
            perror("ioctl");
            close(sock);
            exit(1);
        }
        ethreq.ifr_flags |= IFF_PROMISC;
        if(-1 == ioctl(sock, SIOCGIFFLAGS, &ethreq))
        {
            perror("ioctl");
            close(sock);
            exit(1);
        }

    unsigned int g_uiPktCntLow = 0;
    unsigned int g_uiPktCntHigh = 0;
    unsigned int g_uiPktLenLow = 0;
    unsigned int g_uiPktLenHigh = 0;
    while (1)
    {
        //printf("=====================================\n");
        //注意:在这之前我没有调用bind函数,原因是什么呢?
        n = recvfrom(sock, buffer, 2048, 0, NULL, NULL);

        unsigned int ui12 = buffer[12];
        unsigned int ui13 = buffer[13];
        ui12 &= 0xFF;
        ui13 &= 0xFF;
        unsigned int ui14 = buffer[14];
        unsigned int uiVersion = (ui14 >> 4) & 0xF;
        unsigned int uiIpHdrLen = ui14 & 0xF;

        unsigned char *pucIpSour = (unsigned char *)&buffer[26];
        unsigned char *pucIpDest = (unsigned char *)&buffer[30];

        unsigned int uiPktCnt = g_uiPktCntLow;
        g_uiPktCntLow ++;
        if (g_uiPktCntLow < uiPktCnt)
            g_uiPktCntHigh ++;
        unsigned int uiPktLen = g_uiPktLenLow;
        g_uiPktLenLow += n;
        if (g_uiPktLenLow < uiPktLen)
            g_uiPktLenHigh ++;

        printf("%d-%d, %d-%d (%d), [%02X, %02X], [%X, %X], [%d.%d.%d.%d --> %d.%d.%d.%d]\n",
               g_uiPktCntHigh, g_uiPktCntLow, g_uiPktLenHigh, g_uiPktLenLow, n, ui12, ui13,
               uiVersion, uiIpHdrLen,
               pucIpSour[0],pucIpSour[1],pucIpSour[2],pucIpSour[3], pucIpDest[0],pucIpDest[1],pucIpDest[2],pucIpDest[3]);

    }
}

 

3、

4、

5、

 

转载于:https://www.cnblogs.com/LinuxCode/p/5801850.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值