xref: /openbsd-src/sys/net/if_pflow.c (revision 6f05df2d9be0954bec42d51d943d77bd250fb664)
1 /*	$OpenBSD: if_pflow.c,v 1.48 2014/11/20 14:51:42 krw Exp $	*/
2 
3 /*
4  * Copyright (c) 2011 Florian Obser <florian@narrans.de>
5  * Copyright (c) 2011 Sebastian Benoit <benoit-lists@fb12.de>
6  * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
7  * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/types.h>
23 #include <sys/malloc.h>
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/mbuf.h>
27 #include <sys/socket.h>
28 #include <sys/timeout.h>
29 #include <sys/ioctl.h>
30 #include <sys/kernel.h>
31 #include <sys/sysctl.h>
32 
33 #include <net/if.h>
34 #include <net/if_types.h>
35 #include <net/bpf.h>
36 #include <net/route.h>
37 #include <netinet/in.h>
38 #include <netinet/if_ether.h>
39 #include <netinet/tcp.h>
40 
41 #ifdef INET
42 #include <netinet/ip.h>
43 #include <netinet/ip_var.h>
44 #include <netinet/udp.h>
45 #include <netinet/udp_var.h>
46 #include <netinet/in_pcb.h>
47 #endif /* INET */
48 
49 #include <net/pfvar.h>
50 #include <net/if_pflow.h>
51 
52 #include "bpfilter.h"
53 #include "pflow.h"
54 
55 #define PFLOW_MINMTU	\
56     (sizeof(struct pflow_header) + sizeof(struct pflow_flow))
57 
58 #ifdef PFLOWDEBUG
59 #define DPRINTF(x)	do { printf x ; } while (0)
60 #else
61 #define DPRINTF(x)
62 #endif
63 
64 SLIST_HEAD(, pflow_softc) pflowif_list;
65 struct pflowstats	 pflowstats;
66 
67 void	pflowattach(int);
68 int	pflow_clone_create(struct if_clone *, int);
69 int	pflow_clone_destroy(struct ifnet *);
70 void	pflow_init_timeouts(struct pflow_softc *);
71 int	pflow_calc_mtu(struct pflow_softc *, int, int);
72 void	pflow_setmtu(struct pflow_softc *, int);
73 int	pflowoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
74 	    struct rtentry *);
75 int	pflowioctl(struct ifnet *, u_long, caddr_t);
76 void	pflowstart(struct ifnet *);
77 
78 struct mbuf	*pflow_get_mbuf(struct pflow_softc *, u_int16_t);
79 void	pflow_flush(struct pflow_softc *);
80 int	pflow_sendout_v5(struct pflow_softc *);
81 int	pflow_sendout_ipfix(struct pflow_softc *, sa_family_t);
82 int	pflow_sendout_ipfix_tmpl(struct pflow_softc *);
83 int	pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
84 void	pflow_timeout(void *);
85 void	pflow_timeout6(void *);
86 void	pflow_timeout_tmpl(void *);
87 void	copy_flow_data(struct pflow_flow *, struct pflow_flow *,
88 	struct pf_state *, struct pf_state_key *, int, int);
89 void	copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
90 	struct pflow_ipfix_flow4 *, struct pf_state *, struct pf_state_key *,
91 	struct pflow_softc *, int, int);
92 void	copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
93 	struct pflow_ipfix_flow6 *, struct pf_state *, struct pf_state_key *,
94 	struct pflow_softc *, int, int);
95 int	pflow_pack_flow(struct pf_state *, struct pf_state_key *,
96 	struct pflow_softc *);
97 int	pflow_pack_flow_ipfix(struct pf_state *, struct pf_state_key *,
98 	struct pflow_softc *);
99 int	pflow_get_dynport(void);
100 int	export_pflow_if(struct pf_state*, struct pf_state_key *,
101 	struct pflow_softc *);
102 int	copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
103 int	copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
104 	struct pflow_softc *sc);
105 int	copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
106 	struct pflow_softc *sc);
107 
108 struct if_clone	pflow_cloner =
109     IF_CLONE_INITIALIZER("pflow", pflow_clone_create,
110     pflow_clone_destroy);
111 
112 void
113 pflowattach(int npflow)
114 {
115 	SLIST_INIT(&pflowif_list);
116 	if_clone_attach(&pflow_cloner);
117 }
118 
119 int
120 pflow_clone_create(struct if_clone *ifc, int unit)
121 {
122 	struct ifnet		*ifp;
123 	struct pflow_softc	*pflowif;
124 
125 	if ((pflowif = malloc(sizeof(*pflowif),
126 	    M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
127 		return (ENOMEM);
128 
129 	pflowif->sc_imo.imo_membership = malloc(
130 	    (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
131 	    M_WAITOK|M_ZERO);
132 	pflowif->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
133 	pflowif->sc_receiver_ip.s_addr = INADDR_ANY;
134 	pflowif->sc_receiver_port = 0;
135 	pflowif->sc_sender_ip.s_addr = INADDR_ANY;
136 	pflowif->sc_sender_port = pflow_get_dynport();
137 	pflowif->sc_version = PFLOW_PROTO_DEFAULT;
138 
139 	/* ipfix template init */
140 	bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
141 	pflowif->sc_tmpl_ipfix.set_header.set_id =
142 	    htons(PFLOW_IPFIX_TMPL_SET_ID);
143 	pflowif->sc_tmpl_ipfix.set_header.set_length =
144 	    htons(sizeof(struct pflow_ipfix_tmpl));
145 
146 	/* ipfix IPv4 template */
147 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
148 	    htons(PFLOW_IPFIX_TMPL_IPV4_ID);
149 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
150 	    = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
151 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
152 	    htons(PFIX_IE_sourceIPv4Address);
153 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
154 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
155 	    htons(PFIX_IE_destinationIPv4Address);
156 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
157 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
158 	    htons(PFIX_IE_ingressInterface);
159 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
160 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
161 	    htons(PFIX_IE_egressInterface);
162 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
163 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
164 	    htons(PFIX_IE_packetDeltaCount);
165 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
166 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
167 	    htons(PFIX_IE_octetDeltaCount);
168 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
169 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
170 	    htons(PFIX_IE_flowStartMilliseconds);
171 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
172 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
173 	    htons(PFIX_IE_flowEndMilliseconds);
174 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
175 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
176 	    htons(PFIX_IE_sourceTransportPort);
177 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
178 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
179 	    htons(PFIX_IE_destinationTransportPort);
180 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
181 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
182 	    htons(PFIX_IE_ipClassOfService);
183 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
184 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
185 	    htons(PFIX_IE_protocolIdentifier);
186 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
187 
188 	/* ipfix IPv6 template */
189 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
190 	    htons(PFLOW_IPFIX_TMPL_IPV6_ID);
191 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
192 	    htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
193 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
194 	    htons(PFIX_IE_sourceIPv6Address);
195 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
196 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
197 	    htons(PFIX_IE_destinationIPv6Address);
198 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
199 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
200 	    htons(PFIX_IE_ingressInterface);
201 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
202 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
203 	    htons(PFIX_IE_egressInterface);
204 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
205 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
206 	    htons(PFIX_IE_packetDeltaCount);
207 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
208 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
209 	    htons(PFIX_IE_octetDeltaCount);
210 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
211 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
212 	    htons(PFIX_IE_flowStartMilliseconds);
213 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
214 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
215 	    htons(PFIX_IE_flowEndMilliseconds);
216 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
217 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
218 	    htons(PFIX_IE_sourceTransportPort);
219 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
220 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
221 	    htons(PFIX_IE_destinationTransportPort);
222 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
223 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
224 	    htons(PFIX_IE_ipClassOfService);
225 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
226 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
227 	    htons(PFIX_IE_protocolIdentifier);
228 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
229 
230 	ifp = &pflowif->sc_if;
231 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflow%d", unit);
232 	ifp->if_softc = pflowif;
233 	ifp->if_ioctl = pflowioctl;
234 	ifp->if_output = pflowoutput;
235 	ifp->if_start = pflowstart;
236 	ifp->if_type = IFT_PFLOW;
237 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
238 	ifp->if_hdrlen = PFLOW_HDRLEN;
239 	ifp->if_flags = IFF_UP;
240 	ifp->if_flags &= ~IFF_RUNNING;	/* not running, need receiver */
241 	pflow_setmtu(pflowif, ETHERMTU);
242 	pflow_init_timeouts(pflowif);
243 	if_attach(ifp);
244 	if_alloc_sadl(ifp);
245 
246 #if NBPFILTER > 0
247 	bpfattach(&pflowif->sc_if.if_bpf, ifp, DLT_RAW, 0);
248 #endif
249 
250 	/* Insert into list of pflows */
251 	SLIST_INSERT_HEAD(&pflowif_list, pflowif, sc_next);
252 	return (0);
253 }
254 
255 int
256 pflow_clone_destroy(struct ifnet *ifp)
257 {
258 	struct pflow_softc	*sc = ifp->if_softc;
259 	int			 s;
260 
261 	s = splnet();
262 	if (timeout_initialized(&sc->sc_tmo))
263 		timeout_del(&sc->sc_tmo);
264 	if (timeout_initialized(&sc->sc_tmo6))
265 		timeout_del(&sc->sc_tmo6);
266 	if (timeout_initialized(&sc->sc_tmo_tmpl))
267 		timeout_del(&sc->sc_tmo_tmpl);
268 	pflow_flush(sc);
269 	if_detach(ifp);
270 	SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next);
271 	free(sc->sc_imo.imo_membership, M_IPMOPTS, 0);
272 	free(sc, M_DEVBUF, 0);
273 	splx(s);
274 	return (0);
275 }
276 
277 /*
278  * Start output on the pflow interface.
279  */
280 void
281 pflowstart(struct ifnet *ifp)
282 {
283 	struct mbuf	*m;
284 	int		 s;
285 
286 	for (;;) {
287 		s = splnet();
288 		IF_DROP(&ifp->if_snd);
289 		IF_DEQUEUE(&ifp->if_snd, m);
290 		splx(s);
291 
292 		if (m == NULL)
293 			return;
294 		m_freem(m);
295 	}
296 }
297 
298 int
299 pflowoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
300 	struct rtentry *rt)
301 {
302 	m_freem(m);
303 	return (0);
304 }
305 
306 /* ARGSUSED */
307 int
308 pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
309 {
310 	struct proc		*p = curproc;
311 	struct pflow_softc	*sc = ifp->if_softc;
312 	struct ifreq		*ifr = (struct ifreq *)data;
313 	struct pflowreq		 pflowr;
314 	int			 s, error;
315 
316 	switch (cmd) {
317 	case SIOCSIFADDR:
318 	case SIOCAIFADDR:
319 	case SIOCSIFDSTADDR:
320 	case SIOCSIFFLAGS:
321 		if ((ifp->if_flags & IFF_UP) &&
322 		    sc->sc_receiver_ip.s_addr != INADDR_ANY &&
323 		    sc->sc_receiver_port != 0 &&
324 		    sc->sc_sender_port != 0) {
325 			ifp->if_flags |= IFF_RUNNING;
326 			sc->sc_gcounter=pflowstats.pflow_flows;
327 			/* send templates on startup */
328 			if (sc->sc_version == PFLOW_PROTO_10) {
329 				s = splnet();
330 				pflow_sendout_ipfix_tmpl(sc);
331 				splx(s);
332 			}
333 		} else
334 			ifp->if_flags &= ~IFF_RUNNING;
335 		break;
336 	case SIOCSIFMTU:
337 		if (ifr->ifr_mtu < PFLOW_MINMTU)
338 			return (EINVAL);
339 		if (ifr->ifr_mtu > MCLBYTES)
340 			ifr->ifr_mtu = MCLBYTES;
341 		s = splnet();
342 		if (ifr->ifr_mtu < ifp->if_mtu)
343 			pflow_flush(sc);
344 		pflow_setmtu(sc, ifr->ifr_mtu);
345 		splx(s);
346 		break;
347 
348 	case SIOCGETPFLOW:
349 		bzero(&pflowr, sizeof(pflowr));
350 
351 		pflowr.sender_ip = sc->sc_sender_ip;
352 		pflowr.receiver_ip = sc->sc_receiver_ip;
353 		pflowr.receiver_port = sc->sc_receiver_port;
354 		pflowr.version = sc->sc_version;
355 
356 		if ((error = copyout(&pflowr, ifr->ifr_data,
357 		    sizeof(pflowr))))
358 			return (error);
359 		break;
360 
361 	case SIOCSETPFLOW:
362 		if ((error = suser(p, 0)) != 0)
363 			return (error);
364 		if ((error = copyin(ifr->ifr_data, &pflowr,
365 		    sizeof(pflowr))))
366 			return (error);
367 		if (pflowr.addrmask & PFLOW_MASK_VERSION) {
368 			switch(pflowr.version) {
369 			case PFLOW_PROTO_5:
370 			case PFLOW_PROTO_10:
371 				break;
372 			default:
373 				return(EINVAL);
374 			}
375 		}
376 		s = splnet();
377 
378 		pflow_flush(sc);
379 
380 		if (pflowr.addrmask & PFLOW_MASK_DSTIP)
381 			sc->sc_receiver_ip.s_addr = pflowr.receiver_ip.s_addr;
382 		if (pflowr.addrmask & PFLOW_MASK_DSTPRT)
383 			sc->sc_receiver_port = pflowr.receiver_port;
384 		if (pflowr.addrmask & PFLOW_MASK_SRCIP)
385 			sc->sc_sender_ip.s_addr = pflowr.sender_ip.s_addr;
386 		/* error check is above */
387 		if (pflowr.addrmask & PFLOW_MASK_VERSION)
388 			sc->sc_version = pflowr.version;
389 
390 		pflow_setmtu(sc, ETHERMTU);
391 		pflow_init_timeouts(sc);
392 
393 		splx(s);
394 
395 		if ((ifp->if_flags & IFF_UP) &&
396 		    sc->sc_receiver_ip.s_addr != INADDR_ANY &&
397 		    sc->sc_receiver_port != 0 &&
398 		    sc->sc_sender_port != 0) {
399 			ifp->if_flags |= IFF_RUNNING;
400 			sc->sc_gcounter=pflowstats.pflow_flows;
401 			if (sc->sc_version == PFLOW_PROTO_10) {
402 				s = splnet();
403 				pflow_sendout_ipfix_tmpl(sc);
404 				splx(s);
405 			}
406 		} else
407 			ifp->if_flags &= ~IFF_RUNNING;
408 
409 		break;
410 
411 	default:
412 		return (ENOTTY);
413 	}
414 	return (0);
415 }
416 
417 void
418 pflow_init_timeouts(struct pflow_softc *sc)
419 {
420 	switch (sc->sc_version) {
421 	case PFLOW_PROTO_5:
422 		if (timeout_initialized(&sc->sc_tmo6))
423 			timeout_del(&sc->sc_tmo6);
424 		if (timeout_initialized(&sc->sc_tmo_tmpl))
425 			timeout_del(&sc->sc_tmo_tmpl);
426 		if (!timeout_initialized(&sc->sc_tmo))
427 			timeout_set(&sc->sc_tmo, pflow_timeout, sc);
428 		break;
429 	case PFLOW_PROTO_10:
430 		if (!timeout_initialized(&sc->sc_tmo_tmpl))
431 			timeout_set(&sc->sc_tmo_tmpl, pflow_timeout_tmpl, sc);
432 		if (!timeout_initialized(&sc->sc_tmo))
433 			timeout_set(&sc->sc_tmo, pflow_timeout, sc);
434 		if (!timeout_initialized(&sc->sc_tmo6))
435 			timeout_set(&sc->sc_tmo6, pflow_timeout6, sc);
436 
437 		timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
438 		break;
439 	default: /* NOTREACHED */
440 		break;
441 	}
442 }
443 
444 int
445 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
446 {
447 
448 	sc->sc_maxcount4 = (mtu - hdrsz -
449 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
450 	sc->sc_maxcount6 = (mtu - hdrsz -
451 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
452 	if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
453 		sc->sc_maxcount4 = PFLOW_MAXFLOWS;
454 	if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
455 		sc->sc_maxcount6 = PFLOW_MAXFLOWS;
456 	return (hdrsz + sizeof(struct udpiphdr) +
457 	    MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
458 	    sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6)));
459 }
460 
461 void
462 pflow_setmtu(struct pflow_softc *sc, int mtu_req)
463 {
464 	int	mtu;
465 
466 	if (sc->sc_pflow_ifp && sc->sc_pflow_ifp->if_mtu < mtu_req)
467 		mtu = sc->sc_pflow_ifp->if_mtu;
468 	else
469 		mtu = mtu_req;
470 
471 	switch (sc->sc_version) {
472 	case PFLOW_PROTO_5:
473 		sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
474 		    sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
475 		if (sc->sc_maxcount > PFLOW_MAXFLOWS)
476 		    sc->sc_maxcount = PFLOW_MAXFLOWS;
477 		sc->sc_if.if_mtu = sizeof(struct pflow_header) +
478 		    sizeof(struct udpiphdr) +
479 		    sc->sc_maxcount * sizeof(struct pflow_flow);
480 		break;
481 	case PFLOW_PROTO_10:
482 		sc->sc_if.if_mtu =
483 		    pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
484 		break;
485 	default: /* NOTREACHED */
486 		break;
487 	}
488 }
489 
490 struct mbuf *
491 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
492 {
493 	struct pflow_set_header	 set_hdr;
494 	struct pflow_header	 h;
495 	struct mbuf		*m;
496 
497 	MGETHDR(m, M_DONTWAIT, MT_DATA);
498 	if (m == NULL) {
499 		pflowstats.pflow_onomem++;
500 		return (NULL);
501 	}
502 
503 	MCLGET(m, M_DONTWAIT);
504 	if ((m->m_flags & M_EXT) == 0) {
505 		m_free(m);
506 		pflowstats.pflow_onomem++;
507 		return (NULL);
508 	}
509 
510 	m->m_len = m->m_pkthdr.len = 0;
511 	m->m_pkthdr.rcvif = NULL;
512 
513 	if (sc == NULL)		/* get only a new empty mbuf */
514 		return (m);
515 
516 	if (sc->sc_version == PFLOW_PROTO_5) {
517 		/* populate pflow_header */
518 		h.reserved1 = 0;
519 		h.reserved2 = 0;
520 		h.count = 0;
521 		h.version = htons(PFLOW_PROTO_5);
522 		h.flow_sequence = htonl(sc->sc_gcounter);
523 		h.engine_type = PFLOW_ENGINE_TYPE;
524 		h.engine_id = PFLOW_ENGINE_ID;
525 		m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT);
526 
527 		sc->sc_count = 0;
528 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
529 	} else {
530 		/* populate pflow_set_header */
531 		set_hdr.set_length = 0;
532 		set_hdr.set_id = htons(set_id);
533 		m_copyback(m, 0, PFLOW_SET_HDRLEN, &set_hdr, M_NOWAIT);
534 	}
535 
536 	return (m);
537 }
538 
539 void
540 copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
541     struct pf_state *st, struct pf_state_key *sk, int src, int dst)
542 {
543 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
544 	flow1->src_port = flow2->dest_port = sk->port[src];
545 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
546 	flow1->dest_port = flow2->src_port = sk->port[dst];
547 
548 	flow1->dest_as = flow2->src_as =
549 	    flow1->src_as = flow2->dest_as = 0;
550 	flow1->if_index_in = htons(st->if_index_in);
551 	flow1->if_index_out = htons(st->if_index_out);
552 	flow2->if_index_in = htons(st->if_index_out);
553 	flow2->if_index_out = htons(st->if_index_in);
554 	flow1->dest_mask = flow2->src_mask =
555 	    flow1->src_mask = flow2->dest_mask = 0;
556 
557 	flow1->flow_packets = htonl(st->packets[0]);
558 	flow2->flow_packets = htonl(st->packets[1]);
559 	flow1->flow_octets = htonl(st->bytes[0]);
560 	flow2->flow_octets = htonl(st->bytes[1]);
561 
562 	/*
563 	 * Pretend the flow was created or expired when the machine came up
564 	 * when creation is in the future of the last time a package was seen
565 	 * or was created / expired before this machine came up due to pfsync.
566 	 */
567 	flow1->flow_start = flow2->flow_start = st->creation < 0 ||
568 	    st->creation > st->expire ? htonl(0) : htonl(st->creation * 1000);
569 	flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
570 	    htonl(st->expire * 1000);
571 	flow1->tcp_flags = flow2->tcp_flags = 0;
572 	flow1->protocol = flow2->protocol = sk->proto;
573 	flow1->tos = flow2->tos = st->rule.ptr->tos;
574 }
575 
576 void
577 copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
578     struct pflow_ipfix_flow4 *flow2, struct pf_state *st,
579     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
580 {
581 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
582 	flow1->src_port = flow2->dest_port = sk->port[src];
583 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
584 	flow1->dest_port = flow2->src_port = sk->port[dst];
585 
586 	flow1->if_index_in = htonl(st->if_index_in);
587 	flow1->if_index_out = htonl(st->if_index_out);
588 	flow2->if_index_in = htonl(st->if_index_out);
589 	flow2->if_index_out = htonl(st->if_index_in);
590 
591 	flow1->flow_packets = htobe64(st->packets[0]);
592 	flow2->flow_packets = htobe64(st->packets[1]);
593 	flow1->flow_octets = htobe64(st->bytes[0]);
594 	flow2->flow_octets = htobe64(st->bytes[1]);
595 
596 	/*
597 	 * Pretend the flow was created when the machine came up when creation
598 	 * is in the future of the last time a package was seen due to pfsync.
599 	 */
600 	if (st->creation > st->expire)
601 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
602 		    time_uptime)*1000);
603 	else
604 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
605 		    (time_uptime - st->creation))*1000);
606 	flow1->flow_finish = flow2->flow_finish = htobe64((time_second -
607 	    (time_uptime - st->expire))*1000);
608 
609 	flow1->protocol = flow2->protocol = sk->proto;
610 	flow1->tos = flow2->tos = st->rule.ptr->tos;
611 }
612 
613 void
614 copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
615     struct pflow_ipfix_flow6 *flow2, struct pf_state *st,
616     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
617 {
618 	bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
619 	bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip));
620 	flow1->src_port = flow2->dest_port = sk->port[src];
621 	bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
622 	bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
623 	flow1->dest_port = flow2->src_port = sk->port[dst];
624 
625 	flow1->if_index_in = htonl(st->if_index_in);
626 	flow1->if_index_out = htonl(st->if_index_out);
627 	flow2->if_index_in = htonl(st->if_index_out);
628 	flow2->if_index_out = htonl(st->if_index_in);
629 
630 	flow1->flow_packets = htobe64(st->packets[0]);
631 	flow2->flow_packets = htobe64(st->packets[1]);
632 	flow1->flow_octets = htobe64(st->bytes[0]);
633 	flow2->flow_octets = htobe64(st->bytes[1]);
634 
635 	/*
636 	 * Pretend the flow was created when the machine came up when creation
637 	 * is in the future of the last time a package was seen due to pfsync.
638 	 */
639 	if (st->creation > st->expire)
640 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
641 		    time_uptime)*1000);
642 	else
643 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
644 		    (time_uptime - st->creation))*1000);
645 	flow1->flow_finish = flow2->flow_finish = htobe64((time_second -
646 	    (time_uptime - st->expire))*1000);
647 
648 	flow1->protocol = flow2->protocol = sk->proto;
649 	flow1->tos = flow2->tos = st->rule.ptr->tos;
650 }
651 
652 int
653 export_pflow(struct pf_state *st)
654 {
655 	struct pflow_softc	*sc = NULL;
656 	struct pf_state_key	*sk;
657 
658 	sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
659 
660 	SLIST_FOREACH(sc, &pflowif_list, sc_next) {
661 		switch (sc->sc_version) {
662 		case PFLOW_PROTO_5:
663 			if( sk->af == AF_INET )
664 				export_pflow_if(st, sk, sc);
665 			break;
666 		case PFLOW_PROTO_10:
667 			if( sk->af == AF_INET || sk->af == AF_INET6 )
668 				export_pflow_if(st, sk, sc);
669 			break;
670 		default: /* NOTREACHED */
671 			break;
672 		}
673 	}
674 
675 	return (0);
676 }
677 
678 int
679 export_pflow_if(struct pf_state *st, struct pf_state_key *sk,
680     struct pflow_softc *sc)
681 {
682 	struct pf_state		 pfs_copy;
683 	struct ifnet		*ifp = &sc->sc_if;
684 	u_int64_t		 bytes[2];
685 	int			 ret = 0;
686 
687 	if (!(ifp->if_flags & IFF_RUNNING))
688 		return (0);
689 
690 	if (sc->sc_version == PFLOW_PROTO_10)
691 		return (pflow_pack_flow_ipfix(st, sk, sc));
692 
693 	/* PFLOW_PROTO_5 */
694 	if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
695 	    && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
696 		return (pflow_pack_flow(st, sk, sc));
697 
698 	/* flow > PFLOW_MAXBYTES need special handling */
699 	bcopy(st, &pfs_copy, sizeof(pfs_copy));
700 	bytes[0] = pfs_copy.bytes[0];
701 	bytes[1] = pfs_copy.bytes[1];
702 
703 	while (bytes[0] > PFLOW_MAXBYTES) {
704 		pfs_copy.bytes[0] = PFLOW_MAXBYTES;
705 		pfs_copy.bytes[1] = 0;
706 
707 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
708 			return (ret);
709 		if ((bytes[0] - PFLOW_MAXBYTES) > 0)
710 			bytes[0] -= PFLOW_MAXBYTES;
711 	}
712 
713 	while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) {
714 		pfs_copy.bytes[1] = PFLOW_MAXBYTES;
715 		pfs_copy.bytes[0] = 0;
716 
717 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
718 			return (ret);
719 		if ((bytes[1] - PFLOW_MAXBYTES) > 0)
720 			bytes[1] -= PFLOW_MAXBYTES;
721 	}
722 
723 	pfs_copy.bytes[0] = bytes[0];
724 	pfs_copy.bytes[1] = bytes[1];
725 
726 	return (pflow_pack_flow(&pfs_copy, sk, sc));
727 }
728 
729 int
730 copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc)
731 {
732 	int		s, ret = 0;
733 
734 	s = splnet();
735 	if (sc->sc_mbuf == NULL) {
736 		if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL) {
737 			splx(s);
738 			return (ENOBUFS);
739 		}
740 	}
741 	m_copyback(sc->sc_mbuf, PFLOW_HDRLEN +
742 	    (sc->sc_count * sizeof(struct pflow_flow)),
743 	    sizeof(struct pflow_flow), flow, M_NOWAIT);
744 
745 	if (pflowstats.pflow_flows == sc->sc_gcounter)
746 		pflowstats.pflow_flows++;
747 	sc->sc_gcounter++;
748 	sc->sc_count++;
749 
750 	if (sc->sc_count >= sc->sc_maxcount)
751 		ret = pflow_sendout_v5(sc);
752 
753 	splx(s);
754 	return(ret);
755 }
756 
757 int
758 copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc)
759 {
760 	int		s, ret = 0;
761 
762 	s = splnet();
763 	if (sc->sc_mbuf == NULL) {
764 		if ((sc->sc_mbuf =
765 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) {
766 			splx(s);
767 			return (ENOBUFS);
768 		}
769 		sc->sc_count4 = 0;
770 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
771 	}
772 	m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
773 	    (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
774 	    sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT);
775 
776 	if (pflowstats.pflow_flows == sc->sc_gcounter)
777 		pflowstats.pflow_flows++;
778 	sc->sc_gcounter++;
779 	sc->sc_count4++;
780 
781 	if (sc->sc_count4 >= sc->sc_maxcount4)
782 		ret = pflow_sendout_ipfix(sc, AF_INET);
783 	splx(s);
784 	return(ret);
785 }
786 
787 int
788 copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc)
789 {
790 	int		s, ret = 0;
791 
792 	s = splnet();
793 	if (sc->sc_mbuf6 == NULL) {
794 		if ((sc->sc_mbuf6 =
795 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) {
796 			splx(s);
797 			return (ENOBUFS);
798 		}
799 		sc->sc_count6 = 0;
800 		timeout_add_sec(&sc->sc_tmo6, PFLOW_TIMEOUT);
801 	}
802 	m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN +
803 	    (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)),
804 	    sizeof(struct pflow_ipfix_flow6), flow, M_NOWAIT);
805 
806 	if (pflowstats.pflow_flows == sc->sc_gcounter)
807 		pflowstats.pflow_flows++;
808 	sc->sc_gcounter++;
809 	sc->sc_count6++;
810 
811 	if (sc->sc_count6 >= sc->sc_maxcount6)
812 		ret = pflow_sendout_ipfix(sc, AF_INET6);
813 
814 	splx(s);
815 	return(ret);
816 }
817 
818 int
819 pflow_pack_flow(struct pf_state *st, struct pf_state_key *sk,
820     struct pflow_softc *sc)
821 {
822 	struct pflow_flow	 flow1;
823 	struct pflow_flow	 flow2;
824 	int			 ret = 0;
825 
826 	bzero(&flow1, sizeof(flow1));
827 	bzero(&flow2, sizeof(flow2));
828 
829 	if (st->direction == PF_OUT)
830 		copy_flow_data(&flow1, &flow2, st, sk, 1, 0);
831 	else
832 		copy_flow_data(&flow1, &flow2, st, sk, 0, 1);
833 
834 	if (st->bytes[0] != 0) /* first flow from state */
835 		ret = copy_flow_to_m(&flow1, sc);
836 
837 	if (st->bytes[1] != 0) /* second flow from state */
838 		ret = copy_flow_to_m(&flow2, sc);
839 
840 	return (ret);
841 }
842 
843 int
844 pflow_pack_flow_ipfix(struct pf_state *st, struct pf_state_key *sk,
845     struct pflow_softc *sc)
846 {
847 	struct pflow_ipfix_flow4	 flow4_1, flow4_2;
848 	struct pflow_ipfix_flow6	 flow6_1, flow6_2;
849 	int				 ret = 0;
850 	if (sk->af == AF_INET) {
851 		bzero(&flow4_1, sizeof(flow4_1));
852 		bzero(&flow4_2, sizeof(flow4_2));
853 
854 		if (st->direction == PF_OUT)
855 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
856 			    1, 0);
857 		else
858 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
859 			    0, 1);
860 
861 		if (st->bytes[0] != 0) /* first flow from state */
862 			ret = copy_flow_ipfix_4_to_m(&flow4_1, sc);
863 
864 		if (st->bytes[1] != 0) /* second flow from state */
865 			ret = copy_flow_ipfix_4_to_m(&flow4_2, sc);
866 	} else if (sk->af == AF_INET6) {
867 		bzero(&flow6_1, sizeof(flow6_1));
868 		bzero(&flow6_2, sizeof(flow6_2));
869 
870 		if (st->direction == PF_OUT)
871 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
872 			    1, 0);
873 		else
874 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
875 			    0, 1);
876 
877 		if (st->bytes[0] != 0) /* first flow from state */
878 			ret = copy_flow_ipfix_6_to_m(&flow6_1, sc);
879 
880 		if (st->bytes[1] != 0) /* second flow from state */
881 			ret = copy_flow_ipfix_6_to_m(&flow6_2, sc);
882 	}
883 	return (ret);
884 }
885 
886 void
887 pflow_timeout(void *v)
888 {
889 	struct pflow_softc	*sc = v;
890 	int			 s;
891 
892 	s = splnet();
893 	switch (sc->sc_version) {
894 	case PFLOW_PROTO_5:
895 		pflow_sendout_v5(sc);
896 		break;
897 	case PFLOW_PROTO_10:
898 		pflow_sendout_ipfix(sc, AF_INET);
899 		break;
900 	default: /* NOTREACHED */
901 		break;
902 	}
903 	splx(s);
904 }
905 
906 void
907 pflow_timeout6(void *v)
908 {
909 	struct pflow_softc	*sc = v;
910 	int			 s;
911 
912 	s = splnet();
913 	pflow_sendout_ipfix(sc, AF_INET6);
914 	splx(s);
915 }
916 
917 void
918 pflow_timeout_tmpl(void *v)
919 {
920 	struct pflow_softc	*sc = v;
921 	int			 s;
922 
923 	s = splnet();
924 	pflow_sendout_ipfix_tmpl(sc);
925 	splx(s);
926 }
927 
928 /* This must be called in splnet() */
929 void
930 pflow_flush(struct pflow_softc *sc)
931 {
932 	switch (sc->sc_version) {
933 	case PFLOW_PROTO_5:
934 		pflow_sendout_v5(sc);
935 		break;
936 	case PFLOW_PROTO_10:
937 		pflow_sendout_ipfix(sc, AF_INET);
938 		pflow_sendout_ipfix(sc, AF_INET6);
939 		break;
940 	default: /* NOTREACHED */
941 		break;
942 	}
943 }
944 
945 
946 /* This must be called in splnet() */
947 int
948 pflow_sendout_v5(struct pflow_softc *sc)
949 {
950 	struct mbuf		*m = sc->sc_mbuf;
951 	struct pflow_header	*h;
952 	struct ifnet		*ifp = &sc->sc_if;
953 	struct timespec		tv;
954 
955 	timeout_del(&sc->sc_tmo);
956 
957 	if (m == NULL)
958 		return (0);
959 
960 	sc->sc_mbuf = NULL;
961 	if (!(ifp->if_flags & IFF_RUNNING)) {
962 		m_freem(m);
963 		return (0);
964 	}
965 
966 	pflowstats.pflow_packets++;
967 	h = mtod(m, struct pflow_header *);
968 	h->count = htons(sc->sc_count);
969 
970 	/* populate pflow_header */
971 	h->uptime_ms = htonl(time_uptime * 1000);
972 
973 	getnanotime(&tv);
974 	h->time_sec = htonl(tv.tv_sec);			/* XXX 2038 */
975 	h->time_nanosec = htonl(tv.tv_nsec);
976 
977 	return (pflow_sendout_mbuf(sc, m));
978 }
979 
980 /* This must be called in splnet() */
981 int
982 pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af)
983 {
984 	struct mbuf			*m;
985 	struct pflow_v10_header		*h10;
986 	struct pflow_set_header		*set_hdr;
987 	struct ifnet			*ifp = &sc->sc_if;
988 	u_int32_t			 count;
989 	int				 set_length;
990 
991 	switch (af) {
992 	case AF_INET:
993 		m = sc->sc_mbuf;
994 		timeout_del(&sc->sc_tmo);
995 		if (m == NULL)
996 			return (0);
997 		sc->sc_mbuf = NULL;
998 		count = sc->sc_count4;
999 		set_length = sizeof(struct pflow_set_header)
1000 		    + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4);
1001 		break;
1002 	case AF_INET6:
1003 		m = sc->sc_mbuf6;
1004 		timeout_del(&sc->sc_tmo6);
1005 		if (m == NULL)
1006 			return (0);
1007 		sc->sc_mbuf6 = NULL;
1008 		count = sc->sc_count6;
1009 		set_length = sizeof(struct pflow_set_header)
1010 		    + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6);
1011 		break;
1012 	default: /* NOTREACHED */
1013 		break;
1014 	}
1015 
1016 	if (!(ifp->if_flags & IFF_RUNNING)) {
1017 		m_freem(m);
1018 		return (0);
1019 	}
1020 
1021 	pflowstats.pflow_packets++;
1022 	set_hdr = mtod(m, struct pflow_set_header *);
1023 	set_hdr->set_length = htons(set_length);
1024 
1025 	/* populate pflow_header */
1026 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1027 	if (m == NULL) {
1028 		pflowstats.pflow_onomem++;
1029 		return (ENOBUFS);
1030 	}
1031 	h10 = mtod(m, struct pflow_v10_header *);
1032 	h10->version = htons(PFLOW_PROTO_10);
1033 	h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length);
1034 	h10->time_sec = htonl(time_second);		/* XXX 2038 */
1035 	h10->flow_sequence = htonl(sc->sc_sequence);
1036 	sc->sc_sequence += count;
1037 	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1038 	return (pflow_sendout_mbuf(sc, m));
1039 }
1040 
1041 /* This must be called in splnet() */
1042 int
1043 pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
1044 {
1045 	struct mbuf			*m;
1046 	struct pflow_v10_header		*h10;
1047 	struct ifnet			*ifp = &sc->sc_if;
1048 
1049 	timeout_del(&sc->sc_tmo_tmpl);
1050 
1051 	if (!(ifp->if_flags & IFF_RUNNING)) {
1052 		return (0);
1053 	}
1054 	m = pflow_get_mbuf(NULL, 0);
1055 	if (m == NULL)
1056 		return (0);
1057 	if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),
1058 	    &sc->sc_tmpl_ipfix, M_NOWAIT)) {
1059 		m_freem(m);
1060 		return (0);
1061 	}
1062 	pflowstats.pflow_packets++;
1063 
1064 	/* populate pflow_header */
1065 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1066 	if (m == NULL) {
1067 		pflowstats.pflow_onomem++;
1068 		return (ENOBUFS);
1069 	}
1070 	h10 = mtod(m, struct pflow_v10_header *);
1071 	h10->version = htons(PFLOW_PROTO_10);
1072 	h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct
1073 	    pflow_ipfix_tmpl));
1074 	h10->time_sec = htonl(time_second);		/* XXX 2038 */
1075 	h10->flow_sequence = htonl(sc->sc_sequence);
1076 	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1077 
1078 	timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
1079 	return (pflow_sendout_mbuf(sc, m));
1080 }
1081 
1082 int
1083 pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m)
1084 {
1085 	struct udpiphdr	*ui;
1086 	u_int16_t	 len = m->m_pkthdr.len;
1087 #if NBPFILTER > 0
1088 	struct ifnet	*ifp = &sc->sc_if;
1089 #endif
1090 	struct ip	*ip;
1091 	int		 err;
1092 
1093 	/* UDP Header*/
1094 	M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
1095 	if (m == NULL) {
1096 		pflowstats.pflow_onomem++;
1097 		return (ENOBUFS);
1098 	}
1099 
1100 	ui = mtod(m, struct udpiphdr *);
1101 	ui->ui_pr = IPPROTO_UDP;
1102 	ui->ui_src = sc->sc_sender_ip;
1103 	ui->ui_sport = sc->sc_sender_port;
1104 	ui->ui_dst = sc->sc_receiver_ip;
1105 	ui->ui_dport = sc->sc_receiver_port;
1106 	ui->ui_ulen = htons(sizeof(struct udphdr) + len);
1107 	ui->ui_sum = 0;
1108 	m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
1109 	m->m_pkthdr.ph_rtableid = sc->sc_if.if_rdomain;
1110 
1111 	ip = (struct ip *)ui;
1112 	ip->ip_v = IPVERSION;
1113 	ip->ip_hl = sizeof(struct ip) >> 2;
1114 	ip->ip_id = htons(ip_randomid());
1115 	ip->ip_off = htons(IP_DF);
1116 	ip->ip_tos = IPTOS_LOWDELAY;
1117 	ip->ip_ttl = IPDEFTTL;
1118 	ip->ip_len = htons(sizeof(struct udpiphdr) + len);
1119 
1120 #if NBPFILTER > 0
1121 	if (ifp->if_bpf)
1122 		bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1123 #endif
1124 
1125 	sc->sc_if.if_opackets++;
1126 	sc->sc_if.if_obytes += m->m_pkthdr.len;
1127 
1128 	if ((err = ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL,
1129 	    0))) {
1130 		pflowstats.pflow_oerrors++;
1131 		sc->sc_if.if_oerrors++;
1132 	}
1133 	return (err);
1134 }
1135 
1136 int
1137 pflow_get_dynport(void)
1138 {
1139 	u_int16_t	tmp, low, high, cut;
1140 
1141 	low = ipport_hifirstauto;     /* sysctl */
1142 	high = ipport_hilastauto;
1143 
1144 	cut = arc4random_uniform(1 + high - low) + low;
1145 
1146 	for (tmp = cut; tmp <= high; ++(tmp)) {
1147 		if (!in_baddynamic(tmp, IPPROTO_UDP))
1148 			return (htons(tmp));
1149 	}
1150 
1151 	for (tmp = cut - 1; tmp >= low; --(tmp)) {
1152 		if (!in_baddynamic(tmp, IPPROTO_UDP))
1153 			return (htons(tmp));
1154 	}
1155 
1156 	return (htons(ipport_hilastauto)); /* XXX */
1157 }
1158 
1159 int
1160 pflow_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1161     void *newp, size_t newlen)
1162 {
1163 	if (namelen != 1)
1164 		return (ENOTDIR);
1165 
1166 	switch (name[0]) {
1167 	case NET_PFLOW_STATS:
1168 		if (newp != NULL)
1169 			return (EPERM);
1170 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
1171 		    &pflowstats, sizeof(pflowstats)));
1172 	default:
1173 		return (EOPNOTSUPP);
1174 	}
1175 	return (0);
1176 }
1177