tetragon

Форк
0
/
vtuplefilter.go 
236 строк · 4.5 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Tetragon
3

4
package vtuplefilter
5

6
import (
7
	"fmt"
8
	"net"
9
	"strconv"
10
	"strings"
11

12
	"github.com/cilium/tetragon/pkg/vtuple"
13
)
14

15
type Port = uint16
16
type Addr = net.IP
17

18
type ParseError struct {
19
	msg string
20
}
21

22
func (e *ParseError) Error() string {
23
	return fmt.Sprintf("parsing error: %s", e.msg)
24
}
25

26
func ParseErrorFmt(s string, args ...interface{}) *ParseError {
27
	return &ParseError{
28
		msg: fmt.Sprintf(s, args...),
29
	}
30
}
31

32
// FromLine
33
func FromLine(s string) (Filter, error) {
34
	var fs []Filter
35

36
	for _, ss := range strings.Split(s, ",") {
37
		var f Filter
38
		opts := strings.Split(ss, "=")
39
		if len(opts) != 2 {
40
			return nil, ParseErrorFmt("expecting x=a format for %s", ss)
41
		}
42

43
		switch opts[0] {
44
		case "sport", "dport", "port":
45
			port64, err := strconv.ParseUint(opts[1], 10, 16)
46
			if err != nil {
47
				return nil, ParseErrorFmt("failed to parse %s as port: %s", opts[1], err)
48
			}
49
			port16 := uint16(port64)
50
			switch opts[0] {
51
			case "sport":
52
				f = CreateSrcPortFilter(port16)
53
			case "dport":
54
				f = CreateDstPortFilter(port16)
55
			case "port":
56
				f = CreateAnyPortFilter(port16)
57
			}
58

59
		case "saddr":
60
		case "daddr":
61
		case "addr":
62
			ip := net.ParseIP(opts[1])
63
			if ip == nil {
64
				return nil, ParseErrorFmt("failed to parse %s as ip", opts[1])
65
			}
66

67
			switch opts[0] {
68
			case "saddr":
69
				f = CreateSrcAddrFilter(ip)
70
			case "daddr":
71
				f = CreateDstAddrFilter(ip)
72
			case "addr":
73
				f = CreateAnyAddrFilter(ip)
74
			}
75

76
		case "prot":
77
			switch strings.ToLower(opts[1]) {
78
			case "tcp":
79
				f = &ProtTcpFilter{}
80
			case "udp":
81
				f = &ProtUdpFilter{}
82

83
				// NB: once needed, we can easily do {tcp,udp}{4,6}
84
			}
85

86
		default:
87
			return nil, ParseErrorFmt("cannot parse %s: unknown %s", ss, opts[0])
88
		}
89

90
		if f == nil {
91
			panic("Unexpected error: f should be set")
92
		}
93
		fs = append(fs, f)
94
	}
95

96
	return &And{fs: fs}, nil
97
}
98

99
type Filter interface {
100
	FilterFn(t vtuple.VTuple) bool
101
}
102

103
// Logical operations
104
type And struct {
105
	fs []Filter
106
}
107

108
func (op *And) FilterFn(t vtuple.VTuple) bool {
109
	for _, f := range op.fs {
110
		if !f.FilterFn(t) {
111
			return false
112
		}
113
	} // NB: for 0 filters, AND returns true
114
	return true
115
}
116

117
func CreateAndFilter(fs ...Filter) Filter {
118
	return &And{fs: fs}
119
}
120

121
type Or struct {
122
	fs []Filter
123
}
124

125
func (op *Or) FilterFn(t vtuple.VTuple) bool {
126
	for _, f := range op.fs {
127
		if f.FilterFn(t) {
128
			return true
129
		}
130
	}
131
	// NB: for 0 filters, OR returns false
132
	return false
133
}
134

135
func CreateOrFilter(fs ...Filter) Filter {
136
	return &Or{fs: fs}
137
}
138

139
type Not struct {
140
	f Filter
141
}
142

143
func (op *Not) FilterFn(t vtuple.VTuple) bool {
144
	return !op.f.FilterFn(t)
145
}
146

147
// getters/setters (or projections if you are into SQL)
148

149
type PortFilter struct {
150
	getPort (func(vtuple.VTuple) Port)
151
	pred    (func(Port) bool)
152
}
153

154
// port filters
155

156
func (pf *PortFilter) FilterFn(t vtuple.VTuple) bool {
157
	addr := pf.getPort(t)
158
	return pf.pred(addr)
159
}
160

161
func CreateSrcPortFilter(port Port) Filter {
162
	return &PortFilter{
163
		getPort: func(t vtuple.VTuple) Port { return t.SrcPort() },
164
		pred:    func(p Port) bool { return p == port },
165
	}
166
}
167
func CreateDstPortFilter(port Port) Filter {
168
	return &PortFilter{
169
		getPort: func(t vtuple.VTuple) Port { return t.DstPort() },
170
		pred:    func(p Port) bool { return p == port },
171
	}
172
}
173

174
func CreateAnyPortFilter(port Port) Filter {
175
	srcF := CreateSrcPortFilter(port)
176
	dstF := CreateDstPortFilter(port)
177
	return CreateOrFilter(srcF, dstF)
178
}
179

180
// address filters
181

182
type AddrFilter struct {
183
	getAddr (func(vtuple.VTuple) Addr)
184
	pred    (func(Addr) bool)
185
}
186

187
func (pf *AddrFilter) FilterFn(t vtuple.VTuple) bool {
188
	addr := pf.getAddr(t)
189
	return pf.pred(addr)
190
}
191

192
func CreateSrcAddrFilter(addr Addr) Filter {
193
	return &AddrFilter{
194
		getAddr: func(t vtuple.VTuple) Addr { return t.SrcAddr() },
195
		pred:    func(a Addr) bool { return a.Equal(addr) },
196
	}
197
}
198

199
func CreateDstAddrFilter(addr Addr) Filter {
200
	return &AddrFilter{
201
		getAddr: func(t vtuple.VTuple) Addr { return t.DstAddr() },
202
		pred:    func(a Addr) bool { return a.Equal(addr) },
203
	}
204
}
205

206
func CreateAnyAddrFilter(addr Addr) Filter {
207
	srcF := CreateSrcAddrFilter(addr)
208
	dstF := CreateDstAddrFilter(addr)
209
	return CreateOrFilter(srcF, dstF)
210
}
211

212
// protocol filters
213

214
type ProtTcpFilter struct{}
215

216
func (f *ProtTcpFilter) FilterFn(t vtuple.VTuple) bool {
217
	return t.IsTCP()
218
}
219

220
type ProtUdpFilter struct{}
221

222
func (f *ProtUdpFilter) FilterFn(t vtuple.VTuple) bool {
223
	return t.IsUDP()
224
}
225

226
type ProtIP4Filter struct{}
227

228
func (f *ProtIP4Filter) FilterFn(t vtuple.VTuple) bool {
229
	return t.IsIP4()
230
}
231

232
type ProtIP6Filter struct{}
233

234
func (f *ProtIP6Filter) FilterFn(t vtuple.VTuple) bool {
235
	return t.IsIP6()
236
}
237

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.