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