blob: cad6803671ea06809f1930ccb1674cbfe31cda14 [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001// 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
7package layers
8
9import (
10 "encoding/binary"
11 "errors"
12
13 "github.com/google/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
18type 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.
28func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC }
29
30// DecodeFromBytes decodes the given bytes into this layer.
31func (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.
56func (l *LLC) CanDecode() gopacket.LayerClass {
57 return LayerTypeLLC
58}
59
60// NextLayerType returns the layer type contained by this DecodingLayer.
61func (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// "[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing,
75// on networks using IEEE 802.2 LLC, more protocols than can be distinguished
76// by the 8-bit 802.2 Service Access Point (SAP) fields."
77type SNAP struct {
78 BaseLayer
79 OrganizationalCode []byte
80 Type EthernetType
81}
82
83// LayerType returns gopacket.LayerTypeSNAP.
84func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }
85
86// DecodeFromBytes decodes the given bytes into this layer.
87func (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
88 if len(data) < 5 {
89 return errors.New("SNAP header too small")
90 }
91 s.OrganizationalCode = data[:3]
92 s.Type = EthernetType(binary.BigEndian.Uint16(data[3:5]))
93 s.BaseLayer = BaseLayer{data[:5], data[5:]}
94 return nil
95}
96
97// CanDecode returns the set of layer types that this DecodingLayer can decode.
98func (s *SNAP) CanDecode() gopacket.LayerClass {
99 return LayerTypeSNAP
100}
101
102// NextLayerType returns the layer type contained by this DecodingLayer.
103func (s *SNAP) NextLayerType() gopacket.LayerType {
104 // See BUG(gconnel) in decodeSNAP
105 return s.Type.LayerType()
106}
107
108func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
109 l := &LLC{}
110 err := l.DecodeFromBytes(data, p)
111 if err != nil {
112 return err
113 }
114 p.AddLayer(l)
115 return p.NextDecoder(l.NextLayerType())
116}
117
118func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
119 s := &SNAP{}
120 err := s.DecodeFromBytes(data, p)
121 if err != nil {
122 return err
123 }
124 p.AddLayer(s)
125 // BUG(gconnell): When decoding SNAP, we treat the SNAP type as an Ethernet
126 // type. This may not actually be an ethernet type in all cases,
127 // depending on the organizational code. Right now, we don't check.
128 return p.NextDecoder(s.Type)
129}
130
131// SerializeTo writes the serialized form of this layer into the
132// SerializationBuffer, implementing gopacket.SerializableLayer.
133// See the docs for gopacket.SerializableLayer for more info.
134func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
135 var igFlag, crFlag byte
136 var length int
137
138 if l.Control&0xFF00 != 0 {
139 length = 4
140 } else {
141 length = 3
142 }
143
144 if l.DSAP&0x1 != 0 {
145 return errors.New("DSAP value invalid, should not include IG flag bit")
146 }
147
148 if l.SSAP&0x1 != 0 {
149 return errors.New("SSAP value invalid, should not include CR flag bit")
150 }
151
152 if buf, err := b.PrependBytes(length); err != nil {
153 return err
154 } else {
155 igFlag = 0
156 if l.IG {
157 igFlag = 0x1
158 }
159
160 crFlag = 0
161 if l.CR {
162 crFlag = 0x1
163 }
164
165 buf[0] = l.DSAP + igFlag
166 buf[1] = l.SSAP + crFlag
167
168 if length == 4 {
169 buf[2] = uint8(l.Control >> 8)
170 buf[3] = uint8(l.Control)
171 } else {
172 buf[2] = uint8(l.Control)
173 }
174 }
175
176 return nil
177}
178
179// SerializeTo writes the serialized form of this layer into the
180// SerializationBuffer, implementing gopacket.SerializableLayer.
181// See the docs for gopacket.SerializableLayer for more info.
182func (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
183 if buf, err := b.PrependBytes(5); err != nil {
184 return err
185 } else {
186 buf[0] = s.OrganizationalCode[0]
187 buf[1] = s.OrganizationalCode[1]
188 buf[2] = s.OrganizationalCode[2]
189 binary.BigEndian.PutUint16(buf[3:5], uint16(s.Type))
190 }
191
192 return nil
193}