V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
such
V2EX  ›  程序员

从 Ethernet 到 TCP

  •  
  •   such ·
    8090lambert · 2019-11-01 19:56:07 +08:00 · 1757 次点击
    这是一个创建于 1637 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以太网帧格式

    " 以太网是一种计算机局域网技术。IEEE 组织的 IEEE 802.3 标准制定了以太网的技术标准,它规定了包括物理层的连线、电子信号和介质访问层协议的内容。以太网是目前应用最普遍的局域网技术,取代了其他局域网技术如令牌环、FDDI 和 ARCNET。" -- Wiki 百科

    从 Xerox 公布的 Ethernet I 发展到现在,有过 6 种以太帧格式:

    • Ethernet I
    • Ethernet II
    • Ethernet 802.3 raw
    • Ethernet 802.3 SAP
    • 802.3/802.2 LLC
    • 802.3/802.2 SNAP

    其中主流应用的是 Ethernet II、802.3/802.2 LLC、802.3/802.2 SNAP 这三种,最常用的是 RFC894 定义,也就是 Ethernet II 的帧格式。

    Ethernet II

    • 目标 MAC 地址:6 个字节( 48 位),发送时会先检查目标 MAC 的地址,与当前适配器的物理地址是否一致,不一致就丢弃;
    • 源 MAC 地址:6 个字段( 48 位),发送帧的网络适配器物理地址
    • 类型:上层协议的类型,常见的有,0x0800 表示是 IPV4 协议,0x0806 表示是 ARP 协议,0x86DD 表示是 IPV6 协议,更多详见
    • 数据报文:最小 46 字节,最大 1500 字节( MTU )

    802.3/802.2 LLC

    • DASP:1 个字节,目的服务访问点
    • SSAP:1 个字节,源服务访问点 将 Ethernet II 帧头的类型字段替换为帧长度,并且因为新增加了 DASP, SSAP,Control 这三个各占 1 字节的字段,报文的长度也调整为:43~1497,它们三个字段作为 LLC 的头

    802.3/802.2 SNAP

    • 类型:2 个字节,不同于 Ethernet II 的类型字段
    • OUI ID:3 个字节,通常都为 0 数据报文变为:38~1492 字节

    Ethernet 帧,从最上层(应用层)发送的数据单元( PDU ),每经过一层,都会把上层整个的 PDU 作为下层 PDU 的 data 域,然后加上 自己的协议头;接受端,同下而上的层层拆掉每层的头部。了解了这些,我们尝试抓包具体分析每个字段

    Tcp 报文

    $ tcpdump -i eth1 port 9527 -s 0 -w ./target9527.capwireshark 打开抓到的二进制报文,如图所示:

    建立连接

    Frame 1,表示第 1 帧,源 ip 和目的 ip 分别是:172.24.31.67 和 10.96.77.128 ,都是内网 ip。

    • type:0x0800 表示 IPV4
    • 源 MAC 地址:04:25:c5:83:f5:64
    • 目标设备 mac 地址:5e:38:57:10:84:d9
    • Flags:0x4000,没有拆包,如果请求报文大于 MTU,会拆多次发送
    • Times to live:ttl,存活时间,数据包每经过一个三层路由器设备时,ttl 域的值减 1,当其存活次数为 0 时,便会取消数据包的转发。ttl,默认值是 64,如下图,经过 14 次到达目标 ip,所有 64-13=51
    • SYN:1,表示 请求及建立连接,包括剩下的两次握手请求包

    发送数据包

    从 Frame 4 至 Frame 7 是建立连接后,发送具体请求的数据包。首先,发送了 HTTP 协议的 GET 请求,收到请求后回复了 ACK。具体看下:

    • 在 GET 请求时,设置了标志位 ACK 和 PSHPSH 是告诉接收端,立即交由应用层处理而不必等到Recv socket buffer写满
    • 接收端回复 ACK 和 Seq number,接收端和发送端同样会再回复一个PSH标记的包,要求立即处理
    • 最后,应用层通过 HTTP 协议回复报文,在回复报文时,这里要注意还有个标志位,在报文中,FIN=1,表示在返回的同时请求关闭连接

    断开连接

    tcp 连接是双工的,所以任何建立连接的双方都可以发起关闭连接的请求。自己之前面试也总喜欢问这些问题,看看候选人到底理解的是否透彻, 可是大多数都不怎么清楚。言归正传,剩下的 Frame 8 至 Frame 11 是回复详情的 ACK 和 端开连接的 tcp 包。

    • Frame 8 和 Frame 9,分别回复的是,Frame 6 PSH标志位的请求和 Frame 7 的 HTTP 请求
    • Frame 10 是连接另一边发起了关闭连接的请求,标志位 FIN=1
    • Frame 11 是发起关闭请求方,回复上一个 FIN=1 的 ACK 请求包

    四次挥手全部结束。有同学可以会比较疑惑,不是应该是 4 次请求吗,这里只有三次。解释下这个问题:因为服务端在响应 HTTP 请求时,因为知道自己已经发送完全部数据,所以在响应包里加上了四次挥手中的第一次 FIN=1 的请求

    10 条回复    2019-11-10 13:26:47 +08:00
    fvckDaybyte2
        1
    fvckDaybyte2  
       2019-11-02 11:34:43 +08:00
    为什么用 tcpdump 抓而不是 wireshak 命令,这两个命令功能上有区别吗?
    julyclyde
        2
    julyclyde  
       2019-11-04 17:58:19 +08:00
    错误比较多啊
    TTL 不在传输层而是三层
    TCP 的叫 segment 而不是 datagram
    such
        3
    such  
    OP
       2019-11-06 17:23:23 +08:00
    @julyclyde 首先,我没有说 ttl 在非三层。而且全篇文章,也没有提到 tcp 的 segment,不知您是怎么得到的错误结论?
    such
        4
    such  
    OP
       2019-11-06 18:01:27 +08:00
    @fvckDaybyte2 server 端不在本机,没法直接用 wireshak 抓
    julyclyde
        5
    julyclyde  
       2019-11-07 10:08:46 +08:00
    @such 确实没提到 tcp 的 segment 啊,你说的是“tcp 报文”
    julyclyde
        6
    julyclyde  
       2019-11-07 10:16:08 +08:00
    @fvckDaybyte2 wireshark 依赖于 Xwindow,而 lz 不会做远程 X 显示
    fvckDaybyte2
        7
    fvckDaybyte2  
       2019-11-07 10:34:34 +08:00 via iPhone
    @julyclyde wireshark 命令行版本也会依赖 xwindow ?并没有界面啊……
    such
        8
    such  
    OP
       2019-11-07 14:26:06 +08:00
    @julyclyde 通篇仔细校验了一遍,讲真,没找到哪里有错误
    such
        9
    such  
    OP
       2019-11-07 14:31:29 +08:00
    @fvckDaybyte2 没所谓的,我没用过 wireshark 的命令行工具,但是从 tshark,tcpdump,这些应该差别都不太大,底层应该都是依赖 Unix 的 libpcap 库
    julyclyde
        10
    julyclyde  
       2019-11-10 13:26:47 +08:00
    @fvckDaybyte2 wireshark 的命令行版不依赖 x 的,只很少有人用吧。用那个 tshark 还不如 tcpdump 呢,至少参考资料一抓一大把。用 wireshark 主要就是为了它的交互式展现能力
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5640 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 02:34 · PVG 10:34 · LAX 19:34 · JFK 22:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.