ip_fil.c revision 256281
1/* $FreeBSD: stable/10/contrib/ipfilter/ip_fil.c 255761 2013-09-21 14:22:07Z cy $ */ 2 3/* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 * 8 * $Id$ 9 */ 10#if !defined(lint) 11static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 12static const char rcsid[] = "@(#)$Id$"; 13#endif 14 15#include "ipf.h" 16#include "md5.h" 17#include "ipt.h" 18 19ipf_main_softc_t ipfmain; 20 21static struct ifnet **ifneta = NULL; 22static int nifs = 0; 23 24struct rtentry; 25 26static void ipf_setifpaddr __P((struct ifnet *, char *)); 27void init_ifp __P((void)); 28#if defined(__sgi) && (IRIX < 60500) 29static int no_output __P((struct ifnet *, struct mbuf *, 30 struct sockaddr *)); 31static int write_output __P((struct ifnet *, struct mbuf *, 32 struct sockaddr *)); 33#else 34# if TRU64 >= 1885 35static int no_output __P((struct ifnet *, struct mbuf *, 36 struct sockaddr *, struct rtentry *, char *)); 37static int write_output __P((struct ifnet *, struct mbuf *, 38 struct sockaddr *, struct rtentry *, char *)); 39# else 40static int no_output __P((struct ifnet *, struct mbuf *, 41 struct sockaddr *, struct rtentry *)); 42static int write_output __P((struct ifnet *, struct mbuf *, 43 struct sockaddr *, struct rtentry *)); 44# endif 45#endif 46 47 48int 49ipfattach(softc) 50 ipf_main_softc_t *softc; 51{ 52 return 0; 53} 54 55 56int 57ipfdetach(softc) 58 ipf_main_softc_t *softc; 59{ 60 return 0; 61} 62 63 64/* 65 * Filter ioctl interface. 66 */ 67int 68ipfioctl(softc, dev, cmd, data, mode) 69 ipf_main_softc_t *softc; 70 int dev; 71 ioctlcmd_t cmd; 72 caddr_t data; 73 int mode; 74{ 75 int error = 0, unit = 0, uid; 76 77 uid = getuid(); 78 unit = dev; 79 80 SPL_NET(s); 81 82 error = ipf_ioctlswitch(softc, unit, data, cmd, mode, uid, NULL); 83 if (error != -1) { 84 SPL_X(s); 85 return error; 86 } 87 SPL_X(s); 88 return error; 89} 90 91 92void 93ipf_forgetifp(softc, ifp) 94 ipf_main_softc_t *softc; 95 void *ifp; 96{ 97 register frentry_t *f; 98 99 WRITE_ENTER(&softc->ipf_mutex); 100 for (f = softc->ipf_acct[0][softc->ipf_active]; (f != NULL); 101 f = f->fr_next) 102 if (f->fr_ifa == ifp) 103 f->fr_ifa = (void *)-1; 104 for (f = softc->ipf_acct[1][softc->ipf_active]; (f != NULL); 105 f = f->fr_next) 106 if (f->fr_ifa == ifp) 107 f->fr_ifa = (void *)-1; 108 for (f = softc->ipf_rules[0][softc->ipf_active]; (f != NULL); 109 f = f->fr_next) 110 if (f->fr_ifa == ifp) 111 f->fr_ifa = (void *)-1; 112 for (f = softc->ipf_rules[1][softc->ipf_active]; (f != NULL); 113 f = f->fr_next) 114 if (f->fr_ifa == ifp) 115 f->fr_ifa = (void *)-1; 116 RWLOCK_EXIT(&softc->ipf_mutex); 117 ipf_nat_sync(softc, ifp); 118 ipf_lookup_sync(softc, ifp); 119} 120 121 122static int 123#if defined(__sgi) && (IRIX < 60500) 124no_output(ifp, m, s) 125#else 126# if TRU64 >= 1885 127no_output (ifp, m, s, rt, cp) 128 char *cp; 129# else 130no_output(ifp, m, s, rt) 131# endif 132 struct rtentry *rt; 133#endif 134 struct ifnet *ifp; 135 struct mbuf *m; 136 struct sockaddr *s; 137{ 138 return 0; 139} 140 141 142static int 143#if defined(__sgi) && (IRIX < 60500) 144write_output(ifp, m, s) 145#else 146# if TRU64 >= 1885 147write_output (ifp, m, s, rt, cp) 148 char *cp; 149# else 150write_output(ifp, m, s, rt) 151# endif 152 struct rtentry *rt; 153#endif 154 struct ifnet *ifp; 155 struct mbuf *m; 156 struct sockaddr *s; 157{ 158 char fname[32]; 159 mb_t *mb; 160 ip_t *ip; 161 int fd; 162 163 mb = (mb_t *)m; 164 ip = MTOD(mb, ip_t *); 165 166#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 167 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 168 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 169 sprintf(fname, "/tmp/%s", ifp->if_xname); 170#else 171 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 172#endif 173 fd = open(fname, O_WRONLY|O_APPEND); 174 if (fd == -1) { 175 perror("open"); 176 return -1; 177 } 178 write(fd, (char *)ip, ntohs(ip->ip_len)); 179 close(fd); 180 return 0; 181} 182 183 184static void 185ipf_setifpaddr(ifp, addr) 186 struct ifnet *ifp; 187 char *addr; 188{ 189#ifdef __sgi 190 struct in_ifaddr *ifa; 191#else 192 struct ifaddr *ifa; 193#endif 194 195#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 196 if (ifp->if_addrlist.tqh_first != NULL) 197#else 198# ifdef __sgi 199 if (ifp->in_ifaddr != NULL) 200# else 201 if (ifp->if_addrlist != NULL) 202# endif 203#endif 204 return; 205 206 ifa = (struct ifaddr *)malloc(sizeof(*ifa)); 207#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 208 ifp->if_addrlist.tqh_first = ifa; 209#else 210# ifdef __sgi 211 ifp->in_ifaddr = ifa; 212# else 213 ifp->if_addrlist = ifa; 214# endif 215#endif 216 217 if (ifa != NULL) { 218 struct sockaddr_in *sin; 219 220#ifdef __sgi 221 sin = (struct sockaddr_in *)&ifa->ia_addr; 222#else 223 sin = (struct sockaddr_in *)&ifa->ifa_addr; 224#endif 225#ifdef USE_INET6 226 if (index(addr, ':') != NULL) { 227 struct sockaddr_in6 *sin6; 228 229 sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; 230 sin6->sin6_family = AF_INET6; 231 /* Abort if bad address. */ 232 switch (inet_pton(AF_INET6, addr, &sin6->sin6_addr)) 233 { 234 case 1: 235 break; 236 case -1: 237 perror("inet_pton"); 238 abort(); 239 break; 240 default: 241 abort(); 242 break; 243 } 244 } else 245#endif 246 { 247 sin->sin_family = AF_INET; 248 sin->sin_addr.s_addr = inet_addr(addr); 249 if (sin->sin_addr.s_addr == 0) 250 abort(); 251 } 252 } 253} 254 255struct ifnet * 256get_unit(name, family) 257 char *name; 258 int family; 259{ 260 struct ifnet *ifp, **ifpp, **old_ifneta; 261 char *addr; 262#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 263 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 264 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 265 266 if (!*name) 267 return NULL; 268 269 if (name == NULL) 270 name = "anon0"; 271 272 addr = strchr(name, '='); 273 if (addr != NULL) 274 *addr++ = '\0'; 275 276 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 277 if (!strcmp(name, ifp->if_xname)) { 278 if (addr != NULL) 279 ipf_setifpaddr(ifp, addr); 280 return ifp; 281 } 282 } 283#else 284 char *s, ifname[LIFNAMSIZ+1]; 285 286 if (name == NULL) 287 name = "anon0"; 288 289 addr = strchr(name, '='); 290 if (addr != NULL) 291 *addr++ = '\0'; 292 293 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 294 COPYIFNAME(family, ifp, ifname); 295 if (!strcmp(name, ifname)) { 296 if (addr != NULL) 297 ipf_setifpaddr(ifp, addr); 298 return ifp; 299 } 300 } 301#endif 302 303 if (!ifneta) { 304 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 305 if (!ifneta) 306 return NULL; 307 ifneta[1] = NULL; 308 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 309 if (!ifneta[0]) { 310 free(ifneta); 311 return NULL; 312 } 313 nifs = 1; 314 } else { 315 old_ifneta = ifneta; 316 nifs++; 317 ifneta = (struct ifnet **)realloc(ifneta, 318 (nifs + 1) * sizeof(ifp)); 319 if (!ifneta) { 320 free(old_ifneta); 321 nifs = 0; 322 return NULL; 323 } 324 ifneta[nifs] = NULL; 325 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 326 if (!ifneta[nifs - 1]) { 327 nifs--; 328 return NULL; 329 } 330 } 331 ifp = ifneta[nifs - 1]; 332 333#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 334 TAILQ_INIT(&ifp->if_addrlist); 335#endif 336#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 337 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 338 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 339 (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 340#else 341 s = name + strlen(name) - 1; 342 for (; s > name; s--) { 343 if (!ISDIGIT(*s)) { 344 s++; 345 break; 346 } 347 } 348 349 if ((s > name) && (*s != 0) && ISDIGIT(*s)) { 350 ifp->if_unit = atoi(s); 351 ifp->if_name = (char *)malloc(s - name + 1); 352 (void) strncpy(ifp->if_name, name, s - name); 353 ifp->if_name[s - name] = '\0'; 354 } else { 355 ifp->if_name = strdup(name); 356 ifp->if_unit = -1; 357 } 358#endif 359 ifp->if_output = (void *)no_output; 360 361 if (addr != NULL) { 362 ipf_setifpaddr(ifp, addr); 363 } 364 365 return ifp; 366} 367 368 369char * 370get_ifname(ifp) 371 struct ifnet *ifp; 372{ 373 static char ifname[LIFNAMSIZ]; 374 375#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \ 376 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 377 sprintf(ifname, "%s", ifp->if_xname); 378#else 379 if (ifp->if_unit != -1) 380 sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 381 else 382 strcpy(ifname, ifp->if_name); 383#endif 384 return ifname; 385} 386 387 388 389void 390init_ifp() 391{ 392 struct ifnet *ifp, **ifpp; 393 char fname[32]; 394 int fd; 395 396#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 397 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 398 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 399 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 400 ifp->if_output = (void *)write_output; 401 sprintf(fname, "/tmp/%s", ifp->if_xname); 402 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 403 if (fd == -1) 404 perror("open"); 405 else 406 close(fd); 407 } 408#else 409 410 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 411 ifp->if_output = (void *)write_output; 412 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 413 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 414 if (fd == -1) 415 perror("open"); 416 else 417 close(fd); 418 } 419#endif 420} 421 422 423int 424ipf_fastroute(m, mpp, fin, fdp) 425 mb_t *m, **mpp; 426 fr_info_t *fin; 427 frdest_t *fdp; 428{ 429 struct ifnet *ifp; 430 ip_t *ip = fin->fin_ip; 431 frdest_t node; 432 int error = 0; 433 frentry_t *fr; 434 void *sifp; 435 int sout; 436 437 sifp = fin->fin_ifp; 438 sout = fin->fin_out; 439 fr = fin->fin_fr; 440 ip->ip_sum = 0; 441 442 if (!(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) && 443 (fdp->fd_type == FRD_DSTLIST)) { 444 bzero(&node, sizeof(node)); 445 ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, &node); 446 fdp = &node; 447 } 448 ifp = fdp->fd_ptr; 449 450 if (ifp == NULL) 451 return 0; /* no routing table out here */ 452 453 if (fin->fin_out == 0) { 454 fin->fin_ifp = ifp; 455 fin->fin_out = 1; 456 (void) ipf_acctpkt(fin, NULL); 457 fin->fin_fr = NULL; 458 if (!fr || !(fr->fr_flags & FR_RETMASK)) { 459 u_32_t pass; 460 461 (void) ipf_state_check(fin, &pass); 462 } 463 464 switch (ipf_nat_checkout(fin, NULL)) 465 { 466 case 0 : 467 break; 468 case 1 : 469 ip->ip_sum = 0; 470 break; 471 case -1 : 472 error = -1; 473 goto done; 474 break; 475 } 476 477 } 478 479 m->mb_ifp = ifp; 480 printpacket(fin->fin_out, m); 481 482#if defined(__sgi) && (IRIX < 60500) 483 (*ifp->if_output)(ifp, (void *)ip, NULL); 484# if TRU64 >= 1885 485 (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 486# else 487 (*ifp->if_output)(ifp, (void *)m, NULL, 0); 488# endif 489#endif 490done: 491 fin->fin_ifp = sifp; 492 fin->fin_out = sout; 493 return error; 494} 495 496 497int 498ipf_send_reset(fin) 499 fr_info_t *fin; 500{ 501 ipfkverbose("- TCP RST sent\n"); 502 return 0; 503} 504 505 506int 507ipf_send_icmp_err(type, fin, dst) 508 int type; 509 fr_info_t *fin; 510 int dst; 511{ 512 ipfkverbose("- ICMP unreachable sent\n"); 513 return 0; 514} 515 516 517void 518m_freem(m) 519 mb_t *m; 520{ 521 return; 522} 523 524 525void 526m_copydata(m, off, len, cp) 527 mb_t *m; 528 int off, len; 529 caddr_t cp; 530{ 531 bcopy((char *)m + off, cp, len); 532} 533 534 535int 536ipfuiomove(buf, len, rwflag, uio) 537 caddr_t buf; 538 int len, rwflag; 539 struct uio *uio; 540{ 541 int left, ioc, num, offset; 542 struct iovec *io; 543 char *start; 544 545 if (rwflag == UIO_READ) { 546 left = len; 547 ioc = 0; 548 549 offset = uio->uio_offset; 550 551 while ((left > 0) && (ioc < uio->uio_iovcnt)) { 552 io = uio->uio_iov + ioc; 553 num = io->iov_len; 554 if (num > left) 555 num = left; 556 start = (char *)io->iov_base + offset; 557 if (start > (char *)io->iov_base + io->iov_len) { 558 offset -= io->iov_len; 559 ioc++; 560 continue; 561 } 562 bcopy(buf, start, num); 563 uio->uio_resid -= num; 564 uio->uio_offset += num; 565 left -= num; 566 if (left > 0) 567 ioc++; 568 } 569 if (left > 0) 570 return EFAULT; 571 } 572 return 0; 573} 574 575 576u_32_t 577ipf_newisn(fin) 578 fr_info_t *fin; 579{ 580 static int iss_seq_off = 0; 581 u_char hash[16]; 582 u_32_t newiss; 583 MD5_CTX ctx; 584 585 /* 586 * Compute the base value of the ISS. It is a hash 587 * of (saddr, sport, daddr, dport, secret). 588 */ 589 MD5Init(&ctx); 590 591 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 592 sizeof(fin->fin_fi.fi_src)); 593 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 594 sizeof(fin->fin_fi.fi_dst)); 595 MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 596 597 /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 598 599 MD5Final(hash, &ctx); 600 601 memcpy(&newiss, hash, sizeof(newiss)); 602 603 /* 604 * Now increment our "timer", and add it in to 605 * the computed value. 606 * 607 * XXX Use `addin'? 608 * XXX TCP_ISSINCR too large to use? 609 */ 610 iss_seq_off += 0x00010000; 611 newiss += iss_seq_off; 612 return newiss; 613} 614 615 616/* ------------------------------------------------------------------------ */ 617/* Function: ipf_nextipid */ 618/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 619/* Parameters: fin(I) - pointer to packet information */ 620/* */ 621/* Returns the next IPv4 ID to use for this packet. */ 622/* ------------------------------------------------------------------------ */ 623INLINE u_short 624ipf_nextipid(fin) 625 fr_info_t *fin; 626{ 627 static u_short ipid = 0; 628 ipf_main_softc_t *softc = fin->fin_main_soft; 629 u_short id; 630 631 MUTEX_ENTER(&softc->ipf_rw); 632 if (fin->fin_pktnum != 0) { 633 /* 634 * The -1 is for aligned test results. 635 */ 636 id = (fin->fin_pktnum - 1) & 0xffff; 637 } else { 638 } 639 id = ipid++; 640 MUTEX_EXIT(&softc->ipf_rw); 641 642 return id; 643} 644 645 646INLINE int 647ipf_checkv4sum(fin) 648 fr_info_t *fin; 649{ 650 651 if (fin->fin_flx & FI_SHORT) 652 return 1; 653 654 if (ipf_checkl4sum(fin) == -1) { 655 fin->fin_flx |= FI_BAD; 656 return -1; 657 } 658 return 0; 659} 660 661 662#ifdef USE_INET6 663INLINE int 664ipf_checkv6sum(fin) 665 fr_info_t *fin; 666{ 667 if (fin->fin_flx & FI_SHORT) 668 return 1; 669 670 if (ipf_checkl4sum(fin) == -1) { 671 fin->fin_flx |= FI_BAD; 672 return -1; 673 } 674 return 0; 675} 676#endif 677 678 679#if 0 680/* 681 * See above for description, except that all addressing is in user space. 682 */ 683int 684copyoutptr(softc, src, dst, size) 685 void *src, *dst; 686 size_t size; 687{ 688 caddr_t ca; 689 690 bcopy(dst, (char *)&ca, sizeof(ca)); 691 bcopy(src, ca, size); 692 return 0; 693} 694 695 696/* 697 * See above for description, except that all addressing is in user space. 698 */ 699int 700copyinptr(src, dst, size) 701 void *src, *dst; 702 size_t size; 703{ 704 caddr_t ca; 705 706 bcopy(src, (char *)&ca, sizeof(ca)); 707 bcopy(ca, dst, size); 708 return 0; 709} 710#endif 711 712 713/* 714 * return the first IP Address associated with an interface 715 */ 716int 717ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask) 718 ipf_main_softc_t *softc; 719 int v, atype; 720 void *ifptr; 721 i6addr_t *inp, *inpmask; 722{ 723 struct ifnet *ifp = ifptr; 724#ifdef __sgi 725 struct in_ifaddr *ifa; 726#else 727 struct ifaddr *ifa; 728#endif 729 730#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 731 ifa = ifp->if_addrlist.tqh_first; 732#else 733# ifdef __sgi 734 ifa = (struct in_ifaddr *)ifp->in_ifaddr; 735# else 736 ifa = ifp->if_addrlist; 737# endif 738#endif 739 if (ifa != NULL) { 740 if (v == 4) { 741 struct sockaddr_in *sin, mask; 742 743 mask.sin_addr.s_addr = 0xffffffff; 744 745#ifdef __sgi 746 sin = (struct sockaddr_in *)&ifa->ia_addr; 747#else 748 sin = (struct sockaddr_in *)&ifa->ifa_addr; 749#endif 750 751 return ipf_ifpfillv4addr(atype, sin, &mask, 752 &inp->in4, &inpmask->in4); 753 } 754#ifdef USE_INET6 755 if (v == 6) { 756 struct sockaddr_in6 *sin6, mask; 757 758 sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; 759 ((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff; 760 ((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff; 761 ((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff; 762 ((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff; 763 return ipf_ifpfillv6addr(atype, sin6, &mask, 764 inp, inpmask); 765 } 766#endif 767 } 768 return 0; 769} 770 771 772/* 773 * This function is not meant to be random, rather just produce a 774 * sequence of numbers that isn't linear to show "randomness". 775 */ 776u_32_t 777ipf_random() 778{ 779 static unsigned int last = 0xa5a5a5a5; 780 static int calls = 0; 781 int number; 782 783 calls++; 784 785 /* 786 * These are deliberately chosen to ensure that there is some 787 * attempt to test whether the output covers the range in test n18. 788 */ 789 switch (calls) 790 { 791 case 1 : 792 number = 0; 793 break; 794 case 2 : 795 number = 4; 796 break; 797 case 3 : 798 number = 3999; 799 break; 800 case 4 : 801 number = 4000; 802 break; 803 case 5 : 804 number = 48999; 805 break; 806 case 6 : 807 number = 49000; 808 break; 809 default : 810 number = last; 811 last *= calls; 812 last++; 813 number ^= last; 814 break; 815 } 816 return number; 817} 818 819 820int 821ipf_verifysrc(fin) 822 fr_info_t *fin; 823{ 824 return 1; 825} 826 827 828int 829ipf_inject(fin, m) 830 fr_info_t *fin; 831 mb_t *m; 832{ 833 FREE_MB_T(m); 834 835 return 0; 836} 837 838 839u_int 840ipf_pcksum(fin, hlen, sum) 841 fr_info_t *fin; 842 int hlen; 843 u_int sum; 844{ 845 u_short *sp; 846 u_int sum2; 847 int slen; 848 849 slen = fin->fin_plen - hlen; 850 sp = (u_short *)((u_char *)fin->fin_ip + hlen); 851 852 for (; slen > 1; slen -= 2) 853 sum += *sp++; 854 if (slen) 855 sum += ntohs(*(u_char *)sp << 8); 856 while (sum > 0xffff) 857 sum = (sum & 0xffff) + (sum >> 16); 858 sum2 = (u_short)(~sum & 0xffff); 859 860 return sum2; 861} 862 863 864void * 865ipf_pullup(m, fin, plen) 866 mb_t *m; 867 fr_info_t *fin; 868 int plen; 869{ 870 if (M_LEN(m) >= plen) 871 return fin->fin_ip; 872 873 /* 874 * Fake ipf_pullup failing 875 */ 876 fin->fin_reason = FRB_PULLUP; 877 *fin->fin_mp = NULL; 878 fin->fin_m = NULL; 879 fin->fin_ip = NULL; 880 return NULL; 881} 882