首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从捕获添加自定义层到数据包失败

从捕获添加自定义层到数据包失败
EN

Stack Overflow用户
提问于 2018-07-30 12:28:46
回答 1查看 1.5K关注 0票数 1

我试图在TCP之上实现我自己的解码层,到目前为止,只有当我创建一个没有任何Eth/IP/TCP报头的数据包并手动将其层设置为我的自定义层时,它才能工作。自定义协议的数据位于普通TCP有效负载中。

如何仅将TCP层的有效负载解码为另一层?

代码语言:javascript
复制
package main

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

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

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

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)
            fmt.Println("Sequence number: ", tcp.Seq)
            customLayer := packet.Layer(CustomLayerType)
            if customLayer != nil { // always nil
                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)
            }
        }
        fmt.Println()
    }
}

大部分代码来自这个由地牢执掌的伟大职位

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-31 08:54:33

由于没有人回答,我现在就自己回答。

基本上,我们有三个选项来处理这个问题:

  1. 创建一个扩展的TCP层,它处理额外的字节,并通过将layers.LinkTypeMetadata[layers.LinkTypeTCP]设置为我们的扩展版本来覆盖默认字节。看一下这个例子
  2. 使用gopacket.NewPacketfirstLayerDecoder设置为CustomLayerType,并将其正常解码,从TCP有效负载创建一个新数据包。
  3. 因为您通常不需要一个实际的层,而需要一个填充的CustomLayer结构,所以只需编写一个DecodeBytesToCustomStruct函数来传递TCP有效负载。这样,我们甚至可以从一个数据包有效负载中返回多个结构,否则这是不可能的。

从上面省略所有CustomLayer代码。

代码语言:javascript
复制
type CustomStruct struct {
    SomeByte    byte
    AnotherByte byte
    restOfData  []byte
}

func (customStruct *CustomStruct) DecodeStructFromBytes(data []byte) error { 
    customStruct.SomeByte = data[0]
    customStruct.AnotherByte = data[1]
    customStruct.restOfData = data[2:]
    return nil
}

在你的main.go里

代码语言:javascript
复制
for packet := range packetSource.Packets() {
    tcpLayer := packet.Layer(layers.LayerTypeTCP)
    if tcpLayer != nil {
        tcp, _ := tcpLayer.(*layers.TCP)
        if tcp.Payload != nil && len(tcpLayer.Payload) > 0 {
            customStruct := CustomStruct{}
            customStruct.DecodeStructFromBytes(tcp.Payload)
            fmt.Println("SomeByte element:", customStruct.SomeByte)
        }
    }
}

tcp.Payloadpacket.ApplicationLayer().Payload()相同

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51593997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档