Fix unit tests
[govpp.git] / vendor / github.com / google / gopacket / layers / ctp.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         "fmt"
12         "github.com/google/gopacket"
13 )
14
15 // EthernetCTPFunction is the function code used by the EthernetCTP protocol to identify each
16 // EthernetCTP layer.
17 type EthernetCTPFunction uint16
18
19 // EthernetCTPFunction values.
20 const (
21         EthernetCTPFunctionReply       EthernetCTPFunction = 1
22         EthernetCTPFunctionForwardData EthernetCTPFunction = 2
23 )
24
25 // EthernetCTP implements the EthernetCTP protocol, see http://www.mit.edu/people/jhawk/ctp.html.
26 // We split EthernetCTP up into the top-level EthernetCTP layer, followed by zero or more
27 // EthernetCTPForwardData layers, followed by a final EthernetCTPReply layer.
28 type EthernetCTP struct {
29         BaseLayer
30         SkipCount uint16
31 }
32
33 // LayerType returns gopacket.LayerTypeEthernetCTP.
34 func (c *EthernetCTP) LayerType() gopacket.LayerType {
35         return LayerTypeEthernetCTP
36 }
37
38 // EthernetCTPForwardData is the ForwardData layer inside EthernetCTP.  See EthernetCTP's docs for more
39 // details.
40 type EthernetCTPForwardData struct {
41         BaseLayer
42         Function       EthernetCTPFunction
43         ForwardAddress []byte
44 }
45
46 // LayerType returns gopacket.LayerTypeEthernetCTPForwardData.
47 func (c *EthernetCTPForwardData) LayerType() gopacket.LayerType {
48         return LayerTypeEthernetCTPForwardData
49 }
50
51 // ForwardEndpoint returns the EthernetCTPForwardData ForwardAddress as an endpoint.
52 func (c *EthernetCTPForwardData) ForwardEndpoint() gopacket.Endpoint {
53         return gopacket.NewEndpoint(EndpointMAC, c.ForwardAddress)
54 }
55
56 // EthernetCTPReply is the Reply layer inside EthernetCTP.  See EthernetCTP's docs for more details.
57 type EthernetCTPReply struct {
58         BaseLayer
59         Function      EthernetCTPFunction
60         ReceiptNumber uint16
61         Data          []byte
62 }
63
64 // LayerType returns gopacket.LayerTypeEthernetCTPReply.
65 func (c *EthernetCTPReply) LayerType() gopacket.LayerType {
66         return LayerTypeEthernetCTPReply
67 }
68
69 // Payload returns the EthernetCTP reply's Data bytes.
70 func (c *EthernetCTPReply) Payload() []byte { return c.Data }
71
72 func decodeEthernetCTP(data []byte, p gopacket.PacketBuilder) error {
73         c := &EthernetCTP{
74                 SkipCount: binary.LittleEndian.Uint16(data[:2]),
75                 BaseLayer: BaseLayer{data[:2], data[2:]},
76         }
77         if c.SkipCount%2 != 0 {
78                 return fmt.Errorf("EthernetCTP skip count is odd: %d", c.SkipCount)
79         }
80         p.AddLayer(c)
81         return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
82 }
83
84 // decodeEthernetCTPFromFunctionType reads in the first 2 bytes to determine the EthernetCTP
85 // layer type to decode next, then decodes based on that.
86 func decodeEthernetCTPFromFunctionType(data []byte, p gopacket.PacketBuilder) error {
87         function := EthernetCTPFunction(binary.LittleEndian.Uint16(data[:2]))
88         switch function {
89         case EthernetCTPFunctionReply:
90                 reply := &EthernetCTPReply{
91                         Function:      function,
92                         ReceiptNumber: binary.LittleEndian.Uint16(data[2:4]),
93                         Data:          data[4:],
94                         BaseLayer:     BaseLayer{data, nil},
95                 }
96                 p.AddLayer(reply)
97                 p.SetApplicationLayer(reply)
98                 return nil
99         case EthernetCTPFunctionForwardData:
100                 forward := &EthernetCTPForwardData{
101                         Function:       function,
102                         ForwardAddress: data[2:8],
103                         BaseLayer:      BaseLayer{data[:8], data[8:]},
104                 }
105                 p.AddLayer(forward)
106                 return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
107         }
108         return fmt.Errorf("Unknown EthernetCTP function type %v", function)
109 }