本书 《网络协议栈入门》 采用的代码是 基于 linux 内核 4.4.4 版本的。linux 内核源码下载地址: mirrors.edge.kernel.org
NAT 的行为一直以来都没有很精确的定义,比较流行的是 NAPT 实现,全称 Network Address Port Translation。
看名字就知道,是把 IP 跟 port 进行转换。
NAT 技术在 《TCP/IP详解卷一》第7.3章节,讲解得非常详解,有些内容我就不再写了,直接贴书的内容。
原始 IP 跟端口 转换如下:
为什么需要NAT 技术,因为 IP 地址不够,192.168.1.2 是内网IP 可以重复使用,IP协议里面定义了某些网段是内网IP。
为什么需要客户端先发 SYN 数据包,不能服务器往客户端发 SYN,因为 客户端的IP是重复的,服务器公网IP是唯一的。
客户端找服务器IP能找到,服务器找客户端IP找不到。只能通过 NAT 转发回去给客户端IP。
《TCP/IP详解卷一》的重点内容如下:
请先阅读 《TCP/IP详解卷一》第7.3章节,基于以上背景知识,我们测试一下,本地电脑IP 192.168.0.114 跟 124.223.94.246 的NAT 通信过程。
我们使用 tracert 124.223.94.246
跟踪到的路由信息如下:
上图的 * 代表没有 ICMP 返回 ,所以不知道IP数据包在哪个路由器 TTL变成0了。是否返回 ICMP 告诉 TTL 过期 不是强制性的,有些路由器就是不返回 ICMP,直接丢弃TTL等于 0的数据。
从上图可以看出,IP包出公网,第一个公网IP 是 183.233.42.197,所以我们有理由相信,原始的IP跟端口 就是在这里被替换了,替换成 183.233.42.197
最后传递到 124.223.94.246
, 我们登陆 124.223.94.246
服务器,抓取一下数据包。
发现抓不到上面的 IP 数据,所以上面的 IP 只是路由器转发用的,不是 NAT,直接百度搜 ip,如下:
我们的公网IP 实际上 是 120.231.13.216
,看 124.223.94.246
服务器 的数据包,果然有,如下:
所以,我们的本地 IP 192.168.0.112
跟 124.223.94.246
通信的时候,实际上是经过 NAT 转换成 120.231.13.216
的
由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。