github.com/gopacket/gopacket@v1.1.0/layertype.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 "strconv" 12 ) 13 14 // LayerType is a unique identifier for each type of layer. This enumeration 15 // does not match with any externally available numbering scheme... it's solely 16 // usable/useful within this library as a means for requesting layer types 17 // (see Packet.Layer) and determining which types of layers have been decoded. 18 // 19 // New LayerTypes may be created by calling gopacket.RegisterLayerType. 20 type LayerType int64 21 22 // LayerTypeMetadata contains metadata associated with each LayerType. 23 type LayerTypeMetadata struct { 24 // Name is the string returned by each layer type's String method. 25 Name string 26 // Decoder is the decoder to use when the layer type is passed in as a 27 // Decoder. 28 Decoder Decoder 29 } 30 31 type layerTypeMetadata struct { 32 inUse bool 33 LayerTypeMetadata 34 } 35 36 // DecodersByLayerName maps layer names to decoders for those layers. 37 // This allows users to specify decoders by name to a program and have that 38 // program pick the correct decoder accordingly. 39 var DecodersByLayerName = map[string]Decoder{} 40 41 const maxLayerType = 2000 42 43 var ltMeta [maxLayerType]layerTypeMetadata 44 var ltMetaMap = map[LayerType]layerTypeMetadata{} 45 46 // RegisterLayerType creates a new layer type and registers it globally. 47 // The number passed in must be unique, or a runtime panic will occur. Numbers 48 // 0-999 are reserved for the gopacket library. Numbers 1000-1999 should be 49 // used for common application-specific types, and are very fast. Any other 50 // number (negative or >= 2000) may be used for uncommon application-specific 51 // types, and are somewhat slower (they require a map lookup over an array 52 // index). 53 func RegisterLayerType(num int, meta LayerTypeMetadata) LayerType { 54 if 0 <= num && num < maxLayerType { 55 if ltMeta[num].inUse { 56 panic("Layer type already exists") 57 } 58 } else { 59 if ltMetaMap[LayerType(num)].inUse { 60 panic("Layer type already exists") 61 } 62 } 63 return OverrideLayerType(num, meta) 64 } 65 66 // OverrideLayerType acts like RegisterLayerType, except that if the layer type 67 // has already been registered, it overrides the metadata with the passed-in 68 // metadata intead of panicing. 69 func OverrideLayerType(num int, meta LayerTypeMetadata) LayerType { 70 if 0 <= num && num < maxLayerType { 71 ltMeta[num] = layerTypeMetadata{ 72 inUse: true, 73 LayerTypeMetadata: meta, 74 } 75 } else { 76 ltMetaMap[LayerType(num)] = layerTypeMetadata{ 77 inUse: true, 78 LayerTypeMetadata: meta, 79 } 80 } 81 DecodersByLayerName[meta.Name] = meta.Decoder 82 return LayerType(num) 83 } 84 85 // Decode decodes the given data using the decoder registered with the layer 86 // type. 87 func (t LayerType) Decode(data []byte, c PacketBuilder) error { 88 var d Decoder 89 if 0 <= int(t) && int(t) < maxLayerType { 90 d = ltMeta[int(t)].Decoder 91 } else { 92 d = ltMetaMap[t].Decoder 93 } 94 if d != nil { 95 return d.Decode(data, c) 96 } 97 return fmt.Errorf("Layer type %v has no associated decoder", t) 98 } 99 100 // String returns the string associated with this layer type. 101 func (t LayerType) String() (s string) { 102 if 0 <= int(t) && int(t) < maxLayerType { 103 s = ltMeta[int(t)].Name 104 } else { 105 s = ltMetaMap[t].Name 106 } 107 if s == "" { 108 s = strconv.Itoa(int(t)) 109 } 110 return 111 }