112 lines
3.3 KiB
Go
112 lines
3.3 KiB
Go
|
// 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
|
||
|
}
|