llc.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2012 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. package layers
  7. import (
  8. "encoding/binary"
  9. "errors"
  10. "github.com/google/gopacket"
  11. )
  12. // LLC is the layer used for 802.2 Logical Link Control headers.
  13. // See http://standards.ieee.org/getieee802/download/802.2-1998.pdf
  14. type LLC struct {
  15. BaseLayer
  16. DSAP uint8
  17. IG bool // true means group, false means individual
  18. SSAP uint8
  19. CR bool // true means response, false means command
  20. Control uint16
  21. }
  22. // LayerType returns gopacket.LayerTypeLLC.
  23. func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC }
  24. // DecodeFromBytes decodes the given bytes into this layer.
  25. func (l *LLC) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  26. if len(data) < 3 {
  27. return errors.New("LLC header too small")
  28. }
  29. l.DSAP = data[0] & 0xFE
  30. l.IG = data[0]&0x1 != 0
  31. l.SSAP = data[1] & 0xFE
  32. l.CR = data[1]&0x1 != 0
  33. l.Control = uint16(data[2])
  34. if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {
  35. if len(data) < 4 {
  36. return errors.New("LLC header too small")
  37. }
  38. l.Control = l.Control<<8 | uint16(data[3])
  39. l.Contents = data[:4]
  40. l.Payload = data[4:]
  41. } else {
  42. l.Contents = data[:3]
  43. l.Payload = data[3:]
  44. }
  45. return nil
  46. }
  47. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  48. func (l *LLC) CanDecode() gopacket.LayerClass {
  49. return LayerTypeLLC
  50. }
  51. // NextLayerType returns the layer type contained by this DecodingLayer.
  52. func (l *LLC) NextLayerType() gopacket.LayerType {
  53. switch {
  54. case l.DSAP == 0xAA && l.SSAP == 0xAA:
  55. return LayerTypeSNAP
  56. case l.DSAP == 0x42 && l.SSAP == 0x42:
  57. return LayerTypeSTP
  58. }
  59. return gopacket.LayerTypeZero // Not implemented
  60. }
  61. // SNAP is used inside LLC. See
  62. // http://standards.ieee.org/getieee802/download/802-2001.pdf.
  63. // From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol:
  64. // "[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing,
  65. // on networks using IEEE 802.2 LLC, more protocols than can be distinguished
  66. // by the 8-bit 802.2 Service Access Point (SAP) fields."
  67. type SNAP struct {
  68. BaseLayer
  69. OrganizationalCode []byte
  70. Type EthernetType
  71. }
  72. // LayerType returns gopacket.LayerTypeSNAP.
  73. func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }
  74. // DecodeFromBytes decodes the given bytes into this layer.
  75. func (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  76. if len(data) < 5 {
  77. return errors.New("SNAP header too small")
  78. }
  79. s.OrganizationalCode = data[:3]
  80. s.Type = EthernetType(binary.BigEndian.Uint16(data[3:5]))
  81. s.BaseLayer = BaseLayer{data[:5], data[5:]}
  82. return nil
  83. }
  84. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  85. func (s *SNAP) CanDecode() gopacket.LayerClass {
  86. return LayerTypeLLC
  87. }
  88. // NextLayerType returns the layer type contained by this DecodingLayer.
  89. func (s *SNAP) NextLayerType() gopacket.LayerType {
  90. // See BUG(gconnel) in decodeSNAP
  91. return s.Type.LayerType()
  92. }
  93. func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
  94. l := &LLC{}
  95. err := l.DecodeFromBytes(data, p)
  96. if err != nil {
  97. return err
  98. }
  99. p.AddLayer(l)
  100. return p.NextDecoder(l.NextLayerType())
  101. }
  102. func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
  103. s := &SNAP{}
  104. err := s.DecodeFromBytes(data, p)
  105. if err != nil {
  106. return err
  107. }
  108. p.AddLayer(s)
  109. // BUG(gconnell): When decoding SNAP, we treat the SNAP type as an Ethernet
  110. // type. This may not actually be an ethernet type in all cases,
  111. // depending on the organizational code. Right now, we don't check.
  112. return p.NextDecoder(s.Type)
  113. }
  114. // SerializeTo writes the serialized form of this layer into the
  115. // SerializationBuffer, implementing gopacket.SerializableLayer.
  116. // See the docs for gopacket.SerializableLayer for more info.
  117. func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  118. var igFlag, crFlag byte
  119. var length int
  120. if l.Control&0xFF00 != 0 {
  121. length = 4
  122. } else {
  123. length = 3
  124. }
  125. if l.DSAP&0x1 != 0 {
  126. return errors.New("DSAP value invalid, should not include IG flag bit")
  127. }
  128. if l.SSAP&0x1 != 0 {
  129. return errors.New("SSAP value invalid, should not include CR flag bit")
  130. }
  131. if buf, err := b.PrependBytes(length); err != nil {
  132. return err
  133. } else {
  134. igFlag = 0
  135. if l.IG {
  136. igFlag = 0x1
  137. }
  138. crFlag = 0
  139. if l.CR {
  140. crFlag = 0x1
  141. }
  142. buf[0] = l.DSAP + igFlag
  143. buf[1] = l.SSAP + crFlag
  144. if length == 4 {
  145. buf[2] = uint8(l.Control >> 8)
  146. buf[3] = uint8(l.Control)
  147. } else {
  148. buf[2] = uint8(l.Control)
  149. }
  150. }
  151. return nil
  152. }
  153. // SerializeTo writes the serialized form of this layer into the
  154. // SerializationBuffer, implementing gopacket.SerializableLayer.
  155. // See the docs for gopacket.SerializableLayer for more info.
  156. func (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  157. if buf, err := b.PrependBytes(5); err != nil {
  158. return err
  159. } else {
  160. buf[0] = s.OrganizationalCode[0]
  161. buf[1] = s.OrganizationalCode[1]
  162. buf[2] = s.OrganizationalCode[2]
  163. binary.BigEndian.PutUint16(buf[3:5], uint16(s.Type))
  164. }
  165. return nil
  166. }