【问题标题】:How to get header bytes/length with gopacket如何使用 gopacket 获取标头字节/长度
【发布时间】:2017-03-09 12:31:25
【问题描述】:

尝试使用 gopacket 创建一个以太网数据包(ARP、BGP、UDP、TCP)并获取它的头部字节和长度。

尝试使用下面的示例,尝试列出所有层并找到有效负载位置,然后计算总标头长度和字节:

package main

import (
    "fmt"
    "net"

    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
)

func main() {
    var (
        buffer  gopacket.SerializeBuffer
        options gopacket.SerializeOptions
    )

    // Create the layers
    ethernetLayer := &layers.Ethernet{
        SrcMAC:       net.HardwareAddr{0xff, 0xaa, 0xfa, 0xaa, 0xff, 0xaa},
        DstMAC:       net.HardwareAddr{0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd},
        EthernetType: layers.EthernetTypeIPv4,
    }
    ipLayer := &layers.IPv4{
        SrcIP: net.IP{192, 168, 1, 3},
        DstIP: net.IP{8, 8, 8, 8},
        // Version: 4,
        // IHL:     5,
        Length: 24,
    }
    tcpLayer := &layers.TCP{
        SrcPort: layers.TCPPort(4321),
        DstPort: layers.TCPPort(80),
    }
    fmt.Println(tcpLayer)
    payload := []byte{10, 20, 30, 40, 50, 60}
    buffer = gopacket.NewSerializeBuffer()
    gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(payload))
    outgoingPacket := buffer.Bytes()

    packet := gopacket.NewPacket(outgoingPacket, layers.LayerTypeEthernet, gopacket.Default)

    for _, layer := range packet.Layers() {
        fmt.Println("Packet layer:", layer.LayerType())
    }
}

我收到如下错误:

Packet layer: Ethernet
Packet layer: IPv4
Packet layer: DecodeFailure

我做错了什么吗?

谁能告诉我如何获取标头字节?

【问题讨论】:

    标签: go gopacket


    【解决方案1】:

    首先,正如您注释掉的 IPv4 字段所暗示的那样,layer.Error() 包含更多信息:

    if withErr, ok := layer.(interface{ Error() error }); ok {
        fmt.Pritnln(withError.Error())
    }
    

    在这种情况下,当 IHL 字段设置为 5 时,它表示以 4 字节字为单位的报头长度。由于您指定的长度为 24,因此 IHL 中计算的长度与提供的长度不匹配,gopacket 在尝试将其解析为 IPv6 数据包时崩溃。您可以将长度调整为 20,将标头长度调整为 5,在这种情况下它会正确解析,但不包含 tcp 字段。

    gopacket 并不是真正用于生成数据包,而是用于解析捕获的数据包。

    如果您真的想手动执行此操作,我建议您阅读相关的 RFC 并确保涵盖各种选项、计算校验和、设置协议(tcp 为 6)、正确的长度(tcp 数据包实际上有一个 32 字节的标头如果我没记错的话)等,这是相当复杂的。

    在正常情况下,这一切都应该由操作系统的套接字来处理。为什么要尝试手动生成?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      相关资源
      最近更新 更多