prism.go 4.6 KB

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