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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
/* $OpenBSD: if_pflow.h,v 1.23 2023/12/16 22:16:02 mvs Exp $ */
/*
* Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
* Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _NET_IF_PFLOW_H_
#define _NET_IF_PFLOW_H_
#define PFLOW_ID_LEN sizeof(u_int64_t)
#define PFLOW_MAXFLOWS 30
#define PFLOW_ENGINE_TYPE 42
#define PFLOW_ENGINE_ID 42
#define PFLOW_MAXBYTES 0xffffffff
#define PFLOW_TIMEOUT 30
#define PFLOW_TMPL_TIMEOUT 30 /* rfc 5101 10.3.6 (p.40) recommends 600 */
#define PFLOW_IPFIX_TMPL_SET_ID 2
/* RFC 5102 Information Element Identifiers */
#define PFIX_IE_octetDeltaCount 1
#define PFIX_IE_packetDeltaCount 2
#define PFIX_IE_protocolIdentifier 4
#define PFIX_IE_ipClassOfService 5
#define PFIX_IE_sourceTransportPort 7
#define PFIX_IE_sourceIPv4Address 8
#define PFIX_IE_ingressInterface 10
#define PFIX_IE_destinationTransportPort 11
#define PFIX_IE_destinationIPv4Address 12
#define PFIX_IE_egressInterface 14
#define PFIX_IE_flowEndSysUpTime 21
#define PFIX_IE_flowStartSysUpTime 22
#define PFIX_IE_sourceIPv6Address 27
#define PFIX_IE_destinationIPv6Address 28
#define PFIX_IE_flowStartMilliseconds 152
#define PFIX_IE_flowEndMilliseconds 153
struct pflow_flow {
u_int32_t src_ip;
u_int32_t dest_ip;
u_int32_t nexthop_ip;
u_int16_t if_index_in;
u_int16_t if_index_out;
u_int32_t flow_packets;
u_int32_t flow_octets;
u_int32_t flow_start;
u_int32_t flow_finish;
u_int16_t src_port;
u_int16_t dest_port;
u_int8_t pad1;
u_int8_t tcp_flags;
u_int8_t protocol;
u_int8_t tos;
u_int16_t src_as;
u_int16_t dest_as;
u_int8_t src_mask;
u_int8_t dest_mask;
u_int16_t pad2;
} __packed;
struct pflow_set_header {
u_int16_t set_id;
u_int16_t set_length; /* total length of the set,
in octets, including the set header */
} __packed;
#define PFLOW_SET_HDRLEN sizeof(struct pflow_set_header)
struct pflow_tmpl_hdr {
u_int16_t tmpl_id;
u_int16_t field_count;
} __packed;
struct pflow_tmpl_fspec {
u_int16_t field_id;
u_int16_t len;
} __packed;
/* update pflow_clone_create() when changing pflow_ipfix_tmpl_ipv4 */
struct pflow_ipfix_tmpl_ipv4 {
struct pflow_tmpl_hdr h;
struct pflow_tmpl_fspec src_ip;
struct pflow_tmpl_fspec dest_ip;
struct pflow_tmpl_fspec if_index_in;
struct pflow_tmpl_fspec if_index_out;
struct pflow_tmpl_fspec packets;
struct pflow_tmpl_fspec octets;
struct pflow_tmpl_fspec start;
struct pflow_tmpl_fspec finish;
struct pflow_tmpl_fspec src_port;
struct pflow_tmpl_fspec dest_port;
struct pflow_tmpl_fspec tos;
struct pflow_tmpl_fspec protocol;
#define PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT 12
#define PFLOW_IPFIX_TMPL_IPV4_ID 256
} __packed;
/* update pflow_clone_create() when changing pflow_ipfix_tmpl_v6 */
struct pflow_ipfix_tmpl_ipv6 {
struct pflow_tmpl_hdr h;
struct pflow_tmpl_fspec src_ip;
struct pflow_tmpl_fspec dest_ip;
struct pflow_tmpl_fspec if_index_in;
struct pflow_tmpl_fspec if_index_out;
struct pflow_tmpl_fspec packets;
struct pflow_tmpl_fspec octets;
struct pflow_tmpl_fspec start;
struct pflow_tmpl_fspec finish;
struct pflow_tmpl_fspec src_port;
struct pflow_tmpl_fspec dest_port;
struct pflow_tmpl_fspec tos;
struct pflow_tmpl_fspec protocol;
#define PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT 12
#define PFLOW_IPFIX_TMPL_IPV6_ID 257
} __packed;
struct pflow_ipfix_tmpl {
struct pflow_set_header set_header;
struct pflow_ipfix_tmpl_ipv4 ipv4_tmpl;
struct pflow_ipfix_tmpl_ipv6 ipv6_tmpl;
} __packed;
struct pflow_ipfix_flow4 {
u_int32_t src_ip; /* sourceIPv4Address*/
u_int32_t dest_ip; /* destinationIPv4Address */
u_int32_t if_index_in; /* ingressInterface */
u_int32_t if_index_out; /* egressInterface */
u_int64_t flow_packets; /* packetDeltaCount */
u_int64_t flow_octets; /* octetDeltaCount */
int64_t flow_start; /* flowStartMilliseconds */
int64_t flow_finish; /* flowEndMilliseconds */
u_int16_t src_port; /* sourceTransportPort */
u_int16_t dest_port; /* destinationTransportPort */
u_int8_t tos; /* ipClassOfService */
u_int8_t protocol; /* protocolIdentifier */
/* XXX padding needed? */
} __packed;
struct pflow_ipfix_flow6 {
struct in6_addr src_ip; /* sourceIPv6Address */
struct in6_addr dest_ip; /* destinationIPv6Address */
u_int32_t if_index_in; /* ingressInterface */
u_int32_t if_index_out; /* egressInterface */
u_int64_t flow_packets; /* packetDeltaCount */
u_int64_t flow_octets; /* octetDeltaCount */
int64_t flow_start; /* flowStartMilliseconds */
int64_t flow_finish; /* flowEndMilliseconds */
u_int16_t src_port; /* sourceTransportPort */
u_int16_t dest_port; /* destinationTransportPort */
u_int8_t tos; /* ipClassOfService */
u_int8_t protocol; /* protocolIdentifier */
/* XXX padding needed? */
} __packed;
#ifdef _KERNEL
#include <sys/smr.h>
/*
* Locks used to protect struct members and global data
* I immutable after creation
* m this pflow_softc' `sc_mtx'
* p this pflow_softc' `sc_lock'
*/
struct pflow_softc {
struct mutex sc_mtx;
struct rwlock sc_lock;
int sc_dying; /* [p] */
struct ifnet sc_if;
unsigned int sc_count; /* [m] */
unsigned int sc_count4; /* [m] */
unsigned int sc_count6; /* [m] */
unsigned int sc_maxcount; /* [m] */
unsigned int sc_maxcount4; /* [m] */
unsigned int sc_maxcount6; /* [m] */
u_int32_t sc_gcounter; /* [m] */
u_int32_t sc_sequence; /* [m] */
struct timeout sc_tmo;
struct timeout sc_tmo6;
struct timeout sc_tmo_tmpl;
struct mbuf_queue sc_outputqueue;
struct task sc_outputtask;
struct socket *so; /* [p] */
struct mbuf *send_nam; /* [p] */
struct sockaddr *sc_flowsrc; /* [p] */
struct sockaddr *sc_flowdst; /* [p] */
struct pflow_ipfix_tmpl sc_tmpl_ipfix; /* [I] */
u_int8_t sc_version; /* [m] */
struct mbuf *sc_mbuf; /* [m] current cumulative
mbuf */
struct mbuf *sc_mbuf6; /* [m] current cumulative
mbuf */
SMR_SLIST_ENTRY(pflow_softc) sc_next;
};
extern struct pflow_softc *pflowif;
#endif /* _KERNEL */
struct pflow_header {
u_int16_t version;
u_int16_t count;
u_int32_t uptime_ms;
u_int32_t time_sec;
u_int32_t time_nanosec;
u_int32_t flow_sequence;
u_int8_t engine_type;
u_int8_t engine_id;
u_int8_t reserved1;
u_int8_t reserved2;
} __packed;
#define PFLOW_HDRLEN sizeof(struct pflow_header)
struct pflow_v10_header {
u_int16_t version;
u_int16_t length;
u_int32_t time_sec;
u_int32_t flow_sequence;
u_int32_t observation_dom;
} __packed;
#define PFLOW_IPFIX_HDRLEN sizeof(struct pflow_v10_header)
struct pflowstats {
u_int64_t pflow_flows;
u_int64_t pflow_packets;
u_int64_t pflow_onomem;
u_int64_t pflow_oerrors;
};
/* Supported flow protocols */
#define PFLOW_PROTO_5 5 /* original pflow */
#define PFLOW_PROTO_10 10 /* ipfix */
#define PFLOW_PROTO_MAX 11
#define PFLOW_PROTO_DEFAULT PFLOW_PROTO_5
struct pflow_protos {
const char *ppr_name;
u_int8_t ppr_proto;
};
#define PFLOW_PROTOS { \
{ "5", PFLOW_PROTO_5 }, \
{ "10", PFLOW_PROTO_10 }, \
}
/*
* Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
*/
struct pflowreq {
struct sockaddr_storage flowsrc;
struct sockaddr_storage flowdst;
u_int16_t addrmask;
u_int8_t version;
#define PFLOW_MASK_SRCIP 0x01
#define PFLOW_MASK_DSTIP 0x02
#define PFLOW_MASK_VERSION 0x04
};
#ifdef _KERNEL
int export_pflow(struct pf_state *);
int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
#endif /* _KERNEL */
#endif /* _NET_IF_PFLOW_H_ */
|