Ethan Zhu
©️朱俊辉
All Rights Reserved.

从ifconfig浅谈IP

我们都知道如何查看IP地址,windows上用ipconfig,linux上用ifconfig。
当然,linux上还有其他命令查看ip地址,例如ip addr。
如果你问同样是查看ip地址,ifconfig和ip addr有什么区别吗?这是一个有关net-tools和iproute2的“历史”故事,详细可以去搜索了解一下。

别的不说,我在我的linux上运行一下ip addr,会输出下面的内容

root@test:~# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether fa:16:3e:c7:79:75 brd ff:ff:ff:ff:ff:ff
inet 10.100.122.2/24 brd 10.100.122.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fec7:7975/64 scope link
valid_lft forever preferred_lft forever

这条命令显示了这台机器上所有的网卡。大部分网卡都会有一个IP地址。

ip地址是一个网卡在网络世界的通讯地址,就等同于现实世界中的门牌号码。
我们先来看一下IP地址的结构:
IP地址 = 网络地址 + 主机地址
IP Address = Network ID + Host ID

这很好理解,大家都是六单元1001号,只不过我是A小区的六单元1001,而你是B小区的六单元1001。
上面输出结果中的10.100.122.2就是一个IP地址,这个地址被分为4个部分,每个部分8个bit,所以IP地址总共是32位。

我们如何确定哪部分是 Network ID,哪一部分又是 Host ID 呢?我们有请子网掩码(subnet mask)。
简单来说,subnet mask 就是为了分割 Network ID 和 Host ID 的。subnet mask 也有一段有趣的进化历史,值得一提,如何切割 IP 地址经历了一个从「偷懒」到「机智」的过程。

上图中就是一个「偷懒」的设计方式,可能是没有料到今天会有如此多的计算机。
这里就简单说下前三类,A、B、C类地址。
A类:第一个字节为 Network ID,剩下三个字节为 Host ID
B类:第二个字节为 Network ID,剩下两个字节为 Host ID
C类:第三个字节为 Network ID,剩下一个字节为 Host ID

那如何区分IP地址是哪一类地址呢?
我这里先举例一个IP地址的10进制和2进制
192.168.10.84
11000000.10101000.00001010.1010100

如果第一个字节的起始比特位为 0,则是 A 类地址。
如果第一个字节的起始比特位为 10,则是 B 类地址。
如果第一个字节的起始比特位为 110,则是 C 类地址。
对比上图可以发现,这段IP地址是C类地址

上图就是偷懒型IP分隔方式,漏洞很明显,就是C类地址能包含的最大主机数量实在太少了(当初设计的时候恐怕也没想到,现在估计一个网吧都不够用吧)。而B类地址能包含的主机数量又太多了,6万多台机器放在一个网络下面,一般的企业基本达不到这个规模,闲着的地址就是浪费。后来就有人提出了CIDR来解决前面「偷懒」挖的坑,这也是如今IP所使用的切割方式。

CIDR——Classless Inter-Domain Routing-无类别域间路由

这种方式打破了原来设计的几类地址的做法,将32位的IP地址一分为二,从哪里分呢?如果你注意观察可以看到,上线ifconfig中输出的10.100.122.2/24,这个IP地址中有一个斜杠,斜杠后面有个数字24 ,数字24就是掩码位,这种地址表示形式,就是CIDR。后面24的意思是,32为中,前24位是网络号,后8位是主机号。

如果ip为10.100.122.2/23,由于掩码位是23,可以算出子网掩码的二进制为:
11111111.11111111.11111110.00000000
十进制就是255.255.254.0。这就是子网掩码
由于 Host ID 占用 9 个 bits,这个子网里一共可以有 2 的 9 次方个主机数,也就是 512 个主机,这个子网网段的起始地址为 10.100.122.0,结束地址为  10.100.123.255。我们对于某一个网段内的 IP 地址,有个约定,第一个地址为 Network ID,最后一个地址是该子网内的 Broadcast ID,那么剩下的可用于子网内设备的 IP 地址数量就是 510 个了。

总结:CIDR notation 只是为了以更小的粒度来切分 Network ID 和 Host ID,为了方便路由器能正确的识别出 IP 地址的结构,从而进行路由。

2019-08-23

发表评论