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 }