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