| // Copyright 2012 Google, Inc. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style license |
| // that can be found in the LICENSE file in the root of the source |
| // tree. |
| |
| package gopacket |
| |
| import ( |
| "fmt" |
| "strconv" |
| ) |
| |
| // LayerType is a unique identifier for each type of layer. This enumeration |
| // does not match with any externally available numbering scheme... it's solely |
| // usable/useful within this library as a means for requesting layer types |
| // (see Packet.Layer) and determining which types of layers have been decoded. |
| // |
| // New LayerTypes may be created by calling gopacket.RegisterLayerType. |
| type LayerType int64 |
| |
| // LayerTypeMetadata contains metadata associated with each LayerType. |
| type LayerTypeMetadata struct { |
| // Name is the string returned by each layer type's String method. |
| Name string |
| // Decoder is the decoder to use when the layer type is passed in as a |
| // Decoder. |
| Decoder Decoder |
| } |
| |
| type layerTypeMetadata struct { |
| inUse bool |
| LayerTypeMetadata |
| } |
| |
| // DecodersByLayerName maps layer names to decoders for those layers. |
| // This allows users to specify decoders by name to a program and have that |
| // program pick the correct decoder accordingly. |
| var DecodersByLayerName = map[string]Decoder{} |
| |
| const maxLayerType = 2000 |
| |
| var ltMeta [maxLayerType]layerTypeMetadata |
| var ltMetaMap = map[LayerType]layerTypeMetadata{} |
| |
| // RegisterLayerType creates a new layer type and registers it globally. |
| // The number passed in must be unique, or a runtime panic will occur. Numbers |
| // 0-999 are reserved for the gopacket library. Numbers 1000-1999 should be |
| // used for common application-specific types, and are very fast. Any other |
| // number (negative or >= 2000) may be used for uncommon application-specific |
| // types, and are somewhat slower (they require a map lookup over an array |
| // index). |
| func RegisterLayerType(num int, meta LayerTypeMetadata) LayerType { |
| if 0 <= num && num < maxLayerType { |
| if ltMeta[num].inUse { |
| panic("Layer type already exists") |
| } |
| } else { |
| if ltMetaMap[LayerType(num)].inUse { |
| panic("Layer type already exists") |
| } |
| } |
| return OverrideLayerType(num, meta) |
| } |
| |
| // OverrideLayerType acts like RegisterLayerType, except that if the layer type |
| // has already been registered, it overrides the metadata with the passed-in |
| // metadata intead of panicing. |
| func OverrideLayerType(num int, meta LayerTypeMetadata) LayerType { |
| if 0 <= num && num < maxLayerType { |
| ltMeta[num] = layerTypeMetadata{ |
| inUse: true, |
| LayerTypeMetadata: meta, |
| } |
| } else { |
| ltMetaMap[LayerType(num)] = layerTypeMetadata{ |
| inUse: true, |
| LayerTypeMetadata: meta, |
| } |
| } |
| DecodersByLayerName[meta.Name] = meta.Decoder |
| return LayerType(num) |
| } |
| |
| // Decode decodes the given data using the decoder registered with the layer |
| // type. |
| func (t LayerType) Decode(data []byte, c PacketBuilder) error { |
| var d Decoder |
| if 0 <= int(t) && int(t) < maxLayerType { |
| d = ltMeta[int(t)].Decoder |
| } else { |
| d = ltMetaMap[t].Decoder |
| } |
| if d != nil { |
| return d.Decode(data, c) |
| } |
| return fmt.Errorf("Layer type %v has no associated decoder", t) |
| } |
| |
| // String returns the string associated with this layer type. |
| func (t LayerType) String() (s string) { |
| if 0 <= int(t) && int(t) < maxLayerType { |
| s = ltMeta[int(t)].Name |
| } else { |
| s = ltMetaMap[t].Name |
| } |
| if s == "" { |
| s = strconv.Itoa(int(t)) |
| } |
| return |
| } |