Netfilter学习之NAT类型动态配置(七)全锥型NAT内核空间实现

本文主要是介绍Netfilter学习之NAT类型动态配置(七)全锥型NAT内核空间实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 本文主要实现全锥型NAT的内核空间iptables命令行扩展对应的钩子函数及其功能的实现。实现思路见上文。

1.关键部分实现代码

(1)建立ipt_FULLCONE.c以激活钩子函数,关键在于保持和用户空间libipt的一致性。

static struct xt_target fullcone_tg_reg __read_mostly = {.name		= "FULLCONE",.family		= NFPROTO_IPV4,.target		= fullcone_tg,.targetsize	= sizeof(struct nf_nat_ipv4_multi_range_compat),.table		= "nat",.hooks		= 1 << NF_INET_PRE_ROUTING,.checkentry	= fullcone_tg_check,.destroy	= fullcone_tg_destroy,.me		= THIS_MODULE,
};

在fullcone_tg中调用nf_nat_fullcone_ipv4

static unsigned int
fullcone_tg(struct sk_buff *skb, const struct xt_action_param *par)
{struct nf_nat_range range;const struct nf_nat_ipv4_multi_range_compat *mr;mr = par->targinfo;range.flags = mr->range[0].flags;range.min_proto = mr->range[0].min;range.max_proto = mr->range[0].max;return nf_nat_fullcone_ipv4(skb, xt_hooknum(par), &range,xt_out(par));
}

(2)在nf_nat_fullcone_ipv4.c中实现具体功能

unsigned int
nf_nat_fullcone_ipv4(struct sk_buff *skb, unsigned int hooknum,const struct nf_nat_range *range,const struct net_device *out)
{struct nf_conn *ct;struct nf_conn_nat *nat;enum ip_conntrack_info ctinfo;struct nf_nat_range newrange;__be32 newdst;//we need to monitor packets at prerouting and put dst to nf_nat_setup_infoNF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING);ct = nf_ct_get(skb, &ctinfo);		//get infomationn from socketsnat = nfct_nat(ct);NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY));/* Source address is 0.0.0.0 - locally generated packet that is* probably not supposed to be masqueraded.*/if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)return NF_ACCEPT;newdst = nf_nat_fullcone_match(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);if (newdst){//transfer from original rangememset(&newrange.min_addr, 0, sizeof(newrange.min_addr));memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;newrange.min_addr.ip = newdst;newrange.max_addr.ip = newdst;newrange.min_proto = range->min_proto;newrange.max_proto = range->max_proto;//Hnad modified range to generic setup. Change dst by normal way.return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);}elsereturn NF_ACCEPT;			
}
EXPORT_SYMBOL_GPL(nf_nat_fullcone_ipv4);

(3)进入nf_nat_core.c中,调用nf_nat_setup_info,详细源码介绍可见前文《Netfilter学习之NAT类型动态配置(四)nf_nat_core.c源码解析》

改动代码如下:

unsigned int
nf_nat_setup_info(struct nf_conn *ct,const struct nf_nat_range *range,enum nf_nat_manip_type maniptype)
{struct net *net = nf_ct_net(ct);struct nf_conntrack_tuple curr_tuple, new_tuple;/* Can't setup nat info for confirmed ct. */if (nf_ct_is_confirmed(ct))return NF_ACCEPT;WARN_ON(maniptype != NF_NAT_MANIP_SRC &&maniptype != NF_NAT_MANIP_DST);if (WARN_ON(nf_nat_initialized(ct, maniptype)))return NF_DROP;/* What we've got will look like inverse of reply. Normally* this is what is in the conntrack, except for prior* manipulations (future optimization: if num_manips == 0,* orig_tp = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)*/nf_ct_invert_tuplepr(&curr_tuple,&ct->tuplehash[IP_CT_DIR_REPLY].tuple);get_unique_tuple(&new_tuple, &curr_tuple, range, ct, maniptype);if (!nf_ct_tuple_equal(&new_tuple, &curr_tuple)) {struct nf_conntrack_tuple reply;/* Alter conntrack table so will recognize replies. */nf_ct_invert_tuplepr(&reply, &new_tuple);nf_conntrack_alter_reply(ct, &reply);/* Non-atomic: we own this at the moment. */if (maniptype == NF_NAT_MANIP_SRC)ct->status |= IPS_SRC_NAT;elsect->status |= IPS_DST_NAT;if (nfct_help(ct) && !nfct_seqadj(ct))if (!nfct_seqadj_ext_add(ct))return NF_DROP;}if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip){listnode = (struct MatchTupleList *)kmalloc(sizeof(struct MatchTupleList), GFP_KERNEL);listnode->tuple.src = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src;listnode->tuple.dst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst;listnode->specifiedIP = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip;list_add_tail(&listnode->list, &TupleHead.list);}if (maniptype == NF_NAT_MANIP_SRC) {unsigned int srchash;spinlock_t *lock;srchash = hash_by_src(net,&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);lock = &nf_nat_locks[srchash % CONNTRACK_LOCKS];spin_lock_bh(lock);hlist_add_head_rcu(&ct->nat_bysource,&nf_nat_bysource[srchash]);spin_unlock_bh(lock);}/* It's done. */if (maniptype == NF_NAT_MANIP_DST)ct->status |= IPS_DST_NAT_DONE;elsect->status |= IPS_SRC_NAT_DONE;return NF_ACCEPT;
}
EXPORT_SYMBOL(nf_nat_setup_info);

2.小结

在本文中,我实现了全锥型NAT内核空间的关键部分代码,详细代码可以参考我的github上,在此基础上可以很容易的实现限制型锥形和可变的对称型等类型。


欢迎关注本人公众号,公众号会更新一些不一样的内容,相信一定会有所收获。
在这里插入图片描述

这篇关于Netfilter学习之NAT类型动态配置(七)全锥型NAT内核空间实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138079

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

CentOS7安装配置mysql5.7 tar免安装版

一、CentOS7.4系统自带mariadb # 查看系统自带的Mariadb[root@localhost~]# rpm -qa|grep mariadbmariadb-libs-5.5.44-2.el7.centos.x86_64# 卸载系统自带的Mariadb[root@localhost ~]# rpm -e --nodeps mariadb-libs-5.5.44-2.el7

hadoop开启回收站配置

开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。 开启回收站功能参数说明 (1)默认值fs.trash.interval = 0,0表示禁用回收站;其他值表示设置文件的存活时间。 (2)默认值fs.trash.checkpoint.interval = 0,检查回收站的间隔时间。如果该值为0,则该值设置和fs.trash.interval的参数值相等。

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu