Fix unit tests
[govpp.git] / vendor / github.com / google / gopacket / layers / llc.go
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/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
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 // SNAP is used inside LLC.  See
31 // http://standards.ieee.org/getieee802/download/802-2001.pdf.
32 // From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol:
33 //  "[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing,
34 //  on networks using IEEE 802.2 LLC, more protocols than can be distinguished
35 //  by the 8-bit 802.2 Service Access Point (SAP) fields."
36 type SNAP struct {
37         BaseLayer
38         OrganizationalCode []byte
39         Type               EthernetType
40 }
41
42 // LayerType returns gopacket.LayerTypeSNAP.
43 func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }
44
45 func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
46         l := &LLC{
47                 DSAP:    data[0] & 0xFE,
48                 IG:      data[0]&0x1 != 0,
49                 SSAP:    data[1] & 0xFE,
50                 CR:      data[1]&0x1 != 0,
51                 Control: uint16(data[2]),
52         }
53         if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {
54                 l.Control = l.Control<<8 | uint16(data[3])
55                 l.Contents = data[:4]
56                 l.Payload = data[4:]
57         } else {
58                 l.Contents = data[:3]
59                 l.Payload = data[3:]
60         }
61         p.AddLayer(l)
62         switch {
63         case l.DSAP == 0xAA && l.SSAP == 0xAA:
64                 return p.NextDecoder(LayerTypeSNAP)
65         case l.DSAP == 0x42 && l.SSAP == 0x42:
66                 return p.NextDecoder(LayerTypeSTP)
67         }
68         return p.NextDecoder(gopacket.DecodeUnknown)
69 }
70
71 func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
72         s := &SNAP{
73                 OrganizationalCode: data[:3],
74                 Type:               EthernetType(binary.BigEndian.Uint16(data[3:5])),
75                 BaseLayer:          BaseLayer{data[:5], data[5:]},
76         }
77         p.AddLayer(s)
78         // BUG(gconnell):  When decoding SNAP, we treat the SNAP type as an Ethernet
79         // type.  This may not actually be an ethernet type in all cases,
80         // depending on the organizational code.  Right now, we don't check.
81         return p.NextDecoder(s.Type)
82 }
83
84 // SerializeTo writes the serialized form of this layer into the
85 // SerializationBuffer, implementing gopacket.SerializableLayer.
86 // See the docs for gopacket.SerializableLayer for more info.
87 func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
88         var ig_flag, cr_flag byte
89         var length int
90
91         if l.Control&0xFF00 != 0 {
92                 length = 4
93         } else {
94                 length = 3
95         }
96
97         if l.DSAP&0x1 != 0 {
98                 return errors.New("DSAP value invalid, should not include IG flag bit")
99         }
100
101         if l.SSAP&0x1 != 0 {
102                 return errors.New("SSAP value invalid, should not include CR flag bit")
103         }
104
105         if buf, err := b.PrependBytes(length); err != nil {
106                 return err
107         } else {
108                 ig_flag = 0
109                 if l.IG {
110                         ig_flag = 0x1
111                 }
112
113                 cr_flag = 0
114                 if l.CR {
115                         cr_flag = 0x1
116                 }
117
118                 buf[0] = l.DSAP + ig_flag
119                 buf[1] = l.SSAP + cr_flag
120
121                 if length == 4 {
122                         buf[2] = uint8(l.Control >> 8)
123                         buf[3] = uint8(l.Control)
124                 } else {
125                         buf[2] = uint8(l.Control)
126                 }
127         }
128
129         return nil
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 (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
136         if buf, err := b.PrependBytes(5); err != nil {
137                 return err
138         } else {
139                 buf[0] = s.OrganizationalCode[0]
140                 buf[1] = s.OrganizationalCode[1]
141                 buf[2] = s.OrganizationalCode[2]
142                 binary.BigEndian.PutUint16(buf[3:5], uint16(s.Type))
143         }
144
145         return nil
146 }