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