ip_fil.c revision 255332
1/* $FreeBSD: head/contrib/ipfilter/ip_fil.c 255332 2013-09-06 23:11:19Z 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 inet_pton(AF_INET6, addr, &sin6->sin6_addr); 232 } else 233#endif 234 { 235 sin->sin_family = AF_INET; 236 sin->sin_addr.s_addr = inet_addr(addr); 237 if (sin->sin_addr.s_addr == 0) 238 abort(); 239 } 240 } 241} 242 243struct ifnet * 244get_unit(name, family) 245 char *name; 246 int family; 247{ 248 struct ifnet *ifp, **ifpp, **old_ifneta; 249 char *addr; 250#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 251 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 252 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 253 254 if (!*name) 255 return NULL; 256 257 if (name == NULL) 258 name = "anon0"; 259 260 addr = strchr(name, '='); 261 if (addr != NULL) 262 *addr++ = '\0'; 263 264 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 265 if (!strcmp(name, ifp->if_xname)) { 266 if (addr != NULL) 267 ipf_setifpaddr(ifp, addr); 268 return ifp; 269 } 270 } 271#else 272 char *s, ifname[LIFNAMSIZ+1]; 273 274 if (name == NULL) 275 name = "anon0"; 276 277 addr = strchr(name, '='); 278 if (addr != NULL) 279 *addr++ = '\0'; 280 281 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 282 COPYIFNAME(family, ifp, ifname); 283 if (!strcmp(name, ifname)) { 284 if (addr != NULL) 285 ipf_setifpaddr(ifp, addr); 286 return ifp; 287 } 288 } 289#endif 290 291 if (!ifneta) { 292 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 293 if (!ifneta) 294 return NULL; 295 ifneta[1] = NULL; 296 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 297 if (!ifneta[0]) { 298 free(ifneta); 299 return NULL; 300 } 301 nifs = 1; 302 } else { 303 old_ifneta = ifneta; 304 nifs++; 305 ifneta = (struct ifnet **)realloc(ifneta, 306 (nifs + 1) * sizeof(ifp)); 307 if (!ifneta) { 308 free(old_ifneta); 309 nifs = 0; 310 return NULL; 311 } 312 ifneta[nifs] = NULL; 313 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 314 if (!ifneta[nifs - 1]) { 315 nifs--; 316 return NULL; 317 } 318 } 319 ifp = ifneta[nifs - 1]; 320 321#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 322 TAILQ_INIT(&ifp->if_addrlist); 323#endif 324#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 325 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 326 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 327 (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 328#else 329 s = name + strlen(name) - 1; 330 for (; s > name; s--) { 331 if (!ISDIGIT(*s)) { 332 s++; 333 break; 334 } 335 } 336 337 if ((s > name) && (*s != 0) && ISDIGIT(*s)) { 338 ifp->if_unit = atoi(s); 339 ifp->if_name = (char *)malloc(s - name + 1); 340 (void) strncpy(ifp->if_name, name, s - name); 341 ifp->if_name[s - name] = '\0'; 342 } else { 343 ifp->if_name = strdup(name); 344 ifp->if_unit = -1; 345 } 346#endif 347 ifp->if_output = (void *)no_output; 348 349 if (addr != NULL) { 350 ipf_setifpaddr(ifp, addr); 351 } 352 353 return ifp; 354} 355 356 357char * 358get_ifname(ifp) 359 struct ifnet *ifp; 360{ 361 static char ifname[LIFNAMSIZ]; 362 363#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \ 364 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 365 sprintf(ifname, "%s", ifp->if_xname); 366#else 367 if (ifp->if_unit != -1) 368 sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 369 else 370 strcpy(ifname, ifp->if_name); 371#endif 372 return ifname; 373} 374 375 376 377void 378init_ifp() 379{ 380 struct ifnet *ifp, **ifpp; 381 char fname[32]; 382 int fd; 383 384#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 385 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 386 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 387 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 388 ifp->if_output = (void *)write_output; 389 sprintf(fname, "/tmp/%s", ifp->if_xname); 390 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 391 if (fd == -1) 392 perror("open"); 393 else 394 close(fd); 395 } 396#else 397 398 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 399 ifp->if_output = (void *)write_output; 400 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 401 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 402 if (fd == -1) 403 perror("open"); 404 else 405 close(fd); 406 } 407#endif 408} 409 410 411int 412ipf_fastroute(m, mpp, fin, fdp) 413 mb_t *m, **mpp; 414 fr_info_t *fin; 415 frdest_t *fdp; 416{ 417 struct ifnet *ifp; 418 ip_t *ip = fin->fin_ip; 419 frdest_t node; 420 int error = 0; 421 frentry_t *fr; 422 void *sifp; 423 int sout; 424 425 sifp = fin->fin_ifp; 426 sout = fin->fin_out; 427 fr = fin->fin_fr; 428 ip->ip_sum = 0; 429 430 if (!(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) && 431 (fdp->fd_type == FRD_DSTLIST)) { 432 bzero(&node, sizeof(node)); 433 ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, &node); 434 fdp = &node; 435 } 436 ifp = fdp->fd_ptr; 437 438 if (ifp == NULL) 439 return 0; /* no routing table out here */ 440 441 if (fin->fin_out == 0) { 442 fin->fin_ifp = ifp; 443 fin->fin_out = 1; 444 (void) ipf_acctpkt(fin, NULL); 445 fin->fin_fr = NULL; 446 if (!fr || !(fr->fr_flags & FR_RETMASK)) { 447 u_32_t pass; 448 449 (void) ipf_state_check(fin, &pass); 450 } 451 452 switch (ipf_nat_checkout(fin, NULL)) 453 { 454 case 0 : 455 break; 456 case 1 : 457 ip->ip_sum = 0; 458 break; 459 case -1 : 460 error = -1; 461 goto done; 462 break; 463 } 464 465 } 466 467 m->mb_ifp = ifp; 468 printpacket(fin->fin_out, m); 469 470#if defined(__sgi) && (IRIX < 60500) 471 (*ifp->if_output)(ifp, (void *)ip, NULL); 472# if TRU64 >= 1885 473 (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 474# else 475 (*ifp->if_output)(ifp, (void *)m, NULL, 0); 476# endif 477#endif 478done: 479 fin->fin_ifp = sifp; 480 fin->fin_out = sout; 481 return error; 482} 483 484 485int 486ipf_send_reset(fin) 487 fr_info_t *fin; 488{ 489 ipfkverbose("- TCP RST sent\n"); 490 return 0; 491} 492 493 494int 495ipf_send_icmp_err(type, fin, dst) 496 int type; 497 fr_info_t *fin; 498 int dst; 499{ 500 ipfkverbose("- ICMP unreachable sent\n"); 501 return 0; 502} 503 504 505void 506m_freem(m) 507 mb_t *m; 508{ 509 return; 510} 511 512 513void 514m_copydata(m, off, len, cp) 515 mb_t *m; 516 int off, len; 517 caddr_t cp; 518{ 519 bcopy((char *)m + off, cp, len); 520} 521 522 523int 524ipfuiomove(buf, len, rwflag, uio) 525 caddr_t buf; 526 int len, rwflag; 527 struct uio *uio; 528{ 529 int left, ioc, num, offset; 530 struct iovec *io; 531 char *start; 532 533 if (rwflag == UIO_READ) { 534 left = len; 535 ioc = 0; 536 537 offset = uio->uio_offset; 538 539 while ((left > 0) && (ioc < uio->uio_iovcnt)) { 540 io = uio->uio_iov + ioc; 541 num = io->iov_len; 542 if (num > left) 543 num = left; 544 start = (char *)io->iov_base + offset; 545 if (start > (char *)io->iov_base + io->iov_len) { 546 offset -= io->iov_len; 547 ioc++; 548 continue; 549 } 550 bcopy(buf, start, num); 551 uio->uio_resid -= num; 552 uio->uio_offset += num; 553 left -= num; 554 if (left > 0) 555 ioc++; 556 } 557 if (left > 0) 558 return EFAULT; 559 } 560 return 0; 561} 562 563 564u_32_t 565ipf_newisn(fin) 566 fr_info_t *fin; 567{ 568 static int iss_seq_off = 0; 569 u_char hash[16]; 570 u_32_t newiss; 571 MD5_CTX ctx; 572 573 /* 574 * Compute the base value of the ISS. It is a hash 575 * of (saddr, sport, daddr, dport, secret). 576 */ 577 MD5Init(&ctx); 578 579 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 580 sizeof(fin->fin_fi.fi_src)); 581 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 582 sizeof(fin->fin_fi.fi_dst)); 583 MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 584 585 /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 586 587 MD5Final(hash, &ctx); 588 589 memcpy(&newiss, hash, sizeof(newiss)); 590 591 /* 592 * Now increment our "timer", and add it in to 593 * the computed value. 594 * 595 * XXX Use `addin'? 596 * XXX TCP_ISSINCR too large to use? 597 */ 598 iss_seq_off += 0x00010000; 599 newiss += iss_seq_off; 600 return newiss; 601} 602 603 604/* ------------------------------------------------------------------------ */ 605/* Function: ipf_nextipid */ 606/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 607/* Parameters: fin(I) - pointer to packet information */ 608/* */ 609/* Returns the next IPv4 ID to use for this packet. */ 610/* ------------------------------------------------------------------------ */ 611INLINE u_short 612ipf_nextipid(fin) 613 fr_info_t *fin; 614{ 615 static u_short ipid = 0; 616 ipf_main_softc_t *softc = fin->fin_main_soft; 617 u_short id; 618 619 MUTEX_ENTER(&softc->ipf_rw); 620 if (fin->fin_pktnum != 0) { 621 /* 622 * The -1 is for aligned test results. 623 */ 624 id = (fin->fin_pktnum - 1) & 0xffff; 625 } else { 626 } 627 id = ipid++; 628 MUTEX_EXIT(&softc->ipf_rw); 629 630 return id; 631} 632 633 634INLINE int 635ipf_checkv4sum(fin) 636 fr_info_t *fin; 637{ 638 639 if (fin->fin_flx & FI_SHORT) 640 return 1; 641 642 if (ipf_checkl4sum(fin) == -1) { 643 fin->fin_flx |= FI_BAD; 644 return -1; 645 } 646 return 0; 647} 648 649 650#ifdef USE_INET6 651INLINE int 652ipf_checkv6sum(fin) 653 fr_info_t *fin; 654{ 655 if (fin->fin_flx & FI_SHORT) 656 return 1; 657 658 if (ipf_checkl4sum(fin) == -1) { 659 fin->fin_flx |= FI_BAD; 660 return -1; 661 } 662 return 0; 663} 664#endif 665 666 667#if 0 668/* 669 * See above for description, except that all addressing is in user space. 670 */ 671int 672copyoutptr(softc, src, dst, size) 673 void *src, *dst; 674 size_t size; 675{ 676 caddr_t ca; 677 678 bcopy(dst, (char *)&ca, sizeof(ca)); 679 bcopy(src, ca, size); 680 return 0; 681} 682 683 684/* 685 * See above for description, except that all addressing is in user space. 686 */ 687int 688copyinptr(src, dst, size) 689 void *src, *dst; 690 size_t size; 691{ 692 caddr_t ca; 693 694 bcopy(src, (char *)&ca, sizeof(ca)); 695 bcopy(ca, dst, size); 696 return 0; 697} 698#endif 699 700 701/* 702 * return the first IP Address associated with an interface 703 */ 704int 705ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask) 706 ipf_main_softc_t *softc; 707 int v, atype; 708 void *ifptr; 709 i6addr_t *inp, *inpmask; 710{ 711 struct ifnet *ifp = ifptr; 712#ifdef __sgi 713 struct in_ifaddr *ifa; 714#else 715 struct ifaddr *ifa; 716#endif 717 718#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 719 ifa = ifp->if_addrlist.tqh_first; 720#else 721# ifdef __sgi 722 ifa = (struct in_ifaddr *)ifp->in_ifaddr; 723# else 724 ifa = ifp->if_addrlist; 725# endif 726#endif 727 if (ifa != NULL) { 728 if (v == 4) { 729 struct sockaddr_in *sin, mask; 730 731 mask.sin_addr.s_addr = 0xffffffff; 732 733#ifdef __sgi 734 sin = (struct sockaddr_in *)&ifa->ia_addr; 735#else 736 sin = (struct sockaddr_in *)&ifa->ifa_addr; 737#endif 738 739 return ipf_ifpfillv4addr(atype, sin, &mask, 740 &inp->in4, &inpmask->in4); 741 } 742#ifdef USE_INET6 743 if (v == 6) { 744 struct sockaddr_in6 *sin6, mask; 745 746 sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; 747 ((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff; 748 ((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff; 749 ((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff; 750 ((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff; 751 return ipf_ifpfillv6addr(atype, sin6, &mask, 752 inp, inpmask); 753 } 754#endif 755 } 756 return 0; 757} 758 759 760/* 761 * This function is not meant to be random, rather just produce a 762 * sequence of numbers that isn't linear to show "randomness". 763 */ 764u_32_t 765ipf_random() 766{ 767 static unsigned int last = 0xa5a5a5a5; 768 static int calls = 0; 769 int number; 770 771 calls++; 772 773 /* 774 * These are deliberately chosen to ensure that there is some 775 * attempt to test whether the output covers the range in test n18. 776 */ 777 switch (calls) 778 { 779 case 1 : 780 number = 0; 781 break; 782 case 2 : 783 number = 4; 784 break; 785 case 3 : 786 number = 3999; 787 break; 788 case 4 : 789 number = 4000; 790 break; 791 case 5 : 792 number = 48999; 793 break; 794 case 6 : 795 number = 49000; 796 break; 797 default : 798 number = last; 799 last *= calls; 800 last++; 801 number ^= last; 802 break; 803 } 804 return number; 805} 806 807 808int 809ipf_verifysrc(fin) 810 fr_info_t *fin; 811{ 812 return 1; 813} 814 815 816int 817ipf_inject(fin, m) 818 fr_info_t *fin; 819 mb_t *m; 820{ 821 FREE_MB_T(m); 822 823 return 0; 824} 825 826 827u_int 828ipf_pcksum(fin, hlen, sum) 829 fr_info_t *fin; 830 int hlen; 831 u_int sum; 832{ 833 u_short *sp; 834 u_int sum2; 835 int slen; 836 837 slen = fin->fin_plen - hlen; 838 sp = (u_short *)((u_char *)fin->fin_ip + hlen); 839 840 for (; slen > 1; slen -= 2) 841 sum += *sp++; 842 if (slen) 843 sum += ntohs(*(u_char *)sp << 8); 844 while (sum > 0xffff) 845 sum = (sum & 0xffff) + (sum >> 16); 846 sum2 = (u_short)(~sum & 0xffff); 847 848 return sum2; 849} 850 851 852void * 853ipf_pullup(m, fin, plen) 854 mb_t *m; 855 fr_info_t *fin; 856 int plen; 857{ 858 if (M_LEN(m) >= plen) 859 return fin->fin_ip; 860 861 /* 862 * Fake ipf_pullup failing 863 */ 864 fin->fin_reason = FRB_PULLUP; 865 *fin->fin_mp = NULL; 866 fin->fin_m = NULL; 867 fin->fin_ip = NULL; 868 return NULL; 869} 870