0228-TCP 的標記和選項

波尔發表於2024-08-14

環境

  • Time 2022-11-24
  • WSL-Ubuntu 22.04
  • Rust 1.65.0
  • pnet 0.31.0
  • tun-tap 0.1.3

前言

說明

參考:https://docs.rs/pnet/latest/pnet/index.html
參考:https://www.cnblogs.com/lshs/p/6038494.html

目標

瞭解 TCP 協議頭中的 flags 和 options 欄位的含義。

main.rs

use pnet::packet::ip::IpNextHeaderProtocols;
use pnet::packet::{ipv4::Ipv4Packet, tcp::TcpPacket};
use tun_tap::{Iface, Mode};

fn main() -> std::io::Result<()> {
    let iface = Iface::without_packet_info("tun0", Mode::Tun)?;

    let mut buffer = vec![0; 1500];

    loop {
        let _size = iface.recv(&mut buffer)?;
        let packet = Ipv4Packet::new(&buffer).unwrap();

        if packet.get_version() == 6 {
            println!("IPv6 packet, continue");
            continue;
        }

        if packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp {
            println!("not tcp packet, continue");
            continue;
        }

        // 因為頭部長度的單位是 4 位元組
        let length = packet.get_header_length() as usize * 4;
        let packet = TcpPacket::new(&buffer[length..]).unwrap();

        // 000000010,從右往左算常見的標誌
        // 第 1 位 FIN,斷開連線請求
        // 第 2 位 SYN,請求握手,當前請求就是 SYN 連線建立請求
        // 第 3 位 RST,拒絕連線
        // 第 5 位 ACK,確認報文
        println!("flags {:09b}", packet.get_flags());
        // 2 位元組的視窗大小
        println!("window {}", packet.get_window());
        for option in packet.get_options() {
            // 2 代表 MSS,最大段長度,4 表示,總共 4 位元組,後面的表示 1460
            // TcpOptionNumber(2), length: [4], data: [5, 180]
            // 4 代表可選確認允許,可以從參考資料獲取詳情
            // TcpOptionNumber(4), length: [2], data: []
            // timestamp 欄位,可以從參考資料獲取詳情
            // TcpOptionNumber(8), length: [10], data: [189, 18, 113, 31, 0, 0, 0, 0]
            // 填充
            // TcpOptionNumber(1), length: [], data: []
            // 3 表示視窗擴大,7 表示將視窗左移 7 位,即乘以 128
            // TcpOptionNumber(3), length: [3], data: [7]
            println!("options {:?}", option);
        }
    }
}

程式輸出

flags 000000010
window 64240
options TcpOption { number: TcpOptionNumber(2), length: [4], data: [5, 180] }
options TcpOption { number: TcpOptionNumber(4), length: [2], data: [] }
options TcpOption { number: TcpOptionNumber(8), length: [10], data: [189, 18, 113, 31, 0, 0, 0, 0] }
options TcpOption { number: TcpOptionNumber(1), length: [], data: [] }
options TcpOption { number: TcpOptionNumber(3), length: [3], data: [7] }

Wireshark

TCP標誌

總結

瞭解了 TCP 協議中的 flags 欄位和 options 欄位常見的值的意思。

附錄

相關文章