github.com/gopacket/gopacket@v1.1.0/layers/loopback.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  
    14  	"github.com/gopacket/gopacket"
    15  )
    16  
    17  // Loopback contains the header for loopback encapsulation.  This header is
    18  // used by both BSD and OpenBSD style loopback decoding (pcap's DLT_NULL
    19  // and DLT_LOOP, respectively).
    20  type Loopback struct {
    21  	BaseLayer
    22  	Family ProtocolFamily
    23  }
    24  
    25  // LayerType returns LayerTypeLoopback.
    26  func (l *Loopback) LayerType() gopacket.LayerType { return LayerTypeLoopback }
    27  
    28  // DecodeFromBytes decodes the given bytes into this layer.
    29  func (l *Loopback) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    30  	if len(data) < 4 {
    31  		return errors.New("Loopback packet too small")
    32  	}
    33  
    34  	// The protocol could be either big-endian or little-endian, we're
    35  	// not sure.  But we're PRETTY sure that the value is less than
    36  	// 256, so we can check the first two bytes.
    37  	var prot uint32
    38  	if data[0] == 0 && data[1] == 0 {
    39  		prot = binary.BigEndian.Uint32(data[:4])
    40  	} else {
    41  		prot = binary.LittleEndian.Uint32(data[:4])
    42  	}
    43  	if prot > 0xFF {
    44  		return fmt.Errorf("Invalid loopback protocol %q", data[:4])
    45  	}
    46  
    47  	l.Family = ProtocolFamily(prot)
    48  	l.BaseLayer = BaseLayer{data[:4], data[4:]}
    49  	return nil
    50  }
    51  
    52  // CanDecode returns the set of layer types that this DecodingLayer can decode.
    53  func (l *Loopback) CanDecode() gopacket.LayerClass {
    54  	return LayerTypeLoopback
    55  }
    56  
    57  // NextLayerType returns the layer type contained by this DecodingLayer.
    58  func (l *Loopback) NextLayerType() gopacket.LayerType {
    59  	return l.Family.LayerType()
    60  }
    61  
    62  // SerializeTo writes the serialized form of this layer into the
    63  // SerializationBuffer, implementing gopacket.SerializableLayer.
    64  func (l *Loopback) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
    65  	bytes, err := b.PrependBytes(4)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	binary.LittleEndian.PutUint32(bytes, uint32(l.Family))
    70  	return nil
    71  }
    72  
    73  func decodeLoopback(data []byte, p gopacket.PacketBuilder) error {
    74  	l := Loopback{}
    75  	if err := l.DecodeFromBytes(data, gopacket.NilDecodeFeedback); err != nil {
    76  		return err
    77  	}
    78  	p.AddLayer(&l)
    79  	return p.NextDecoder(l.Family)
    80  }