go 网络数据包分析,3

将自定义层添加到捕获的数据包

参考链接:

https://www.thinbug.com/q/51593997

https://damianzaremba.co.uk/2017/12/decoding-arista-ethertype-headers-with-gopacket/

DEMO1

package main

import (
        "fmt"
        "github.com/google/gopacket"
        "github.com/google/gopacket/layers"
        "github.com/google/gopacket/pcap"
        "log"
)

var (
        pcapFile string = "capt.pcap"
        handle   *pcap.Handle
        err      error
)

type CustomLayer struct {
        SomeByte    byte
        AnotherByte byte
        restOfData  []byte
}

func (customLayer *CustomLayer) DecodeStructFromBytes(data []byte) error {
        customLayer.SomeByte = data[0]
        customLayer.AnotherByte = data[1]
        customLayer.restOfData = data[2:]

        return nil
}

var CustomLayerType = gopacket.RegisterLayerType(
        2001,
        gopacket.LayerTypeMetadata{
                "CustomLayerType",
                gopacket.DecodeFunc(decodeCustomLayer),
        },
)

func (l *CustomLayer) LayerType() gopacket.LayerType {
        return CustomLayerType
}

func (l *CustomLayer) LayerContents() []byte {
        return []byte{l.SomeByte, l.AnotherByte}
}

func (l *CustomLayer) LayerPayload() []byte {
        return l.restOfData
}

func decodeCustomLayer(data []byte, p gopacket.PacketBuilder) error {
        p.AddLayer(&CustomLayer{data[0], data[1], data[2:]})

        // nil means this is the last layer. No more decoding
        return nil
}

func main() {
        handle, err = pcap.OpenOffline(pcapFile)
        if err != nil {
                log.Fatal(err)
        }
        defer handle.Close()

        packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
        for packet := range packetSource.Packets() {
                tcpLayer := packet.Layer(layers.LayerTypeTCP)
                if tcpLayer != nil {
                        fmt.Println("TCP layer detected.")

                        tcp, _ := tcpLayer.(*layers.TCP)
                        if tcp.Payload != nil {
                                customStruct := CustomLayer{}
                                customStruct.DecodeStructFromBytes(tcp.Payload)
                                fmt.Println("SomeByte element:", customStruct.SomeByte)
                        }
                }
        }
}

  

DEMO2

package main

import (
        "fmt"
        "github.com/google/gopacket"
)

// Create custom layer structure
type CustomLayer struct {
        // This layer just has two bytes at the front
        SomeByte    byte
        AnotherByte byte
        restOfData  []byte
}

// Register the layer type so we can use it
// The first argument is an ID. Use negative
// or 2000+ for custom layers. It must be unique
var CustomLayerType = gopacket.RegisterLayerType(
        2001,
        gopacket.LayerTypeMetadata{
                "CustomLayerType",
                gopacket.DecodeFunc(decodeCustomLayer),
        },
)

// When we inquire about the type, what type of layer should
// we say it is? We want it to return our custom layer type
func (l CustomLayer) LayerType() gopacket.LayerType {
        return CustomLayerType
}

// LayerContents returns the information that our layer
// provides. In this case it is a header layer so
// we return the header information
func (l CustomLayer) LayerContents() []byte {
        return []byte{l.SomeByte, l.AnotherByte}
}

// LayerPayload returns the subsequent layer built
// on top of our layer or raw payload
func (l CustomLayer) LayerPayload() []byte {
        return l.restOfData
}

// Custom decode function. We can name it whatever we want
// but it should have the same arguments and return value
// When the layer is registered we tell it to use this decode function
func decodeCustomLayer(data []byte, p gopacket.PacketBuilder) error {
        // AddLayer appends to the list of layers that the packet has
        p.AddLayer(&CustomLayer{data[0], data[1], data[2:]})
        // The return value tells the packet what layer to expect
        // with the rest of the data. It could be another header layer,
        // nothing, or a payload layer.
        // nil means this is the last layer. No more decoding
        // return nil
        // Returning another layer type tells it to decode
        // the next layer with that layer\'s decoder function
        // return p.NextDecoder(layers.LayerTypeEthernet)
        // Returning payload type means the rest of the data
        // is raw payload. It will set the application layer
        // contents with the payload
        return p.NextDecoder(gopacket.LayerTypePayload)

}
func main() {
        // If you create your own encoding and decoding you can essentially
        // create your own protocol or implement a protocol that is not
        // already defined in the layers package. In our example we are just
        // wrapping a normal ethernet packet with our own layer.
        // Creating your own protocol is good if you want to create
        // some obfuscated binary data type that was difficult for others
        // to decode
        // Finally, decode your packets:
        rawBytes := []byte{0xF0, 0x0F, 65, 65, 66, 67, 68}
        packet := gopacket.NewPacket(
                rawBytes,
                CustomLayerType,
                gopacket.Default,
        )
        fmt.Println("Created packet out of raw bytes.")
        fmt.Println(packet)
        // Decode the packet as our custom layer
        customLayer := packet.Layer(CustomLayerType)
        if customLayer != nil {
                fmt.Println("Packet was successfully decoded with custom layer decoder.")
                customLayerContent, _ := customLayer.(*CustomLayer)
                // Now we can access the elements of the custom struct
                fmt.Println("Payload: ", customLayerContent.LayerPayload())
                fmt.Println("SomeByte element:", customLayerContent.SomeByte)
                fmt.Println("AnotherByte element:", customLayerContent.AnotherByte)
        }
}