ip_fil.c revision 341804
1/* $FreeBSD: stable/10/contrib/ipfilter/ip_fil.c 341804 2018-12-11 01:49:06Z 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 (*ifp->if_output)(ifp, (void *)m, NULL, 0); 483done: 484 fin->fin_ifp = sifp; 485 fin->fin_out = sout; 486 return error; 487} 488 489 490int 491ipf_send_reset(fin) 492 fr_info_t *fin; 493{ 494 ipfkverbose("- TCP RST sent\n"); 495 return 0; 496} 497 498 499int 500ipf_send_icmp_err(type, fin, dst) 501 int type; 502 fr_info_t *fin; 503 int dst; 504{ 505 ipfkverbose("- ICMP unreachable sent\n"); 506 return 0; 507} 508 509 510void 511m_freem(m) 512 mb_t *m; 513{ 514 return; 515} 516 517 518void 519m_copydata(m, off, len, cp) 520 mb_t *m; 521 int off, len; 522 caddr_t cp; 523{ 524 bcopy((char *)m + off, cp, len); 525} 526 527 528int 529ipfuiomove(buf, len, rwflag, uio) 530 caddr_t buf; 531 int len, rwflag; 532 struct uio *uio; 533{ 534 int left, ioc, num, offset; 535 struct iovec *io; 536 char *start; 537 538 if (rwflag == UIO_READ) { 539 left = len; 540 ioc = 0; 541 542 offset = uio->uio_offset; 543 544 while ((left > 0) && (ioc < uio->uio_iovcnt)) { 545 io = uio->uio_iov + ioc; 546 num = io->iov_len; 547 if (num > left) 548 num = left; 549 start = (char *)io->iov_base + offset; 550 if (start > (char *)io->iov_base + io->iov_len) { 551 offset -= io->iov_len; 552 ioc++; 553 continue; 554 } 555 bcopy(buf, start, num); 556 uio->uio_resid -= num; 557 uio->uio_offset += num; 558 left -= num; 559 if (left > 0) 560 ioc++; 561 } 562 if (left > 0) 563 return EFAULT; 564 } 565 return 0; 566} 567 568 569u_32_t 570ipf_newisn(fin) 571 fr_info_t *fin; 572{ 573 static int iss_seq_off = 0; 574 u_char hash[16]; 575 u_32_t newiss; 576 MD5_CTX ctx; 577 578 /* 579 * Compute the base value of the ISS. It is a hash 580 * of (saddr, sport, daddr, dport, secret). 581 */ 582 MD5Init(&ctx); 583 584 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 585 sizeof(fin->fin_fi.fi_src)); 586 MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 587 sizeof(fin->fin_fi.fi_dst)); 588 MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 589 590 /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 591 592 MD5Final(hash, &ctx); 593 594 memcpy(&newiss, hash, sizeof(newiss)); 595 596 /* 597 * Now increment our "timer", and add it in to 598 * the computed value. 599 * 600 * XXX Use `addin'? 601 * XXX TCP_ISSINCR too large to use? 602 */ 603 iss_seq_off += 0x00010000; 604 newiss += iss_seq_off; 605 return newiss; 606} 607 608 609/* ------------------------------------------------------------------------ */ 610/* Function: ipf_nextipid */ 611/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 612/* Parameters: fin(I) - pointer to packet information */ 613/* */ 614/* Returns the next IPv4 ID to use for this packet. */ 615/* ------------------------------------------------------------------------ */ 616INLINE u_short 617ipf_nextipid(fin) 618 fr_info_t *fin; 619{ 620 static u_short ipid = 0; 621 ipf_main_softc_t *softc = fin->fin_main_soft; 622 u_short id; 623 624 MUTEX_ENTER(&softc->ipf_rw); 625 if (fin->fin_pktnum != 0) { 626 /* 627 * The -1 is for aligned test results. 628 */ 629 id = (fin->fin_pktnum - 1) & 0xffff; 630 } else { 631 } 632 id = ipid++; 633 MUTEX_EXIT(&softc->ipf_rw); 634 635 return id; 636} 637 638 639INLINE int 640ipf_checkv4sum(fin) 641 fr_info_t *fin; 642{ 643 644 if (fin->fin_flx & FI_SHORT) 645 return 1; 646 647 if (ipf_checkl4sum(fin) == -1) { 648 fin->fin_flx |= FI_BAD; 649 return -1; 650 } 651 return 0; 652} 653 654 655#ifdef USE_INET6 656INLINE int 657ipf_checkv6sum(fin) 658 fr_info_t *fin; 659{ 660 if (fin->fin_flx & FI_SHORT) 661 return 1; 662 663 if (ipf_checkl4sum(fin) == -1) { 664 fin->fin_flx |= FI_BAD; 665 return -1; 666 } 667 return 0; 668} 669#endif 670 671 672#if 0 673/* 674 * See above for description, except that all addressing is in user space. 675 */ 676int 677copyoutptr(softc, src, dst, size) 678 void *src, *dst; 679 size_t size; 680{ 681 caddr_t ca; 682 683 bcopy(dst, (char *)&ca, sizeof(ca)); 684 bcopy(src, ca, size); 685 return 0; 686} 687 688 689/* 690 * See above for description, except that all addressing is in user space. 691 */ 692int 693copyinptr(src, dst, size) 694 void *src, *dst; 695 size_t size; 696{ 697 caddr_t ca; 698 699 bcopy(src, (char *)&ca, sizeof(ca)); 700 bcopy(ca, dst, size); 701 return 0; 702} 703#endif 704 705 706/* 707 * return the first IP Address associated with an interface 708 */ 709int 710ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask) 711 ipf_main_softc_t *softc; 712 int v, atype; 713 void *ifptr; 714 i6addr_t *inp, *inpmask; 715{ 716 struct ifnet *ifp = ifptr; 717#ifdef __sgi 718 struct in_ifaddr *ifa; 719#else 720 struct ifaddr *ifa; 721#endif 722 723#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 724 ifa = ifp->if_addrlist.tqh_first; 725#else 726# ifdef __sgi 727 ifa = (struct in_ifaddr *)ifp->in_ifaddr; 728# else 729 ifa = ifp->if_addrlist; 730# endif 731#endif 732 if (ifa != NULL) { 733 if (v == 4) { 734 struct sockaddr_in *sin, mask; 735 736 mask.sin_addr.s_addr = 0xffffffff; 737 738#ifdef __sgi 739 sin = (struct sockaddr_in *)&ifa->ia_addr; 740#else 741 sin = (struct sockaddr_in *)&ifa->ifa_addr; 742#endif 743 744 return ipf_ifpfillv4addr(atype, sin, &mask, 745 &inp->in4, &inpmask->in4); 746 } 747#ifdef USE_INET6 748 if (v == 6) { 749 struct sockaddr_in6 *sin6, mask; 750 751 sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; 752 ((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff; 753 ((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff; 754 ((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff; 755 ((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff; 756 return ipf_ifpfillv6addr(atype, sin6, &mask, 757 inp, inpmask); 758 } 759#endif 760 } 761 return 0; 762} 763 764 765/* 766 * This function is not meant to be random, rather just produce a 767 * sequence of numbers that isn't linear to show "randomness". 768 */ 769u_32_t 770ipf_random() 771{ 772 static unsigned int last = 0xa5a5a5a5; 773 static int calls = 0; 774 int number; 775 776 calls++; 777 778 /* 779 * These are deliberately chosen to ensure that there is some 780 * attempt to test whether the output covers the range in test n18. 781 */ 782 switch (calls) 783 { 784 case 1 : 785 number = 0; 786 break; 787 case 2 : 788 number = 4; 789 break; 790 case 3 : 791 number = 3999; 792 break; 793 case 4 : 794 number = 4000; 795 break; 796 case 5 : 797 number = 48999; 798 break; 799 case 6 : 800 number = 49000; 801 break; 802 default : 803 number = last; 804 last *= calls; 805 last++; 806 number ^= last; 807 break; 808 } 809 return number; 810} 811 812 813int 814ipf_verifysrc(fin) 815 fr_info_t *fin; 816{ 817 return 1; 818} 819 820 821int 822ipf_inject(fin, m) 823 fr_info_t *fin; 824 mb_t *m; 825{ 826 FREE_MB_T(m); 827 828 return 0; 829} 830 831 832u_int 833ipf_pcksum(fin, hlen, sum) 834 fr_info_t *fin; 835 int hlen; 836 u_int sum; 837{ 838 u_short *sp; 839 u_int sum2; 840 int slen; 841 842 slen = fin->fin_plen - hlen; 843 sp = (u_short *)((u_char *)fin->fin_ip + hlen); 844 845 for (; slen > 1; slen -= 2) 846 sum += *sp++; 847 if (slen) 848 sum += ntohs(*(u_char *)sp << 8); 849 while (sum > 0xffff) 850 sum = (sum & 0xffff) + (sum >> 16); 851 sum2 = (u_short)(~sum & 0xffff); 852 853 return sum2; 854} 855 856 857void * 858ipf_pullup(m, fin, plen) 859 mb_t *m; 860 fr_info_t *fin; 861 int plen; 862{ 863 if (M_LEN(m) >= plen) 864 return fin->fin_ip; 865 866 /* 867 * Fake ipf_pullup failing 868 */ 869 fin->fin_reason = FRB_PULLUP; 870 *fin->fin_mp = NULL; 871 fin->fin_m = NULL; 872 fin->fin_ip = NULL; 873 return NULL; 874} 875