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