1/* $FreeBSD$ */ 2 3/* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8#include "ipf.h" 9#include "ipt.h" 10#include <sys/ioctl.h> 11#include <sys/file.h> 12 13#if !defined(lint) 14static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed"; 15static const char rcsid[] = "@(#)$Id$"; 16#endif 17 18extern char *optarg; 19extern struct ipread pcap, iptext, iphex; 20extern struct ifnet *get_unit __P((char *, int)); 21extern void init_ifp __P((void)); 22extern ipnat_t *natparse __P((char *, int)); 23extern hostmap_t **ipf_hm_maptable; 24extern hostmap_t *ipf_hm_maplist; 25 26ipfmutex_t ipl_mutex, ipf_auth_mx, ipf_rw, ipf_stinsert; 27ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; 28ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw, ipf_frcache; 29ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_authlk; 30ipfrwlock_t ipf_tokens; 31int opts = OPT_DONTOPEN; 32int use_inet6 = 0; 33int docksum = 0; 34int pfil_delayed_copy = 0; 35int main __P((int, char *[])); 36int loadrules __P((char *, int)); 37int kmemcpy __P((char *, long, int)); 38int kstrncpy __P((char *, long, int n)); 39int blockreason; 40void dumpnat __P((void *)); 41void dumpgroups __P((ipf_main_softc_t *)); 42void dumprules __P((frentry_t *)); 43void drain_log __P((char *)); 44void fixv4sums __P((mb_t *, ip_t *)); 45 46#if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \ 47 (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \ 48 defined(__osf__) || defined(linux) 49int ipftestioctl __P((int, ioctlcmd_t, ...)); 50int ipnattestioctl __P((int, ioctlcmd_t, ...)); 51int ipstatetestioctl __P((int, ioctlcmd_t, ...)); 52int ipauthtestioctl __P((int, ioctlcmd_t, ...)); 53int ipscantestioctl __P((int, ioctlcmd_t, ...)); 54int ipsynctestioctl __P((int, ioctlcmd_t, ...)); 55int ipooltestioctl __P((int, ioctlcmd_t, ...)); 56#else 57int ipftestioctl __P((dev_t, ioctlcmd_t, void *)); 58int ipnattestioctl __P((dev_t, ioctlcmd_t, void *)); 59int ipstatetestioctl __P((dev_t, ioctlcmd_t, void *)); 60int ipauthtestioctl __P((dev_t, ioctlcmd_t, void *)); 61int ipsynctestioctl __P((dev_t, ioctlcmd_t, void *)); 62int ipscantestioctl __P((dev_t, ioctlcmd_t, void *)); 63int ipooltestioctl __P((dev_t, ioctlcmd_t, void *)); 64#endif 65 66static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ipftestioctl, 67 ipnattestioctl, 68 ipstatetestioctl, 69 ipauthtestioctl, 70 ipsynctestioctl, 71 ipscantestioctl, 72 ipooltestioctl, 73 NULL }; 74static ipf_main_softc_t *softc = NULL; 75 76 77int 78main(argc,argv) 79 int argc; 80 char *argv[]; 81{ 82 char *datain, *iface, *ifname, *logout; 83 int fd, i, dir, c, loaded, dump, hlen; 84 struct in_addr sip; 85 struct ifnet *ifp; 86 struct ipread *r; 87 mb_t mb, *m, *n; 88 ip_t *ip; 89 90 m = &mb; 91 dir = 0; 92 dump = 0; 93 hlen = 0; 94 loaded = 0; 95 r = &iptext; 96 iface = NULL; 97 logout = NULL; 98 datain = NULL; 99 sip.s_addr = 0; 100 ifname = "anon0"; 101 102 initparse(); 103 104 ipf_load_all(); 105 106 softc = ipf_create_all(NULL); 107 if (softc == NULL) 108 exit(1); 109 110 if (ipf_init_all(softc) == -1) 111 exit(1); 112 113 i = 1; 114 if (ipftestioctl(IPL_LOGIPF, SIOCFRENB, &i) != 0) 115 exit(1); 116 117 while ((c = getopt(argc, argv, "6bCdDF:i:I:l:N:P:or:RS:T:vxX")) != -1) 118 switch (c) 119 { 120 case '6' : 121#ifdef USE_INET6 122 use_inet6 = 1; 123#else 124 fprintf(stderr, "IPv6 not supported\n"); 125 exit(1); 126#endif 127 break; 128 case 'b' : 129 opts |= OPT_BRIEF; 130 break; 131 case 'd' : 132 opts |= OPT_DEBUG; 133 break; 134 case 'C' : 135 docksum = 1; 136 break; 137 case 'D' : 138 dump = 1; 139 break; 140 case 'F' : 141 if (strcasecmp(optarg, "pcap") == 0) 142 r = &pcap; 143 else if (strcasecmp(optarg, "hex") == 0) 144 r = &iphex; 145 else if (strcasecmp(optarg, "text") == 0) 146 r = &iptext; 147 break; 148 case 'i' : 149 datain = optarg; 150 break; 151 case 'I' : 152 ifname = optarg; 153 break; 154 case 'l' : 155 logout = optarg; 156 break; 157 case 'N' : 158 if (ipnat_parsefile(-1, ipnat_addrule, ipnattestioctl, 159 optarg) == -1) 160 return -1; 161 loaded = 1; 162 opts |= OPT_NAT; 163 break; 164 case 'o' : 165 opts |= OPT_SAVEOUT; 166 break; 167 case 'P' : 168 if (ippool_parsefile(-1, optarg, ipooltestioctl) == -1) 169 return -1; 170 loaded = 1; 171 break; 172 case 'r' : 173 if (ipf_parsefile(-1, ipf_addrule, iocfunctions, 174 optarg) == -1) 175 return -1; 176 loaded = 1; 177 break; 178 case 'S' : 179 sip.s_addr = inet_addr(optarg); 180 break; 181 case 'R' : 182 opts |= OPT_NORESOLVE; 183 break; 184 case 'T' : 185 ipf_dotuning(-1, optarg, ipftestioctl); 186 break; 187 case 'v' : 188 opts |= OPT_VERBOSE; 189 break; 190 case 'x' : 191 opts |= OPT_HEX; 192 break; 193 } 194 195 if (loaded == 0) { 196 (void)fprintf(stderr,"no rules loaded\n"); 197 exit(-1); 198 } 199 200 if (opts & OPT_SAVEOUT) 201 init_ifp(); 202 203 if (datain) 204 fd = (*r->r_open)(datain); 205 else 206 fd = (*r->r_open)("-"); 207 208 if (fd < 0) { 209 perror("error opening input"); 210 exit(-1); 211 } 212 213 m->m_data = (char *)m->mb_buf; 214 while ((i = (*r->r_readip)(m, &iface, &dir)) > 0) { 215 216 if ((iface == NULL) || (*iface == '\0')) 217 iface = ifname; 218 219 ip = MTOD(m, ip_t *); 220 ifp = get_unit(iface, IP_V(ip)); 221 222 if (IP_V(ip) == 4) { 223 if ((r->r_flags & R_DO_CKSUM) || docksum) 224 fixv4sums(m, ip); 225 hlen = IP_HL(ip) << 2; 226 if (sip.s_addr) 227 dir = !(sip.s_addr == ip->ip_src.s_addr); 228 } 229#ifdef USE_INET6 230 else 231 hlen = sizeof(ip6_t); 232#endif 233 /* ipfr_slowtimer(); */ 234 blockreason = 0; 235 m = &mb; 236 m->mb_ifp = ifp; 237 m->mb_len = i; 238 i = ipf_check(softc, ip, hlen, ifp, dir, &m); 239 if ((opts & OPT_NAT) == 0) 240 switch (i) 241 { 242 case -4 : 243 (void)printf("preauth"); 244 break; 245 case -3 : 246 (void)printf("account"); 247 break; 248 case -2 : 249 (void)printf("auth"); 250 break; 251 case -1 : 252 (void)printf("block"); 253 break; 254 case 0 : 255 (void)printf("pass"); 256 break; 257 case 1 : 258 if (m == NULL) 259 (void)printf("bad-packet"); 260 else 261 (void)printf("nomatch"); 262 break; 263 case 3 : 264 (void)printf("block return-rst"); 265 break; 266 case 4 : 267 (void)printf("block return-icmp"); 268 break; 269 case 5 : 270 (void)printf("block return-icmp-as-dest"); 271 break; 272 default : 273 (void)printf("recognised return %#x\n", i); 274 break; 275 } 276 277 if (!(opts & OPT_BRIEF)) { 278 putchar(' '); 279 if (m != NULL) 280 printpacket(dir, m); 281 else 282 printpacket(dir, &mb); 283 printf("--------------"); 284 } else if ((opts & (OPT_BRIEF|OPT_NAT)) == 285 (OPT_NAT|OPT_BRIEF)) { 286 if (m != NULL) 287 printpacket(dir, m); 288 else 289 PRINTF("%d\n", blockreason); 290 } 291 292 ipf_state_flush(softc, 1, 0); 293 294 if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL)) 295#if defined(__sgi) && (IRIX < 60500) 296 (*ifp->if_output)(ifp, (void *)m, NULL); 297#else 298# if TRU64 >= 1885 299 (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 300# else 301 (*ifp->if_output)(ifp, (void *)m, NULL, 0); 302# endif 303#endif 304 305 while ((m != NULL) && (m != &mb)) { 306 n = m->mb_next; 307 freembt(m); 308 m = n; 309 } 310 311 if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF)) 312 putchar('\n'); 313 dir = 0; 314 if (iface != ifname) { 315 free(iface); 316 iface = ifname; 317 } 318 m = &mb; 319 m->mb_data = (char *)m->mb_buf; 320 } 321 322 if (i != 0) 323 fprintf(stderr, "readip failed: %d\n", i); 324 (*r->r_close)(); 325 326 if (logout != NULL) { 327 drain_log(logout); 328 } 329 330 if (dump == 1) { 331 dumpnat(softc->ipf_nat_soft); 332 ipf_state_dump(softc, softc->ipf_state_soft); 333 ipf_lookup_dump(softc, softc->ipf_state_soft); 334 dumpgroups(softc); 335 } 336 337 ipf_fini_all(softc); 338 339 ipf_destroy_all(softc); 340 341 ipf_unload_all(); 342 343 ipf_mutex_clean(); 344 ipf_rwlock_clean(); 345 346 if (getenv("FINDLEAKS")) { 347 fflush(stdout); 348 abort(); 349 } 350 return 0; 351} 352 353 354#if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \ 355 (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \ 356 defined(__osf__) || defined(linux) 357int ipftestioctl(int dev, ioctlcmd_t cmd, ...) 358{ 359 caddr_t data; 360 va_list ap; 361 int i; 362 363 dev = dev; /* gcc -Wextra */ 364 va_start(ap, cmd); 365 data = va_arg(ap, caddr_t); 366 va_end(ap); 367 368 i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD); 369 if (opts & OPT_DEBUG) 370 fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n", 371 (u_int)cmd, data, i, softc->ipf_interror); 372 if (i != 0) { 373 errno = i; 374 return -1; 375 } 376 return 0; 377} 378 379 380int ipnattestioctl(int dev, ioctlcmd_t cmd, ...) 381{ 382 caddr_t data; 383 va_list ap; 384 int i; 385 386 dev = dev; /* gcc -Wextra */ 387 va_start(ap, cmd); 388 data = va_arg(ap, caddr_t); 389 va_end(ap); 390 391 i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD); 392 if (opts & OPT_DEBUG) 393 fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n", 394 (u_int)cmd, data, i); 395 if (i != 0) { 396 errno = i; 397 return -1; 398 } 399 return 0; 400} 401 402 403int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...) 404{ 405 caddr_t data; 406 va_list ap; 407 int i; 408 409 dev = dev; /* gcc -Wextra */ 410 va_start(ap, cmd); 411 data = va_arg(ap, caddr_t); 412 va_end(ap); 413 414 i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD); 415 if ((opts & OPT_DEBUG) || (i != 0)) 416 fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n", 417 (u_int)cmd, data, i); 418 if (i != 0) { 419 errno = i; 420 return -1; 421 } 422 return 0; 423} 424 425 426int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...) 427{ 428 caddr_t data; 429 va_list ap; 430 int i; 431 432 dev = dev; /* gcc -Wextra */ 433 va_start(ap, cmd); 434 data = va_arg(ap, caddr_t); 435 va_end(ap); 436 437 i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD); 438 if ((opts & OPT_DEBUG) || (i != 0)) 439 fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n", 440 (u_int)cmd, data, i); 441 if (i != 0) { 442 errno = i; 443 return -1; 444 } 445 return 0; 446} 447 448 449int ipscantestioctl(int dev, ioctlcmd_t cmd, ...) 450{ 451 caddr_t data; 452 va_list ap; 453 int i; 454 455 dev = dev; /* gcc -Wextra */ 456 va_start(ap, cmd); 457 data = va_arg(ap, caddr_t); 458 va_end(ap); 459 460 i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD); 461 if ((opts & OPT_DEBUG) || (i != 0)) 462 fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n", 463 (u_int)cmd, data, i); 464 if (i != 0) { 465 errno = i; 466 return -1; 467 } 468 return 0; 469} 470 471 472int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...) 473{ 474 caddr_t data; 475 va_list ap; 476 int i; 477 478 dev = dev; /* gcc -Wextra */ 479 va_start(ap, cmd); 480 data = va_arg(ap, caddr_t); 481 va_end(ap); 482 483 i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD); 484 if ((opts & OPT_DEBUG) || (i != 0)) 485 fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n", 486 (u_int)cmd, data, i); 487 if (i != 0) { 488 errno = i; 489 return -1; 490 } 491 return 0; 492} 493 494 495int ipooltestioctl(int dev, ioctlcmd_t cmd, ...) 496{ 497 caddr_t data; 498 va_list ap; 499 int i; 500 501 dev = dev; /* gcc -Wextra */ 502 va_start(ap, cmd); 503 data = va_arg(ap, caddr_t); 504 va_end(ap); 505 506 i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); 507 if ((opts & OPT_DEBUG) || (i != 0)) 508 fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n", 509 (u_int)cmd, data, i, softc->ipf_interror); 510 if (i != 0) { 511 errno = i; 512 return -1; 513 } 514 return 0; 515} 516#else 517int ipftestioctl(dev, cmd, data) 518 dev_t dev; 519 ioctlcmd_t cmd; 520 void *data; 521{ 522 int i; 523 524 dev = dev; /* gcc -Wextra */ 525 i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD); 526 if ((opts & OPT_DEBUG) || (i != 0)) 527 fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n", 528 cmd, data, i, softc->ipf_interror); 529 if (i != 0) { 530 errno = i; 531 return -1; 532 } 533 return 0; 534} 535 536 537int ipnattestioctl(dev, cmd, data) 538 dev_t dev; 539 ioctlcmd_t cmd; 540 void *data; 541{ 542 int i; 543 544 dev = dev; /* gcc -Wextra */ 545 i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD); 546 if ((opts & OPT_DEBUG) || (i != 0)) 547 fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n", cmd, data, i); 548 if (i != 0) { 549 errno = i; 550 return -1; 551 } 552 return 0; 553} 554 555 556int ipstatetestioctl(dev, cmd, data) 557 dev_t dev; 558 ioctlcmd_t cmd; 559 void *data; 560{ 561 int i; 562 563 dev = dev; /* gcc -Wextra */ 564 i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD); 565 if ((opts & OPT_DEBUG) || (i != 0)) 566 fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n", cmd, data, i); 567 if (i != 0) { 568 errno = i; 569 return -1; 570 } 571 return 0; 572} 573 574 575int ipauthtestioctl(dev, cmd, data) 576 dev_t dev; 577 ioctlcmd_t cmd; 578 void *data; 579{ 580 int i; 581 582 dev = dev; /* gcc -Wextra */ 583 i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD); 584 if ((opts & OPT_DEBUG) || (i != 0)) 585 fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n", cmd, data, i); 586 if (i != 0) { 587 errno = i; 588 return -1; 589 } 590 return 0; 591} 592 593 594int ipsynctestioctl(dev, cmd, data) 595 dev_t dev; 596 ioctlcmd_t cmd; 597 void *data; 598{ 599 int i; 600 601 dev = dev; /* gcc -Wextra */ 602 i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD); 603 if ((opts & OPT_DEBUG) || (i != 0)) 604 fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n", cmd, data, i); 605 if (i != 0) { 606 errno = i; 607 return -1; 608 } 609 return 0; 610} 611 612 613int ipscantestioctl(dev, cmd, data) 614 dev_t dev; 615 ioctlcmd_t cmd; 616 void *data; 617{ 618 int i; 619 620 dev = dev; /* gcc -Wextra */ 621 i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD); 622 if ((opts & OPT_DEBUG) || (i != 0)) 623 fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n", cmd, data, i); 624 if (i != 0) { 625 errno = i; 626 return -1; 627 } 628 return 0; 629} 630 631 632int ipooltestioctl(dev, cmd, data) 633 dev_t dev; 634 ioctlcmd_t cmd; 635 void *data; 636{ 637 int i; 638 639 dev = dev; /* gcc -Wextra */ 640 i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); 641 if (opts & OPT_DEBUG) 642 fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n", 643 cmd, data, i, softc->ipf_interror); 644 if (i != 0) { 645 errno = i; 646 return -1; 647 } 648 return 0; 649} 650#endif 651 652 653int kmemcpy(addr, offset, size) 654 char *addr; 655 long offset; 656 int size; 657{ 658 bcopy((char *)offset, addr, size); 659 return 0; 660} 661 662 663int kstrncpy(buf, pos, n) 664 char *buf; 665 long pos; 666 int n; 667{ 668 char *ptr; 669 670 ptr = (char *)pos; 671 672 while ((n > 0) && (*buf++ = *ptr++)) 673 ; 674 return 0; 675} 676 677 678/* 679 * Display the built up NAT table rules and mapping entries. 680 */ 681void dumpnat(arg) 682 void *arg; 683{ 684 ipf_nat_softc_t *softn = arg; 685 hostmap_t *hm; 686 ipnat_t *ipn; 687 nat_t *nat; 688 689 printf("List of active MAP/Redirect filters:\n"); 690 for (ipn = softn->ipf_nat_list; ipn != NULL; ipn = ipn->in_next) 691 printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 692 printf("\nList of active sessions:\n"); 693 for (nat = softn->ipf_nat_instances; nat; nat = nat->nat_next) { 694 printactivenat(nat, opts, 0); 695 if (nat->nat_aps) 696 printf("\tproxy active\n"); 697 } 698 699 printf("\nHostmap table:\n"); 700 for (hm = softn->ipf_hm_maplist; hm != NULL; hm = hm->hm_next) 701 printhostmap(hm, hm->hm_hv); 702} 703 704 705void dumpgroups(softc) 706 ipf_main_softc_t *softc; 707{ 708 frgroup_t *fg; 709 int i; 710 711 printf("List of groups configured (set 0)\n"); 712 for (i = 0; i < IPL_LOGSIZE; i++) 713 for (fg = softc->ipf_groups[i][0]; fg != NULL; 714 fg = fg->fg_next) { 715 printf("Dev.%d. Group %s Ref %d Flags %#x\n", 716 i, fg->fg_name, fg->fg_ref, fg->fg_flags); 717 dumprules(fg->fg_start); 718 } 719 720 printf("List of groups configured (set 1)\n"); 721 for (i = 0; i < IPL_LOGSIZE; i++) 722 for (fg = softc->ipf_groups[i][1]; fg != NULL; 723 fg = fg->fg_next) { 724 printf("Dev.%d. Group %s Ref %d Flags %#x\n", 725 i, fg->fg_name, fg->fg_ref, fg->fg_flags); 726 dumprules(fg->fg_start); 727 } 728 729 printf("Rules configured (set 0, in)\n"); 730 dumprules(softc->ipf_rules[0][0]); 731 printf("Rules configured (set 0, out)\n"); 732 dumprules(softc->ipf_rules[1][0]); 733 printf("Rules configured (set 1, in)\n"); 734 dumprules(softc->ipf_rules[0][1]); 735 printf("Rules configured (set 1, out)\n"); 736 dumprules(softc->ipf_rules[1][1]); 737 738 printf("Accounting rules configured (set 0, in)\n"); 739 dumprules(softc->ipf_acct[0][0]); 740 printf("Accounting rules configured (set 0, out)\n"); 741 dumprules(softc->ipf_acct[0][1]); 742 printf("Accounting rules configured (set 1, in)\n"); 743 dumprules(softc->ipf_acct[1][0]); 744 printf("Accounting rules configured (set 1, out)\n"); 745 dumprules(softc->ipf_acct[1][1]); 746} 747 748void dumprules(rulehead) 749 frentry_t *rulehead; 750{ 751 frentry_t *fr; 752 753 for (fr = rulehead; fr != NULL; fr = fr->fr_next) { 754#ifdef USE_QUAD_T 755 printf("%"PRIu64" ",(unsigned long long)fr->fr_hits); 756#else 757 printf("%ld ", fr->fr_hits); 758#endif 759 printfr(fr, ipftestioctl); 760 } 761} 762 763 764void drain_log(filename) 765 char *filename; 766{ 767 char buffer[DEFAULT_IPFLOGSIZE]; 768 struct iovec iov; 769 struct uio uio; 770 size_t resid; 771 int fd, i; 772 773 fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); 774 if (fd == -1) { 775 perror("drain_log:open"); 776 return; 777 } 778 779 for (i = 0; i <= IPL_LOGMAX; i++) 780 while (1) { 781 bzero((char *)&iov, sizeof(iov)); 782 iov.iov_base = buffer; 783 iov.iov_len = sizeof(buffer); 784 785 bzero((char *)&uio, sizeof(uio)); 786 uio.uio_iov = &iov; 787 uio.uio_iovcnt = 1; 788 uio.uio_resid = iov.iov_len; 789 resid = uio.uio_resid; 790 791 if (ipf_log_read(softc, i, &uio) == 0) { 792 /* 793 * If nothing was read then break out. 794 */ 795 if (uio.uio_resid == resid) 796 break; 797 write(fd, buffer, resid - uio.uio_resid); 798 } else 799 break; 800 } 801 802 close(fd); 803} 804 805 806void fixv4sums(m, ip) 807 mb_t *m; 808 ip_t *ip; 809{ 810 u_char *csump, *hdr, p; 811 fr_info_t tmp; 812 int len; 813 814 p = 0; 815 len = 0; 816 bzero((char *)&tmp, sizeof(tmp)); 817 818 csump = (u_char *)ip; 819 if (IP_V(ip) == 4) { 820 ip->ip_sum = 0; 821 ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2); 822 tmp.fin_hlen = IP_HL(ip) << 2; 823 csump += IP_HL(ip) << 2; 824 p = ip->ip_p; 825 len = ntohs(ip->ip_len); 826#ifdef USE_INET6 827 } else if (IP_V(ip) == 6) { 828 tmp.fin_hlen = sizeof(ip6_t); 829 csump += sizeof(ip6_t); 830 p = ((ip6_t *)ip)->ip6_nxt; 831 len = ntohs(((ip6_t *)ip)->ip6_plen); 832 len += sizeof(ip6_t); 833#endif 834 } 835 tmp.fin_plen = len; 836 tmp.fin_dlen = len - tmp.fin_hlen; 837 838 switch (p) 839 { 840 case IPPROTO_TCP : 841 hdr = csump; 842 csump += offsetof(tcphdr_t, th_sum); 843 break; 844 case IPPROTO_UDP : 845 hdr = csump; 846 csump += offsetof(udphdr_t, uh_sum); 847 break; 848 case IPPROTO_ICMP : 849 hdr = csump; 850 csump += offsetof(icmphdr_t, icmp_cksum); 851 break; 852 default : 853 csump = NULL; 854 hdr = NULL; 855 break; 856 } 857 if (hdr != NULL) { 858 tmp.fin_m = m; 859 tmp.fin_mp = &m; 860 tmp.fin_dp = hdr; 861 tmp.fin_ip = ip; 862 tmp.fin_plen = len; 863 *csump = 0; 864 *(u_short *)csump = fr_cksum(&tmp, ip, p, hdr); 865 } 866} 867