2

Gopacket 支持解析信标和探测响应帧中的信息元素,如下所示:

for _, layer := range packet.Layers() {
    if layer.LayerType() == layers.LayerTypeDot11InformationElement {
        dot11info, ok := layer.(*layers.Dot11InformationElement)
        }
}

但是 gopacket 不支持解析探测请求帧中的信息元素。我只能packet.Layer(layers.LayerTypeDot11MgmtProbeReq).(*layers.Dot11MgmtProbeReq) 用来获取Contents和Payload,信息元素在这个Contents中。

那么如何解析探测请求帧中的这些信息元素呢?

4

2 回答 2

2

我相信你必须自己写。你已经尝试过这个实现了吗?

解析器如下:

func (pr *capturedRequest) decodeProbeRequestLayer(probeLayer *layers.Dot11MgmtProbeReq) {
    var body []byte
    body = probeLayer.LayerContents()
    for i := uint64(0); i < uint64(len(body)); {
        id := layers.Dot11InformationElementID(body[i])
        i++
        switch id {
        case layers.Dot11InformationElementIDSSID:
            elemLen := uint64(body[i])
            i++
            if elemLen > 0 {
                pr.SSID = string(body[i : i+elemLen])
                i += elemLen
            }
            break
        case layers.Dot11InformationElementIDVendor:
            pr.VendorSpecific = body[i+1:]
            return
        default:
            elemLen := uint64(body[i])
            i += 1 + elemLen
            break
        }
    }
}
于 2020-01-17T17:18:36.270 回答
1

注意,您不能像从信标或探测响应中那样仅从探测请求中解析 IE 的原因是,gopacket 本身从未实际分配给结构的Payload字段Dot11MgmtProbeReq。参见Dot11MgmtBeaconDot11MgmtProbeRespDecodeFromBytes_ Dot11MgmtProbeReq没有​​这样的方法。用以下代码替换gopacket 可以解决此问题(尽管这对您来说可能有点过分):Dot11MgmtProbeReq

type Dot11MgmtProbeReq struct {
    Dot11Mgmt
}

func decodeDot11MgmtProbeReq(data []byte, p gopacket.PacketBuilder) error {
    d := &Dot11MgmtProbeReq{}
    return decodingLayerDecoder(d, data, p)
}

func (m *Dot11MgmtProbeReq) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtProbeReq }
func (m *Dot11MgmtProbeReq) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeReq }
func (m *Dot11MgmtProbeReq) NextLayerType() gopacket.LayerType {
    return LayerTypeDot11InformationElement
}
func (m *Dot11MgmtProbeReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    m.Payload = data
    return m.Dot11Mgmt.DecodeFromBytes(data, df)
}

一般来说,提取 IE 的一种直接方法是设置一个核心函数,将 IE 列表从当前帧传递到一个函数,该函数将所有相关元素解码为map[string][]byte字符串,其中字符串是字符串的人类可读名称。这样,可以在特定情况下请求任何特定于帧的字段。(您需要编写一个 map[layers.Dot11InformationElementID]string` 来执行此操作)。

于 2020-03-05T09:50:27.157 回答