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