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