1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
// Copyright 2015 Google, Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.
// http://www.tcpdump.org/linktypes/LINKTYPE_IEEE802_11_PRISM.html
package layers
import (
"encoding/binary"
"errors"
"github.com/gopacket/gopacket"
)
func decodePrismValue(data []byte, pv *PrismValue) {
pv.DID = PrismDID(binary.LittleEndian.Uint32(data[0:4]))
pv.Status = binary.LittleEndian.Uint16(data[4:6])
pv.Length = binary.LittleEndian.Uint16(data[6:8])
pv.Data = data[8 : 8+pv.Length]
}
type PrismDID uint32
const (
PrismDIDType1HostTime PrismDID = 0x10044
PrismDIDType2HostTime PrismDID = 0x01041
PrismDIDType1MACTime PrismDID = 0x20044
PrismDIDType2MACTime PrismDID = 0x02041
PrismDIDType1Channel PrismDID = 0x30044
PrismDIDType2Channel PrismDID = 0x03041
PrismDIDType1RSSI PrismDID = 0x40044
PrismDIDType2RSSI PrismDID = 0x04041
PrismDIDType1SignalQuality PrismDID = 0x50044
PrismDIDType2SignalQuality PrismDID = 0x05041
PrismDIDType1Signal PrismDID = 0x60044
PrismDIDType2Signal PrismDID = 0x06041
PrismDIDType1Noise PrismDID = 0x70044
PrismDIDType2Noise PrismDID = 0x07041
PrismDIDType1Rate PrismDID = 0x80044
PrismDIDType2Rate PrismDID = 0x08041
PrismDIDType1TransmittedFrameIndicator PrismDID = 0x90044
PrismDIDType2TransmittedFrameIndicator PrismDID = 0x09041
PrismDIDType1FrameLength PrismDID = 0xA0044
PrismDIDType2FrameLength PrismDID = 0x0A041
)
const (
PrismType1MessageCode uint16 = 0x00000044
PrismType2MessageCode uint16 = 0x00000041
)
func (p PrismDID) String() string {
dids := map[PrismDID]string{
PrismDIDType1HostTime: "Host Time",
PrismDIDType2HostTime: "Host Time",
PrismDIDType1MACTime: "MAC Time",
PrismDIDType2MACTime: "MAC Time",
PrismDIDType1Channel: "Channel",
PrismDIDType2Channel: "Channel",
PrismDIDType1RSSI: "RSSI",
PrismDIDType2RSSI: "RSSI",
PrismDIDType1SignalQuality: "Signal Quality",
PrismDIDType2SignalQuality: "Signal Quality",
PrismDIDType1Signal: "Signal",
PrismDIDType2Signal: "Signal",
PrismDIDType1Noise: "Noise",
PrismDIDType2Noise: "Noise",
PrismDIDType1Rate: "Rate",
PrismDIDType2Rate: "Rate",
PrismDIDType1TransmittedFrameIndicator: "Transmitted Frame Indicator",
PrismDIDType2TransmittedFrameIndicator: "Transmitted Frame Indicator",
PrismDIDType1FrameLength: "Frame Length",
PrismDIDType2FrameLength: "Frame Length",
}
if str, ok := dids[p]; ok {
return str
}
return "Unknown DID"
}
type PrismValue struct {
DID PrismDID
Status uint16
Length uint16
Data []byte
}
func (pv *PrismValue) IsSupplied() bool {
return pv.Status == 1
}
var ErrPrismExpectedMoreData = errors.New("Expected more data.")
var ErrPrismInvalidCode = errors.New("Invalid header code.")
func decodePrismHeader(data []byte, p gopacket.PacketBuilder) error {
d := &PrismHeader{}
return decodingLayerDecoder(d, data, p)
}
type PrismHeader struct {
BaseLayer
Code uint16
Length uint16
DeviceName string
Values []PrismValue
}
func (m *PrismHeader) LayerType() gopacket.LayerType { return LayerTypePrismHeader }
func (m *PrismHeader) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
m.Code = binary.LittleEndian.Uint16(data[0:4])
m.Length = binary.LittleEndian.Uint16(data[4:8])
m.DeviceName = string(data[8:24])
m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: data[m.Length:len(data)]}
switch m.Code {
case PrismType1MessageCode:
fallthrough
case PrismType2MessageCode:
// valid message code
default:
return ErrPrismInvalidCode
}
offset := uint16(24)
m.Values = make([]PrismValue, (m.Length-offset)/12)
for i := 0; i < len(m.Values); i++ {
decodePrismValue(data[offset:offset+12], &m.Values[i])
offset += 12
}
if offset != m.Length {
return ErrPrismExpectedMoreData
}
return nil
}
func (m *PrismHeader) CanDecode() gopacket.LayerClass { return LayerTypePrismHeader }
func (m *PrismHeader) NextLayerType() gopacket.LayerType { return LayerTypeDot11 }
|