1 // Copyright 2012 Google, Inc. All rights reserved.
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
12 "github.com/google/gopacket"
15 // EthernetCTPFunction is the function code used by the EthernetCTP protocol to identify each
17 type EthernetCTPFunction uint16
19 // EthernetCTPFunction values.
21 EthernetCTPFunctionReply EthernetCTPFunction = 1
22 EthernetCTPFunctionForwardData EthernetCTPFunction = 2
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 {
33 // LayerType returns gopacket.LayerTypeEthernetCTP.
34 func (c *EthernetCTP) LayerType() gopacket.LayerType {
35 return LayerTypeEthernetCTP
38 // EthernetCTPForwardData is the ForwardData layer inside EthernetCTP. See EthernetCTP's docs for more
40 type EthernetCTPForwardData struct {
42 Function EthernetCTPFunction
46 // LayerType returns gopacket.LayerTypeEthernetCTPForwardData.
47 func (c *EthernetCTPForwardData) LayerType() gopacket.LayerType {
48 return LayerTypeEthernetCTPForwardData
51 // ForwardEndpoint returns the EthernetCTPForwardData ForwardAddress as an endpoint.
52 func (c *EthernetCTPForwardData) ForwardEndpoint() gopacket.Endpoint {
53 return gopacket.NewEndpoint(EndpointMAC, c.ForwardAddress)
56 // EthernetCTPReply is the Reply layer inside EthernetCTP. See EthernetCTP's docs for more details.
57 type EthernetCTPReply struct {
59 Function EthernetCTPFunction
64 // LayerType returns gopacket.LayerTypeEthernetCTPReply.
65 func (c *EthernetCTPReply) LayerType() gopacket.LayerType {
66 return LayerTypeEthernetCTPReply
69 // Payload returns the EthernetCTP reply's Data bytes.
70 func (c *EthernetCTPReply) Payload() []byte { return c.Data }
72 func decodeEthernetCTP(data []byte, p gopacket.PacketBuilder) error {
74 SkipCount: binary.LittleEndian.Uint16(data[:2]),
75 BaseLayer: BaseLayer{data[:2], data[2:]},
77 if c.SkipCount%2 != 0 {
78 return fmt.Errorf("EthernetCTP skip count is odd: %d", c.SkipCount)
81 return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
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]))
89 case EthernetCTPFunctionReply:
90 reply := &EthernetCTPReply{
92 ReceiptNumber: binary.LittleEndian.Uint16(data[2:4]),
94 BaseLayer: BaseLayer{data, nil},
97 p.SetApplicationLayer(reply)
99 case EthernetCTPFunctionForwardData:
100 forward := &EthernetCTPForwardData{
102 ForwardAddress: data[2:8],
103 BaseLayer: BaseLayer{data[:8], data[8:]},
106 return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
108 return fmt.Errorf("Unknown EthernetCTP function type %v", function)