To be continued...
IPv6简述
IPv6是Internet Protocol Version 6的缩写,其中Internet Protocol译为“互联网协议”。
IPv6是IETF(互联网工程任务组,Internet Engineering Task Force)设计的用于替代IPv4的下一代IP协议,号称可以为全世界的每一粒沙子编上一个网址。
由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍。
表示方法
- 点分十六进制表示法。
IPv6的地址长度为128位,是IPv4地址长度的4倍。于是IPv4点分十进制格式不再适用,采用十六进制表示。IPv6有3种表示方法。
-
冒分十六进制表示法
格式为X:X:X:X:X:X:X:X,其中每个X表示地址中的16b,以十六进制表示,例如:
ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
这种表示法中,每个X的前导0是可以省略的,例如:
2001:0DB8:0000:0023:0008:0800:200C:417A→ 2001:DB8:0:23:8:800:200C:417A -
0位压缩表示法
在某些情况下,一个IPv6地址中间可能包含很长的一段0,可以把连续的一段0压缩为“::”。但为保证地址解析的唯一性,地址中”::”只能出现一次,例如:
FF01:0:0:0:0:0:0:1101 → FF01::1101
0:0:0:0:0:0:0:1 → ::1
0:0:0:0:0:0:0:0 → ::
- 内嵌IPv4地址表示法
为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六进制表示,而最后32b地址则使用IPv4的点分十进制表示,
例如::192.168.0.1与::FFFF:192.168.0.1就是两个典型的例子,注意在前96b中,压缩0位的方法依旧适用。如net/ip.go所示:
var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
- 网络传输数值格式表示法。
IPv6的地址长度为128位,总共16个字节,数值格式表示法直接取16个数值即可。每字节的大小为0-FF(255),点分十六进制表示法中的每段大小为0-FFFF(65535)。
总结:IPv6的解析比IPv4解析相对复杂,但是inet组织提供了相互转换的函数接口,直接将点分十六进制表示法与网络传输数值格式表示法之间进行转换。
对于IPv4地址和IPv6地址都适用,函数中p和n分别代表表达(presentation)和数值(numeric)。
#include <arpe/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr); //将点分十进制的ip地址转化为用于网络传输的数值格式
返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len); //将数值格式转化为点分十进制的ip地址格式
返回值:若成功则为指向结构的指针,若出错则为NULL
CIDR
CIDR全称Classless Inter-Domain Routing(无类域间路由),相比CIDR,现在全球的IPv4地址(通过32位比特位表示)早在上世纪80年代就被划分成了A、B、C、D、E五大类地址,其中A类地址的比特位以0开头,B类地址以10打头,C类地址以110打头,D类地址以1110打头,E类地址以1111打头。其中D类地址主要用于路由组播,E类地址暂时保留。每一类地址剩余的比特部分又被划分为网络和主机两部分,具体划分请见下图:
每一类IP地址具体范围如下图所示,其中A、B、C三类地址各自预留了一块内网保留地址。
虽然有了这五类地址(实际可利用的只有三类)的划分,但是IPv4地址资源的分配要比这个细得多,毕竟全球那么多组织和企业在伸手要,为了对这几大类IP地址更加细分,相关组织引入了通过掩码来细化IP段,从而进行更细粒度的分配。IPv4的掩码与IP地址一样也是用32位比特位进行表示,我们可以在IP地址后面加一个“
/XX”来指明用于CIDR的掩码,其中XX为一个不大于32的数字,例如如果指定XX=22,那么就表明要使用“11111111.11111111.11111100.00000000”(22个比特1+10个比特0)作为IP细分的掩码,这种做法相当于不再只单独使用原来的ABCDE五类地址来划分IP地址,因此名字中使用了Classless这个词。
(ENV) ➜ /Users/xsky/go/src/ ☞ git:(master) ✗ ipcalc 192.168.129.53/14
Address: 192.168.129.53 11000000.101010 00.10000001.00110101
Netmask: 255.252.0.0 = 14 11111111.111111 00.00000000.00000000
Wildcard: 0.3.255.255 00000000.000000 11.11111111.11111111
=>
Network: 192.168.0.0/14 11000000.101010 00.00000000.00000000
HostMin: 192.168.0.1 11000000.101010 00.00000000.00000001
HostMax: 192.171.255.254 11000000.101010 11.11111111.11111110
Broadcast: 192.171.255.255 11000000.101010 11.11111111.11111111
Hosts/Net: 262142 Class C, In Part Private Internet
ARP
ARP为IP地址到对应的硬件地址直接提供动态的映射。
Address Resolution Protocol (ARP) Message Format
ARP
Linux Bridge
基本概念
bridge是一个虚拟网络设备,具有网络设备的特性(可以配置IP、MAC地址等);而且bridge还是一个虚拟交换机,和物理交换机设备功能类似。网桥是一种在链路层实现中继,对帧进行转发的技术,根据MAC分区块,可隔离碰撞,将网络的多个网段在数据链路层连接起来的网络设备。
对于普通的物理设备来说,只有两端,从一段进来的数据会从另一端出去,比如物理网卡从外面网络中收到的数据会转发到内核协议栈中,而从协议栈过来的数据会转发到外面的物理网络中。而bridge不同,bridge有多个端口,数据可以从任何端口进来,进来之后从哪个口出去原理与物理交换机类似,需要看mac地址。
bridge是建立在从设备上(物理设备、虚拟设备、vlan设备等,即attach一个从设备,类似于现实世界中的交换机和一个用户终端之间连接了一根网线),并且可以为bridge配置一个IP(参考LinuxBridge MAC地址行为),这样该主机就可以通过这个bridge设备与网络中的其他主机进行通信了。另外它的从设备被虚拟化为端口port,它们的IP及MAC都不在可用,且它们被设置为接受任何包,最终由bridge设备来决定数据包的去向:接收到本机、转发、丢弃、广播。
发送功能
接收功能
数据结构框图:
作用
bridge是用于连接两个不同网段的常见手段,不同网络段通过bridge连接后就如同在一个网段一样,工作原理很简单就是L2数据链路层进行数据包的转发。bridge如果没有指定hw MAC, br0的MAC地址会根据bridge中port的变化,自动选择port中最小的一个MAC地址作为bridge的MAC地址。
(ENV) [root@ceph-2 ~]# ip link add br-mac type bridge
(ENV) [root@ceph-2 ~]# ip link add mac-veth01 type veth peer name mac-veth02
(ENV) [root@ceph-2 ~]# ip a
15: br-mac: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 46:20:38:68:60:bf brd ff:ff:ff:ff:ff:ff
16: mac-veth02@mac-veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a1 brd ff:ff:ff:ff:ff:ff
17: mac-veth01@mac-veth02: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 66:e7:7c:34:ad:18 brd ff:ff:ff:ff:ff:ff
(ENV) [root@ceph-2 ~]# ip link set dev mac-veth01 master br-mac
(ENV) [root@ceph-2 ~]# ip a
15: br-mac: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 66:e7:7c:34:ad:18 brd ff:ff:ff:ff:ff:ff // 可以看到bridge的Mac地址变为和mac-veth01一样
16: mac-veth02@mac-veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a1 brd ff:ff:ff:ff:ff:ff
17: mac-veth01@mac-veth02: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 66:e7:7c:34:ad:18 brd ff:ff:ff:ff:ff:ff
(ENV) [root@ceph-2 ~]# ip link set dev mac-veth02 master br-mac
(ENV) [root@ceph-2 ~]# ip a
15: br-mac: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a1 brd ff:ff:ff:ff:ff:ff // 可以看到bridge的Mac地址变为和mac-veth02一样
16: mac-veth02@mac-veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a1 brd ff:ff:ff:ff:ff:ff
17: mac-veth01@mac-veth02: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 66:e7:7c:34:ad:18 brd ff:ff:ff:ff:ff:ff
(ENV) [root@ceph-2 ~]# ifconfig mac-veth02 hw ether 56:da:6e:b5:e3:a0 // 修改mac-veth02的mac地址
(ENV) [root@ceph-2 ~]# ip a
15: br-mac: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a0 brd ff:ff:ff:ff:ff:ff // 可以看到bridge的Mac地址变为和mac-veth02一样
16: mac-veth02@mac-veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a0 brd ff:ff:ff:ff:ff:ff
17: mac-veth01@mac-veth02: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 66:e7:7c:34:ad:18 brd ff:ff:ff:ff:ff:ff
(ENV) [root@ceph-2 ~]# ifconfig mac-veth01 hw ether 56:da:6e:b5:e3:10 // 修改mac-veth01的mac地址
(ENV) [root@ceph-2 ~]# ip a
15: br-mac: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:10 brd ff:ff:ff:ff:ff:ff // 可以看到bridge的Mac地址变为和mac-veth01一样
16: mac-veth02@mac-veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:a0 brd ff:ff:ff:ff:ff:ff
17: mac-veth01@mac-veth02: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br-mac state DOWN qlen 1000
link/ether 56:da:6e:b5:e3:10 brd ff:ff:ff:ff:ff:ff
(ENV) [root@ceph-2 ~]#
总结
网桥是在链路层上对网络进行互连,而路由器则是在网络层上对网络进行互连。
TCP/IP
在TCP/IP协议族中, 网络层IP提供的是一种不可靠的服务,也就是说,它只是尽可能快地把packet从源节点送到目的节点,但是并不提供任何可靠性保证。而另一方面,TCP在不可靠的IP层上提供了一个可靠的运输层。为了提供这种可靠的服务,TCP采用了超时重传、发送和接收端到端的确认分组等机制。
IP是TCP/IP协议族中最为核心的协议。所有的TCP,UDP,ICMP及IGMP数据都是以IP数据报格式传输。IP在其header中存入了一个8bit的数值字段Protocol,以表明数据属于那一层,详细可查看 List of IP protocol numbers
- 不可靠(unreliable)它不能保证IP数据报能成功地到达目的地。任何要求的可靠性必须由上层来提供(例如TCP)。
- 无连接(connectionless)IP并不维护任何关于后续数据报的状态信息,每个数据报的处理是独立的。这也说明,IP数据报可以不按发送顺序接收。
ICMP
ICMP是IP层协议的附属协议。IP层用它来于其他主机或者路由器交换错误报文和其他重要信息。有一些网络工具是基于ICMP报文,例如traceroute,ping等。如果我们关闭ICMP回应功能,则可能导致ping无法接收到应答。
(ENV) [root@10.255.101.74 ~]# cat /proc/sys/net/ipv4/icmp_echo_ignore_all
0
(ENV) [root@10.255.101.74 ~]# echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all
(ENV) 🍺 /Users/xsky/go/src/xsky-demon ☞ git:(master) ✗ ping 10.255.101.74
PING 10.255.101.74 (10.255.101.74): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
Request timeout for icmp_seq 5
^C
--- 10.255.101.74 ping statistics ---
7 packets transmitted, 0 packets received, 100.0% packet loss
需要注意的是:
- ICMP是基于IP协议工作的,但是它并不是传输层的功能,因此仍然把它归结为网络层协议。
- ping命令是基于ICMP,是在网络层。而端口号,是传输层的内容。所以在ICMP中根本就不关注端口号这样的信息。例如一般情况下telnet是23端口,ssh是22端口。
NAT
有四种类型的NAT:
-
Static NAT(SNAT) -
Dynamic NAT(DNAT)
The mapping of internal private IP address into the router's public IP address is not static, but dynamic. Dynamic NAT is also calledIP masquerading, because it masks the internal hosts and makes it difficult for external hackers to monitor specific host. -
PAT(Port Address Translation)
With PAT, each host on a LAN is translated to the router's WAN-side public IP address, with a different port number assignment. Port numbers are used to map traffic from specific hosts on the network. -
Port Forwarding
Port forwarding deals more with incoming traffic, and the typical scenario is when you have only one public IP address but with several public servers.
Linux系统接收网络报文
- 首先网络报文通过物理网线发送到网卡。
- 网络驱动程序会把网络中的报文读出来放到 ring buffer 中,这个过程使用 DMA(Direct Memory Access),不需要 CPU 参与。
- 内核从 ring buffer 中读取报文进行处理,执行 IP 和 TCP/UDP 层的逻辑,最后把报文放到应用程序的 socket buffer 中。
-
应用程序从 socket buffer 中读取报文进行处理。
以太网数据帧的分用过程
广播和多播
- 多播地址为
D类地址,以1110开头,范围从224.0.0.0到239.255.255.255。 - 使用同一个 IP 多播地址接收多播数据包的所有主机构成了一个主机组(host group),也称为
多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。 - IPv4 的
D 类地址是多播地址。IEEE 把一块以太网多播组地址分给 IANA 以支持IP多播。块的地址都以01:00:5e开头,第25位为 0,低23 位为 IPv4 多播地址( D类地址 )的低 23 位。IPv4 多播地址与 MAC 地!
址的映射关系如图所示:
- 由于多播地址( D类地址 )中的最高
5bit在映射过程中被忽略,因此每个以太网多播地址对应的多播组是不唯一的。32 个不同的多播组号被映射为一个以太网地址。
Namespaces
References
- 使用Go语言计算网络IP地址的CIDR
- Address Resolution Protocol
- libvirt Networking
- Introduction to Linux interfaces for virtual networking
- Linux-虚拟网络设备-LinuxBridge
- Linux下的虚拟Bridge实现
- Custom NAT-based network
- ICMP协议详解
- linux 系统 UDP 丢包问题分析思路
- Multicast IP Address to MAC address mapping
- 多播地址基础
- 如何快速算出192.168.1.53/27的广播地址?
- “三次握手,四次挥手”你真的懂吗?















网友评论