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 }