layertype.go 3.3 KB

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