summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/layerclass.go
blob: 775cd098770d61aa7a5bb635f5d1ab8eb09d3875 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// 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

// LayerClass is a set of LayerTypes, used for grabbing one of a number of
// different types from a packet.
type LayerClass interface {
	// Contains returns true if the given layer type should be considered part
	// of this layer class.
	Contains(LayerType) bool
	// LayerTypes returns the set of all layer types in this layer class.
	// Note that this may not be a fast operation on all LayerClass
	// implementations.
	LayerTypes() []LayerType
}

// Contains implements LayerClass.
func (l LayerType) Contains(a LayerType) bool {
	return l == a
}

// LayerTypes implements LayerClass.
func (l LayerType) LayerTypes() []LayerType {
	return []LayerType{l}
}

// LayerClassSlice implements a LayerClass with a slice.
type LayerClassSlice []bool

// Contains returns true if the given layer type should be considered part
// of this layer class.
func (s LayerClassSlice) Contains(t LayerType) bool {
	return int(t) < len(s) && s[t]
}

// LayerTypes returns all layer types in this LayerClassSlice.
// Because of LayerClassSlice's implementation, this could be quite slow.
func (s LayerClassSlice) LayerTypes() (all []LayerType) {
	for i := 0; i < len(s); i++ {
		if s[i] {
			all = append(all, LayerType(i))
		}
	}
	return
}

// NewLayerClassSlice creates a new LayerClassSlice by creating a slice of
// size max(types) and setting slice[t] to true for each type t.  Note, if
// you implement your own LayerType and give it a high value, this WILL create
// a very large slice.
func NewLayerClassSlice(types []LayerType) LayerClassSlice {
	var max LayerType
	for _, typ := range types {
		if typ > max {
			max = typ
		}
	}
	t := make([]bool, int(max+1))
	for _, typ := range types {
		t[typ] = true
	}
	return t
}

// LayerClassMap implements a LayerClass with a map.
type LayerClassMap map[LayerType]bool

// Contains returns true if the given layer type should be considered part
// of this layer class.
func (m LayerClassMap) Contains(t LayerType) bool {
	return m[t]
}

// LayerTypes returns all layer types in this LayerClassMap.
func (m LayerClassMap) LayerTypes() (all []LayerType) {
	for t := range m {
		all = append(all, t)
	}
	return
}

// NewLayerClassMap creates a LayerClassMap and sets map[t] to true for each
// type in types.
func NewLayerClassMap(types []LayerType) LayerClassMap {
	m := LayerClassMap{}
	for _, typ := range types {
		m[typ] = true
	}
	return m
}

// NewLayerClass creates a LayerClass, attempting to be smart about which type
// it creates based on which types are passed in.
func NewLayerClass(types []LayerType) LayerClass {
	for _, typ := range types {
		if typ > maxLayerType {
			// NewLayerClassSlice could create a very large object, so instead create
			// a map.
			return NewLayerClassMap(types)
		}
	}
	return NewLayerClassSlice(types)
}