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