网络层IP协议

        本篇将详细的介绍有关网络层 IP 协议的相关知识,主要讲解了有关 IP 协议的基本概念、协议头格式、IP 地址的网段划分、特殊的 IP 地址、私有 IP 和 公有 IP以及网络层路由;同时还讲解了 IP 报文分片和组装的过程,NAT 技术的原理以及内网穿透和内网打洞。

        对于 IP 而言,其作用就是:提供一种能力,将数据从源主机跨网络送至到目的主机(经过 IP 协议的传输并不会能保证是可靠的传输,因为可靠性是由上层传输层协议,IP 只是提供一种能力)。

        主机:配有 IP 地址,但是不进行路由控制的设备

        路由器:即配有 IP 地址,又能进行路由控制

        结点:路由器和主机的统称

目录

IP 协议报头格式

网段划分

特殊IP与IP数量限制

私有IP地址和公网IP地址

路由

IP的分片与组装

NAT

内网穿透和内网打

IP 协议报头格式

        对于 IP 协议报文的格式如下:

        协议的各个字段表示的含义如下:

        4位版本:表征当前的IP协议是IPv4还是IPv6版本(IPv4:4字节、IPv6:16字节)
        4位首部长度:表征当前首部的长度,4位最大表示的数为15,不过单位是4字节,所以最大可以表示60字节
        8位服务类型(TOS):3位优先权字段(当前已经弃用),4位TOS字段和1位保留字段(必修置为0).4位TOS分别表示为:最小延时、最大吞吐量、最高可靠性以及最小成本(这四者相互冲突,只能选择其中一个,对于shh/telnet这样的应用程序最小延时比较重要,对于ftp这样的应用程序,最大吞吐量比较重要)
        16位总长度:表示整个IP报文的长度(直到首部长度和总长度之后就可以成功的将报文分离)
        16位标识(id):唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的
        3位标志:第一位为保留位、第二位表示是否禁止分片、第三位表示更多分片:若不是最后一个分片则为1,若是最后一个分片则表示0
        13位片偏移:是分片相对于原始IP报文开始处的偏移,表示当前的分片处于源IP的哪个位置,但是实际计算出的13位片偏移需要乘上8才会得到真正的偏移位置(因为报文的长度最长可有16位的长度,而这里仅仅只有13位,所以需要将计算出来的偏移位置右移三位,等到拿出计算的时候又将其左移回去)
        8位生存时间(Time To Live,TTL):数据报达到目的地的最大报文跳数,一般是64,没经过一个路由,TTL就会减一,若TTL减到0都还没有到达,那么该报文就会被丢弃(防止出现路由环路的问题)
        8位协议:表征来自传输层的数据是UDP还是TCP报文数据
        16位首部校验和:使用CRC进行校验,鉴别头部是否在传输的过程中损坏
        32位源IP地址:表示发送端的IP地址
        32位目的IP地址:表示目的地的IP地址

网段划分

        对于我们的 IP 资源来说,是非常有限且有用的资源,因为现在更加常用的还是 IPv4,只有 32 位,也就是只有 40 多亿个 IP 地址可以使用。所以我们的 IP 地址都是经过合理划分,来给不同的区域、国家、组织、学校等使用。

        IP 地址尝试用点分十进制来表示,将 32 位的 IP 地址划分为 4 份,每份八个比特,然后对于每份使用十进制表示,中间使用 ” . “ 表示,比如:192.168.155.10。

        IP 地址同时被划分为了两部分:网络号和主机号。

        网络号:保证互相连接的两个网段具有不同的标识(在同一个网段中的标识都是一样的)

        主机号:在同一个网段中,主机之间具有相同的网络号,但是必须有不同的主机号。

         如上所示,对于不同的网段网络号不同,同一个网段主机号不同。同时我们还会发现其中的路由器有着两个及以上的 IP 地址,同时连接着多个网段,所以路由器就是我们连接不同网段的枢纽。当有新的设备需要接入网络的时候,路由器就会主动给新的主机分配对应的主机号和网络号,所以对于我们的路由器的作用有:

        1. 路由

        2. 构建子网

        所以我们需要合理的设置主机号和网络号,保证在相互连接的网络中,每台主机的 IP 地址都是不相同的,这样的划分就为网段划分

        其中一种的网段划分方式为:将所有的 IP 地址划分为五类,如下图:

        在点分十进制中表示即为:

A类:0.0.0.0 到 127.255.255.255
B类:128.0.0.0 到 191.255.255.255
C类:192.0.0.0 到 223.255.255.255
D类:224.0.0.0 到 239.255.255.255
E类:240.0.0.0 到 247.255.255.255

        随着网络的迅速发展,这样的网段划分方法的局限性很快就显现出来了,大多数组织都申请 B 类网络地址,导致 B 类很快就被划分完了,但是若申请 A 类,A 类的地址又很难用完,C 类地址又不够使用,所以这样的网段划分方法的局限性很大。

        所以为了解决以上的缺陷,就提出了一种新的网段划分方案,叫做 CIDR(Classless Interdomain Routing),这样的解决方法就是引入一个额外的子网掩码(subnet mask)来区分网络号和主机号,子网掩码也是一个 32 位的正整数,通常使用一串 0 来结尾。将 IP 地址和子网掩码进行按位与操作就可以得到对应的网络号,在 CIDR 中的主机号和网络号和 A、B、C 类地址无关。如下:

         按照如上的方法我们就可以计算出某个 IP 地址对应的网络号,以及对应的网段中的地址范围(对于网段范围而言,网段范围中的全 0 或者全 1 的IP 地址有着特殊作用,一般不会给用户分配这个 IP 地址,所以计算出的子网地址范围减去 2 就为用户能分到的 IP 数量)。

        又由于子网掩码分别就是前部分是全 1,后部分是全 0,所以对于使用 CIDR 分配的 IP 地址我们可以将其表示为 140.252.20.68/24,后面这个 / + num 表示的为前多少个 bit 位为子网掩码,这样就可以方便的表示出 CIDR 的 IP 地址。

        前面已经提到对于每个网段的网络号是不同的,所以当我们传输的数据需要跨网段发送数据的时候,在网络中的路由器就可以根据数据报目的 IP 的网络号来分辨当前这个 IP 是否需要发送到我这个网段。所以对于网段划分的目的就是:通过精心的设计,合理的划分,可以高效支持未来的报文路径查找,大大提高查找目的主机的效率

特殊IP与IP数量限制

        在网络中也存在一些特殊的 IP 地址,这些特殊的 IP 有着特定的作用,如下:

IP地址中主机号地址全部设置为0,代表这个局域网(只有网络号,主机号为0,刚好和局域网号相同)
IP地址中的主机号全部设为1,表示广播地址,用于给一个链路中相互连接的所有主机发送数据报
127.* 的IP地址用于本机环回测试,通常是127.0.0.1

        一个 IP 地址是由一个 4 字节的 32 位的正整数组成的。所以一共只存在 2^32 次方个 IP 地址,大概也就是43亿左右,而 TCP/IP 协议规定,每个主机都需要一个 IP 地址。然而在全球中的能够联网的主机绝对超过了 43 亿,所以这个时候 IP 地址的数量就不够用了。虽然 CIDR 网段划分法一定程度上缓解了 IP 地址不够使用的问题,但还是不够用,这时候有三种方法可以解决,如下:

        1. 动态分配 IP 地址,只给接入网络的设备分配 IP 地址,当设备退出网络之后取消它的 IP 地址,也就是说同一个 IP 地址可以让多个设备在不同时间使用。

        2. NAT技术,后文介绍

        3. IPv6,IPv6 并不是 IPv4 的简单升级,这是互不相干的两个协议,彼此之间并不兼容。

私有IP地址和公网IP地址

        当在一个组织内部组建局域网,只在局域网内部通信,而不将其直接连接在互联网上,理论上我们使用任意的 IP 都可以,但是 RFC1918 规定了组建局域网的私有 IP 地址只能是如下的 IP 地址(所有的设备都是连接在局域网中的,所以所有设备的 IP 都是属于的范围)

10.*,前8位是网络号,共16777216个IP地址
172.16.*到172.31.*,前12位是网络号,共1048576个地址
192.168.*,前16位是网络号,共65536个地址

        只要是包含在以上 IP 范围内的 IP 地址,我们都将其称为私有 IP 地址,反之称其为公网 IP。对于私有 IP 而言,并不能出现在公网的网络中,私有 IP 地址可以在不同的局域网中重复。

        真实的网络情况如下:

        如上所示,只要是局域网中的 IP 地址都是私有 IP 地址,只有当接入广域网的 IP 地址才会配有公网 IP。上图中一共搭建了两层局域网,先是由运营商路由器连接各家用路由器搭建了一层局域网,然后是家用路由器连接各主机设备搭建了第二层局域网。(注:对于搭建局域网的层数并没有限制,只是这里刚好搭建了两层)

        家用路由器:构建出的局域网通常用于一个家庭或人数较少的组织使用,用的 IP 地址网络号一般是以 192.168.* 开头的私有 IP,因为家用网络中接入的设备并不会太多。家用路由器通常至少会配一个LAN口IP(子网IP),用于将家庭中的设备接入到外面的网络;以及一个WAN口IP,用于和运营商路由器连接

        运营商路由器:构建出的局域网通常用于连接各家用路由器,配有的LAN口IP(子网IP) ,用于连接局域网中的各家用路由器;WAN口IP:通常用于接入到公网,与公网中的服务器相连接。

        当处于局域网中的一个设备想要和公网中的某个设备通信的时候,其大致流程如下:

        当家用设备中的某个主机拟定了某个报文之后,首先会对比目的 IP 地址的网络号和本主机所在的局域网的 IP 地址网络号相对比,发现不相符,这个时候就会将报文传输到路由器,将其放到由运营商构建的局域网中,依旧对比目的 IP 的网络号和本局域网的 IP 地址,还是发现不相符,这个时候就会由运营商路由器将其转发到公网中,这个时候就能达到对应的服务器。

        当服务器拿到对应的报文之后,准备应答对应报文的时候,发现来自 192.168.* 私有 IP 的主机,但是在网络中有着无数这样 IP 的主机,所以这个时候就不知道该将应答转发给谁,所以这就是不能让私有 IP 入公网的原因,所以内网中的数据在向外网转发的时候,需要将对应的 src IP 地址转化为路由器中的 WAN 口 IP,若外网想要向内网中发送数据报,则将 dst IP 转化为对应的内网 IP,这样的方法即为即为我们的 NAT 技术,对于 NAT 技术我们在下文中在详细讲解。

路由

        在网络中,我们的报文需要从源地址走向目的地址,但是网络之间相互交错,该如何到达正确的目的地址呢?这个时候数据报在网络中传输的时候就需要通过路由来寻找达到目的地址的路径。所以路由的作用就是将 IP 从源 IP 地址导航到目的 IP 地址。

        路由的过程如下:

当IP数据报到达路由器的时候,路由器会先查看目的IP
路由器决定这个数据报能直接发送给目标主机,还是需要发送给下一个路由器
依次反复,直到到达目的 IP 地址

        我们可以使用 route 命令查看在我们主机上的路由表,如下:

         对于如上路由表的 Destination 是目的网络地址(其中的default代表的意思为:若在当前路由表中查不到对应的转发地址或者接口,则将其按照 default 条目转发),Genmask 是子网掩码,Gateway 是下一跳地址,Iface 是发送接口,Flags 中的 U 标志表示此条目有效(我们可以禁止某些条目),G 标志表示此条目的下一跳地址是某个路由器的地址(若没有 G 标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发)

        对于如上的路由表其实并不具有代表性,因为这是一台云服务器,这样的路由表只能将对应的 IP 地址和自己网段的网络号相对比,若是则接收,若不上则交给对应的路由器,让路由器直接去路由。       

IP的分片与组装

        在网络层的下层数据链路层,对于数据转发的最大单元 MTU 设定为 1500 字节,也就是说从网络层传下来的 IP 报文最大为  1500 字节,然而对于 IP 报文来说,最长可以达到 65535 个字节,说明 IP 报文如果要向下层传输数据,若报文长度大于 1500 字节必须要将我们的数据拆分,也就是分片,分成多片

        当然不能仅仅分片就完事了,当数据到达目的 IP 主机的时候,还需要在对方的网络层将数据组装起来,因为从传输层向下传输的数据就是完整的,所以当数据向上传输的时候也必须是完整的,所以还需要在对端网络层将数据组装起来,然后在向上交付数据。

        但在分片的同时,并不希望将数据报分片很多,因为只要一个分片报文的丢失,就会导致整个被分片的报文失效,所以分片会增加丢包的概率,所以这也会促使传输层向网络层交付的数据减小长度,让其尽量的不需要在网络层被分片(所以在TCP中的滑动窗口中的数据都是小分多次的滑动发送,并不是直接发送一大块)。

        那么我们该如何将报文分片和组装呢?我们先谈组装,只要知道了组装的原理也就知道的了分片的原理。

        在传输的报文中有的报文没有分片,有的报文是分片的,那么我们首先需要识别哪些报文是分片的,哪些不是,如何识别报文是否分片,我们需要使用 IP 首部中的 16 位标识、3 位标志和 13 位片偏移这三个字段来判断,被分片的报文数据的特征有:16 位标识相同,3 位标志位中的第三位为 1 或者 3 位标志位中的第三位为 0 且13 为片偏移不为 0(每个 IP 报文的 16 位标识都是不同的,但是被分片的 IP 报文属于一个报文中的一部分,所以被分片的 IP 报文的标识是一样的;对于 3 位标志中的第三位表示是否分片,所以第三和标志位为 1 的一定是被分片的报文,但是最后一个被分片的报文第三个标志位为 0,所以还需要使用 13 位片偏移来识别是否是最后一个被分片的报文),所以对于没有分片的 IP 报文特征为:3位标志中的第三位为 0 且 13 位片偏移中的值为 0

        所以我们想要将一个 IP 报文给组装起来,只需要识别出哪些报文是被分片的报文,然后将其先放在接收缓冲区中,等待所有 16 位标识相同的 IP 分片报文都被收集之后,按照 13 位偏移将报文排序,然后将除了第一个报文之后的报文首部都分离之后组装起来向上交付即可(在组装之前还需要判断当前的分片报文中是否存在丢失报文,对于第一个分片报文是否丢失可以通过检查是存在片偏移为 0 的分片报文,对于中间部分的分片报文丢失可以通过片偏移加上自身长度是否等于下一个报文的片偏移,对于最后一个分片报文则是判断是否存在三位标志中的第三位为 0 且2片偏移大于 0 的情况)。

        若想要将一个 IP 报文分片,只要大于 1480 字节的传输层数据报(加上 IP 首部 1500)都需要将其分片,但是对于分片而言,对于每个分片报文长度最大分片 1480 字节,因为还需要加上首部长度。同时还需要注意分片之后的报文长度必须是 8 的倍数(因为 13 位片偏移不足以表示长度超过 2^13 位的 IP 报文,所以想要让其可以表示最长 16 位的数据,就需要将计算出来的片偏移除 8 放入到 13 位片偏移中,也就是将计算出的片偏移右移 3 位),如下为将一个长度为 3000 字节的传输层数据报分片的结果:

NAT

        在前文中我们也已经提到 NAT 技术可以用于解决 IP 地址不够用问题,同时还大致演示了一个报文从内网转发到内网的过程,不过以上的演示是不完全正确的,因为在向外网转发的过程中需要改变源 IP 地址(内网 IP 地址不能入公网),所以,NAT 能够将私有 IP 对外通信时转化为全局 IP 地址(也就是将一种私有 IP 地址转换为公网 IP 地址的技术)

        NAT 实现的原理:

        在我们的路由器中会构建一个名为 NAPT 的转化表,当一个报文从内网向公网经过路由器转发的时候,会将报文中的源地址和源端口切换成路由器上的端口号和 IP 地址,同时使用 NAPT 表记录下报文源端口、源地址和转换之后的地址端口的映射信息,当外面的主机向该主机发送应答报文的时候,应答报文填写的是路由器对应的端口和地址,到达路由器之后路由器会通过地址、端口的映射信息,将目的主机的地址和端口转换成内网的地址和端口

        既然路由器的 IP 地址只有几个,怎么能和内网中的主机建立那么多的映射呢?通常进行通信的是主机上的进程,也就是只有 IP 地址加上端口号才能标识唯一一个进程,同样对于路由器也一样,只需要使用一个 IP 和多个端口就可以标识多个通信的进程,所以能映射主机的多少和 IP 地址无关,而是和 IP 地址以及端口号有关

内网穿透和内网打洞

        内网穿透和内网打洞都是建立在 NAT 技术下的两种技术。

        内网穿透:

        当我们想要使用在内网的某台主机上部署服务的时候,可以让主机先访问外网的某台服务器,通过访问外网的服务器,就让内网的主机和外网建立了映射关系(NAT),所以外网的主机想要访问该主机部署的服务的时候,就可以通过访问在外网服务器上的映射过后的 iP 和端口,就可以访问到内网中部署的任务。这样的应用场景就是典型的内网穿透。

        内网打洞:

        当我们想要发消息给外网中的某台主机的时候,若我们可以直接的知道连接外网主机的路由器的 IP 地址和端口号,我们就可以直接发消息给对应路由器,然后在由路由器转发给对应的主机,这样就不需要先发送给服务器,然后在层层转发,而是直接通过对方的路由器找到主机,这就是内网打洞(通常要获得对方主机连接外网的路由器的 IP 和端口)。如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值