github.com/gopacket/gopacket@v1.1.0/layers/llc.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  
    13  	"github.com/gopacket/gopacket"
    14  )
    15  
    16  // LLC is the layer used for 802.2 Logical Link Control headers.
    17  // See http://standards.ieee.org/getieee802/download/802.2-1998.pdf
    18  type LLC struct {
    19  	BaseLayer
    20  	DSAP    uint8
    21  	IG      bool // true means group, false means individual
    22  	SSAP    uint8
    23  	CR      bool // true means response, false means command
    24  	Control uint16
    25  }
    26  
    27  // LayerType returns gopacket.LayerTypeLLC.
    28  func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC }
    29  
    30  // DecodeFromBytes decodes the given bytes into this layer.
    31  func (l *LLC) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    32  	if len(data) < 3 {
    33  		return errors.New("LLC header too small")
    34  	}
    35  	l.DSAP = data[0] & 0xFE
    36  	l.IG = data[0]&0x1 != 0
    37  	l.SSAP = data[1] & 0xFE
    38  	l.CR = data[1]&0x1 != 0
    39  	l.Control = uint16(data[2])
    40  
    41  	if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {
    42  		if len(data) < 4 {
    43  			return errors.New("LLC header too small")
    44  		}
    45  		l.Control = l.Control<<8 | uint16(data[3])
    46  		l.Contents = data[:4]
    47  		l.Payload = data[4:]
    48  	} else {
    49  		l.Contents = data[:3]
    50  		l.Payload = data[3:]
    51  	}
    52  	return nil
    53  }
    54  
    55  // CanDecode returns the set of layer types that this DecodingLayer can decode.
    56  func (l *LLC) CanDecode() gopacket.LayerClass {
    57  	return LayerTypeLLC
    58  }
    59  
    60  // NextLayerType returns the layer type contained by this DecodingLayer.
    61  func (l *LLC) NextLayerType() gopacket.LayerType {
    62  	switch {
    63  	case l.DSAP == 0xAA && l.SSAP == 0xAA:
    64  		return LayerTypeSNAP
    65  	case l.DSAP == 0x42 && l.SSAP == 0x42:
    66  		return LayerTypeSTP
    67  	}
    68  	return gopacket.LayerTypeZero // Not implemented
    69  }
    70  
    71  // SNAP is used inside LLC.  See
    72  // http://standards.ieee.org/getieee802/download/802-2001.pdf.
    73  // From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol:
    74  //
    75  //	"[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing,
    76  //	on networks using IEEE 802.2 LLC, more protocols than can be distinguished
    77  //	by the 8-bit 802.2 Service Access Point (SAP) fields."
    78  type SNAP struct {
    79  	BaseLayer
    80  	OrganizationalCode []byte
    81  	Type               EthernetType
    82  }
    83  
    84  // LayerType returns gopacket.LayerTypeSNAP.
    85  func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }
    86  
    87  // DecodeFromBytes decodes the given bytes into this layer.
    88  func (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    89  	if len(data) < 5 {
    90  		return errors.New("SNAP header too small")
    91  	}
    92  	s.OrganizationalCode = data[:3]
    93  	s.Type = EthernetType(binary.BigEndian.Uint16(data[3:5]))
    94  	s.BaseLayer = BaseLayer{data[:5], data[5:]}
    95  	return nil
    96  }
    97  
    98  // CanDecode returns the set of layer types that this DecodingLayer can decode.
    99  func (s *SNAP) CanDecode() gopacket.LayerClass {
   100  	return LayerTypeSNAP
   101  }
   102  
   103  // NextLayerType returns the layer type contained by this DecodingLayer.
   104  func (s *SNAP) NextLayerType() gopacket.LayerType {
   105  	// See BUG(gconnel) in decodeSNAP
   106  	return s.Type.LayerType()
   107  }
   108  
   109  func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
   110  	l := &LLC{}
   111  	err := l.DecodeFromBytes(data, p)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	p.AddLayer(l)
   116  	return p.NextDecoder(l.NextLayerType())
   117  }
   118  
   119  func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
   120  	s := &SNAP{}
   121  	err := s.DecodeFromBytes(data, p)
   122  	if err != nil {
   123  		return err
   124  	}
   125  	p.AddLayer(s)
   126  	// BUG(gconnell):  When decoding SNAP, we treat the SNAP type as an Ethernet
   127  	// type.  This may not actually be an ethernet type in all cases,
   128  	// depending on the organizational code.  Right now, we don't check.
   129  	return p.NextDecoder(s.Type)
   130  }
   131  
   132  // SerializeTo writes the serialized form of this layer into the
   133  // SerializationBuffer, implementing gopacket.SerializableLayer.
   134  // See the docs for gopacket.SerializableLayer for more info.
   135  func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   136  	var igFlag, crFlag byte
   137  	var length int
   138  
   139  	if l.Control&0xFF00 != 0 {
   140  		length = 4
   141  	} else {
   142  		length = 3
   143  	}
   144  
   145  	if l.DSAP&0x1 != 0 {
   146  		return errors.New("DSAP value invalid, should not include IG flag bit")
   147  	}
   148  
   149  	if l.SSAP&0x1 != 0 {
   150  		return errors.New("SSAP value invalid, should not include CR flag bit")
   151  	}
   152  
   153  	if buf, err := b.PrependBytes(length); err != nil {
   154  		return err
   155  	} else {
   156  		igFlag = 0
   157  		if l.IG {
   158  			igFlag = 0x1
   159  		}
   160  
   161  		crFlag = 0
   162  		if l.CR {
   163  			crFlag = 0x1
   164  		}
   165  
   166  		buf[0] = l.DSAP + igFlag
   167  		buf[1] = l.SSAP + crFlag
   168  
   169  		if length == 4 {
   170  			buf[2] = uint8(l.Control >> 8)
   171  			buf[3] = uint8(l.Control)
   172  		} else {
   173  			buf[2] = uint8(l.Control)
   174  		}
   175  	}
   176  
   177  	return nil
   178  }
   179  
   180  // SerializeTo writes the serialized form of this layer into the
   181  // SerializationBuffer, implementing gopacket.SerializableLayer.
   182  // See the docs for gopacket.SerializableLayer for more info.
   183  func (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   184  	if buf, err := b.PrependBytes(5); err != nil {
   185  		return err
   186  	} else {
   187  		buf[0] = s.OrganizationalCode[0]
   188  		buf[1] = s.OrganizationalCode[1]
   189  		buf[2] = s.OrganizationalCode[2]
   190  		binary.BigEndian.PutUint16(buf[3:5], uint16(s.Type))
   191  	}
   192  
   193  	return nil
   194  }