1/* $OpenBSD: if_pflow.h,v 1.24 2025/11/13 17:12:30 chris Exp $ */
2
3/*
4 * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef _NET_IF_PFLOW_H_
21#define _NET_IF_PFLOW_H_
22
23#define PFLOW_ID_LEN sizeof(u_int64_t)
24
25#define PFLOW_MAXFLOWS 30
26#define PFLOW_ENGINE_TYPE 42
27#define PFLOW_ENGINE_ID 42
28#define PFLOW_MAXBYTES 0xffffffff
29#define PFLOW_TIMEOUT 30
30#define PFLOW_TMPL_TIMEOUT 30 /* rfc 5101 10.3.6 (p.40) recommends 600 */
31
32#define PFLOW_IPFIX_TMPL_SET_ID 2
33
34/* RFC 5102 Information Element Identifiers */
35
36#define PFIX_IE_octetDeltaCount 1
37#define PFIX_IE_packetDeltaCount 2
38#define PFIX_IE_protocolIdentifier 4
39#define PFIX_IE_ipClassOfService 5
40#define PFIX_IE_sourceTransportPort 7
41#define PFIX_IE_sourceIPv4Address 8
42#define PFIX_IE_ingressInterface 10
43#define PFIX_IE_destinationTransportPort 11
44#define PFIX_IE_destinationIPv4Address 12
45#define PFIX_IE_egressInterface 14
46#define PFIX_IE_flowEndSysUpTime 21
47#define PFIX_IE_flowStartSysUpTime 22
48#define PFIX_IE_sourceIPv6Address 27
49#define PFIX_IE_destinationIPv6Address 28
50#define PFIX_IE_flowStartMilliseconds 152
51#define PFIX_IE_flowEndMilliseconds 153
52#define PFIX_IE_postNATSourceIPv4Address 225
53#define PFIX_IE_postNATDestinationIPv4Address 226
54#define PFIX_IE_postNAPTSourceTransportPort 227
55#define PFIX_IE_postNAPTDestinationTransportPort 228
56
57struct pflow_flow {
58 u_int32_t src_ip;
59 u_int32_t dest_ip;
60 u_int32_t nexthop_ip;
61 u_int16_t if_index_in;
62 u_int16_t if_index_out;
63 u_int32_t flow_packets;
64 u_int32_t flow_octets;
65 u_int32_t flow_start;
66 u_int32_t flow_finish;
67 u_int16_t src_port;
68 u_int16_t dest_port;
69 u_int8_t pad1;
70 u_int8_t tcp_flags;
71 u_int8_t protocol;
72 u_int8_t tos;
73 u_int16_t src_as;
74 u_int16_t dest_as;
75 u_int8_t src_mask;
76 u_int8_t dest_mask;
77 u_int16_t pad2;
78} __packed;
79
80struct pflow_set_header {
81 u_int16_t set_id;
82 u_int16_t set_length; /* total length of the set,
83 in octets, including the set header */
84} __packed;
85
86#define PFLOW_SET_HDRLEN sizeof(struct pflow_set_header)
87
88struct pflow_tmpl_hdr {
89 u_int16_t tmpl_id;
90 u_int16_t field_count;
91} __packed;
92
93struct pflow_tmpl_fspec {
94 u_int16_t field_id;
95 u_int16_t len;
96} __packed;
97
98/* update pflow_clone_create() when changing pflow_ipfix_tmpl_ipv4 */
99struct pflow_ipfix_tmpl_ipv4 {
100 struct pflow_tmpl_hdr h;
101 struct pflow_tmpl_fspec src_ip;
102 struct pflow_tmpl_fspec dest_ip;
103 struct pflow_tmpl_fspec if_index_in;
104 struct pflow_tmpl_fspec if_index_out;
105 struct pflow_tmpl_fspec packets;
106 struct pflow_tmpl_fspec octets;
107 struct pflow_tmpl_fspec start;
108 struct pflow_tmpl_fspec finish;
109 struct pflow_tmpl_fspec src_port;
110 struct pflow_tmpl_fspec dest_port;
111 struct pflow_tmpl_fspec tos;
112 struct pflow_tmpl_fspec protocol;
113#define PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT 12
114#define PFLOW_IPFIX_TMPL_IPV4_ID 256
115} __packed;
116
117struct pflow_ipfix_tmpl_nat_ipv4 {
118 struct pflow_tmpl_hdr h;
119 struct pflow_tmpl_fspec src_ip;
120 struct pflow_tmpl_fspec dest_ip;
121 struct pflow_tmpl_fspec if_index_in;
122 struct pflow_tmpl_fspec if_index_out;
123 struct pflow_tmpl_fspec packets;
124 struct pflow_tmpl_fspec octets;
125 struct pflow_tmpl_fspec start;
126 struct pflow_tmpl_fspec finish;
127 struct pflow_tmpl_fspec post_src_ip;
128 struct pflow_tmpl_fspec post_dest_ip;
129 struct pflow_tmpl_fspec post_src_port;
130 struct pflow_tmpl_fspec post_dest_port;
131 struct pflow_tmpl_fspec src_port;
132 struct pflow_tmpl_fspec dest_port;
133 struct pflow_tmpl_fspec tos;
134 struct pflow_tmpl_fspec protocol;
135#define PFLOW_IPFIX_TMPL_NAT_IPV4_FIELD_COUNT 16
136#define PFLOW_IPFIX_TMPL_NAT_IPV4_ID 257
137} __packed;
138
139/* update pflow_clone_create() when changing pflow_ipfix_tmpl_v6 */
140struct pflow_ipfix_tmpl_ipv6 {
141 struct pflow_tmpl_hdr h;
142 struct pflow_tmpl_fspec src_ip;
143 struct pflow_tmpl_fspec dest_ip;
144 struct pflow_tmpl_fspec if_index_in;
145 struct pflow_tmpl_fspec if_index_out;
146 struct pflow_tmpl_fspec packets;
147 struct pflow_tmpl_fspec octets;
148 struct pflow_tmpl_fspec start;
149 struct pflow_tmpl_fspec finish;
150 struct pflow_tmpl_fspec src_port;
151 struct pflow_tmpl_fspec dest_port;
152 struct pflow_tmpl_fspec tos;
153 struct pflow_tmpl_fspec protocol;
154#define PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT 12
155#define PFLOW_IPFIX_TMPL_IPV6_ID 258
156} __packed;
157
158struct pflow_ipfix_tmpl {
159 struct pflow_set_header set_header;
160 struct pflow_ipfix_tmpl_ipv4 ipv4_tmpl;
161 struct pflow_ipfix_tmpl_nat_ipv4 ipv4_nat_tmpl;
162 struct pflow_ipfix_tmpl_ipv6 ipv6_tmpl;
163} __packed;
164
165struct pflow_ipfix_flow4 {
166 u_int32_t src_ip; /* sourceIPv4Address*/
167 u_int32_t dest_ip; /* destinationIPv4Address */
168 u_int32_t if_index_in; /* ingressInterface */
169 u_int32_t if_index_out; /* egressInterface */
170 u_int64_t flow_packets; /* packetDeltaCount */
171 u_int64_t flow_octets; /* octetDeltaCount */
172 int64_t flow_start; /* flowStartMilliseconds */
173 int64_t flow_finish; /* flowEndMilliseconds */
174 u_int16_t src_port; /* sourceTransportPort */
175 u_int16_t dest_port; /* destinationTransportPort */
176 u_int8_t tos; /* ipClassOfService */
177 u_int8_t protocol; /* protocolIdentifier */
178 /* XXX padding needed? */
179} __packed;
180
181struct pflow_ipfix_nat_flow4 {
182 u_int32_t src_ip; /* sourceIPv4Address*/
183 u_int32_t dest_ip; /* destinationIPv4Address */
184 u_int32_t if_index_in; /* ingressInterface */
185 u_int32_t if_index_out; /* egressInterface */
186 u_int64_t flow_packets; /* packetDeltaCount */
187 u_int64_t flow_octets; /* octetDeltaCount */
188 int64_t flow_start; /* flowStartMilliseconds */
189 int64_t flow_finish; /* flowEndMilliseconds */
190 u_int32_t post_src_ip; /* postNATSourceIPv4Address */
191 u_int32_t post_dest_ip; /* postNATDestinationIPv4Address */
192 u_int16_t post_src_port; /* postNAPTSourceTransportPort */
193 u_int16_t post_dest_port; /* postNAPTDestinationTransportPort */
194 u_int16_t src_port; /* sourceTransportPort */
195 u_int16_t dest_port; /* destinationTransportPort */
196 u_int8_t tos; /* ipClassOfService */
197 u_int8_t protocol; /* protocolIdentifier */
198 /* XXX padding needed? */
199} __packed;
200
201struct pflow_ipfix_flow6 {
202 struct in6_addr src_ip; /* sourceIPv6Address */
203 struct in6_addr dest_ip; /* destinationIPv6Address */
204 u_int32_t if_index_in; /* ingressInterface */
205 u_int32_t if_index_out; /* egressInterface */
206 u_int64_t flow_packets; /* packetDeltaCount */
207 u_int64_t flow_octets; /* octetDeltaCount */
208 int64_t flow_start; /* flowStartMilliseconds */
209 int64_t flow_finish; /* flowEndMilliseconds */
210 u_int16_t src_port; /* sourceTransportPort */
211 u_int16_t dest_port; /* destinationTransportPort */
212 u_int8_t tos; /* ipClassOfService */
213 u_int8_t protocol; /* protocolIdentifier */
214 /* XXX padding needed? */
215} __packed;
216
217#ifdef _KERNEL
218
219#include <sys/smr.h>
220
221/*
222 * Locks used to protect struct members and global data
223 * I immutable after creation
224 * m this pflow_softc' `sc_mtx'
225 * p this pflow_softc' `sc_lock'
226 */
227
228struct pflow_softc {
229 struct mutex sc_mtx;
230 struct rwlock sc_lock;
231
232 int sc_dying; /* [p] */
233 struct ifnet sc_if;
234
235 unsigned int sc_count; /* [m] */
236 unsigned int sc_count4; /* [m] */
237 unsigned int sc_count4_nat; /* [m] */
238 unsigned int sc_count6; /* [m] */
239 unsigned int sc_maxcount; /* [m] */
240 unsigned int sc_maxcount4; /* [m] */
241 unsigned int sc_maxcount6; /* [m] */
242 u_int32_t sc_gcounter; /* [m] */
243 u_int32_t sc_sequence; /* [m] */
244 struct timeout sc_tmo;
245 struct timeout sc_tmo6;
246 struct timeout sc_tmo_tmpl;
247 struct timeout sc_tmo_nat;
248 struct mbuf_queue sc_outputqueue;
249 struct task sc_outputtask;
250 struct socket *so; /* [p] */
251 struct mbuf *send_nam; /* [p] */
252 struct sockaddr *sc_flowsrc; /* [p] */
253 struct sockaddr *sc_flowdst; /* [p] */
254 struct pflow_ipfix_tmpl sc_tmpl_ipfix; /* [I] */
255 u_int8_t sc_version; /* [m] */
256 struct mbuf *sc_mbuf; /* [m] current cumulative
257 mbuf */
258 struct mbuf *sc_mbuf6; /* [m] current cumulative
259 mbuf */
260 struct mbuf *sc_mbuf_nat; /* [m] current cumulative
261 mbuf */
262 SMR_SLIST_ENTRY(pflow_softc) sc_next;
263};
264
265extern struct pflow_softc *pflowif;
266
267#endif /* _KERNEL */
268
269struct pflow_header {
270 u_int16_t version;
271 u_int16_t count;
272 u_int32_t uptime_ms;
273 u_int32_t time_sec;
274 u_int32_t time_nanosec;
275 u_int32_t flow_sequence;
276 u_int8_t engine_type;
277 u_int8_t engine_id;
278 u_int8_t reserved1;
279 u_int8_t reserved2;
280} __packed;
281
282#define PFLOW_HDRLEN sizeof(struct pflow_header)
283
284struct pflow_v10_header {
285 u_int16_t version;
286 u_int16_t length;
287 u_int32_t time_sec;
288 u_int32_t flow_sequence;
289 u_int32_t observation_dom;
290} __packed;
291
292#define PFLOW_IPFIX_HDRLEN sizeof(struct pflow_v10_header)
293
294struct pflowstats {
295 u_int64_t pflow_flows;
296 u_int64_t pflow_packets;
297 u_int64_t pflow_onomem;
298 u_int64_t pflow_oerrors;
299};
300
301/* Supported flow protocols */
302#define PFLOW_PROTO_5 5 /* original pflow */
303#define PFLOW_PROTO_10 10 /* ipfix */
304#define PFLOW_PROTO_MAX 11
305
306#define PFLOW_PROTO_DEFAULT PFLOW_PROTO_5
307
308struct pflow_protos {
309 const char *ppr_name;
310 u_int8_t ppr_proto;
311};
312
313#define PFLOW_PROTOS { \
314 { "5", PFLOW_PROTO_5 }, \
315 { "10", PFLOW_PROTO_10 }, \
316}
317
318/*
319 * Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
320 */
321struct pflowreq {
322 struct sockaddr_storage flowsrc;
323 struct sockaddr_storage flowdst;
324 u_int16_t addrmask;
325 u_int8_t version;
326#define PFLOW_MASK_SRCIP 0x01
327#define PFLOW_MASK_DSTIP 0x02
328#define PFLOW_MASK_VERSION 0x04
329};
330
331#ifdef _KERNEL
332int export_pflow(struct pf_state *);
333int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
334#endif /* _KERNEL */
335
336#endif /* _NET_IF_PFLOW_H_ */