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