You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go中使用Conn.Write发送原始IP包异常问题求助

原生Ping实现中原始数据包发送异常问题

我实现了一个原生ping功能,生成包含IP头部+ICMP回显请求包的原始IP数据包,并使用Conn.Write发送。最终字节流中前20字节是IP头部,后8字节是ICMP载荷:

45 00 00 1c 00 00 00 00 40 01 26 a0 c0 a8 00 64 68 f4 2a 41 08 00 f7 ff 00 00 00 00
                                                           |----------icmp---------|
|--------------------ip header-----------------------------|

但发送该字节流后无法收到回显回复,Wireshark显示数据包畸形且字节错位。然而,若将ICMP字节放在IP头部之前(即08 00 f7 ff 00 00 00 00 45 00 00 1c 00 00 00 00 40 01 26 e0 c0 a8 00 64 68 f4 2a 01),却能收到回显回复。

复现代码

package main

import (
    "log"
    "net"
    "bytes"
    "fmt"
)

func main() {
    conn, err := net.Dial("ip4:icmp", "104.244.42.129")
    if err != nil {
        log.Fatal(err)
    }

    // this does not work although byte order is correct
    packet := []byte{0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x26, 0xa0, 0xc0, 0xa8, 0x00, 0x64, 0x68, 0xf4, 0x2a, 0x41, 0x08, 0x00, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00} 

    // this works although byte order is wrong
    // packet := []byte{0x08, 0x00, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x26, 0xa0, 0xc0, 0xa8, 0x00, 0x64, 0x68, 0xf4, 0x2a, 0x41} 

    _, err = conn.Write(packet)
    if err != nil {
        log.Fatal(err)
    }

    reply := make([]byte, 1048)

    _, err = conn.Read(reply)
    if err != nil {
        log.Fatal(err)
    }
    reply = bytes.Trim(reply, "\x00")

    fmt.Println(reply)
}

我的猜想

  • 排除字节序问题,序列化时已使用网络字节序,问题在于缓冲区写入顺序(头部在前还是载荷在前),常理应为头部先写入,但反过来才生效:
func (p *Packet) Serialize() ([]byte, error) {
    buf := new(bytes.Buffer)
    headerSerialized, err := p.Header.Serialize()
    if err != nil {
        return nil, errors.Wrapf(err, "error serializing IPv4 packet header")
    }
    // buf.Write(p.Payload) // writing payload before header seems wrong, but it works
    buf.Write(headerSerialized)
    buf.Write(p.Payload) // this seems right, but doesn't work

    return buf.Bytes(), nil
}
  • 怀疑内核网络栈自动添加IP头导致字节错位,但无法解释两种发送情况的差异。
  • 疑惑Conn.Write是否为发送原始数据包的正确工具,但未深入源码分析,希望先得到帮助。

恳请各位提供技术帮助与见解。

内容的提问来源于stack exchange,提问作者Swagnik Dutta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 18:42:32