1 /* 2 * Copyright (C) 1993-2001, 2003 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 7 * Use is subject to license terms. 8 */ 9 10 #pragma ident "%Z%%M% %I% %E% SMI" 11 12 #if !defined(lint) 13 static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.121 2003/06/28 17:01:55 darrenr Exp $"; 14 #endif 15 16 #ifndef SOLARIS 17 #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 18 #endif 19 20 #if defined(KERNEL) || defined(_KERNEL) 21 # undef KERNEL 22 # undef _KERNEL 23 # define KERNEL 1 24 # define _KERNEL 1 25 #endif 26 #include <sys/param.h> 27 #if defined(__FreeBSD__) && !defined(__FreeBSD_version) 28 # if defined(IPFILTER_LKM) 29 # ifndef __FreeBSD_cc_version 30 # include <osreldate.h> 31 # else 32 # if __FreeBSD_cc_version < 430000 33 # include <osreldate.h> 34 # endif 35 # endif 36 # endif 37 #endif 38 #include <sys/errno.h> 39 #include <sys/types.h> 40 41 #ifdef _KERNEL 42 # include <sys/systm.h> 43 # include <sys/fcntl.h> 44 #else 45 # define _KERNEL 46 # ifdef __OpenBSD__ 47 struct file; 48 # endif 49 50 # include <sys/uio.h> 51 # undef _KERNEL 52 #endif 53 54 #include <sys/file.h> 55 #include <sys/ioctl.h> 56 57 #include <stdio.h> 58 #include <string.h> 59 #include <stdlib.h> 60 #include <ctype.h> 61 #include <fcntl.h> 62 63 #ifdef __sgi 64 # include <sys/ptimers.h> 65 #endif 66 #include <sys/time.h> 67 #if !SOLARIS 68 # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) 69 # include <sys/dirent.h> 70 # else 71 # include <sys/dir.h> 72 # endif 73 #else 74 # include <sys/filio.h> 75 #endif 76 #include <sys/protosw.h> 77 #include <sys/socket.h> 78 79 #include <stdio.h> 80 #include <string.h> 81 #include <stdlib.h> 82 #include <ctype.h> 83 #include <fcntl.h> 84 85 #ifdef __hpux 86 # define _NET_ROUTE_INCLUDED 87 #endif 88 #include <net/if.h> 89 #ifdef sun 90 # include <net/af.h> 91 #endif 92 #if __FreeBSD_version >= 300000 93 # include <net/if_var.h> 94 #endif 95 #ifdef __sgi 96 #include <sys/debug.h> 97 # ifdef IFF_DRVRLOCK /* IRIX6 */ 98 #include <sys/hashing.h> 99 # endif 100 #endif 101 #include <net/route.h> 102 #include <netinet/in.h> 103 #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \ 104 !defined(__hpux) 105 # include <netinet/in_var.h> 106 #endif 107 #include <netinet/in_systm.h> 108 #include <netinet/ip.h> 109 #include <netinet/ip_var.h> 110 #include <netinet/tcp.h> 111 #if defined(__osf__) 112 # include <netinet/tcp_timer.h> 113 #endif 114 #include <netinet/udp.h> 115 #include <netinet/tcpip.h> 116 #include <netinet/ip_icmp.h> 117 #include <unistd.h> 118 #include <syslog.h> 119 #ifdef __hpux 120 # undef _NET_ROUTE_INCLUDED 121 #endif 122 #if SOLARIS2 >= 10 123 #include "ip_compat.h" 124 #include "ip_fil.h" 125 #include "ip_nat.h" 126 #include "ip_frag.h" 127 #include "ip_state.h" 128 #include "ip_proxy.h" 129 #include "ip_auth.h" 130 #else 131 #include "netinet/ip_compat.h" 132 #include "netinet/ip_fil.h" 133 #include "netinet/ip_nat.h" 134 #include "netinet/ip_frag.h" 135 #include "netinet/ip_state.h" 136 #include "netinet/ip_proxy.h" 137 #include "netinet/ip_auth.h" 138 #endif 139 #ifdef IPFILTER_SYNC 140 #include "netinet/ip_sync.h" 141 #endif 142 #ifdef IPFILTER_SCAN 143 #include "netinet/ip_scan.h" 144 #endif 145 #if SOLARIS2 >= 10 146 #include "ip_pool.h" 147 #else 148 #include "netinet/ip_pool.h" 149 #endif 150 #ifdef IPFILTER_COMPILED 151 # include "netinet/ip_rules.h" 152 #endif 153 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 154 # include <sys/malloc.h> 155 #endif 156 #ifdef __hpux 157 struct rtentry; 158 #endif 159 160 #include <sys/md5.h> 161 162 #if !defined(__osf__) 163 extern struct protosw inetsw[]; 164 #endif 165 166 #include "ipt.h" 167 static struct ifnet **ifneta = NULL; 168 static int nifs = 0; 169 170 static int frzerostats __P((caddr_t)); 171 void init_ifp __P((void)); 172 #if defined(__sgi) && (IRIX < 605) 173 static int no_output __P((struct ifnet *, struct mbuf *, 174 struct sockaddr *)); 175 static int write_output __P((struct ifnet *, struct mbuf *, 176 struct sockaddr *)); 177 #else 178 # if TRU64 >= 1885 179 static int no_output __P((struct ifnet *, struct mbuf *, 180 struct sockaddr *, struct rtentry *, char *)); 181 static int write_output __P((struct ifnet *, struct mbuf *, 182 struct sockaddr *, struct rtentry *, char *)); 183 # else 184 static int no_output __P((struct ifnet *, struct mbuf *, 185 struct sockaddr *, struct rtentry *)); 186 static int write_output __P((struct ifnet *, struct mbuf *, 187 struct sockaddr *, struct rtentry *)); 188 # endif 189 #endif 190 191 192 int iplattach() 193 { 194 fr_running = 1; 195 return 0; 196 } 197 198 199 int ipldetach() 200 { 201 fr_running = -1; 202 return 0; 203 } 204 205 206 static int frzerostats(data) 207 caddr_t data; 208 { 209 friostat_t fio; 210 int error; 211 212 fr_getstat(&fio); 213 error = copyoutptr(&fio, data, sizeof(fio)); 214 if (error) 215 return EFAULT; 216 217 bzero((char *)frstats, sizeof(*frstats) * 2); 218 219 return 0; 220 } 221 222 223 224 /* 225 * Filter ioctl interface. 226 */ 227 int iplioctl(dev, cmd, data, mode) 228 int dev; 229 #if defined(__NetBSD__) || defined(__OpenBSD__) || \ 230 (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) 231 u_long cmd; 232 #else 233 int cmd; 234 #endif 235 caddr_t data; 236 int mode; 237 { 238 int error = 0, unit = 0, tmp; 239 friostat_t fio; 240 241 unit = dev; 242 243 SPL_NET(s); 244 245 if (unit == IPL_LOGNAT) { 246 if (fr_running > 0) 247 error = fr_nat_ioctl(data, cmd, mode); 248 else 249 error = EIO; 250 SPL_X(s); 251 return error; 252 } 253 if (unit == IPL_LOGSTATE) { 254 if (fr_running > 0) 255 error = fr_state_ioctl(data, cmd, mode); 256 else 257 error = EIO; 258 SPL_X(s); 259 return error; 260 } 261 if (unit == IPL_LOGAUTH) { 262 if (fr_running > 0) { 263 if ((cmd == SIOCADAFR) || (cmd == SIOCRMAFR)) { 264 if (!(mode & FWRITE)) { 265 error = EPERM; 266 } else { 267 error = frrequest(unit, cmd, data, 268 fr_active, 1); 269 } 270 } else { 271 error = fr_auth_ioctl(data, mode, cmd); 272 } 273 } else 274 error = EIO; 275 SPL_X(s); 276 return error; 277 } 278 if (unit == IPL_LOGSYNC) { 279 #ifdef IPFILTER_SYNC 280 if (fr_running > 0) 281 error = fr_sync_ioctl(data, cmd, mode); 282 else 283 #endif 284 error = EIO; 285 SPL_X(s); 286 return error; 287 } 288 if (unit == IPL_LOGSCAN) { 289 #ifdef IPFILTER_SCAN 290 if (fr_running > 0) 291 error = fr_scan_ioctl(data, cmd, mode); 292 else 293 #endif 294 error = EIO; 295 SPL_X(s); 296 return error; 297 } 298 if (unit == IPL_LOGLOOKUP) { 299 if (fr_running > 0) 300 error = ip_lookup_ioctl(data, cmd, mode); 301 else 302 error = EIO; 303 SPL_X(s); 304 return error; 305 } 306 307 switch (cmd) 308 { 309 case FIONREAD : 310 #ifdef IPFILTER_LOG 311 error = COPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data, 312 sizeof(iplused[IPL_LOGIPF])); 313 #endif 314 break; 315 case SIOCFRENB : 316 if (!(mode & FWRITE)) 317 error = EPERM; 318 else { 319 error = COPYIN(data, &tmp, sizeof(tmp)); 320 if (error) 321 break; 322 if (tmp) 323 error = iplattach(); 324 else 325 error = ipldetach(); 326 } 327 break; 328 case SIOCSETFF : 329 if (!(mode & FWRITE)) 330 error = EPERM; 331 else 332 error = COPYIN(data, &fr_flags, sizeof(fr_flags)); 333 break; 334 case SIOCGETFF : 335 error = COPYOUT(&fr_flags, data, sizeof(fr_flags)); 336 break; 337 case SIOCFUNCL : 338 error = fr_resolvefunc(data); 339 break; 340 case SIOCINAFR : 341 case SIOCRMAFR : 342 case SIOCADAFR : 343 case SIOCZRLST : 344 if (!(mode & FWRITE)) 345 error = EPERM; 346 else 347 error = frrequest(unit, cmd, data, fr_active, 1); 348 break; 349 case SIOCINIFR : 350 case SIOCRMIFR : 351 case SIOCADIFR : 352 if (!(mode & FWRITE)) 353 error = EPERM; 354 else 355 error = frrequest(unit, cmd, data, 1 - fr_active, 1); 356 break; 357 case SIOCSWAPA : 358 if (!(mode & FWRITE)) 359 error = EPERM; 360 else { 361 bzero((char *)frcache, sizeof(frcache[0]) * 2); 362 *(u_int *)data = fr_active; 363 fr_active = 1 - fr_active; 364 } 365 break; 366 case SIOCGETFS : 367 fr_getstat(&fio); 368 error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); 369 break; 370 case SIOCFRZST : 371 if (!(mode & FWRITE)) 372 error = EPERM; 373 else 374 error = frzerostats(data); 375 break; 376 case SIOCIPFFL : 377 if (!(mode & FWRITE)) 378 error = EPERM; 379 else { 380 error = COPYIN(data, &tmp, sizeof(tmp)); 381 if (!error) { 382 tmp = frflush(unit, tmp); 383 error = COPYOUT(&tmp, data, sizeof(tmp)); 384 } 385 } 386 break; 387 case SIOCSTLCK : 388 error = COPYIN(data, &tmp, sizeof(tmp)); 389 if (error == 0) { 390 fr_state_lock = tmp; 391 fr_nat_lock = tmp; 392 fr_frag_lock = tmp; 393 fr_auth_lock = tmp; 394 } else 395 error = EFAULT; 396 break; 397 #ifdef IPFILTER_LOG 398 case SIOCIPFFB : 399 if (!(mode & FWRITE)) 400 error = EPERM; 401 else 402 *(int *)data = ipflog_clear(unit); 403 break; 404 #endif /* IPFILTER_LOG */ 405 case SIOCGFRST : 406 error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); 407 break; 408 case SIOCFRSYN : 409 if (!(mode & FWRITE)) 410 error = EPERM; 411 else { 412 frsync(); 413 } 414 break; 415 default : 416 error = EINVAL; 417 break; 418 } 419 SPL_X(s); 420 return error; 421 } 422 423 424 void fr_forgetifp(ifp) 425 void *ifp; 426 { 427 register frentry_t *f; 428 429 WRITE_ENTER(&ipf_mutex); 430 for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) 431 if (f->fr_ifa == ifp) 432 f->fr_ifa = (void *)-1; 433 for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) 434 if (f->fr_ifa == ifp) 435 f->fr_ifa = (void *)-1; 436 for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) 437 if (f->fr_ifa == ifp) 438 f->fr_ifa = (void *)-1; 439 for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) 440 if (f->fr_ifa == ifp) 441 f->fr_ifa = (void *)-1; 442 #ifdef USE_INET6 443 for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) 444 if (f->fr_ifa == ifp) 445 f->fr_ifa = (void *)-1; 446 for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) 447 if (f->fr_ifa == ifp) 448 f->fr_ifa = (void *)-1; 449 for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) 450 if (f->fr_ifa == ifp) 451 f->fr_ifa = (void *)-1; 452 for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) 453 if (f->fr_ifa == ifp) 454 f->fr_ifa = (void *)-1; 455 #endif 456 RWLOCK_EXIT(&ipf_mutex); 457 fr_natsync(ifp); 458 } 459 460 461 void fr_resolvdest(fdp, v) 462 frdest_t *fdp; 463 int v; 464 { 465 fdp->fd_ifp = NULL; 466 467 if (*fdp->fd_ifname) { 468 fdp->fd_ifp = GETIFP(fdp->fd_ifname, v); 469 if (!fdp->fd_ifp) 470 fdp->fd_ifp = (struct ifnet *)-1; 471 } 472 } 473 474 475 #if defined(__sgi) && (IRIX < 605) 476 static int no_output(ifp, m, s) 477 #else 478 # if TRU64 >= 1885 479 static int no_output (ifp, m, s, rt, cp) 480 char *cp; 481 # else 482 static int no_output(ifp, m, s, rt) 483 # endif 484 struct rtentry *rt; 485 #endif 486 struct ifnet *ifp; 487 struct mbuf *m; 488 struct sockaddr *s; 489 { 490 return 0; 491 } 492 493 494 #if defined(__sgi) && (IRIX < 605) 495 static int write_output(ifp, m, s) 496 #else 497 # if TRU64 >= 1885 498 static int write_output (ifp, m, s, rt, cp) 499 char *cp; 500 # else 501 static int write_output(ifp, m, s, rt) 502 # endif 503 struct rtentry *rt; 504 #endif 505 struct ifnet *ifp; 506 struct mbuf *m; 507 struct sockaddr *s; 508 { 509 char fname[32]; 510 mb_t *mb; 511 ip_t *ip; 512 int fd; 513 514 mb = (mb_t *)m; 515 ip = MTOD(mb, ip_t *); 516 517 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 518 (defined(OpenBSD) && (OpenBSD >= 199603)) 519 sprintf(fname, "/tmp/%s", ifp->if_xname); 520 #else 521 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 522 #endif 523 fd = open(fname, O_WRONLY|O_APPEND); 524 if (fd == -1) { 525 perror("open"); 526 return -1; 527 } 528 write(fd, (char *)ip, ntohs(ip->ip_len)); 529 close(fd); 530 return 0; 531 } 532 533 534 struct ifnet *get_unit(name, v) 535 char *name; 536 int v; 537 { 538 struct ifnet *ifp, **ifa, **old_ifneta; 539 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 540 (defined(OpenBSD) && (OpenBSD >= 199603)) 541 542 if (name == NULL) 543 name = "anon0"; 544 545 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 546 if (!strcmp(name, ifp->if_xname)) 547 return ifp; 548 } 549 #else 550 char *s, ifname[LIFNAMSIZ+1]; 551 552 if (name == NULL) 553 name = "anon0"; 554 555 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 556 COPYIFNAME(ifp, ifname); 557 if (!strcmp(name, ifname)) 558 return ifp; 559 } 560 #endif 561 562 if (!ifneta) { 563 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 564 if (!ifneta) 565 return NULL; 566 ifneta[1] = NULL; 567 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 568 if (!ifneta[0]) { 569 free(ifneta); 570 return NULL; 571 } 572 nifs = 1; 573 } else { 574 old_ifneta = ifneta; 575 nifs++; 576 ifneta = (struct ifnet **)realloc(ifneta, 577 (nifs + 1) * sizeof(*ifa)); 578 if (!ifneta) { 579 free(old_ifneta); 580 nifs = 0; 581 return NULL; 582 } 583 ifneta[nifs] = NULL; 584 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 585 if (!ifneta[nifs - 1]) { 586 nifs--; 587 return NULL; 588 } 589 } 590 ifp = ifneta[nifs - 1]; 591 592 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 593 (defined(OpenBSD) && (OpenBSD >= 199603)) 594 strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 595 #else 596 for (s = name; *s && !isdigit(*s); s++) 597 ; 598 if (*s && isdigit(*s)) { 599 ifp->if_unit = atoi(s); 600 ifp->if_name = (char *)malloc(s - name + 1); 601 strncpy(ifp->if_name, name, s - name); 602 ifp->if_name[s - name] = '\0'; 603 } else { 604 ifp->if_name = strdup(name); 605 ifp->if_unit = -1; 606 } 607 #endif 608 ifp->if_output = no_output; 609 return ifp; 610 } 611 612 613 char *get_ifname(ifp) 614 struct ifnet *ifp; 615 { 616 static char ifname[LIFNAMSIZ]; 617 618 #if defined(__OpenBSD__) || defined(__NetBSD__) 619 sprintf(ifname, "%s", ifp->if_xname); 620 #else 621 sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 622 #endif 623 return ifname; 624 } 625 626 627 628 void init_ifp() 629 { 630 struct ifnet *ifp, **ifa; 631 char fname[32]; 632 int fd; 633 634 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 635 (defined(OpenBSD) && (OpenBSD >= 199603)) 636 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 637 ifp->if_output = write_output; 638 sprintf(fname, "/tmp/%s", ifp->if_xname); 639 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 640 if (fd == -1) 641 perror("open"); 642 else 643 close(fd); 644 } 645 #else 646 647 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 648 ifp->if_output = write_output; 649 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 650 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 651 if (fd == -1) 652 perror("open"); 653 else 654 close(fd); 655 } 656 #endif 657 } 658 659 660 int fr_fastroute(m, mpp, fin, fdp) 661 mb_t *m, **mpp; 662 fr_info_t *fin; 663 frdest_t *fdp; 664 { 665 struct ifnet *ifp = fdp->fd_ifp; 666 ip_t *ip = fin->fin_ip; 667 668 if (!ifp) 669 return 0; /* no routing table out here */ 670 671 ip->ip_len = htons((u_short)ip->ip_len); 672 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 673 ip->ip_sum = 0; 674 #if defined(__sgi) && (IRIX < 605) 675 (*ifp->if_output)(ifp, (void *)ip, NULL); 676 # if TRU64 >= 1885 677 (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 678 # else 679 (*ifp->if_output)(ifp, (void *)m, NULL, 0); 680 # endif 681 #endif 682 return 0; 683 } 684 685 686 int fr_send_reset(fin) 687 fr_info_t *fin; 688 { 689 verbose("- TCP RST sent\n"); 690 return 0; 691 } 692 693 694 int fr_send_icmp_err(type, fin, dst) 695 int type; 696 fr_info_t *fin; 697 int dst; 698 { 699 verbose("- TCP RST sent\n"); 700 return 0; 701 } 702 703 704 void frsync() 705 { 706 return; 707 } 708 709 710 void m_freem(m) 711 mb_t *m; 712 { 713 return; 714 } 715 716 717 void m_copydata(m, off, len, cp) 718 mb_t *m; 719 int off, len; 720 caddr_t cp; 721 { 722 bcopy((char *)m + off, cp, len); 723 } 724 725 726 int ipfuiomove(buf, len, rwflag, uio) 727 caddr_t buf; 728 int len, rwflag; 729 struct uio *uio; 730 { 731 int left, ioc, num, offset; 732 struct iovec *io; 733 char *start; 734 735 if (rwflag == UIO_READ) { 736 left = len; 737 ioc = 0; 738 739 offset = uio->uio_offset; 740 741 while ((left > 0) && (ioc < uio->uio_iovcnt)) { 742 io = uio->uio_iov + ioc; 743 num = io->iov_len; 744 if (num > left) 745 num = left; 746 start = (char *)io->iov_base + offset; 747 if (start > (char *)io->iov_base + io->iov_len) { 748 offset -= io->iov_len; 749 ioc++; 750 continue; 751 } 752 bcopy(buf, start, num); 753 uio->uio_resid -= num; 754 uio->uio_offset += num; 755 left -= num; 756 if (left > 0) 757 ioc++; 758 } 759 if (left > 0) 760 return EFAULT; 761 } 762 return 0; 763 } 764 765 766 u_32_t fr_newisn(fin) 767 fr_info_t *fin; 768 { 769 static int iss_seq_off = 0; 770 u_char hash[16]; 771 u_32_t newiss; 772 MD5_CTX ctx; 773 774 /* 775 * Compute the base value of the ISS. It is a hash 776 * of (saddr, sport, daddr, dport, secret). 777 */ 778 MD5Init(&ctx); 779 780 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 781 sizeof(fin->fin_fi.fi_src)); 782 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 783 sizeof(fin->fin_fi.fi_dst)); 784 MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 785 786 /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 787 788 MD5Final(hash, &ctx); 789 790 memcpy(&newiss, hash, sizeof(newiss)); 791 792 /* 793 * Now increment our "timer", and add it in to 794 * the computed value. 795 * 796 * XXX Use `addin'? 797 * XXX TCP_ISSINCR too large to use? 798 */ 799 iss_seq_off += 0x00010000; 800 newiss += iss_seq_off; 801 return newiss; 802 } 803 804 805 /* ------------------------------------------------------------------------ */ 806 /* Function: fr_nextipid */ 807 /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 808 /* Parameters: fin(I) - pointer to packet information */ 809 /* */ 810 /* Returns the next IPv4 ID to use for this packet. */ 811 /* ------------------------------------------------------------------------ */ 812 INLINE u_short fr_nextipid(fin) 813 fr_info_t *fin; 814 { 815 static u_short ipid = 0; 816 u_short id; 817 818 MUTEX_ENTER(&ipf_rw); 819 id = ipid++; 820 MUTEX_EXIT(&ipf_rw); 821 822 return id; 823 } 824 825 826 INLINE void fr_checkv4sum(fin) 827 fr_info_t *fin; 828 { 829 if (fr_checkl4sum(fin) == -1) 830 fin->fin_flx |= FI_BAD; 831 } 832 833 834 #ifdef USE_INET6 835 INLINE void fr_checkv6sum(fin) 836 fr_info_t *fin; 837 { 838 if (fr_checkl4sum(fin) == -1) 839 fin->fin_flx |= FI_BAD; 840 } 841 #endif 842