blob: 3abfee1e9bada2fa1c8d5cee5209cdedec81fd55 [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001// 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
7package gopacket
8
9import (
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.
20type LayerType int64
21
22// LayerTypeMetadata contains metadata associated with each LayerType.
23type 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
31type 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.
39var DecodersByLayerName = map[string]Decoder{}
40
41const maxLayerType = 2000
42
43var ltMeta [maxLayerType]layerTypeMetadata
44var 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).
53func 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.
69func 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.
87func (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.
101func (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}