系统相关
首页 > 系统相关> > OpenWrt内核模块开发(六)-通过linux netfilter框架实现mac地址过滤

OpenWrt内核模块开发(六)-通过linux netfilter框架实现mac地址过滤

作者:互联网

文章目录

mac_filter

功能简介

通过内核模块的方式向netfilter框架注册钩子函数,由于mac在ip层以下,常规的做法是在二层设备进行mac地址过滤的(比如交换机),这里我们在ip层分析mac层数据,达到过滤效果。

网络接口层(MAC)

网络接口层在发送端将上层的IP数据报封装成帧后发送到网络上;数据帧通过网络到达接收端时,该结点的网络接口层对数据帧拆封,并检查帧中包含的MAC地址。如果该地址就是本机的MAC地址或者是广播地址,则上传到网络层,否则丢弃该帧。

简单点讲就是mac层,通常我们称之为二层,比如交换机就属于二层设备,而路由器属于三层设备(ip路由)。

netfilter注册钩子函数

这里我们将hooknum设置为NF_INET_FORWARD

static struct nf_hook_ops mac_filter_ops[] __read_mostly = {
    {
        .hook = mac_filter_hook,
        .pf = PF_INET,
        .hooknum = NF_INET_FORWARD,
        .priority = NF_IP_PRI_FILTER + 1,
    },
};

static int __init mac_filter_init(void)
{
    printk("mac filter....init\n");
    nf_register_net_hooks(&init_net, mac_filter_ops, ARRAY_SIZE(mac_filter_ops));
    return 0;
}

mac过滤钩子函数分析

源码

static u_int32_t mac_filter_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    u_int8_t smac[ETH_ALEN] = {0};
    struct ethhdr *ethhdr = NULL;
    u_int8_t filter_mac_buf[32] = "00:0C:29:F1:34:8F";
    u_int8_t mac_buf[32] = {0};
    ethhdr = eth_hdr(skb);
    if (!ethhdr)
    {
        return NF_ACCEPT;
    }
    memcpy(smac, ethhdr->h_source, ETH_ALEN);
    if (!skb->dev){
        return NF_ACCEPT;
    }

    printk("dev=%s, source mac = %02X:%02X:%02X:%02X:%02X:%02X\n",
           skb->dev->name, smac[0], smac[1], smac[2], smac[3], smac[4], smac[5]);
    if (0== memcmp(skb->dev->name, "br", 2)){
        sprintf(mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X", smac[0], smac[1], smac[2], smac[3], smac[4], smac[5]);
        if (0 == strcmp(mac_buf, filter_mac_buf)){
            printk("----drop dev=%s, source mac = %02X:%02X:%02X:%02X:%02X:%02X\n",
                skb->dev->name, smac[0], smac[1], smac[2], smac[3], smac[4], smac[5]);
            return NF_DROP;
        }
    }
    return NF_ACCEPT;
}

分析

编译运行

参考前面章节

insmod mac_filter.ko

测试结果

root@OpenWrt:/fros# insmod mac_filter.ko 
root@OpenWrt:/fros# <4>[38235.271118] mac filter....init

root@OpenWrt:/fros# <4>[38241.873151] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38241.876006] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38242.896581] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38242.899173] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38245.374032] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38245.376519] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38246.978437] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38246.979705] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38248.264021] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38248.265541] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38249.425204] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38249.426521] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38250.592095] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38250.593375] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38251.827786] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38251.829108] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38252.874176] dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38252.876592] ----drop dev=br-lan, source mac = 00:0C:29:F1:34:8F
<4>[38253.905311] dev=br-lan, source mac = 00:0C:29:F1:34:8F

作者简介

OpenWrt应用过滤插件作者(应用过滤用于控制app联网,可以过滤游戏、视频、聊天等几百款app)
从事嵌入式Linux开发近10年,主要负责路由器网通产品研发,精通OpenWrt系统,包括luci、消息机制、内核模块等。擅长模块:路由器上网行为管理、智能流控、上网认证、防火墙、虚拟服务器、多wan负载均衡等

开源作品地址:
https://github.com/destan19/OpenAppFilter

源码和文档

关注微信公众号可以获取更多技术文档、固件、源码等
微信扫码关注:

标签:00,0C,29,dev,source,mac,OpenWrt,内核模块
来源: https://blog.csdn.net/dxt1107/article/details/118891804