Netfilter 之 iptable_mangle
2024-09-30 05:18:10
初始化
iptable_mangle_table_init函数通过调用ipt_register_table完成mangle表注册和钩子函数注册的功能;该流程与iptable_filter的函数调用的函数一致,此处不再重复分析,详情请移步<iptable_filter分析>;
static int __net_init iptable_mangle_table_init(struct net *net)
{
struct ipt_replace *repl;
int ret; /* 已经初始化 */
if (net->ipv4.iptable_mangle)
return ; /* 分配初始化用于下面注册的结构 */
repl = ipt_alloc_initial_table(&packet_mangler);
if (repl == NULL)
return -ENOMEM;
/* 注册表和钩子函数 */
ret = ipt_register_table(net, &packet_mangler, repl, mangle_ops,
&net->ipv4.iptable_mangle);
kfree(repl);
return ret;
}
钩子函数
从下面的钩子函数可以看到其分布于全部5个钩子点;
#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
( << NF_INET_LOCAL_IN) | \
( << NF_INET_FORWARD) | \
( << NF_INET_LOCAL_OUT) | \
( << NF_INET_POST_ROUTING))
static const struct xt_table packet_mangler = {
.name = "mangle",
.valid_hooks = MANGLE_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV4,
.priority = NF_IP_PRI_MANGLE,
.table_init = iptable_mangle_table_init,
};
iptable_mangle_hook为mangle钩子函数,如果当前是处于LOCAL_OUT钩子点,则需要调用ip_mangle_out函数,其他店则调用ipt_do_table进行规则匹配;ipt_do_table函数此处不再重复分析,详情请移步<iptable_filter分析>;
static unsigned int
iptable_mangle_hook(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
/* LOCAL_OUT钩子点,调用mangle_out */
if (state->hook == NF_INET_LOCAL_OUT)
return ipt_mangle_out(skb, state);
/* 规则匹配 */
return ipt_do_table(skb, state, state->net->ipv4.iptable_mangle);
}
ipt_mangle_out首先保存ip头部的一些信息,然后调用ipt_do_table进行规则匹配,规则之后检查ip头中的保存字段是否发生变化,如果发生变化,则需要重新查路由;
static unsigned int
ipt_mangle_out(struct sk_buff *skb, const struct nf_hook_state *state)
{
unsigned int ret;
const struct iphdr *iph;
u_int8_t tos;
__be32 saddr, daddr;
u_int32_t mark;
int err; /* root is playing with raw sockets. */
/* 原始套接字 */
if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT; /* Save things which could affect route */ mark = skb->mark;
iph = ip_hdr(skb);
saddr = iph->saddr;
daddr = iph->daddr;
tos = iph->tos; /* 进行规则匹配 */
ret = ipt_do_table(skb, state, state->net->ipv4.iptable_mangle);
/* Reroute for ANY change. */
/* 经过规则后 */
if (ret != NF_DROP && ret != NF_STOLEN) {
iph = ip_hdr(skb); /* 判断ip头中的字段是否有改变 */
if (iph->saddr != saddr ||
iph->daddr != daddr ||
skb->mark != mark ||
iph->tos != tos) {
/* 重新查路由 */
err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
if (err < )
ret = NF_DROP_ERR(err);
}
} return ret;
}
最新文章
- 关于ubuntu16.04中mysql root登陆不了的情况下(大多是未设置密码的情况)
- [WCF编程]12.事务:事务协议与管理器
- js 阻止事件冒泡和默认行为 preventDefault、stopPropagation、return false
- 冲刺阶段 day 9
- 单击HighCharts柱形体弹框显示详细信息
- Field+offset(len)
- 线程中CreateEvent和SetEvent及WaitForSingleObject的用法
- zencart安装第三步出现空白
- IOS 7 Study - UIDatePicker
- Comparison method violates its general contract
- xml的生成与解析_老师笔记
- CSS3中的选择器
- Qt之QNetworkInterface(查询网络接口),QHostInfo(查询主机IP)
- highstock
- null transform hack 强制使用硬件加速
- render函数(转)
- Spring的Aspect切面类不能拦截Controller中的方法
- 如何在VS Code中进行golang编程
- Unbuntu18.04通过apt源方式安装mysql5.7.22
- runloop timer
热门文章
- 深入JavaScript对象(Object)与类(class),详细了解类、原型
- jQuery实现购物车效果
- JS-上下文练习
- 内核开机logo
- 使用pycharm 编写代码 并在远程主机上运行
- linux后台启动项目命令
- Computer Vision_1_Active Appearance Models:Active Appearance Models——2001
- redis系列一: windows下安装redis
- (备忘)Nodepad++常用快捷键
- MinGW-W64 编译 LLVM 与 Clang