Как получить байты / длину заголовка с помощью gopacket

Попробуйте использовать gopacket для создания пакета Ethernet (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

Я что-то там не так сделал?

Может кто-нибудь дать мне представление, как я могу получить байты заголовка?

1 ответ

Во-первых, как следует из ваших закомментированных полей IPv4, layer.Error() содержит больше информации:

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

В этом случае, когда поле IHL установлено в 5, это обозначает длину заголовка в 4 байтовых словах. Поскольку вы указали длину 24, существует несоответствие между вычисленной длиной в МГП и предоставленной длиной и gopacket вылетает при попытке разобрать это как пакет IPv6. Вы можете настроить длину до 20 и длину заголовка до 5, в этом случае он анализируется без ошибок, но он не содержит полей tcp.

gopacket на самом деле не предназначен для генерации пакетов, но для анализа захваченных.

Если вы действительно хотите сделать это вручную, я предлагаю вам прочитать соответствующие RFC и убедиться, что вы охватываете различные опции, вычисляете контрольные суммы, устанавливаете протокол (6 для tcp), правильную длину (пакеты tcp на самом деле имеют 32-байтовый заголовок, если я ' м не ошибаюсь) и т д

В нормальных условиях об этом должны позаботиться сокеты вашей операционной системы. Почему вы пытаетесь сгенерировать это вручную?

Другие вопросы по тегам