blob: 775cd098770d61aa7a5bb635f5d1ab8eb09d3875 [file] [log] [blame]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001// 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
9// LayerClass is a set of LayerTypes, used for grabbing one of a number of
10// different types from a packet.
11type LayerClass interface {
12 // Contains returns true if the given layer type should be considered part
13 // of this layer class.
14 Contains(LayerType) bool
15 // LayerTypes returns the set of all layer types in this layer class.
16 // Note that this may not be a fast operation on all LayerClass
17 // implementations.
18 LayerTypes() []LayerType
19}
20
21// Contains implements LayerClass.
22func (l LayerType) Contains(a LayerType) bool {
23 return l == a
24}
25
26// LayerTypes implements LayerClass.
27func (l LayerType) LayerTypes() []LayerType {
28 return []LayerType{l}
29}
30
31// LayerClassSlice implements a LayerClass with a slice.
32type LayerClassSlice []bool
33
34// Contains returns true if the given layer type should be considered part
35// of this layer class.
36func (s LayerClassSlice) Contains(t LayerType) bool {
37 return int(t) < len(s) && s[t]
38}
39
40// LayerTypes returns all layer types in this LayerClassSlice.
41// Because of LayerClassSlice's implementation, this could be quite slow.
42func (s LayerClassSlice) LayerTypes() (all []LayerType) {
43 for i := 0; i < len(s); i++ {
44 if s[i] {
45 all = append(all, LayerType(i))
46 }
47 }
48 return
49}
50
51// NewLayerClassSlice creates a new LayerClassSlice by creating a slice of
52// size max(types) and setting slice[t] to true for each type t. Note, if
53// you implement your own LayerType and give it a high value, this WILL create
54// a very large slice.
55func NewLayerClassSlice(types []LayerType) LayerClassSlice {
56 var max LayerType
57 for _, typ := range types {
58 if typ > max {
59 max = typ
60 }
61 }
62 t := make([]bool, int(max+1))
63 for _, typ := range types {
64 t[typ] = true
65 }
66 return t
67}
68
69// LayerClassMap implements a LayerClass with a map.
70type LayerClassMap map[LayerType]bool
71
72// Contains returns true if the given layer type should be considered part
73// of this layer class.
74func (m LayerClassMap) Contains(t LayerType) bool {
75 return m[t]
76}
77
78// LayerTypes returns all layer types in this LayerClassMap.
79func (m LayerClassMap) LayerTypes() (all []LayerType) {
80 for t := range m {
81 all = append(all, t)
82 }
83 return
84}
85
86// NewLayerClassMap creates a LayerClassMap and sets map[t] to true for each
87// type in types.
88func NewLayerClassMap(types []LayerType) LayerClassMap {
89 m := LayerClassMap{}
90 for _, typ := range types {
91 m[typ] = true
92 }
93 return m
94}
95
96// NewLayerClass creates a LayerClass, attempting to be smart about which type
97// it creates based on which types are passed in.
98func NewLayerClass(types []LayerType) LayerClass {
99 for _, typ := range types {
100 if typ > maxLayerType {
101 // NewLayerClassSlice could create a very large object, so instead create
102 // a map.
103 return NewLayerClassMap(types)
104 }
105 }
106 return NewLayerClassSlice(types)
107}