知识点回顾
我们肯定使用过ifconfig
命令来查询计算机中的网络设备。不知道你有没有注意过其中的netmask
(子网掩码),但你真的知道它的来龙去脉吗?今天我们就来重新认识一下netmask
。
在进入主题内容前我们先来回顾一些关于IP
的知识点。每一个需要使用互联网的设备都必须具有一个唯一标识,而这个唯一标识就是IP
地址。就像在生活中你要打电话别个时,你必须知道这个人的手机号码不然你就无法联系到他,可以说IP
地址就类似于你的手机号码。
IP
地址采用分层设计,并可以将其分为如下五类。不同种类的IP
地址网络号和主机号都是不一样的。
各类IP
的地址范围如下,方便记忆:
子网掩码的由来,为什么需要子网掩码
IP
地址结构设计之初是两层结构,将IP
地址分为网络号
和主机号
,不同的网络号
下包含一系列的主机(网络设备)。在这种结构下大量的主机连接在同一个网络下,当主机数量少的网络还能正常的工作,然而这种方式缺乏弹性,当主机数量过多的时候会带来一系列的问题。举个例子,当一个公司规模较小的时候,分为两个层级
部门—>员工。当有消息要传达到一个部门时只需要把消息一个个传达给指定部门的人员即可,当一个部门人员较少时这样不会有太大的问题。随着公司的快速发展,各个部门的人员越来越多,此时如果有消息传达给一个部门,只能把消息一个一个的发给部门里的员工;部门里并不是所有的员工都需要知道这个消息,但我们没有其它的信息来对员工进行分类,所以只能把消息发给部门里的所有员工。这样做的缺点显而易见,不仅管理不太方便,而且有些员工会收到自己不需要的消息。为了解决这个问题,公司往往会在目前的基础上新增一个层级:组。
部门—>分组—>员工
在部门的下面设置组,将对应的员工分配在对应的组,不仅可以方便管理还可以避免消息(资源)的浪费。
软件设计也是来源于生活。为了更好的适应于更大的网络和更好更方便的管理网络设备,于是提出了子网这个设计。
增加了子网相对以前的二层IP
地址有哪些优点呢?
- 弹性,可以自定义子网和子网中的主机数
- 对公网的不可见性,对于子网的划分只存在于组织(可以认为是局域网)内。还是上面的例子,不管公司的组织架构怎么调整在公外面看来你还是那个公司
- 通过子网可以对网络进行分组,不同分组的主机进行广播只有本组的主机才可以收到消息
- 子网掩码将大的网络域,分为更小的子网。较小的网络会创建较小的广播,从而产生较少的广播流量。 此外,子网还通过将网络问题隔离到特定的存在来简化故障排除
IP
地址是固定的32位,那如何在原来二层结构的IP
地址进行的子网的划分呢? 此时就是轮到子网掩码上场了。
为了在不改变IP
地址结构的前提下,于是人们提出了子网掩码。
但是用哪几位数据来表示子网呢,答案是从主机号中借位来充当子网。
FOR EXAMPLE:
B类地址:154.71.0.0, 如果不使用子网的话,154.71这个网络号可以容纳65534(pow(2,10)-2)个主机。然而你可以通过子网掩码对这个网络进行子网划分。你可以使用1位来表示子网,则剩余的15位来表示主机号;如果使用2位来表示子网,则剩余的14位来表示主机号,以此类推。你使用越多的位数来表示子网,相应的用来表示主机号的位数也就越好。最少要使用2位来表示主机号,因为减去主机后全为0和全为1的两个IP
地址。
假如你要使用5位来作子网,则subnet id
这5位在子网掩码中必须为1,表示这5位用于子网。
1 | # RFC950 |
上面这段话的大致意思是在IP
地址中全为0或全为1的有特殊的含义或特殊的用途。比如IP
地址128.9.255.255
是网络号为128.9
的文播地址,发往128.9.255.255
的网络包会广播至该网络的所有主机。地址128.9.0.0
会被解释为此网络,也不建议使用。
因此上面5-bit
的子网建议使用除0和31以外的子网。
子网计算器
有无子网通信有何差异
在无子网这个概念之前,假如主机A访问主机B,主机A会判断主机B和自己是不是在同一个网段,即拥有同样的网络号,如果网络号相同则A会通过ARP获得B的MAC地址然后进行通信;如果网络不相同,则将请求发送给默认网关然后再由网关进行路由。
1 | IF ip_net_number(dg.ip_dest) = ip_net_number(my_ip_addr) |
实现子网划分后,主机A判断和主机B是否在同一个子网,如果在同一个子网A会通过ARP获得B的MAC地址然后进行通信;如果不在同一个子网,则将请求发送给默认网关然后再由网关进行路由。
1 | IF bitwise_and(dg.ip_dest, my_ip_mask) = bitwise_and(my_ip_addr,my_ip_mask) |
子网掩码是如何发现的
当网络启动的时候主机如何确定自己的子网掩码呢?
首先主机会从磁盘文件中获取子网掩码信息,如果存在则直接使用;如果磁盘上没有记录子网掩码信息,主机将会发出广播信息以此请求子网掩码。
例子:来自rfc950
- 假如在A类网络
36.0.0.0
有主机IP
为36.40.0.123
,网关为32.40.0.62
,使用8-bit
作为subnet id
则其子掩码为255.255.0.0
。 - 如果主机不知道自己的
IP
地址则会通过RARP
协议获取自己的IP
地址。然后发送ICMP
请求到广播地址255.255.255.255
:
key | val |
---|---|
Source address: | 36.40.0.123 |
Destination address: | 255.255.255.255 |
Protocol: | ICMP = 1 |
Type: | Address Mask Request = AM1 |
Code: | 0 |
Mask: | 0 |
- 然后网关可以直接回复网络包给主机
36.40.0.123
,主机便获取到了自己的子网掩码
key | val |
---|---|
Source address: | 36.40.0.62 |
Destination address: | 36.40.0.123 |
Protocol: | ICMP = 1 |
Type: | Address Mask Request = AM2 |
Code: | 0 |
Mask: | 255.255.0.0 |
- 假如主机根本不知道自己的主机号则会发出如下内容的包。
key | val |
---|---|
Source address: | 0.0.0.0 |
Destination address: | 255.255.255.255 |
Protocol: | ICMP = 1 |
Type: | Address Mask Request = AM1 |
Code: | 0 |
Mask: | 0 |
网关将会收到数据包,然后回复如下内容的数据包:
|key|val|
|—-|—-|
|Source address:|36.40.0.62|
|Destination address:|255.255.255.255|
|Protocol:|ICMP = 1|
|Type:|Address Mask Request = AM2|
|Code:|0|
|Mask:|255.255.0.0|
- 如果主机不允许进行广播消息并且假设主机知道网关的地址,主机刚会直接发数据包给网关请求子网掩码。
无法获取子网掩码的情况
在如下三种情况下,经过多次尝试后仍可能无法获取子网掩码:
1.网络与其它所有网络隔离
2.未使用子网而且没有其它主机可以提供子网掩码
3.此网络上的所有网关都未能启动。
在第一种和第二种情况,子网掩码等于网络号。在第三种情况下,无法确定主机的子网掩码因此最安全的做法就是将子网掩码设置为网络号,虽然可能是错误的。当网关正常工作后,网关会广播Address Mask Reply
类型的数据包,主机收到数据包后,会更正自己的子网掩码。
REF:
1.RFC950
2.tcpipguide.com