Fix unit tests
[govpp.git] / vendor / github.com / google / gopacket / layers / ethernet.go
1 // Copyright 2012 Google, Inc. All rights reserved.
2 // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style license
5 // that can be found in the LICENSE file in the root of the source
6 // tree.
7
8 package layers
9
10 import (
11         "encoding/binary"
12         "errors"
13         "fmt"
14         "github.com/google/gopacket"
15         "net"
16 )
17
18 // EthernetBroadcast is the broadcast MAC address used by Ethernet.
19 var EthernetBroadcast = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
20
21 // Ethernet is the layer for Ethernet frame headers.
22 type Ethernet struct {
23         BaseLayer
24         SrcMAC, DstMAC net.HardwareAddr
25         EthernetType   EthernetType
26         // Length is only set if a length field exists within this header.  Ethernet
27         // headers follow two different standards, one that uses an EthernetType, the
28         // other which defines a length the follows with a LLC header (802.3).  If the
29         // former is the case, we set EthernetType and Length stays 0.  In the latter
30         // case, we set Length and EthernetType = EthernetTypeLLC.
31         Length uint16
32 }
33
34 // LayerType returns LayerTypeEthernet
35 func (e *Ethernet) LayerType() gopacket.LayerType { return LayerTypeEthernet }
36
37 func (e *Ethernet) LinkFlow() gopacket.Flow {
38         return gopacket.NewFlow(EndpointMAC, e.SrcMAC, e.DstMAC)
39 }
40
41 func (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
42         if len(data) < 14 {
43                 return errors.New("Ethernet packet too small")
44         }
45         eth.DstMAC = net.HardwareAddr(data[0:6])
46         eth.SrcMAC = net.HardwareAddr(data[6:12])
47         eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14]))
48         eth.BaseLayer = BaseLayer{data[:14], data[14:]}
49         if eth.EthernetType < 0x0600 {
50                 eth.Length = uint16(eth.EthernetType)
51                 eth.EthernetType = EthernetTypeLLC
52                 if cmp := len(eth.Payload) - int(eth.Length); cmp < 0 {
53                         df.SetTruncated()
54                 } else if cmp > 0 {
55                         // Strip off bytes at the end, since we have too many bytes
56                         eth.Payload = eth.Payload[:len(eth.Payload)-cmp]
57                 }
58                 //      fmt.Println(eth)
59         }
60         return nil
61 }
62
63 // SerializeTo writes the serialized form of this layer into the
64 // SerializationBuffer, implementing gopacket.SerializableLayer.
65 // See the docs for gopacket.SerializableLayer for more info.
66 func (eth *Ethernet) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
67         if len(eth.DstMAC) != 6 {
68                 return fmt.Errorf("invalid dst MAC: %v", eth.DstMAC)
69         }
70         if len(eth.SrcMAC) != 6 {
71                 return fmt.Errorf("invalid src MAC: %v", eth.SrcMAC)
72         }
73         payload := b.Bytes()
74         bytes, err := b.PrependBytes(14)
75         if err != nil {
76                 return err
77         }
78         copy(bytes, eth.DstMAC)
79         copy(bytes[6:], eth.SrcMAC)
80         if eth.Length != 0 || eth.EthernetType == EthernetTypeLLC {
81                 if opts.FixLengths {
82                         eth.Length = uint16(len(payload))
83                 }
84                 if eth.EthernetType != EthernetTypeLLC {
85                         return fmt.Errorf("ethernet type %v not compatible with length value %v", eth.EthernetType, eth.Length)
86                 } else if eth.Length > 0x0600 {
87                         return fmt.Errorf("invalid ethernet length %v", eth.Length)
88                 }
89                 binary.BigEndian.PutUint16(bytes[12:], eth.Length)
90         } else {
91                 binary.BigEndian.PutUint16(bytes[12:], uint16(eth.EthernetType))
92         }
93         length := len(b.Bytes())
94         if length < 60 {
95                 // Pad out to 60 bytes.
96                 padding, err := b.AppendBytes(60 - length)
97                 if err != nil {
98                         return err
99                 }
100                 copy(padding, lotsOfZeros[:])
101         }
102         return nil
103 }
104
105 func (eth *Ethernet) CanDecode() gopacket.LayerClass {
106         return LayerTypeEthernet
107 }
108
109 func (eth *Ethernet) NextLayerType() gopacket.LayerType {
110         return eth.EthernetType.LayerType()
111 }
112
113 func decodeEthernet(data []byte, p gopacket.PacketBuilder) error {
114         eth := &Ethernet{}
115         err := eth.DecodeFromBytes(data, p)
116         if err != nil {
117                 return err
118         }
119         p.AddLayer(eth)
120         p.SetLinkLayer(eth)
121         return p.NextDecoder(eth.EthernetType)
122 }