以太网数据帧结构
UDP段、IP数据包,以太网帧图示
通信过程中,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示。
不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层主教座数据包(datagram),在链路层叫做帧(frame)。数据封装称帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。
第三行是以太网帧数据包的基本格式。
测试环境
机器名 | mac | ip | port |
---|---|---|---|
tcp_server | 00:0c:29:8b:37:da | 10.1.2.7 | 9502 |
tcp_client | 00:50:56:c0:00:08 | 10.1.2.1 | 12345 |
抓包 客户端向服务端发送 'hello world’
# 原始数据帧 | |
00 0c 29 8b 37 da 00 50 56 c0 00 08 08 00 # Ethernet_II格式数据帧首部 | |
45 00 00 33 28 5b 40 00 80 06 ba 80 0a 01 02 01 0a 01 02 07 # ip协议头 | |
30 39 25 1e 84 a4 e6 82 cf f2 ea 28 50 18 10 0a 7b 45 00 00 # tcp协议头 | |
68 65 6c 6c 6f 20 77 6f 72 6c 64 # data |
以太网数据帧构成
Ethernet_II格式、数据帧首部 链路层
总长度 14B
以太网帧图示
其中,以太网首部占用14字节、FCS(Frame Check Sequece)(帧校验码)长4个字节,用于检验数据在传输过程中数据是否出现了错误,为CRC32校验码。
以太网首部占用14字节,首位开始是目的地址占用六个字节,其次是源地址,占用6个字节,然后是类型占用两个字节。以太网帧除去首部14字节和尾部FCS,4字节,(共18字节)剩下的中间的部分就是IP数据报
字段名称 | 长度(byte) | 含义 |
---|---|---|
D.MAC | 6 | 接收方MAC地址,网络包接收方的MAC地址,在局域网中使用这一地址来传输网络包 |
S.MAC | 6 | 网络包发送方MAC地址,接收方通过它来判断是谁发送了这个包 |
Type | 2 | 使用的协议类型 TCP通信中IP协议与ARP协议较常见 0000-05DC:IEEE802.3 0800:IP协议 0806:ARP协议 86DD:IPv6 |
以太网帧格式
目的MAC地址(6字节) | 源MAC地址(6字节) | 类型(2字节) | 数据(45--1500字节) | CRC |
---|---|---|---|---|
1.IP数据报
目的MAC地址(6B) | 源MAC地址(6B) | 类型0x0800 | IP 数据包 | CRC |
---|---|---|---|---|
2.ARP请求应答
目的MAC地址(6B) | 源MAC地址(6B) | 类型0x0806 | ARP请求应答(28B) | CRC |
---|---|---|---|---|
3.RARP请求应答
目的MAC地址(6B) | 源MAC地址(6B) | 类型0x0835 | RARP请求应答 | CRC |
---|---|---|---|---|
ICMP协议:差错控制协议
ARP协议:地址解析协议
实例
# Ethernet_II格式数据帧首部 14 bytes | |
00 0c 29 8b 37 da # 目标MAC地址 00:0c:29:8b:37:da | |
00 50 56 c0 00 08 # 源MAC地址 00:50:56:c0:00:08 | |
08 00 # IP协议 |
IP协议数据包首部 网络层
总长度 20B+
IP数据报格式如下图所示,IP 数据报文由首部(称为报头)和数据两部分组成。首部的前一部分是固定长度,共 20 字节(如图所示前五行为IP首部),是所有 IP 数据报必须具有的。在首部的固定部分的后面是一些可选字段,其长度是可变的。
字段名称 | 长度(bit) | 含义 |
---|---|---|
版本号(Version) | 4 | 协议的版本一般的值为 0100(IPv4) 0110(IPv6) |
头部长度(IHL) | 4 | Header Length,描述IP包头的长度, 因为在IP包头中有变长的可选部分。长度 = 值 * 4, 4bit最大 ‘1111’ = 15, IP头长度为20 - 60(15 * 4) 字节 |
服务类型(ToS) | 8 | Type of Service,服务类型8位 按位被如下定义 PPP DTRC0 PPP:定义包的优先级,取值越大越重要 000 普通 (Routine) 001 优先的 (Priority) 010 立即的发送 (Immediate) 011 闪电式的 (Flash) 100 比闪电还闪电式的 (Flash Override) 101 CRI/TIC/ECP(找不到这个词的翻译) 110 网间控制 (Internetwork Control) 111 网络控制 (Network Control) D 时延: 0:普通 1:延迟尽量小 T 吞吐量: 0:普通 1:流量尽量大 R 可靠性: 0:普通 1:可靠性尽量大 M 传输成本: 0:普通 1:成本尽量小 0 最后一位被保留,恒定为0<br/ |
总长度 | 16 | Total Length IP包总长度 以字节为单位计算的IP包的长度 (包括头部和数据),所以IP包最大长度65535字节 |
ID号 | 16 | 该字段和Flag和Fragment Offest字段联合使用,对较大的 上层数据包进行分段(fragment)操作。路由器将一个包拆 分后,所有拆分开的小包被标记相同的值,以便目的端设备<br/ >能够区分哪个包属于被拆分开的包的一部分。 |
标志(Flags) | 3 | 长度3比特。该字段第一位不使用。第二位是DF (Don’t Fragment)位,DF位设为1时表明路由器不能对该 上层数据包分段。如果一个上层数据包无法在不分段的情况 下进行转发,则路由器会丢弃该上层数据包并返回一个错误 信息。第三位是MF(More Fragments)位,当路由器对一 个上层数据包分段,则路由器会在除了最后一个分段的IP包 的包头中将MF位设为1。 |
分片偏移量 | 13 | Fragment Offest 表示该IP包在该组分片包中位置,接收端 靠此来组装还原IP包。 |
生存时间(TTL) | 8 | 当IP包进行传送时,先会对该字段赋予某个特定的值。当IP 包经过每一个沿途的路由器的时候,每个沿途的路由器会将 IP包的TTL值减少1。如果TTL减少为0,则该IP包会被丢弃。 这个字段可以防止由于路由环路而导致IP包在网络中不停被转发。 |
协议号 | 8 | 标识了上层所使用的协议。以下是比较常用的协议号: 1 ICMP 2 IGMP 6 TCP 17 UDP 88 IGRP 89 OSPF |
头部校验和 | 16 | Header Checksum 用来做IP头部的正确性检测,但不包含数据部分。 因为每个 路由器要改变TTL的值,所以路由器会为每个通过的数据包重 新计算这个值。 |
发送方IP地址 | 32 | Source Addresses 发送方IP地址。除非使用NAT,否则 整个传输的过程中,这两个地址不会改变 |
接收方IP地址 | 32 | Destination Addresses 接收方IP地址。除非使用NAT,否则 整个传输的过程中,这两个地址不会改变 |
可选字段 | 一般测试使用 |
实例
# ip协议头20字节 | |
4 # 协议版本 ipv4 | |
5 # ip协议头长度 5 * 4 = 20字节 | |
00 # 服务类型 000-0-0-0-0-0 | |
00 33 # ip包总长度 hex => dec 51字节 | |
28 5b # ID号 | |
40 00 # 标志与分片偏移量 0100 0000 0000 0000 DF位为1 不允许分包 偏移量为0 | |
80 # 生存时间 dec 128 | |
06 # 协议号 TCP协议 | |
ba 80 # 头部校验和 | |
0a 01 02 01 # 发送方ip 10.1.2.1 | |
0a 01 02 07 # 接收方ip 10.1.2.7 | |
# ip协议头 头部校验和计算方法 | |
# 1. 头部校验和置0; | |
# 2. 对IP头部中的每16bit进行二进制求和; | |
# 3. 如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的 值; | |
# 4. 将该16bit的值取反,存入校验和字段。 |
TCP协议头 传输层
图示
总长度 20B+
字段名 | 长度(bit) | 含义 |
---|---|---|
源端口号 | 16 | 发送网络包的程序的端口号 |
目的端口号 | 16 | 网络包的接收方程序的端口号 |
序列号 seq | 32 | 发送的时候,TCP 协议为每个包编号(sequence number, 简称 SEQ),以便接收的一方按照顺序还原。万一发生丢包 ,也可以知道丢失的是哪一个包。 当前序列号 + 数据长度 = 下一个包的序列号 |
确认序列号 ack | 32 | 期待要收到下一个数据包的编号,ack与seq搭配确保数据的 完整性,确认号只有ACK位为1时才有效。 |
首部长度(数据偏移量) | 4 | 表示数据部分的起始位置,也可以认为表示头部的长度 |
保留 | 6 | 保留,未使用 |
控制位 | 6 | 该字段中的每个比特分别表示以下通信控制含义。 URG:表示紧急指针字段有效 ACK:接收数据序号字段有效,一般表示数据已被接收方接收 该位只有在连接未建立时为0,连接建立后始终为1 PSH:表示通过flush操作发送的数据,指示接收方在接收到 该报文段以后,应尽快将这个报文段交给应用程序,而不是 在缓冲区排队。 RST:强制断开连接,用于异常中断的情况 SYN:同步序号,用于建立连接过程,在连接请求中发送SYN=1 和ACK=0 , 应答 SYN=1和ACK=1 FIN:用于释放连接,为1时表示发送方已经没有数据发送了, 即关闭本方数据流。 |
窗口 | 16 | 接收方告知发送方窗口大小(即无需等待确认可一起发送的数据量) |
校验和 | 16 | 用来检查是否出现错误 |
紧急指针 | 16 | 只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个 正的偏移量,和顺序号字段中的值相加表示紧急数据最后一 个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急 数据的一种方式。 |
选项和填充 | 不定 | 最常见的可选字段是最长报文大小,又称为MSS (Maximum Segment Size),每个连接方通常都在通 信的第一个报文段(为建立连接而设置SYN标志为1的那 个段)中指明这个选项,它表示本端所能接受的最大报 文段的长度。选项长度不一定是32位的整数倍,所以要 加填充位,即在这个字段中加入额外的零,以保证TCP 头是32的整数倍。 |
数据 | 可选 |
实例
# tcp协议头 20字节 | |
30 39 # 源端口 12345 | |
25 1e # 目的端口 9502 | |
84 a4 e6 82 # 序列号 | |
cf f2 ea 28 # 确认序列号 | |
5 # 首部长度 5 * 32 / 8 = 20 bytes | |
0 1 8 # 000000 保留 011000 ACK=1 PSH=1 | |
10 0a # 窗口大小 4106 | |
7b 45 # 校验和 | |
00 00 # URG=0 无效 | |
# 传输的数据 | |
68 65 6c 6c 6f 20 77 6f 72 6c 64 # ascii码 | |
h e l l o w o r l d |
附录
每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。举例来说,现在收到了4号包,但是没有收到5号包。ACK 就会记录,期待收到5号包。过了一段时间,5号包收到了,那么下一轮 ACK 会更新编号。如果5号包还是没收到,但是收到了6号包或7号包,那么 ACK 里面的编号不会变化,总是显示5号包。这会导致大量重复内容的 ACK。如果发送方发现收到三个连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即5号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。 |
UDP协议
例题讲解
(1)Client段和Server段的以太网网卡48位地址是[填空1]和[填空2] | |
根据以太网数据帧(OSI二层)的数据包头部,分别是目的MAC地址(6字节)、源MAC地址(6字节)、类型(2字节),所以根据上图Frame#1帧中的前6个字节是Client MAC地址,紧接着6个字节是 Server端地址。 | |
分别是: | |
填空1:00-80-c8-5a-e3-88 | |
填空2:00-60-2f-87-01-03 | |
(2)Frame#1帧中封装的IP分组的总长度[填空3]首部长度[填空4]IP数据长度[填空5]。 # 44 20 24 | |
Frame1帧总长度58字节,由于题干说,已通过侦差错校验,所以这个以太网帧不包含FCS帧(4字节) ,所以IP数据报的长度应该是Frame1帧总长度58字节减去以太网帧首部14字节,IP分组的长度应该是44字节,IP首部长度是固定不变的20B(记下来就行),IP数据部分长度是44B-20B=24B | |
(3) Client段和Server段的32位IP地址(用点分十进制格式表示)[填空6]和[填空7]。 | |
根据Ip数据包的20字节长度中IP地址的排列位置,可知源Ip地址(4字节)和目的IP地址(4字节)分别在20字节的后八个字节中。58-14-20+8=32,从Frame#1帧中的倒数第32个字节(两个16进制数是1个字节)往后数8个字节。 | |
0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 | |
0 1 2 3 4 5 6 7 8 9 a b c d e f | |
# IP 首部20个字节 | |
58-14B(帧首部)=44字节(IP数据包)=20字节(IP首部)+24(上层数据udp/tcp) | |
8c 80 63 05 # client Ip地址 140.128.99.5 | |
10001100 10000000 01100011 00000101 | |
140 128 99 5 | |
8c 80 64 74 # server IP地址 140.128.100.116 | |
10001100 10000000 01100100 01110100 | |
140 128 100 116 | |
(4) Frame#1帧中封装的IP分组和生存时间值是[填空8]协议字段值是[填空9]。# 63 6 | |
先从Frame#1帧中找到生存时间值(1个字节)对应的十六进制数,14+4+4=22,Frame#1帧中的第23个字节就是TTL了。TTL的十六进制数为3f(0011 1111),转换成十进制为2^6-1=63 | |
协议字段(1字节)值的十六进制数为06,就是十进制的6了。 | |
(5) IP分组中封装的是[填空10]的数据 # tcp | |
由于本题建立的是TCP链接,所以以太网帧封装的是TCP段。 | |
58-14(Frame帧头)-20(IP包头)=24字节 | |
24字节-20字节(TCP头部长度)=4(应用层数据),也即是seq(4字节),就是TCP三次握手中的第一次(请求建立连接的一方) |
分类: 网络编程