首页 > 解决方案 > gopacket 快速层解析

问题描述

我尝试使用以下官方示例https://youtu.be/APDnbmTKjgM?t=1135快速解析数据包层

    var ip4 layers.IPv4
    var tcp layers.TCP
    var udp layers.UDP
    var sip layers.SIP
    parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &ip4, &tcp, &udp, &sip)
    decodedLayers := []gopacket.LayerType{}
    // ...
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        parser.DecodeLayers(packet.Data(), &decodedLayers)
        for _, layerType := range decodedLayers {
            fmt.Println(layerType) // prints nothing/ seems program doesn't iterate at all
        }

但这个例子不起作用。为了比较另一种常用方法 - 遍历 packet.Layers() 正常工作。

gopacket.NewDecodingLayerParser 方法有什么问题?

完整代码:

package main

import (
    "fmt"
    "log"
    "strings"
    "time"

    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
)

func main() {
    var ip4 layers.IPv4
    var tcp layers.TCP
    var udp layers.UDP
    var sip layers.SIP
    parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &ip4, &tcp, &udp, &sip)
    decodedLayers := []gopacket.LayerType{}
    // get devices
    devices, err := pcap.FindAllDevs()
    if err != nil {
        log.Fatal(err)
    }

    var device pcap.Interface
    // look for "any" device
    for i := range devices {
        if strings.Contains(devices[i].Name, "any") {
            device = devices[i]
            log.Printf("%+v\n", device)
            break
        }
    }
    // start listening to "any" device
    handle, err := pcap.OpenLive(device.Name, int32(65535), false, -1*time.Second)
    if err != nil {
        log.Println(err)
    }
    defer handle.Close()
    // set filters
    handle.SetBPFFilter("(udp or tcp) and port 5060")
    // read loop
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        parser.DecodeLayers(packet.Data(), &decodedLayers)
        for _, layerType := range decodedLayers {
            fmt.Println(layerType) // prints nothing and seems program doesn't iterate at all
        }

        // other approach - is to iterate over packet.Layers():
        //for _, layer := range packet.Layers() {
        // fmt.Println(string(layer.LayerPayload())) // prints payload
        // }
    }
}

标签: gogopacket

解决方案


推荐阅读