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

相关文章

springboot rocketmq配置生产者和消息者的步骤

《springbootrocketmq配置生产者和消息者的步骤》本文介绍了如何在SpringBoot中集成RocketMQ,包括添加依赖、配置application.yml、创建生产者和消费者,并展... 目录1. 添加依赖2. 配置application.yml3. 创建生产者4. 创建消费者5. 使用在

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

Vue ElementUI中Upload组件批量上传的实现代码

《VueElementUI中Upload组件批量上传的实现代码》ElementUI中Upload组件批量上传通过获取upload组件的DOM、文件、上传地址和数据,封装uploadFiles方法,使... ElementUI中Upload组件如何批量上传首先就是upload组件 <el-upl

Docker部署Jenkins持续集成(CI)工具的实现

《Docker部署Jenkins持续集成(CI)工具的实现》Jenkins是一个流行的开源自动化工具,广泛应用于持续集成(CI)和持续交付(CD)的环境中,本文介绍了使用Docker部署Jenkins... 目录前言一、准备工作二、设置变量和目录结构三、配置 docker 权限和网络四、启动 Jenkins

Python3脚本实现Excel与TXT的智能转换

《Python3脚本实现Excel与TXT的智能转换》在数据处理的日常工作中,我们经常需要将Excel中的结构化数据转换为其他格式,本文将使用Python3实现Excel与TXT的智能转换,需要的可以... 目录场景应用:为什么需要这种转换技术解析:代码实现详解核心代码展示改进点说明实战演练:从Excel到

如何使用CSS3实现波浪式图片墙

《如何使用CSS3实现波浪式图片墙》:本文主要介绍了如何使用CSS3的transform属性和动画技巧实现波浪式图片墙,通过设置图片的垂直偏移量,并使用动画使其周期性地改变位置,可以创建出动态且具有波浪效果的图片墙,同时,还强调了响应式设计的重要性,以确保图片墙在不同设备上都能良好显示,详细内容请阅读本文,希望能对你有所帮助...

MySQL zip安装包配置教程

《MySQLzip安装包配置教程》这篇文章详细介绍了如何使用zip安装包在Windows11上安装MySQL8.0,包括下载、解压、配置环境变量、初始化数据库、安装服务以及更改密码等步骤,感兴趣的朋... 目录mysql zip安装包配置教程1、下载zip安装包:2、安装2.1 解压zip包到安装目录2.2

C# string转unicode字符的实现

《C#string转unicode字符的实现》本文主要介绍了C#string转unicode字符的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1. 获取字符串中每个字符的 Unicode 值示例代码:输出:2. 将 Unicode 值格式化