热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

文章目录mac_filter功能简介网络接口层(MAC)netfilter注册钩子函数mac过滤钩子函数分析编译运行测试结果作者简介源码和文档mac_filter功能简介通过内核模




文章目录


    • mac_filter
    • 功能简介
    • 网络接口层(MAC)
    • 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;
}

分析


  • 获取以太网头部信息ethhdr
    虽然netfilter hook已经处于ip层,但skb保存了所有头部信息,可以通过指针偏移获取到以太网头部,从而获取到源mac地址
  • 判断数据的方向
    这里只对lan侧设备mac地址进行匹配,也就是从桥接口上来的数据才进行分析

编译运行

参考前面章节

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


源码和文档

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



推荐阅读
author-avatar
mobiledu2502877277
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有