github.com/gopacket/gopacket@v1.1.0/layers/linux_sll.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  	"errors"
    12  	"fmt"
    13  	"net"
    14  
    15  	"github.com/gopacket/gopacket"
    16  )
    17  
    18  type LinuxSLLPacketType uint16
    19  
    20  const (
    21  	LinuxSLLPacketTypeHost      LinuxSLLPacketType = 0 // To us
    22  	LinuxSLLPacketTypeBroadcast LinuxSLLPacketType = 1 // To all
    23  	LinuxSLLPacketTypeMulticast LinuxSLLPacketType = 2 // To group
    24  	LinuxSLLPacketTypeOtherhost LinuxSLLPacketType = 3 // To someone else
    25  	LinuxSLLPacketTypeOutgoing  LinuxSLLPacketType = 4 // Outgoing of any type
    26  	// These ones are invisible by user level
    27  	LinuxSLLPacketTypeLoopback  LinuxSLLPacketType = 5 // MC/BRD frame looped back
    28  	LinuxSLLPacketTypeFastroute LinuxSLLPacketType = 6 // Fastrouted frame
    29  )
    30  
    31  func (l LinuxSLLPacketType) String() string {
    32  	switch l {
    33  	case LinuxSLLPacketTypeHost:
    34  		return "host"
    35  	case LinuxSLLPacketTypeBroadcast:
    36  		return "broadcast"
    37  	case LinuxSLLPacketTypeMulticast:
    38  		return "multicast"
    39  	case LinuxSLLPacketTypeOtherhost:
    40  		return "otherhost"
    41  	case LinuxSLLPacketTypeOutgoing:
    42  		return "outgoing"
    43  	case LinuxSLLPacketTypeLoopback:
    44  		return "loopback"
    45  	case LinuxSLLPacketTypeFastroute:
    46  		return "fastroute"
    47  	}
    48  	return fmt.Sprintf("Unknown(%d)", int(l))
    49  }
    50  
    51  type LinuxSLL struct {
    52  	BaseLayer
    53  	PacketType   LinuxSLLPacketType
    54  	AddrLen      uint16
    55  	Addr         net.HardwareAddr
    56  	EthernetType EthernetType
    57  	AddrType     uint16
    58  }
    59  
    60  // LayerType returns LayerTypeLinuxSLL.
    61  func (sll *LinuxSLL) LayerType() gopacket.LayerType { return LayerTypeLinuxSLL }
    62  
    63  func (sll *LinuxSLL) CanDecode() gopacket.LayerClass {
    64  	return LayerTypeLinuxSLL
    65  }
    66  
    67  func (sll *LinuxSLL) LinkFlow() gopacket.Flow {
    68  	return gopacket.NewFlow(EndpointMAC, sll.Addr, nil)
    69  }
    70  
    71  func (sll *LinuxSLL) NextLayerType() gopacket.LayerType {
    72  	return sll.EthernetType.LayerType()
    73  }
    74  
    75  func (sll *LinuxSLL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    76  	if len(data) < 16 {
    77  		return errors.New("Linux SLL packet too small")
    78  	}
    79  	sll.PacketType = LinuxSLLPacketType(binary.BigEndian.Uint16(data[0:2]))
    80  	sll.AddrType = binary.BigEndian.Uint16(data[2:4])
    81  	sll.AddrLen = binary.BigEndian.Uint16(data[4:6])
    82  
    83  	sll.Addr = net.HardwareAddr(data[6 : sll.AddrLen+6])
    84  	sll.EthernetType = EthernetType(binary.BigEndian.Uint16(data[14:16]))
    85  	sll.BaseLayer = BaseLayer{data[:16], data[16:]}
    86  
    87  	return nil
    88  }
    89  
    90  func decodeLinuxSLL(data []byte, p gopacket.PacketBuilder) error {
    91  	sll := &LinuxSLL{}
    92  	if err := sll.DecodeFromBytes(data, p); err != nil {
    93  		return err
    94  	}
    95  	p.AddLayer(sll)
    96  	p.SetLinkLayer(sll)
    97  	return p.NextDecoder(sll.EthernetType)
    98  }