Netfilter例子,在内核中捕捉ARP请求并更新内核ARP表

#include <linux/module.h>      // 内核模块必需的头文件
#include <linux/kernel.h>      // 内核函数必需的头文件
#include <linux/init.h>        // 内核初始化函数必需的头文件
#include <linux/netfilter.h>   // Netfilter 必需的头文件
#include <linux/netfilter_arp.h>  // ARP过滤器必需的头文件
#include <linux/if_ether.h>    // 定义Ethernet帧头的头文件
#include <linux/skbuff.h>      // 定义网络数据包的头文件
#include <linux/ip.h>          // 定义IP报文的头文件
#include <linux/tcp.h>         // 定义TCP报文的头文件
#include <linux/udp.h>         // 定义UDP报文的头文件
#include <net/ip.h>            // 定义网络协议的头文件
#include <net/udp.h>           // 定义网络协议的头文件
#include <net/tcp.h>           // 定义网络协议的头文件
#include <linux/if_arp.h>      // 定义ARP报文的头文件
#include <linux/in.h>          // 定义网络协议的头文件

static struct nf_hook_ops nfho;  // Netfilter钩子

// 在内核ARP表中查找指定的MAC地址
void update_arp_table(struct sk_buff *skb) {
    struct ethhdr *ethh;
    struct arphdr *arph;
    struct arpreq req;

    ethh = (struct ethhdr *)skb_mac_header(skb);  // 获取以太网头
    arph = (struct arphdr *)(skb_network_header(skb) + sizeof(struct ethhdr));  // 获取ARP头

    if (ethh->h_proto != htons(ETH_P_ARP)) {  // 确保数据包是ARP请求
        return;
    }

    if (arph->ar_op != htons(ARPOP_REQUEST)) {  // 确保数据包是ARP请求
        return;
    }

    memcpy(req.arp_pa.sa_data, arph->ar_sip, 4);  // 保存源IP地址
    memcpy(req.arp_ha.sa_data, ethh->h_source, ETH_ALEN);  // 保存源MAC地址
    req.arp_pa.sa_family = AF_INET;  // 设置协议族为IPv4

    if (dev_ioctl(sock_net(skb->sk), SIOCGARP, (unsigned long)&req) < 0) {  // 在内核ARP表中查找指定的MAC地址
        return;
    }

    memcpy(ethh->h_dest, ethh->h_source, ETH_ALEN);  // 将目标MAC地址设置为源MAC地址
    memcpy(ethh->h_source, req.arp_ha.sa_data, ETH_ALEN);  // 将源MAC地址设置为ARP表中的MAC地址
}

// Netfilter钩子函数,用于捕捉ARP请求并更新内核ARP表
unsigned int hf_hook_function(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
    if (!skb) {  // 确保数据包不是空的
        return NF_ACCEPT;
    }

    update_arp_table(skb);  // 更新内核ARP表

    return NF_ACCEPT;  // 接受所有ARP请求
}

static int __init hf_init(void) {
    nfho.hook = hf_hook_function;  // 设置Netfilter钩子函数
    nfho.hooknum = NF_ARP_IN;  // 在ARP输入路径中捕捉数据包
    nfho.pf = PF_INET;  // 只处理IPv4数据包
    nfho.priority = NF_IP_PRI_FIRST;  // 设置钩子函数的优先级

    nf_register_hook(&nfho);  // 注册Netfilter钩子

    return 0;
}

static void __exit hf_exit(void) {
    nf_unregister_hook(&nfho);  // 注销Netfilter钩子
}

module_init(hf_init);  // 注册内核模块初始化函数
module_exit(hf_exit);  // 注册内核模块退出函数

MODULE_LICENSE("GPL"); // 声明内核模块许可证
MODULE_AUTHOR(“Your Name Here”); // 声明内核模块作者
MODULE_DESCRIPTION(“Netfilter ARP Hook”); // 声明内核模块描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值