如何使用gopacket获取头字节/长度
尝试使用gopacket创建一个以太网数据包(ARP、BGP、UDP、TCP),并获取它的头字节和长度 尝试使用以下示例,尝试列出所有层并找到有效负载位置,然后计算总标题长度和字节数:如何使用gopacket获取头字节/长度,go,gopacket,Go,Gopacket,尝试使用gopacket创建一个以太网数据包(ARP、BGP、UDP、TCP),并获取它的头字节和长度 尝试使用以下示例,尝试列出所有层并找到有效负载位置,然后计算总标题长度和字节数: package main import ( "fmt" "net" "github.com/google/gopacket" "github.com/google/gopacket/layers" ) func main() { var ( buffe
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
我做错什么了吗
有人能告诉我如何获取头字节吗?首先,正如您注释掉的IPv4字段所暗示的,
layer.Error()
包含更多信息:
if withErr, ok := layer.(interface{ Error() error }); ok {
fmt.Pritnln(withError.Error())
}
在这种情况下,当IHL字段设置为5时,它以4字节字表示报头长度。由于您指定的长度为24,IHL中计算的长度与提供的长度不匹配,因此试图将其解析为IPv6数据包时,gopacket
崩溃。您可以将长度调整为20,将头长度调整为5,在这种情况下,它会无误地解析,但不包含tcp字段
gopacket
并非真正用于生成数据包,而是用于解析捕获的数据包
如果您真的想手动执行此操作,我建议您阅读相关的RFC,并确保涵盖各种选项、计算校验和、设置协议(tcp为6)、正确的长度(如果我没有弄错的话,tcp数据包实际上有一个32字节的头)等,这是非常复杂的
在正常情况下,这一切都应该由操作系统的套接字来处理。为什么要尝试手动生成此文件