TCP/IP 系列之 Header 篇

这是 TCP/IP 系列的第二篇,阅读目标是建立对网络包结构的初步认识。

上一篇里,我们提到一次完整的 TCP 会话其实是一个字节流,只不过我们可以按照一定的规则来切割这个字节流,从而划分出一个个的网络包。我们经常说抓包分析网络故障,这个抓包里所指的包在不同的语境下其实意义并不相同,首先我们得对包的构成形成具象的认知。

再看七层协议

刚毕业那会,大家都喜欢在简历上写「精通 TCP/IP 协议」,面试被问起时就必答三次握手和 OSI 七层模型,再多就说不出来了。问七层模型是什么就机械式的从上至下背诵一遍,这离精通还差了一本【TCP/IP 详解】。

我在完整的学习过一遍网络协议栈之后,深感所谓的七层模型是偏工业的说法,看到七层协议图之后,其实很难明白这七层是如何一层层互相构成的,更符合大脑感官的是另一种认知形式,是一种洋葱形的结构,层层叠叠互相包裹,可以用下图表示:

左边是教材上的结构,右边是我所说的洋葱式的结构。如果以一个 HTTP 请求为例,右图中 Application 部分就代表我们用 Charles 抓包时所感知的部分,这一部分要最后转化为光信号,在光纤中传输,还需要经过一层层的转化,这个转化过程说白了,就是在每一层加上一个 header。

  • Application 层(HTTP)的数据在经过传输层(TCP Layer)的时候,会加上 TCP 的 header,成为一个 TCP Segment。
  • 传输层(TCP)的 Segment 在经过网络层(IP Layer)的时候,会加上 IP 的 header,成为一个 IP Packet。
  • 网络层的 IP Packet 在经过链路层(Link Layer)的时候,会加上Link Layer 的 header,成为一个 Frame。
  • 最后 Frame 会在物理层,将数字信号转化为物理信号传输。

这里值得特别注意的是,在每一层,有不同的英文术语来对应包的概念,比如在 TCP 层的包叫做 Segment,在 IP 层的叫做 Packet,在链路层的叫做 Frame,另外和 TCP 位于同一层的 UDP 包我们一般叫做 Datagram,不同协议层里术语并不一样,好处是,在交流的时候,我们选择不同的英文单词就能预先确立是在那一层讨论协议。而 Segment、Packet、Frame、Datagram 等翻译成中文的时候,都是译为「包」,大家说读英文原版资料是不是更好,这些术语我们需要特别记忆,可以对照下图:

 +-------------+-------------------------+
 | Application |  HTTP Packet            |
 +-------------+-------------------------+
 | Transport   |  TCP Segment            |
 +-------------+-------------------------+
 | Network     |  IP Packet              |
 +-------------+-------------------------+
 | Link        |  Frame                  | 
 +-------------+-------------------------+         光纤
 | Physical    |  Bits                   | ====================> 
 +-------------+-------------------------+

不过有些场景下,我们也会用 Packet 来泛指每一层的包,但是用每一层自己的术语会更准确和专业,这些行话和习惯我们也需要了解。

我们可以用一个公式来表示每一层协议的构成:

Packet = Protocol Header + Payload

每一层的包都可以用这个公式来表示。Payload 指传入这一层的数据内容,比如:

TCP Segment = TCP header + HTTP data

有了这个认知之后,对于每一层协议的学习,最后就落实到每一层 header 的学习上了,学习 TCP 就是研究 TCP header 的构成,header 里的每一个 bit 位都有特别的用处,来实现协议层对于网络传输的控制。这也是为什么我经常会说,所谓的网络协议学习就是 header 学习,这也是本文标题的含义所在。

深入 Header

【TCP/IP 详解】大致有 1000 页,通读的过程会很漫长且枯燥,知道每一层协议都是关于 header 的设计之后,大家其实可以先跳跃式的阅读,先学习感兴趣的部分,有了收获知识的正向反馈之后,在回过头来填补更多的知识细节。比如大家一般都对 TCP 协议比较感兴趣(确实也是最有意思的部分,后面的文章也重点分析),那么可以先跳到第十二章:

Chapter 12 TCP: The Transmission Control Protocol(Preliminaries)

或者第十三章,真正明白所谓的三次握手:

Chapter 13 TCP Connection Management

由于每一层的设计都是独立的,所以先学习传输层并不会有什么障碍,这也是分层架构的意义所在,各层各司其职,互不依赖具体的实现。

我们的学习行为,大致上可以分为两类,理解(理解思想)和记忆(强行记忆)。对于 header 的学习,除了理解 header 每个 bit 的意义之外,还需要一些记忆行为,对于一些关键信息的强制性记忆,有助于我们形成更深刻的认知。我们以 TCP 的 header 为例:

上图是一个 TCP header,以下是一些需要「死记硬背」的信息点:

一个 TCP Header 一般有 20 个字节,如果启用了 options,header的长度可以达到 60 个字节。上图中每一行是 4 个 bytes,32 个 bits。我先带大家学习下前 5 行,每一行是 4 Bytes,五行刚好是 20 个 bytes。计算机世界中,通常会以 bit,byte,word(4 个 byte)等不同粒度来描述信息,header 的学习一般是以 4 个字节为一个单位来展示的。

  • 第一行,由 Source port 和 Destination port 构成,二者各占 2 个字节,刚好一起占据第一行的 4 个字节。这两个字段分别表示 TCP 连接中的,发送方端口号和接收方的端口号,既然一个 port 只占 2 个 bytes,那么端口值的范围自然就是 0~65535 啦。
  • 第二行,Sequence number,表示发送方的序列号。这个序列号表示的是什么呢?一个 TCP 流是有无数个 0 和 1 构成,这些 0 和 1 以 8 个 bit 为单位,可以分割成一个个的 byte,TCP 是可靠传输协议,每一个 byte 都是有标号的,因为我们需要追踪每个 byte 是否被成功传输了,每个 byte 的标号就是我们这里的 sequence number。假设我们建立 TCP 连接的时候,发一个 sync 包,我们就以 0 标记 sync 包的第一个字节,那么 sync 包中的 Sequence 值就是 0。实际应用中,处于安全考虑,TCP 流的第一个 Sequence number 一般不会是 0,而是一个随机数。Sequence number 占据 4 个字节,也就是 2 的 32 次方,这个数字并不算大,每个包都会用掉一些,如果达到最大值之后,就取余从 0 重新开始。
  • 第三行,Acknowledge number,表示接收方 ack 的序列号。接收方收到发送方一个的 TCP 包之后,取出其中的 sequence number,在下一个接收方自己要发送的包中,设置 ack 比特位为 1,同时设置 acknowledge number 为 sequence number + 1。所以接收方的 acknowledge number 表示的是,接收方期待接收的下一个包起始字节的标号,大家可以仔细理解下这一句话。所以 acknowledge number 和 sequence number 是配对使用的。
  • 第四行,这一行尤其重要,出于篇幅的考虑,其中细节会在后续的文章中讲解。这里简单提下从 CWR 到 FIN 的 8 个 bit,这 8 个 bit 里每一位都是一个标记位,用来标记当前 TCP 包的特殊含义。比如我们所说的三次握手,第一个 sync 包,就是将 SYN 位置为 1。第二个 syn + ack 包就是将 header 的 ACK 和 SYN 位都置为 1。第三个 ack 包即将 ACK 位置 1。剩余的几个 bit 位暂时不展开讲了,大家可以自己看书先学习下。
  • 第五行,这一行只有两个字段,即 Checksum 和 Urgent pointer。checksum 是个通用的计算机概念,做完整性校验之用,在很多协议(IP,UDP,ICMP)中都有应用,这个值有包的发送方去计算,之后由包的接收方取出来校验。Urgent pointer 为两个字节的偏移量,加上当前包的 sequence number,用来标记某一个范围内的 bytes 为特殊用途数据。

怎么样、其实没有多少信息量对不对?这么跟着理解一遍 header 中的每一个 bytes 之后,是不是加深了对 TCP 的理解呢?

同理,学习完 TCP 的 header 之后,大家可以再去把 IP 的 header,frame 的 header 都搜索出来,对照关键字段去理解学习,最后再配合【TCP/IP 详解】一书阅读效果更好。

Tcpdump 实战

上面是理论部分,可能有些枯燥,大家可以在理解之后,使用 tcpdump 抓包实战下,进一步加深理解。我们就来抓包,基于上面 tcp header 的学习,抓下三次握手的包 :)

我们可以用如下命令来抓三次握手的包:

sudo tcpdump -i en0 "tcp[tcpflags] & (tcp-syn|tcp-ack) != 0"

输出结果为:

  • 18:18:45.687476 IP 192.168.3.7.65284 > 59.37.116.101.https: Flags [S], seq 3942311653, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 589105996 ecr 0,sackOK,eol], length 0
  • 18:18:45.719744 IP 59.37.116.101.https > 192.168.3.7.65284: Flags [S.], seq 303118583, ack 3942311654, win 14280, options [mss 1412,sackOK,TS val 1712930033 ecr 589105996,nop,wscale 8], length 0
  • 18:18:45.719986 IP 192.168.3.7.65284 > 59.37.116.101.https: Flags [.], ack 1, win 4112, options [nop,nop,TS val 589106029 ecr 1712930033], length 0

你能根据上面 tcp header 的学习,理解上面 tcpdump 命令的含义吗?tcpflags 指的是 header 中的哪些位呢?

对于 tcpdump 的使用还不太了解的同学,可以翻阅我之前的一篇介绍文章。

当然 TCP 里还包含着很多有趣的知识点,大家可以先行阅读,后面我会逐步讲解,比如 TCP 的 ARQ 机制,Flow Control 等。

总结

这次新启的 TCP/IP 系列文章对我来说,会是一次耗时费力,旷日持久的旅途。希望能够慢火细熬,徐徐烹制,将这道倾注心力、营养丰盛的网络协议佳肴制作完成,与君共享。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容