github.com/gopacket/gopacket@v1.1.0/layerclass.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  // LayerClass is a set of LayerTypes, used for grabbing one of a number of
    10  // different types from a packet.
    11  type LayerClass interface {
    12  	// Contains returns true if the given layer type should be considered part
    13  	// of this layer class.
    14  	Contains(LayerType) bool
    15  	// LayerTypes returns the set of all layer types in this layer class.
    16  	// Note that this may not be a fast operation on all LayerClass
    17  	// implementations.
    18  	LayerTypes() []LayerType
    19  }
    20  
    21  // Contains implements LayerClass.
    22  func (l LayerType) Contains(a LayerType) bool {
    23  	return l == a
    24  }
    25  
    26  // LayerTypes implements LayerClass.
    27  func (l LayerType) LayerTypes() []LayerType {
    28  	return []LayerType{l}
    29  }
    30  
    31  // LayerClassSlice implements a LayerClass with a slice.
    32  type LayerClassSlice []bool
    33  
    34  // Contains returns true if the given layer type should be considered part
    35  // of this layer class.
    36  func (s LayerClassSlice) Contains(t LayerType) bool {
    37  	return int(t) < len(s) && s[t]
    38  }
    39  
    40  // LayerTypes returns all layer types in this LayerClassSlice.
    41  // Because of LayerClassSlice's implementation, this could be quite slow.
    42  func (s LayerClassSlice) LayerTypes() (all []LayerType) {
    43  	for i := 0; i < len(s); i++ {
    44  		if s[i] {
    45  			all = append(all, LayerType(i))
    46  		}
    47  	}
    48  	return
    49  }
    50  
    51  // NewLayerClassSlice creates a new LayerClassSlice by creating a slice of
    52  // size max(types) and setting slice[t] to true for each type t.  Note, if
    53  // you implement your own LayerType and give it a high value, this WILL create
    54  // a very large slice.
    55  func NewLayerClassSlice(types []LayerType) LayerClassSlice {
    56  	var max LayerType
    57  	for _, typ := range types {
    58  		if typ > max {
    59  			max = typ
    60  		}
    61  	}
    62  	t := make([]bool, int(max+1))
    63  	for _, typ := range types {
    64  		t[typ] = true
    65  	}
    66  	return t
    67  }
    68  
    69  // LayerClassMap implements a LayerClass with a map.
    70  type LayerClassMap map[LayerType]bool
    71  
    72  // Contains returns true if the given layer type should be considered part
    73  // of this layer class.
    74  func (m LayerClassMap) Contains(t LayerType) bool {
    75  	return m[t]
    76  }
    77  
    78  // LayerTypes returns all layer types in this LayerClassMap.
    79  func (m LayerClassMap) LayerTypes() (all []LayerType) {
    80  	for t := range m {
    81  		all = append(all, t)
    82  	}
    83  	return
    84  }
    85  
    86  // NewLayerClassMap creates a LayerClassMap and sets map[t] to true for each
    87  // type in types.
    88  func NewLayerClassMap(types []LayerType) LayerClassMap {
    89  	m := LayerClassMap{}
    90  	for _, typ := range types {
    91  		m[typ] = true
    92  	}
    93  	return m
    94  }
    95  
    96  // NewLayerClass creates a LayerClass, attempting to be smart about which type
    97  // it creates based on which types are passed in.
    98  func NewLayerClass(types []LayerType) LayerClass {
    99  	for _, typ := range types {
   100  		if typ > maxLayerType {
   101  			// NewLayerClassSlice could create a very large object, so instead create
   102  			// a map.
   103  			return NewLayerClassMap(types)
   104  		}
   105  	}
   106  	return NewLayerClassSlice(types)
   107  }