-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
prism.go
146 lines (122 loc) · 4.58 KB
/
prism.go
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/google/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 }