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