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