1 /* 2 * Copyright (C) 1993-2001, 2003 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * Copyright 2005 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, 4, tmp); 383 error = COPYOUT(&tmp, data, sizeof(tmp)); 384 } 385 } 386 break; 387 #ifdef USE_INET6 388 case SIOCIPFL6 : 389 if (!(mode & FWRITE)) 390 error = EPERM; 391 else { 392 error = COPYIN(data, &tmp, sizeof(tmp)); 393 if (!error) { 394 tmp = frflush(unit, 6, tmp); 395 error = COPYOUT(&tmp, data, sizeof(tmp)); 396 } 397 } 398 break; 399 #endif 400 case SIOCSTLCK : 401 error = COPYIN(data, &tmp, sizeof(tmp)); 402 if (error == 0) { 403 fr_state_lock = tmp; 404 fr_nat_lock = tmp; 405 fr_frag_lock = tmp; 406 fr_auth_lock = tmp; 407 } else 408 error = EFAULT; 409 break; 410 #ifdef IPFILTER_LOG 411 case SIOCIPFFB : 412 if (!(mode & FWRITE)) 413 error = EPERM; 414 else 415 *(int *)data = ipflog_clear(unit); 416 break; 417 #endif /* IPFILTER_LOG */ 418 case SIOCGFRST : 419 error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); 420 break; 421 case SIOCFRSYN : 422 if (!(mode & FWRITE)) 423 error = EPERM; 424 else { 425 frsync(); 426 } 427 break; 428 default : 429 error = EINVAL; 430 break; 431 } 432 SPL_X(s); 433 return error; 434 } 435 436 437 void fr_forgetifp(ifp) 438 void *ifp; 439 { 440 register frentry_t *f; 441 442 WRITE_ENTER(&ipf_mutex); 443 for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) 444 if (f->fr_ifa == ifp) 445 f->fr_ifa = (void *)-1; 446 for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) 447 if (f->fr_ifa == ifp) 448 f->fr_ifa = (void *)-1; 449 for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) 450 if (f->fr_ifa == ifp) 451 f->fr_ifa = (void *)-1; 452 for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) 453 if (f->fr_ifa == ifp) 454 f->fr_ifa = (void *)-1; 455 #ifdef USE_INET6 456 for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) 457 if (f->fr_ifa == ifp) 458 f->fr_ifa = (void *)-1; 459 for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) 460 if (f->fr_ifa == ifp) 461 f->fr_ifa = (void *)-1; 462 for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) 463 if (f->fr_ifa == ifp) 464 f->fr_ifa = (void *)-1; 465 for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) 466 if (f->fr_ifa == ifp) 467 f->fr_ifa = (void *)-1; 468 #endif 469 RWLOCK_EXIT(&ipf_mutex); 470 fr_natsync(ifp); 471 } 472 473 474 void fr_resolvdest(fdp, v) 475 frdest_t *fdp; 476 int v; 477 { 478 fdp->fd_ifp = NULL; 479 480 if (*fdp->fd_ifname) { 481 fdp->fd_ifp = GETIFP(fdp->fd_ifname, v); 482 if (!fdp->fd_ifp) 483 fdp->fd_ifp = (struct ifnet *)-1; 484 } 485 } 486 487 488 #if defined(__sgi) && (IRIX < 605) 489 static int no_output(ifp, m, s) 490 #else 491 # if TRU64 >= 1885 492 static int no_output (ifp, m, s, rt, cp) 493 char *cp; 494 # else 495 static int no_output(ifp, m, s, rt) 496 # endif 497 struct rtentry *rt; 498 #endif 499 struct ifnet *ifp; 500 struct mbuf *m; 501 struct sockaddr *s; 502 { 503 return 0; 504 } 505 506 507 #if defined(__sgi) && (IRIX < 605) 508 static int write_output(ifp, m, s) 509 #else 510 # if TRU64 >= 1885 511 static int write_output (ifp, m, s, rt, cp) 512 char *cp; 513 # else 514 static int write_output(ifp, m, s, rt) 515 # endif 516 struct rtentry *rt; 517 #endif 518 struct ifnet *ifp; 519 struct mbuf *m; 520 struct sockaddr *s; 521 { 522 char fname[32]; 523 mb_t *mb; 524 ip_t *ip; 525 int fd; 526 527 mb = (mb_t *)m; 528 ip = MTOD(mb, ip_t *); 529 530 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 531 (defined(OpenBSD) && (OpenBSD >= 199603)) 532 sprintf(fname, "/tmp/%s", ifp->if_xname); 533 #else 534 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 535 #endif 536 fd = open(fname, O_WRONLY|O_APPEND); 537 if (fd == -1) { 538 perror("open"); 539 return -1; 540 } 541 write(fd, (char *)ip, ntohs(ip->ip_len)); 542 close(fd); 543 return 0; 544 } 545 546 547 struct ifnet *get_unit(name, v) 548 char *name; 549 int v; 550 { 551 struct ifnet *ifp, **ifa, **old_ifneta; 552 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 553 (defined(OpenBSD) && (OpenBSD >= 199603)) 554 555 if (name == NULL) 556 name = "anon0"; 557 558 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 559 if (!strcmp(name, ifp->if_xname)) 560 return ifp; 561 } 562 #else 563 char *s, ifname[LIFNAMSIZ+1]; 564 565 if (name == NULL) 566 name = "anon0"; 567 568 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 569 COPYIFNAME(ifp, ifname); 570 if (!strcmp(name, ifname)) 571 return ifp; 572 } 573 #endif 574 575 if (!ifneta) { 576 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 577 if (!ifneta) 578 return NULL; 579 ifneta[1] = NULL; 580 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 581 if (!ifneta[0]) { 582 free(ifneta); 583 return NULL; 584 } 585 nifs = 1; 586 } else { 587 old_ifneta = ifneta; 588 nifs++; 589 ifneta = (struct ifnet **)realloc(ifneta, 590 (nifs + 1) * sizeof(*ifa)); 591 if (!ifneta) { 592 free(old_ifneta); 593 nifs = 0; 594 return NULL; 595 } 596 ifneta[nifs] = NULL; 597 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 598 if (!ifneta[nifs - 1]) { 599 nifs--; 600 return NULL; 601 } 602 } 603 ifp = ifneta[nifs - 1]; 604 605 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 606 (defined(OpenBSD) && (OpenBSD >= 199603)) 607 strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 608 #else 609 for (s = name; *s && !isdigit(*s); s++) 610 ; 611 if (*s && isdigit(*s)) { 612 ifp->if_unit = atoi(s); 613 ifp->if_name = (char *)malloc(s - name + 1); 614 strncpy(ifp->if_name, name, s - name); 615 ifp->if_name[s - name] = '\0'; 616 } else { 617 ifp->if_name = strdup(name); 618 ifp->if_unit = -1; 619 } 620 #endif 621 ifp->if_output = no_output; 622 return ifp; 623 } 624 625 626 char *get_ifname(ifp) 627 struct ifnet *ifp; 628 { 629 static char ifname[LIFNAMSIZ]; 630 631 #if defined(__OpenBSD__) || defined(__NetBSD__) 632 sprintf(ifname, "%s", ifp->if_xname); 633 #else 634 sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 635 #endif 636 return ifname; 637 } 638 639 640 641 void init_ifp() 642 { 643 struct ifnet *ifp, **ifa; 644 char fname[32]; 645 int fd; 646 647 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 648 (defined(OpenBSD) && (OpenBSD >= 199603)) 649 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 650 ifp->if_output = write_output; 651 sprintf(fname, "/tmp/%s", ifp->if_xname); 652 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 653 if (fd == -1) 654 perror("open"); 655 else 656 close(fd); 657 } 658 #else 659 660 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { 661 ifp->if_output = write_output; 662 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 663 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 664 if (fd == -1) 665 perror("open"); 666 else 667 close(fd); 668 } 669 #endif 670 } 671 672 673 int fr_fastroute(m, mpp, fin, fdp) 674 mb_t *m, **mpp; 675 fr_info_t *fin; 676 frdest_t *fdp; 677 { 678 struct ifnet *ifp = fdp->fd_ifp; 679 ip_t *ip = fin->fin_ip; 680 681 if (!ifp) 682 return 0; /* no routing table out here */ 683 684 ip->ip_len = htons((u_short)ip->ip_len); 685 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 686 ip->ip_sum = 0; 687 #if defined(__sgi) && (IRIX < 605) 688 (*ifp->if_output)(ifp, (void *)ip, NULL); 689 # if TRU64 >= 1885 690 (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 691 # else 692 (*ifp->if_output)(ifp, (void *)m, NULL, 0); 693 # endif 694 #endif 695 return 0; 696 } 697 698 699 int fr_send_reset(fin) 700 fr_info_t *fin; 701 { 702 verbose("- TCP RST sent\n"); 703 return 0; 704 } 705 706 707 int fr_send_icmp_err(type, fin, dst) 708 int type; 709 fr_info_t *fin; 710 int dst; 711 { 712 verbose("- TCP RST sent\n"); 713 return 0; 714 } 715 716 717 void frsync() 718 { 719 return; 720 } 721 722 723 void m_freem(m) 724 mb_t *m; 725 { 726 return; 727 } 728 729 730 void m_copydata(m, off, len, cp) 731 mb_t *m; 732 int off, len; 733 caddr_t cp; 734 { 735 bcopy((char *)m + off, cp, len); 736 } 737 738 739 int ipfuiomove(buf, len, rwflag, uio) 740 caddr_t buf; 741 int len, rwflag; 742 struct uio *uio; 743 { 744 int left, ioc, num, offset; 745 struct iovec *io; 746 char *start; 747 748 if (rwflag == UIO_READ) { 749 left = len; 750 ioc = 0; 751 752 offset = uio->uio_offset; 753 754 while ((left > 0) && (ioc < uio->uio_iovcnt)) { 755 io = uio->uio_iov + ioc; 756 num = io->iov_len; 757 if (num > left) 758 num = left; 759 start = (char *)io->iov_base + offset; 760 if (start > (char *)io->iov_base + io->iov_len) { 761 offset -= io->iov_len; 762 ioc++; 763 continue; 764 } 765 bcopy(buf, start, num); 766 uio->uio_resid -= num; 767 uio->uio_offset += num; 768 left -= num; 769 if (left > 0) 770 ioc++; 771 } 772 if (left > 0) 773 return EFAULT; 774 } 775 return 0; 776 } 777 778 779 u_32_t fr_newisn(fin) 780 fr_info_t *fin; 781 { 782 static int iss_seq_off = 0; 783 u_char hash[16]; 784 u_32_t newiss; 785 MD5_CTX ctx; 786 787 /* 788 * Compute the base value of the ISS. It is a hash 789 * of (saddr, sport, daddr, dport, secret). 790 */ 791 MD5Init(&ctx); 792 793 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 794 sizeof(fin->fin_fi.fi_src)); 795 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 796 sizeof(fin->fin_fi.fi_dst)); 797 MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 798 799 /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 800 801 MD5Final(hash, &ctx); 802 803 memcpy(&newiss, hash, sizeof(newiss)); 804 805 /* 806 * Now increment our "timer", and add it in to 807 * the computed value. 808 * 809 * XXX Use `addin'? 810 * XXX TCP_ISSINCR too large to use? 811 */ 812 iss_seq_off += 0x00010000; 813 newiss += iss_seq_off; 814 return newiss; 815 } 816 817 818 /* ------------------------------------------------------------------------ */ 819 /* Function: fr_nextipid */ 820 /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 821 /* Parameters: fin(I) - pointer to packet information */ 822 /* */ 823 /* Returns the next IPv4 ID to use for this packet. */ 824 /* ------------------------------------------------------------------------ */ 825 INLINE u_short fr_nextipid(fin) 826 fr_info_t *fin; 827 { 828 static u_short ipid = 0; 829 u_short id; 830 831 MUTEX_ENTER(&ipf_rw); 832 id = ipid++; 833 MUTEX_EXIT(&ipf_rw); 834 835 return id; 836 } 837 838 839 INLINE void fr_checkv4sum(fin) 840 fr_info_t *fin; 841 { 842 if (fr_checkl4sum(fin) == -1) 843 fin->fin_flx |= FI_BAD; 844 } 845 846 847 #ifdef USE_INET6 848 INLINE void fr_checkv6sum(fin) 849 fr_info_t *fin; 850 { 851 if (fr_checkl4sum(fin) == -1) 852 fin->fin_flx |= FI_BAD; 853 } 854 #endif 855