123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // Copyright 2012 Google, Inc. All rights reserved.
- //
- // Use of this source code is governed by a BSD-style license
- // that can be found in the LICENSE file in the root of the source
- // tree.
- package layers
- import (
- "encoding/binary"
- "fmt"
- "github.com/google/gopacket"
- )
- // EthernetCTPFunction is the function code used by the EthernetCTP protocol to identify each
- // EthernetCTP layer.
- type EthernetCTPFunction uint16
- // EthernetCTPFunction values.
- const (
- EthernetCTPFunctionReply EthernetCTPFunction = 1
- EthernetCTPFunctionForwardData EthernetCTPFunction = 2
- )
- // EthernetCTP implements the EthernetCTP protocol, see http://www.mit.edu/people/jhawk/ctp.html.
- // We split EthernetCTP up into the top-level EthernetCTP layer, followed by zero or more
- // EthernetCTPForwardData layers, followed by a final EthernetCTPReply layer.
- type EthernetCTP struct {
- BaseLayer
- SkipCount uint16
- }
- // LayerType returns gopacket.LayerTypeEthernetCTP.
- func (c *EthernetCTP) LayerType() gopacket.LayerType {
- return LayerTypeEthernetCTP
- }
- // EthernetCTPForwardData is the ForwardData layer inside EthernetCTP. See EthernetCTP's docs for more
- // details.
- type EthernetCTPForwardData struct {
- BaseLayer
- Function EthernetCTPFunction
- ForwardAddress []byte
- }
- // LayerType returns gopacket.LayerTypeEthernetCTPForwardData.
- func (c *EthernetCTPForwardData) LayerType() gopacket.LayerType {
- return LayerTypeEthernetCTPForwardData
- }
- // ForwardEndpoint returns the EthernetCTPForwardData ForwardAddress as an endpoint.
- func (c *EthernetCTPForwardData) ForwardEndpoint() gopacket.Endpoint {
- return gopacket.NewEndpoint(EndpointMAC, c.ForwardAddress)
- }
- // EthernetCTPReply is the Reply layer inside EthernetCTP. See EthernetCTP's docs for more details.
- type EthernetCTPReply struct {
- BaseLayer
- Function EthernetCTPFunction
- ReceiptNumber uint16
- Data []byte
- }
- // LayerType returns gopacket.LayerTypeEthernetCTPReply.
- func (c *EthernetCTPReply) LayerType() gopacket.LayerType {
- return LayerTypeEthernetCTPReply
- }
- // Payload returns the EthernetCTP reply's Data bytes.
- func (c *EthernetCTPReply) Payload() []byte { return c.Data }
- func decodeEthernetCTP(data []byte, p gopacket.PacketBuilder) error {
- c := &EthernetCTP{
- SkipCount: binary.LittleEndian.Uint16(data[:2]),
- BaseLayer: BaseLayer{data[:2], data[2:]},
- }
- if c.SkipCount%2 != 0 {
- return fmt.Errorf("EthernetCTP skip count is odd: %d", c.SkipCount)
- }
- p.AddLayer(c)
- return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
- }
- // decodeEthernetCTPFromFunctionType reads in the first 2 bytes to determine the EthernetCTP
- // layer type to decode next, then decodes based on that.
- func decodeEthernetCTPFromFunctionType(data []byte, p gopacket.PacketBuilder) error {
- function := EthernetCTPFunction(binary.LittleEndian.Uint16(data[:2]))
- switch function {
- case EthernetCTPFunctionReply:
- reply := &EthernetCTPReply{
- Function: function,
- ReceiptNumber: binary.LittleEndian.Uint16(data[2:4]),
- Data: data[4:],
- BaseLayer: BaseLayer{data, nil},
- }
- p.AddLayer(reply)
- p.SetApplicationLayer(reply)
- return nil
- case EthernetCTPFunctionForwardData:
- forward := &EthernetCTPForwardData{
- Function: function,
- ForwardAddress: data[2:8],
- BaseLayer: BaseLayer{data[:8], data[8:]},
- }
- p.AddLayer(forward)
- return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
- }
- return fmt.Errorf("Unknown EthernetCTP function type %v", function)
- }
|