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)
	}
}

  

原文地址:https://www.cnblogs.com/wangjq19920210/p/14119075.html