github.com/gopacket/gopacket@v1.1.0/parser.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 gopacket
     8  
     9  import (
    10  	"fmt"
    11  )
    12  
    13  // A container for single LayerType->DecodingLayer mapping.
    14  type decodingLayerElem struct {
    15  	typ LayerType
    16  	dec DecodingLayer
    17  }
    18  
    19  // DecodingLayer is an interface for packet layers that can decode themselves.
    20  //
    21  // The important part of DecodingLayer is that they decode themselves in-place.
    22  // Calling DecodeFromBytes on a DecodingLayer totally resets the entire layer to
    23  // the new state defined by the data passed in.  A returned error leaves the
    24  // DecodingLayer in an unknown intermediate state, thus its fields should not be
    25  // trusted.
    26  //
    27  // Because the DecodingLayer is resetting its own fields, a call to
    28  // DecodeFromBytes should normally not require any memory allocation.
    29  type DecodingLayer interface {
    30  	// DecodeFromBytes resets the internal state of this layer to the state
    31  	// defined by the passed-in bytes.  Slices in the DecodingLayer may
    32  	// reference the passed-in data, so care should be taken to copy it
    33  	// first should later modification of data be required before the
    34  	// DecodingLayer is discarded.
    35  	DecodeFromBytes(data []byte, df DecodeFeedback) error
    36  	// CanDecode returns the set of LayerTypes this DecodingLayer can
    37  	// decode.  For Layers that are also DecodingLayers, this will most
    38  	// often be that Layer's LayerType().
    39  	CanDecode() LayerClass
    40  	// NextLayerType returns the LayerType which should be used to decode
    41  	// the LayerPayload.
    42  	NextLayerType() LayerType
    43  	// LayerPayload is the set of bytes remaining to decode after a call to
    44  	// DecodeFromBytes.
    45  	LayerPayload() []byte
    46  }
    47  
    48  // DecodingLayerFunc decodes given packet and stores decoded LayerType
    49  // values into specified slice. Returns either first encountered
    50  // unsupported LayerType value or decoding error. In case of success,
    51  // returns (LayerTypeZero, nil).
    52  type DecodingLayerFunc func([]byte, *[]LayerType) (LayerType, error)
    53  
    54  // DecodingLayerContainer stores all DecodingLayer-s and serves as a
    55  // searching tool for DecodingLayerParser.
    56  type DecodingLayerContainer interface {
    57  	// Put adds new DecodingLayer to container. The new instance of
    58  	// the same DecodingLayerContainer is returned so it may be
    59  	// implemented as a value receiver.
    60  	Put(DecodingLayer) DecodingLayerContainer
    61  	// Decoder returns DecodingLayer to decode given LayerType and
    62  	// true if it was found. If no decoder found, return false.
    63  	Decoder(LayerType) (DecodingLayer, bool)
    64  	// LayersDecoder returns DecodingLayerFunc which decodes given
    65  	// packet, starting with specified LayerType and DecodeFeedback.
    66  	LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc
    67  }
    68  
    69  // DecodingLayerSparse is a sparse array-based implementation of
    70  // DecodingLayerContainer. Each DecodingLayer is addressed in an
    71  // allocated slice by LayerType value itself. Though this is the
    72  // fastest container it may be memory-consuming if used with big
    73  // LayerType values.
    74  type DecodingLayerSparse []DecodingLayer
    75  
    76  // Put implements DecodingLayerContainer interface.
    77  func (dl DecodingLayerSparse) Put(d DecodingLayer) DecodingLayerContainer {
    78  	maxLayerType := LayerType(len(dl) - 1)
    79  	for _, typ := range d.CanDecode().LayerTypes() {
    80  		if typ > maxLayerType {
    81  			maxLayerType = typ
    82  		}
    83  	}
    84  
    85  	if extra := maxLayerType - LayerType(len(dl)) + 1; extra > 0 {
    86  		dl = append(dl, make([]DecodingLayer, extra)...)
    87  	}
    88  
    89  	for _, typ := range d.CanDecode().LayerTypes() {
    90  		dl[typ] = d
    91  	}
    92  	return dl
    93  }
    94  
    95  // LayersDecoder implements DecodingLayerContainer interface.
    96  func (dl DecodingLayerSparse) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {
    97  	return LayersDecoder(dl, first, df)
    98  }
    99  
   100  // Decoder implements DecodingLayerContainer interface.
   101  func (dl DecodingLayerSparse) Decoder(typ LayerType) (DecodingLayer, bool) {
   102  	if int64(typ) < int64(len(dl)) {
   103  		decoder := dl[typ]
   104  		return decoder, decoder != nil
   105  	}
   106  	return nil, false
   107  }
   108  
   109  // DecodingLayerArray is an array-based implementation of
   110  // DecodingLayerContainer. Each DecodingLayer is searched linearly in
   111  // an allocated slice in one-by-one fashion.
   112  type DecodingLayerArray []decodingLayerElem
   113  
   114  // Put implements DecodingLayerContainer interface.
   115  func (dl DecodingLayerArray) Put(d DecodingLayer) DecodingLayerContainer {
   116  TYPES:
   117  	for _, typ := range d.CanDecode().LayerTypes() {
   118  		for i := range dl {
   119  			if dl[i].typ == typ {
   120  				dl[i].dec = d
   121  				continue TYPES
   122  			}
   123  		}
   124  		dl = append(dl, decodingLayerElem{typ, d})
   125  	}
   126  	return dl
   127  }
   128  
   129  // Decoder implements DecodingLayerContainer interface.
   130  func (dl DecodingLayerArray) Decoder(typ LayerType) (DecodingLayer, bool) {
   131  	for i := range dl {
   132  		if dl[i].typ == typ {
   133  			return dl[i].dec, true
   134  		}
   135  	}
   136  	return nil, false
   137  }
   138  
   139  // LayersDecoder implements DecodingLayerContainer interface.
   140  func (dl DecodingLayerArray) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {
   141  	return LayersDecoder(dl, first, df)
   142  }
   143  
   144  // DecodingLayerMap is an map-based implementation of
   145  // DecodingLayerContainer. Each DecodingLayer is searched in a map
   146  // hashed by LayerType value.
   147  type DecodingLayerMap map[LayerType]DecodingLayer
   148  
   149  // Put implements DecodingLayerContainer interface.
   150  func (dl DecodingLayerMap) Put(d DecodingLayer) DecodingLayerContainer {
   151  	for _, typ := range d.CanDecode().LayerTypes() {
   152  		if dl == nil {
   153  			dl = make(map[LayerType]DecodingLayer)
   154  		}
   155  		dl[typ] = d
   156  	}
   157  	return dl
   158  }
   159  
   160  // Decoder implements DecodingLayerContainer interface.
   161  func (dl DecodingLayerMap) Decoder(typ LayerType) (DecodingLayer, bool) {
   162  	d, ok := dl[typ]
   163  	return d, ok
   164  }
   165  
   166  // LayersDecoder implements DecodingLayerContainer interface.
   167  func (dl DecodingLayerMap) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {
   168  	return LayersDecoder(dl, first, df)
   169  }
   170  
   171  // Static code check.
   172  var (
   173  	_ = []DecodingLayerContainer{
   174  		DecodingLayerSparse(nil),
   175  		DecodingLayerMap(nil),
   176  		DecodingLayerArray(nil),
   177  	}
   178  )
   179  
   180  // DecodingLayerParser parses a given set of layer types.  See DecodeLayers for
   181  // more information on how DecodingLayerParser should be used.
   182  type DecodingLayerParser struct {
   183  	// DecodingLayerParserOptions is the set of options available to the
   184  	// user to define the parser's behavior.
   185  	DecodingLayerParserOptions
   186  	dlc   DecodingLayerContainer
   187  	first LayerType
   188  	df    DecodeFeedback
   189  
   190  	decodeFunc DecodingLayerFunc
   191  
   192  	// Truncated is set when a decode layer detects that the packet has been
   193  	// truncated.
   194  	Truncated bool
   195  }
   196  
   197  // AddDecodingLayer adds a decoding layer to the parser.  This adds support for
   198  // the decoding layer's CanDecode layers to the parser... should they be
   199  // encountered, they'll be parsed.
   200  func (l *DecodingLayerParser) AddDecodingLayer(d DecodingLayer) {
   201  	l.SetDecodingLayerContainer(l.dlc.Put(d))
   202  }
   203  
   204  // SetTruncated is used by DecodingLayers to set the Truncated boolean in the
   205  // DecodingLayerParser.  Users should simply read Truncated after calling
   206  // DecodeLayers.
   207  func (l *DecodingLayerParser) SetTruncated() {
   208  	l.Truncated = true
   209  }
   210  
   211  // NewDecodingLayerParser creates a new DecodingLayerParser and adds in all
   212  // of the given DecodingLayers with AddDecodingLayer.
   213  //
   214  // Each call to DecodeLayers will attempt to decode the given bytes first by
   215  // treating them as a 'first'-type layer, then by using NextLayerType on
   216  // subsequently decoded layers to find the next relevant decoder.  Should a
   217  // deoder not be available for the layer type returned by NextLayerType,
   218  // decoding will stop.
   219  //
   220  // NewDecodingLayerParser uses DecodingLayerMap container by
   221  // default.
   222  func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser {
   223  	dlp := &DecodingLayerParser{first: first}
   224  	dlp.df = dlp // Cast this once to the interface
   225  	// default container
   226  	dlc := DecodingLayerContainer(DecodingLayerMap(make(map[LayerType]DecodingLayer)))
   227  	for _, d := range decoders {
   228  		dlc = dlc.Put(d)
   229  	}
   230  
   231  	dlp.SetDecodingLayerContainer(dlc)
   232  	return dlp
   233  }
   234  
   235  // SetDecodingLayerContainer specifies container with decoders. This
   236  // call replaces all decoders already registered in given instance of
   237  // DecodingLayerParser.
   238  func (l *DecodingLayerParser) SetDecodingLayerContainer(dlc DecodingLayerContainer) {
   239  	l.dlc = dlc
   240  	l.decodeFunc = l.dlc.LayersDecoder(l.first, l.df)
   241  }
   242  
   243  // DecodeLayers decodes as many layers as possible from the given data.  It
   244  // initially treats the data as layer type 'typ', then uses NextLayerType on
   245  // each subsequent decoded layer until it gets to a layer type it doesn't know
   246  // how to parse.
   247  //
   248  // For each layer successfully decoded, DecodeLayers appends the layer type to
   249  // the decoded slice.  DecodeLayers truncates the 'decoded' slice initially, so
   250  // there's no need to empty it yourself.
   251  //
   252  // This decoding method is about an order of magnitude faster than packet
   253  // decoding, because it only decodes known layers that have already been
   254  // allocated.  This means it doesn't need to allocate each layer it returns...
   255  // instead it overwrites the layers that already exist.
   256  //
   257  // Example usage:
   258  //
   259  //	func main() {
   260  //	  var eth layers.Ethernet
   261  //	  var ip4 layers.IPv4
   262  //	  var ip6 layers.IPv6
   263  //	  var tcp layers.TCP
   264  //	  var udp layers.UDP
   265  //	  var payload gopacket.Payload
   266  //	  parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &ip6, &tcp, &udp, &payload)
   267  //	  var source gopacket.PacketDataSource = getMyDataSource()
   268  //	  decodedLayers := make([]gopacket.LayerType, 0, 10)
   269  //	  for {
   270  //	    data, _, err := source.ReadPacketData()
   271  //	    if err != nil {
   272  //	      fmt.Println("Error reading packet data: ", err)
   273  //	      continue
   274  //	    }
   275  //	    fmt.Println("Decoding packet")
   276  //	    err = parser.DecodeLayers(data, &decodedLayers)
   277  //	    for _, typ := range decodedLayers {
   278  //	      fmt.Println("  Successfully decoded layer type", typ)
   279  //	      switch typ {
   280  //	        case layers.LayerTypeEthernet:
   281  //	          fmt.Println("    Eth ", eth.SrcMAC, eth.DstMAC)
   282  //	        case layers.LayerTypeIPv4:
   283  //	          fmt.Println("    IP4 ", ip4.SrcIP, ip4.DstIP)
   284  //	        case layers.LayerTypeIPv6:
   285  //	          fmt.Println("    IP6 ", ip6.SrcIP, ip6.DstIP)
   286  //	        case layers.LayerTypeTCP:
   287  //	          fmt.Println("    TCP ", tcp.SrcPort, tcp.DstPort)
   288  //	        case layers.LayerTypeUDP:
   289  //	          fmt.Println("    UDP ", udp.SrcPort, udp.DstPort)
   290  //	      }
   291  //	    }
   292  //	    if decodedLayers.Truncated {
   293  //	      fmt.Println("  Packet has been truncated")
   294  //	    }
   295  //	    if err != nil {
   296  //	      fmt.Println("  Error encountered:", err)
   297  //	    }
   298  //	  }
   299  //	}
   300  //
   301  // If DecodeLayers is unable to decode the next layer type, it will return the
   302  // error UnsupportedLayerType.
   303  func (l *DecodingLayerParser) DecodeLayers(data []byte, decoded *[]LayerType) (err error) {
   304  	l.Truncated = false
   305  	if !l.IgnorePanic {
   306  		defer panicToError(&err)
   307  	}
   308  	typ, err := l.decodeFunc(data, decoded)
   309  	if typ != LayerTypeZero {
   310  		// no decoder
   311  		if l.IgnoreUnsupported {
   312  			return nil
   313  		}
   314  		return UnsupportedLayerType(typ)
   315  	}
   316  	return err
   317  }
   318  
   319  // UnsupportedLayerType is returned by DecodingLayerParser if DecodeLayers
   320  // encounters a layer type that the DecodingLayerParser has no decoder for.
   321  type UnsupportedLayerType LayerType
   322  
   323  // Error implements the error interface, returning a string to say that the
   324  // given layer type is unsupported.
   325  func (e UnsupportedLayerType) Error() string {
   326  	return fmt.Sprintf("No decoder for layer type %v", LayerType(e))
   327  }
   328  
   329  func panicToError(e *error) {
   330  	if r := recover(); r != nil {
   331  		*e = fmt.Errorf("panic: %v", r)
   332  	}
   333  }
   334  
   335  // DecodingLayerParserOptions provides options to affect the behavior of a given
   336  // DecodingLayerParser.
   337  type DecodingLayerParserOptions struct {
   338  	// IgnorePanic determines whether a DecodingLayerParser should stop
   339  	// panics on its own (by returning them as an error from DecodeLayers)
   340  	// or should allow them to raise up the stack.  Handling errors does add
   341  	// latency to the process of decoding layers, but is much safer for
   342  	// callers.  IgnorePanic defaults to false, thus if the caller does
   343  	// nothing decode panics will be returned as errors.
   344  	IgnorePanic bool
   345  	// IgnoreUnsupported will stop parsing and return a nil error when it
   346  	// encounters a layer it doesn't have a parser for, instead of returning an
   347  	// UnsupportedLayerType error.  If this is true, it's up to the caller to make
   348  	// sure that all expected layers have been parsed (by checking the decoded
   349  	// slice).
   350  	IgnoreUnsupported bool
   351  }