1 // Copyright 2012 Google, Inc. All rights reserved.
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
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.
19 // New LayerTypes may be created by calling gopacket.RegisterLayerType.
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.
26 // Decoder is the decoder to use when the layer type is passed in as a
31 type layerTypeMetadata struct {
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{}
41 const maxLayerType = 2000
43 var ltMeta [maxLayerType]layerTypeMetadata
44 var ltMetaMap = map[LayerType]layerTypeMetadata{}
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
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")
59 if ltMetaMap[LayerType(num)].inUse {
60 panic("Layer type already exists")
63 return OverrideLayerType(num, meta)
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{
73 LayerTypeMetadata: meta,
76 ltMetaMap[LayerType(num)] = layerTypeMetadata{
78 LayerTypeMetadata: meta,
81 DecodersByLayerName[meta.Name] = meta.Decoder
85 // Decode decodes the given data using the decoder registered with the layer
87 func (t LayerType) Decode(data []byte, c PacketBuilder) error {
89 if 0 <= int(t) && int(t) < maxLayerType {
90 d = ltMeta[int(t)].Decoder
92 d = ltMetaMap[t].Decoder
95 return d.Decode(data, c)
97 return fmt.Errorf("Layer type %v has no associated decoder", t)
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
105 s = ltMetaMap[t].Name
108 s = strconv.Itoa(int(t))