Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | /* * Copyright (c) 2000-2025 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _NETINET6_ND6_H_ #define _NETINET6_ND6_H_ #include <sys/appleapiopts.h> #include <sys/types.h> #include <netinet/in.h> #ifndef BSD_KERNEL_PRIVATE #include <netinet6/in6_var.h> #endif #include <net/net_kev.h> /* see net/route.h, or net/if_inarp.h */ #ifndef RTF_ANNOUNCE #define RTF_ANNOUNCE RTF_PROTO2 #endif #include <sys/queue.h> #ifdef BSD_KERNEL_PRIVATE #include <net/flowadv.h> #include <kern/locks.h> #include <sys/tree.h> #include <sys/eventhandler.h> #include <netinet6/nd6_var.h> #include <sys/sdt.h> #include <net/if_var.h> struct llinfo_nd6 { /* * The following are protected by rnh_lock */ struct llinfo_nd6 *ln_next; struct llinfo_nd6 *ln_prev; struct rtentry *ln_rt; /* * The following are protected by rt_lock */ struct ifnet *ln_exclifp; /* excluded interface (prefix proxy) */ struct mbuf *ln_hold; /* last packet until resolved/timeout */ uint32_t ln_asked; /* # of queries already sent for this addr */ short ln_state; /* reachability state */ short ln_router; /* 2^0: ND6 router bit */ u_int32_t ln_flags; /* flags; see below */ u_int64_t ln_expire; /* lifetime for NDP state transition */ u_int64_t ln_lastused; /* last used timestamp */ struct if_llreach *ln_llreach; /* link-layer reachability record */ }; /* Values for ln_flags */ #define ND6_LNF_TIMER_SKIP 0x1 /* modified by nd6_timer() */ #define ND6_LNF_IN_USE 0x2 /* currently in llinfo_nd6 list */ #endif /* BSD_KERNEL_PRIVATE */ #define ND6_LLINFO_PURGE -3 #define ND6_LLINFO_NOSTATE -2 /* * We don't need the WAITDELETE state any more, but we keep the definition * in a comment line instead of removing it. This is necessary to avoid * unintentionally reusing the value for another purpose, which might * affect backward compatibility with old applications. * (20000711 jinmei@kame.net) */ /* #define ND6_LLINFO_WAITDELETE -1 */ #define ND6_LLINFO_INCOMPLETE 0 #define ND6_LLINFO_REACHABLE 1 #define ND6_LLINFO_STALE 2 #define ND6_LLINFO_DELAY 3 #define ND6_LLINFO_PROBE 4 #ifdef BSD_KERNEL_PRIVATE #define ND6_CACHE_STATE_TRANSITION(ln, nstate) do {\ DTRACE_IP2(nd6_state_transition, struct llinfo_nd6 *, (ln), int, (nstate));\ if (nd6_debug >= 3) {\ struct rtentry *ln_rt = (ln) != NULL ? (ln)->ln_rt : NULL; \ nd6log3(info,\ "[%s:%d]: NDP cache entry changed from %s -> %s for address %s.\n",\ __func__,\ __LINE__,\ ndcache_state2str((ln)->ln_state),\ ndcache_state2str((nstate)),\ ln_rt != NULL ? ip6_sprintf(&SIN6(rt_key(ln_rt))->sin6_addr) : "N/A");\ }\ if ((ln) != NULL) {\ if ((ln)->ln_rt != NULL && (ln)->ln_rt->rt_ifp != NULL &&\ ((ln)->ln_rt->rt_ifp->if_eflags & IFEF_IPV6_ND6ALT) &&\ ((ln)->ln_state == ND6_LLINFO_REACHABLE)) {\ VERIFY((nstate) != ND6_LLINFO_STALE &&\ (nstate) != ND6_LLINFO_DELAY &&\ (nstate) != ND6_LLINFO_PROBE);\ }\ (ln)->ln_state = (nstate);\ }\ } while(0) #define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE) #define ND6_LLINFO_PERMANENT(n) \ (((n)->ln_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE)) #define ND6_EUI64_GBIT 0x01 #define ND6_EUI64_UBIT 0x02 #define ND6_EUI64_TO_IFID(in6) \ do {(in6)->s6_addr[8] ^= ND6_EUI64_UBIT; } while (0) #define ND6_EUI64_GROUP(in6) ((in6)->s6_addr[8] & ND6_EUI64_GBIT) #define ND6_EUI64_INDIVIDUAL(in6) (!ND6_EUI64_GROUP(in6)) #define ND6_EUI64_LOCAL(in6) ((in6)->s6_addr[8] & ND6_EUI64_UBIT) #define ND6_EUI64_UNIVERSAL(in6) (!ND6_EUI64_LOCAL(in6)) #define ND6_IFID_LOCAL(in6) (!ND6_EUI64_LOCAL(in6)) #define ND6_IFID_UNIVERSAL(in6) (!ND6_EUI64_UNIVERSAL(in6)) #endif /* BSD_KERNEL_PRIVATE */ #if !defined(BSD_KERNEL_PRIVATE) struct nd_ifinfo { #else /* For binary compatibility, this structure must not change */ /* NOTE: nd_ifinfo is defined in nd6_var.h */ struct nd_ifinfo_compat { #endif /* !BSD_KERNEL_PRIVATE */ u_int32_t linkmtu; /* LinkMTU */ u_int32_t maxmtu; /* Upper bound of LinkMTU */ u_int32_t basereachable; /* BaseReachableTime */ u_int32_t reachable; /* Reachable Time */ u_int32_t retrans; /* Retrans Timer */ u_int32_t flags; /* Flags */ int recalctm; /* BaseReacable re-calculation timer */ u_int8_t chlim; /* CurHopLimit */ u_int8_t receivedra; /* the following 3 members are for privacy extension for addrconf */ u_int8_t randomseed0[8]; /* upper 64 bits of SHA256 digest */ u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */ u_int8_t randomid[8]; /* current random ID */ }; #define ND6_IFF_PERFORMNUD 0x1 #if defined(PRIVATE) /* * APPLE: not used. Interface specific router advertisements are handled with a * specific ifnet flag: IFEF_ACCEPT_RTADVD */ #define ND6_IFF_ACCEPT_RTADV 0x2 /* APPLE: NOT USED not related to ND. */ #define ND6_IFF_PREFER_SOURCE 0x4 /* IPv6 operation is disabled due to * DAD failure. (XXX: not ND-specific) */ #define ND6_IFF_IFDISABLED 0x8 #define ND6_IFF_DONT_SET_IFROUTE 0x10 /* NOT USED */ #endif /* PRIVATE */ #define ND6_IFF_PROXY_PREFIXES 0x20 #define ND6_IFF_IGNORE_NA 0x40 #if defined(PRIVATE) #define ND6_IFF_INSECURE 0x80 #endif #define ND6_IFF_REPLICATED 0x100 /* sleep proxy registered */ #define ND6_IFF_DAD 0x200 /* Perform DAD on the interface */ extern int dad_enhanced; #define ND6_DAD_ENHANCED_DEFAULT 1 struct in6_nbrinfo { char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ struct in6_addr addr; /* IPv6 address of the neighbor */ long asked; /* # of queries already sent for this addr */ int isrouter; /* if it acts as a router */ int state; /* reachability state */ int expire; /* lifetime for NDP state transition */ }; #if defined(BSD_KERNEL_PRIVATE) struct in6_nbrinfo_32 { char ifname[IFNAMSIZ]; struct in6_addr addr; u_int32_t asked; int isrouter; int state; int expire; }; struct in6_nbrinfo_64 { char ifname[IFNAMSIZ]; struct in6_addr addr; long asked; int isrouter __attribute__((aligned(8))); int state; int expire; } __attribute__((aligned(8))); #endif /* BSD_KERNEL_PRIVATE */ #if defined(BSD_KERNEL_PRIVATE) #define ND6_PROCESS_RTI_ENABLE 1 #define ND6_PROCESS_RTI_DISABLE 0 #define ND6_PROCESS_RTI_DEFAULT ND6_PROCESS_RTI_ENABLE extern int nd6_process_rti; #endif /* BSD_KERNEL_PRIVATE */ /* valid values for stateflags */ #define NDDRF_INSTALLED 0x01 /* installed in the routing table */ #define NDDRF_IFSCOPE 0x02 /* installed as a scoped route */ #define NDDRF_STATIC 0x04 /* for internal use only */ #define NDDRF_MAPPED 0x08 /* Default router addr is mapped to a different one for routing */ #define NDDRF_INELIGIBLE 0x10 /* Default router entry is ineligible for default router selection */ #define NDDRF_LOCAL 0x20 /* Router's address is locally hosted as well */ struct in6_defrouter { struct sockaddr_in6 rtaddr; u_char flags; u_char stateflags; u_short rtlifetime; u_long expire; u_short if_index; }; #if defined(BSD_KERNEL_PRIVATE) struct in6_defrouter_32 { struct sockaddr_in6 rtaddr; u_char flags; u_char stateflags; u_short rtlifetime; u_int32_t expire; u_short if_index; }; struct in6_defrouter_64 { struct sockaddr_in6 rtaddr; u_char flags; u_char stateflags; u_short rtlifetime; u_long expire __attribute__((aligned(8))); u_short if_index __attribute__((aligned(8))); } __attribute__((aligned(8))); #endif /* BSD_KERNEL_PRIVATE */ struct in6_prefix { struct sockaddr_in6 prefix; struct prf_ra raflags; u_char prefixlen; u_char origin; u_long vltime; u_long pltime; u_long expire; u_int32_t flags; int refcnt; u_short if_index; u_short advrtrs; /* number of advertisement routers */ /* struct sockaddr_in6 advrtr[] */ }; #if defined(BSD_KERNEL_PRIVATE) struct in6_prefix_32 { struct sockaddr_in6 prefix; struct prf_ra raflags; u_char prefixlen; u_char origin; u_int32_t vltime; u_int32_t pltime; u_int32_t expire; u_int32_t flags; int refcnt; u_short if_index; u_short advrtrs; /* number of advertisement routers */ /* struct sockaddr_in6 advrtr[] */ }; struct in6_prefix_64 { struct sockaddr_in6 prefix; struct prf_ra raflags; u_char prefixlen; u_char origin; u_long vltime __attribute__((aligned(8))); u_long pltime __attribute__((aligned(8))); u_long expire __attribute__((aligned(8))); u_int32_t flags __attribute__((aligned(8))); int refcnt; u_short if_index; u_short advrtrs; /* struct sockaddr_in6 advrtr[] */ }; #endif /* BSD_KERNEL_PRIVATE */ struct in6_ondireq { char ifname[IFNAMSIZ]; struct { u_int32_t linkmtu; /* LinkMTU */ u_int32_t maxmtu; /* Upper bound of LinkMTU */ u_int32_t basereachable; /* BaseReachableTime */ u_int32_t reachable; /* Reachable Time */ u_int32_t retrans; /* Retrans Timer */ u_int32_t flags; /* Flags */ int recalctm; /* BaseReacable re-calculation timer */ u_int8_t chlim; /* CurHopLimit */ /* Number of routers learned on the interface */ u_int8_t receivedra; /* * The current collision count value * being used for secure address generation. */ u_int8_t collision_count; } ndi; }; #if !defined(BSD_KERNEL_PRIVATE) struct in6_ndireq { char ifname[IFNAMSIZ]; struct nd_ifinfo ndi; }; #else struct in6_ndireq { char ifname[IFNAMSIZ]; struct nd_ifinfo_compat ndi; }; #endif /* !BSD_KERNEL_PRIVATE */ struct in6_ndifreq { char ifname[IFNAMSIZ]; u_long ifindex; }; #define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */ #define RTR_SOLICITATION_INTERVAL 4 /* 4sec */ #if defined(BSD_KERNEL_PRIVATE) struct in6_ndifreq_32 { char ifname[IFNAMSIZ]; u_int32_t ifindex; }; struct in6_ndifreq_64 { char ifname[IFNAMSIZ]; u_int64_t ifindex __attribute__((aligned(8))); }; #endif /* BSD_KERNEL_PRIVATE */ struct in6_route_info { struct in6_addr prefix; u_int8_t prefixlen; u_short defrtrs; /* number of default routers */ /* struct in6_defrouter defrtr[] */ } __attribute__((aligned(8))); #if defined(BSD_KERNEL_PRIVATE) struct in6_route_info_32 { struct in6_addr prefix; u_int8_t prefixlen; u_short defrtrs; /* number of default routers */ /* struct in6_defrouter defrtr[] */ }; struct in6_route_info_64 { struct in6_addr prefix; u_int8_t prefixlen; u_short defrtrs; /* number of default routers */ /* struct in6_defrouter defrtr[] */ } __attribute__((aligned(8))); #endif /* BSD_KERNEL_PRIVATE */ /* Prefix status */ #define NDPRF_ONLINK 0x1 #define NDPRF_DETACHED 0x2 #define NDPRF_STATIC 0x100 #define NDPRF_IFSCOPE 0x1000 #define NDPRF_PRPROXY 0x2000 #ifdef BSD_KERNEL_PRIVATE #define NDPRF_PROCESSED_ONLINK 0x08000 #define NDPRF_PROCESSED_SERVICE 0x10000 #define NDPRF_DEFUNCT 0x20000 #define NDPRF_CLAT46 0x40000 #define CLAT46_COLLISION_COUNT_OFFSET 128 #endif /* BSD_KERNEL_PRIVATE */ /* protocol constants */ #define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */ #define RTR_SOLICITATION_INTERVAL 4 /* 4sec */ #define MAX_RTR_SOLICITATIONS 3 #define ND6_INFINITE_LIFETIME 0xffffffff #define ND6_MAX_LIFETIME 0x7fffffff #ifdef BSD_KERNEL_PRIVATE #define ND_IFINFO(ifp) \ ((ifp == NULL) ? NULL : \ ((IN6_IFEXTRA(ifp) == NULL) ? NULL : \ (&IN6_IFEXTRA(ifp)->nd_ifinfo))) /* * In a more readable form, we derive linkmtu based on: * * if (ifp == NULL) * linkmtu = IPV6_MMTU * else if (ND_IFINFO(ifp) == NULL || !ND_IFINFO(ifp)->initialized) * linkmtu = ifp->if_mtu; * else if (ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < ifp->if_mtu) * linkmtu = ND_IFINFO(ifp)->linkmtu; * else if ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < ifp->if_mtu)) * linkmtu = ND_IFINFO(ifp)->maxmtu; * else * linkmtu = ifp->if_mtu; */ #define IN6_LINKMTU(ifp) \ (ifp == NULL ? IPV6_MMTU : \ (ND_IFINFO(ifp) == NULL || !ND_IFINFO(ifp)->initialized) ? \ (ifp)->if_mtu : ((ND_IFINFO(ifp)->linkmtu && \ ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) ? ND_IFINFO(ifp)->linkmtu : \ ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) ? \ ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu))) /* node constants */ #define MAX_REACHABLE_TIME 3600000 /* msec */ #define REACHABLE_TIME 30000 /* msec */ #define RETRANS_TIMER 1000 /* msec */ #define MAX_RA_RETRANS_TIMER 10000 /* msec */ #define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */ #define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */ #define DEF_TEMP_VALID_LIFETIME 604800 /* 1 week */ #define DEF_TEMP_PREFERRED_LIFETIME 86400 /* 1 day */ #define TEMPADDR_REGEN_ADVANCE 5 /* sec */ #define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */ #define ND_COMPUTE_RTIME(x) \ (((MIN_RANDOM_FACTOR * (x >> 10)) + (RandomULong() & \ ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000) #define IP6_USE_TMPADDR_DEFAULT 1 #define IP6_ULA_USE_TMPADDR_DEFAULT 0 /* prefix expiry times */ #define ND6_PREFIX_EXPIRY_UNSPEC -1 #define ND6_PREFIX_EXPIRY_NEVER 0 TAILQ_HEAD(nd_drhead, nd_defrouter); struct nd_defrouter { decl_lck_mtx_data(, nddr_lock); decl_lck_mtx_data(, nddr_ref_lock); TAILQ_ENTRY(nd_defrouter) dr_entry; struct in6_addr rtaddr; u_int32_t nddr_refcount; u_int32_t nddr_debug; u_int64_t expire; u_int64_t base_calendartime; /* calendar time at creation */ u_int64_t base_uptime; /* uptime at creation */ u_char flags; /* flags on RA message */ u_char stateflags; u_int32_t rtlifetime; int err; struct ifnet *ifp; struct in6_addr rtaddr_mapped; /* Mapped gateway address for routing */ boolean_t is_reachable; void (*nddr_trace)(struct nd_defrouter *, int); /* trace callback fn */ }; #define NDDR_LOCK_ASSERT_HELD(_nddr) \ LCK_MTX_ASSERT(&(_nddr)->nddr_lock, LCK_MTX_ASSERT_OWNED) #define NDDR_LOCK_ASSERT_NOTHELD(_nddr) \ LCK_MTX_ASSERT(&(_nddr)->nddr_lock, LCK_MTX_ASSERT_NOTOWNED) #define NDDR_LOCK(_nddr) \ lck_mtx_lock(&(_nddr)->nddr_lock) #define NDDR_LOCK_SPIN(_nddr) \ lck_mtx_lock_spin(&(_nddr)->nddr_lock) #define NDDR_CONVERT_LOCK(_nddr) do { \ NDPR_LOCK_ASSERT_HELD(_nddr); \ lck_mtx_convert_spin(&(_nddr)->nddr_lock); \ } while (0) #define NDDR_UNLOCK(_nddr) \ lck_mtx_unlock(&(_nddr)->nddr_lock) #define NDDR_REF_LOCK(_nddr) \ lck_mtx_lock(&(_nddr)->nddr_ref_lock) #define NDDR_REF_LOCK_SPIN(_nddr) \ lck_mtx_lock_spin(&(_nddr)->nddr_ref_lock) #define NDDR_REF_UNLOCK(_nddr) \ lck_mtx_unlock(&(_nddr)->nddr_ref_lock) #define NDDR_ADDREF(_nddr) \ nddr_addref(_nddr) #define NDDR_REMREF(_nddr) \ nddr_remref(_nddr) \ TAILQ_HEAD(nd_rtihead, nd_route_info); /* * The ordering below is important and it should always start * with nd_drhead as the first element. * It gets passed in as the generic nd_drhead to router management code. * The extra information stored here includes the prefix/prefix-length * which the router list belongs to. */ struct nd_route_info { struct nd_drhead nd_rti_router_list; TAILQ_ENTRY(nd_route_info) nd_rti_entry; struct in6_addr nd_rti_prefix; u_int8_t nd_rti_prefixlen; }; struct nd_route_info *ndrti_alloc(void); void nd6_rti_list_wait(const char *); void nd6_rti_list_signal_done(void); void ndrti_free(struct nd_route_info *rti); void nd6_rtilist_remove(struct nd_route_info *); void nd6_rtilist_update(struct nd_route_info *, struct nd_defrouter *); int nd6_rtilist_add(struct nd_route_info *, struct nd_defrouter *, struct nd_route_info **); void nd6_rti_purge(struct nd_route_info *); void nd6_rti_delreq(struct nd_route_info *); void nd6_rti_select(struct nd_route_info *, struct ifnet *); /* define struct prproxy_sols_tree */ RB_HEAD(prproxy_sols_tree, nd6_prproxy_soltgt); struct nd_prefix { decl_lck_mtx_data(, ndpr_lock); decl_lck_mtx_data(, ndpr_ref_lock); u_int32_t ndpr_refcount; /* reference count */ u_int32_t ndpr_debug; /* see ifa_debug flags */ struct ifnet *ndpr_ifp; struct rtentry *ndpr_rt; LIST_ENTRY(nd_prefix) ndpr_entry; struct sockaddr_in6 ndpr_prefix; /* prefix */ struct in6_addr ndpr_mask; /* netmask derived from the prefix */ struct in6_addr ndpr_addr; /* address that is derived from the prefix */ u_int32_t ndpr_vltime; /* advertised valid lifetime */ u_int32_t ndpr_pltime; /* advertised preferred lifetime */ u_int64_t ndpr_preferred; /* preferred time of the prefix */ u_int64_t ndpr_expire; /* expiration time of the prefix */ u_int64_t ndpr_lastupdate; /* rx time of last advertisement */ u_int64_t ndpr_base_calendartime; /* calendar time at creation */ u_int64_t ndpr_base_uptime; /* uptime at creation */ struct prf_ra ndpr_flags; unsigned int ndpr_genid; /* protects ndpr_advrtrs */ u_int32_t ndpr_stateflags; /* actual state flags */ /* list of routers that advertise the prefix: */ LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs; u_char ndpr_plen; int ndpr_addrcnt; /* reference counter from addresses */ int ndpr_manual_addrcnt; /* reference counter non-autoconf addresses */ u_int32_t ndpr_allmulti_cnt; /* total all-multi reqs */ u_int32_t ndpr_prproxy_sols_cnt; /* total # of proxied NS */ struct prproxy_sols_tree ndpr_prproxy_sols; /* tree of proxied NS */ void (*ndpr_trace)(struct nd_prefix *, int); /* trace callback fn */ }; #define ndpr_next ndpr_entry.le_next #define ndpr_raf ndpr_flags #define ndpr_raf_onlink ndpr_flags.onlink #define ndpr_raf_auto ndpr_flags.autonomous #define ndpr_raf_router ndpr_flags.router /* * We keep expired prefix for certain amount of time, for validation purposes. * 1800s = MaxRtrAdvInterval */ #define NDPR_KEEP_EXPIRED (1800 * 2) #define NDPR_LOCK_ASSERT_HELD(_ndpr) \ LCK_MTX_ASSERT(&(_ndpr)->ndpr_lock, LCK_MTX_ASSERT_OWNED) #define NDPR_LOCK_ASSERT_NOTHELD(_ndpr) \ LCK_MTX_ASSERT(&(_ndpr)->ndpr_lock, LCK_MTX_ASSERT_NOTOWNED) #define NDPR_LOCK(_ndpr) \ lck_mtx_lock(&(_ndpr)->ndpr_lock) #define NDPR_LOCK_SPIN(_ndpr) \ lck_mtx_lock_spin(&(_ndpr)->ndpr_lock) #define NDPR_CONVERT_LOCK(_ndpr) do { \ NDPR_LOCK_ASSERT_HELD(_ndpr); \ lck_mtx_convert_spin(&(_ndpr)->ndpr_lock); \ } while (0) #define NDPR_UNLOCK(_ndpr) \ lck_mtx_unlock(&(_ndpr)->ndpr_lock) #define NDPR_REF_LOCK(_ndpr) \ lck_mtx_lock(&(_ndpr)->ndpr_ref_lock) #define NDPR_REF_LOCK_SPIN(_ndpr) \ lck_mtx_lock_spin(&(_ndpr)->ndpr_ref_lock) #define NDPR_REF_UNLOCK(_ndpr) \ lck_mtx_unlock(&(_ndpr)->ndpr_ref_lock) #define NDPR_ADDREF(_ndpr) \ ndpr_addref(_ndpr) #define NDPR_REMREF(_ndpr) \ ndpr_remref(_ndpr) \ /* * Message format for use in obtaining information about prefixes * from inet6 sysctl function */ struct inet6_ndpr_msghdr { u_short inpm_msglen; /* to skip over non-understood messages */ u_char inpm_version; /* future binary compatibility */ u_char inpm_type; /* message type */ struct in6_addr inpm_prefix; u_int32_t prm_vltim; u_int32_t prm_pltime; u_int32_t prm_expire; u_int32_t prm_preferred; struct in6_prflags prm_flags; u_short prm_index; /* index for associated ifp */ u_char prm_plen; /* length of prefix in bits */ }; #define prm_raf_onlink prm_flags.prf_ra.onlink #define prm_raf_auto prm_flags.prf_ra.autonomous #define prm_statef_onlink prm_flags.prf_state.onlink #define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid #define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd struct nd_pfxrouter { LIST_ENTRY(nd_pfxrouter) pfr_entry; #define pfr_next pfr_entry.le_next struct nd_defrouter *router; }; LIST_HEAD(nd_prhead, nd_prefix); struct nd_prefix_list { struct nd_prefix_list *next; struct nd_prefix pr; }; #endif /* BSD_KERNEL_PRIVATE */ #if defined(PRIVATE) struct kev_nd6_ndfailure { struct net_event_data link_data; }; struct kev_nd6_ndalive { struct net_event_data link_data; }; struct nd6_ra_prefix { struct sockaddr_in6 prefix; struct prf_ra raflags; u_int32_t prefixlen; u_int32_t origin; u_int64_t vltime; u_int64_t pltime; u_int64_t expire; u_int32_t flags; u_int32_t refcnt; u_int32_t if_index; u_int32_t pad; }; /* ND6 router advertisement valid bits */ #define KEV_ND6_DATA_VALID_MTU (0x1 << 0) #define KEV_ND6_DATA_VALID_PREFIX (0x1 << 1) struct kev_nd6_ra_data { u_int32_t mtu; u_int32_t list_index; u_int32_t list_length; u_int32_t flags; struct nd6_ra_prefix prefix; u_int32_t pad; }; struct kev_nd6_event { struct net_event_data link_data; struct in6_addr in6_address; uint32_t val; }; struct nd6_lookup_ipv6_args { char ifname[IFNAMSIZ]; struct sockaddr_in6 ip6_dest; u_int32_t ll_dest_len; union { char buffer[256]; struct sockaddr_dl _sdl; } ll_dest_; }; #define ll_dest_sdl ll_dest_._sdl #endif /* PRIVATE */ #if defined(BSD_KERNEL_PRIVATE) /* nd6.c */ extern int nd6_prune; extern int nd6_prune_lazy; extern int nd6_delay; extern int nd6_umaxtries; extern int nd6_mmaxtries; extern int nd6_useloopback; extern int nd6_accept_6to4; extern int nd6_maxnudhint; extern int nd6_gctimer; extern struct llinfo_nd6 llinfo_nd6; extern struct nd_drhead nd_defrouter_list; extern struct nd_rtihead nd_rti_list; extern struct nd_prhead nd_prefix; extern int nd6_debug; extern int nd6_onlink_ns_rfc4861; extern int nd6_optimistic_dad; #include <os/log.h> #define nd6log0(type, ...) do { os_log_##type(OS_LOG_DEFAULT, ##__VA_ARGS__); } while (0) #define nd6log(type, ...) do { if (nd6_debug >= 1) os_log_##type(OS_LOG_DEFAULT, ##__VA_ARGS__); } while (0) #define nd6log2(type, ...) do { if (nd6_debug >= 2) os_log_##type(OS_LOG_DEFAULT, ##__VA_ARGS__); } while (0) #define nd6log3(type, ...) do { if (nd6_debug >= 3) os_log_##type(OS_LOG_DEFAULT, ##__VA_ARGS__); } while (0) #define nd6log4(type, ...) do { if (nd6_debug >= 4) os_log_##type(OS_LOG_DEFAULT, ##__VA_ARGS__); } while (0) #define ND6_OPTIMISTIC_DAD_LINKLOCAL (1 << 0) #define ND6_OPTIMISTIC_DAD_AUTOCONF (1 << 1) #define ND6_OPTIMISTIC_DAD_TEMPORARY (1 << 2) #define ND6_OPTIMISTIC_DAD_DYNAMIC (1 << 3) #define ND6_OPTIMISTIC_DAD_SECURED (1 << 4) #define ND6_OPTIMISTIC_DAD_MANUAL (1 << 5) #define ND6_OPTIMISTIC_DAD_DEFAULT \ (ND6_OPTIMISTIC_DAD_LINKLOCAL | ND6_OPTIMISTIC_DAD_AUTOCONF | \ ND6_OPTIMISTIC_DAD_TEMPORARY | ND6_OPTIMISTIC_DAD_DYNAMIC | \ ND6_OPTIMISTIC_DAD_SECURED | ND6_OPTIMISTIC_DAD_MANUAL) /* nd6_rtr.c */ extern int nd6_defifindex; extern int ip6_desync_factor; /* seconds */ /* ND6_INFINITE_LIFETIME does not apply to temporary addresses */ extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */ extern u_int32_t ip6_temp_valid_lifetime; /* seconds */ extern int ip6_temp_regen_advance; /* seconds */ union nd_opts { struct nd_opt_hdr *nd_opt_array[26]; /* max = Route information option */ struct { struct nd_opt_hdr *zero; struct nd_opt_hdr *src_lladdr; struct nd_opt_hdr *tgt_lladdr; struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */ struct nd_opt_rd_hdr *rh; struct nd_opt_mtu *mtu; struct nd_opt_hdr *__res6; struct nd_opt_hdr *__res7; struct nd_opt_hdr *__res8; struct nd_opt_hdr *__res9; struct nd_opt_hdr *__res10; struct nd_opt_hdr *__res11; struct nd_opt_hdr *__res12; struct nd_opt_hdr *__res13; struct nd_opt_nonce *nonce; struct nd_opt_hdr *__res15; struct nd_opt_hdr *__res16; struct nd_opt_hdr *__res17; struct nd_opt_hdr *__res18; struct nd_opt_hdr *__res19; struct nd_opt_hdr *__res20; struct nd_opt_hdr *__res21; struct nd_opt_hdr *__res22; struct nd_opt_hdr *__res23; struct nd_opt_route_info *rti_beg; struct nd_opt_hdr *__res25; struct nd_opt_hdr *__ended_by(last) search; /* multiple opts */ struct nd_opt_hdr *last; /* multiple opts */ uint8_t done; uint8_t initialized; struct nd_opt_prefix_info *pi_end; /* multiple prefix opts, end */ struct nd_opt_route_info *rti_end; /* multiple route info opts, end */ } nd_opt_each; }; #define nd_opts_src_lladdr nd_opt_each.src_lladdr #define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr #define nd_opts_pi nd_opt_each.pi_beg #define nd_opts_pi_end nd_opt_each.pi_end #define nd_opts_rh nd_opt_each.rh #define nd_opts_mtu nd_opt_each.mtu #define nd_opts_nonce nd_opt_each.nonce #define nd_opts_rti nd_opt_each.rti_beg #define nd_opts_rti_end nd_opt_each.rti_end #define nd_opts_search nd_opt_each.search #define nd_opts_last nd_opt_each.last #define nd_opts_done nd_opt_each.done #define nd_opts_initialized nd_opt_each.initialized #define ND_OPT_LLADDR(opt, optlen, val, vallen) ({ \ (vallen) = opt->optlen << 3; \ struct nd_opt_hdr* __hdr = __unsafe_forge_bidi_indexable(struct nd_opt_hdr *, \ (opt), sizeof(struct nd_opt_hdr) + (vallen)); \ (val) = (char *)(__hdr + 1); \ }) #if __has_ptrcheck #define TAKE_ND_NEXT_OPT(opt, start, end) ({ \ size_t __ndoptlen = (u_char*)ndopts.end - (u_char*)ndopts.start; \ struct nd_opt_hdr* __hdr = __unsafe_forge_bidi_indexable(struct nd_opt_hdr *, (opt), __ndoptlen); \ __hdr; \ }) #else #define TAKE_ND_NEXT_OPT(opt, start, end) ({ \ (struct nd_opt_hdr *)opt; \ }) #endif /* XXX: need nd6_var.h?? */ /* nd6.c */ extern int nd6_sched_timeout_want; extern void nd6_sched_timeout(struct timeval *, struct timeval *); extern void nd6_init(void); extern void nd6_ifreset(struct ifnet *ifp); extern void nd6_ifattach(struct ifnet *); extern int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *, int); extern void nd6_option_init(void *__sized_by(icmp6len), size_t icmp6len, union nd_opts *); extern struct nd_opt_hdr *nd6_option(union nd_opts *); extern int nd6_options(union nd_opts *); extern struct rtentry *nd6_lookup(struct in6_addr *, int, struct ifnet *, int); extern void nd6_setmtu(struct ifnet *); extern void nd6_purge(struct ifnet *); extern void nd6_free(struct rtentry *); extern void nd6_nud_hint(struct rtentry *, struct in6_addr *, int); extern int nd6_resolve(struct ifnet *, struct rtentry *, struct mbuf *, struct sockaddr *, u_char *); extern void nd6_rtrequest(int, struct rtentry *, struct sockaddr *); extern int nd6_ioctl(u_long cmd, caddr_t __counted_by(IOCPARM_LEN(cmd)), struct ifnet *); extern void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, char *lladdr __sized_by(lladdrlen), int lladdrlen, int, int, int *); extern int nd6_output_list(struct ifnet *, struct ifnet *, struct mbuf *, struct sockaddr_in6 *, struct rtentry *, struct flowadv *); extern int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *, struct sockaddr_in6 *, struct rtentry *, struct flowadv *); extern int nd6_need_cache(struct ifnet *); extern void nd6_drain(void *); extern void nd6_post_msg(u_int32_t, struct nd_prefix_list *, u_int32_t, u_int32_t); extern int nd6_setifinfo(struct ifnet *, u_int32_t, u_int32_t); extern const char *ndcache_state2str(short); extern void ln_setexpire(struct llinfo_nd6 *, uint64_t); /* nd6_nbr.c */ extern void nd6_nbr_init(void); extern void nd6_na_input(struct mbuf *, int, int); extern void nd6_na_output(struct ifnet *, const struct in6_addr *, const struct in6_addr *, u_int32_t, int, struct sockaddr *); extern void nd6_ns_input(struct mbuf *, int, int); extern void nd6_ns_output(struct ifnet *, const struct in6_addr *, const struct in6_addr *, struct llinfo_nd6 *, uint8_t *__counted_by(noncelen) nonce, size_t noncelen); static inline caddr_t __header_indexable __stateful_pure nd6_ifptomac(struct ifnet *ifp) { switch (ifp->if_type) { case IFT_ARCNET: case IFT_ETHER: case IFT_IEEE8023ADLAG: case IFT_FDDI: case IFT_IEEE1394: #ifdef IFT_L2VLAN case IFT_L2VLAN: #endif #ifdef IFT_IEEE80211 case IFT_IEEE80211: #endif #ifdef IFT_CARP case IFT_CARP: #endif case IFT_BRIDGE: case IFT_ISO88025: return (caddr_t)IF_LLADDR(ifp); default: return NULL; } } extern void nd6_dad_start(struct ifaddr *, int *); extern void nd6_dad_stop(struct ifaddr *); extern void nd6_llreach_alloc(struct rtentry *, struct ifnet *, void * __sized_by(alen), unsigned int alen, boolean_t); extern void nd6_llreach_set_reachable(struct ifnet *, void *__sized_by(alen) addr, unsigned int alen); extern void nd6_llreach_use(struct llinfo_nd6 *); extern void nd6_alt_node_addr_decompose(struct ifnet *, struct sockaddr *, struct sockaddr_dl *, struct sockaddr_in6 *); extern int nd6_alt_node_present(struct ifnet *, struct sockaddr_in6 *, struct sockaddr_dl *, int32_t, int, int); extern int nd6_alt_node_absent(struct ifnet *, struct sockaddr_in6 *, struct sockaddr_dl *); /* nd6_rtr.c */ extern struct in6_ifaddr *in6_pfx_newpersistaddr(struct nd_prefix *, int, int *, boolean_t, uint8_t); extern void nd6_rtr_init(void); extern void nd6_rs_input(struct mbuf *, int, int); extern void nd6_ra_input(struct mbuf *, int, int); extern void prelist_del(struct nd_prefix *); extern struct nd_defrouter *defrtrlist_update(struct nd_defrouter *, struct nd_drhead *); extern void defrouter_select(struct ifnet *, struct nd_drhead *); extern void defrouter_reset(void); extern int defrtrlist_ioctl(u_long cmd, caddr_t __sized_by(IOCPARM_LEN(cmd))); extern void defrtrlist_del(struct nd_defrouter *, struct nd_drhead *); extern int defrtrlist_add_static(struct nd_defrouter *); extern int defrtrlist_del_static(struct nd_defrouter *); extern void nd_prefix_busy_wait(void); extern void nd_prefix_busy_signal(void); extern void prelist_remove(struct nd_prefix *); extern int prelist_update(struct nd_prefix *, struct nd_defrouter *, struct mbuf *, int); extern int nd6_prelist_add(struct nd_prefix *, struct nd_defrouter *, struct nd_prefix **, boolean_t); extern int nd6_prefix_onlink(struct nd_prefix *); extern int nd6_prefix_onlink_scoped(struct nd_prefix *, unsigned int); extern int nd6_prefix_offlink(struct nd_prefix *); extern void pfxlist_onlink_check(bool); extern void defrouter_set_reachability(struct in6_addr *, struct ifnet *, boolean_t); extern struct nd_defrouter *defrouter_lookup(struct nd_drhead *, struct in6_addr *, struct ifnet *); extern struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *, struct nd_defrouter *); extern struct nd_prefix *nd6_prefix_lookup(struct nd_prefix *, int); extern int in6_init_prefix_ltimes(struct nd_prefix *ndpr); extern void rt6_flush(struct in6_addr *, struct ifnet *); extern int nd6_setdefaultiface(int); extern int in6_tmpifadd(const struct in6_ifaddr *, int); extern void nddr_addref(struct nd_defrouter *); extern struct nd_defrouter *nddr_remref(struct nd_defrouter *); extern uint64_t nddr_getexpire(struct nd_defrouter *); extern void ndpr_addref(struct nd_prefix *); extern struct nd_prefix *ndpr_remref(struct nd_prefix *); extern uint64_t ndpr_getexpire(struct nd_prefix *); extern void defrouter_delreq(struct nd_defrouter *, struct nd_route_info *); /* nd6_prproxy.c */ struct ip6_hdr; extern u_int32_t nd6_prproxy; extern int nd6_if_prproxy(struct ifnet *, boolean_t); extern void nd6_prproxy_prelist_update(struct nd_prefix *, struct nd_prefix *); extern boolean_t nd6_prproxy_ifaddr(struct in6_ifaddr *); extern void nd6_proxy_find_fwdroute(struct ifnet *, struct route_in6 *); extern boolean_t nd6_prproxy_isours(struct mbuf *, struct ip6_hdr *, struct route_in6 *, unsigned int); extern void nd6_prproxy_ns_output(struct ifnet *, struct ifnet *, struct in6_addr *, struct in6_addr *, struct llinfo_nd6 *); extern void nd6_prproxy_ns_input(struct ifnet *, struct in6_addr *, char *__sized_by(lladdrlen) lladdr, int lladdrlen, struct in6_addr *, struct in6_addr *, uint8_t *__counted_by(noncelen) nonce, size_t noncelen); extern void nd6_prproxy_na_input(struct ifnet *, struct in6_addr *, struct in6_addr *, struct in6_addr *, int); extern void nd6_prproxy_sols_reap(struct nd_prefix *); extern void nd6_prproxy_sols_prune(struct nd_prefix *, u_int32_t); extern int nd6_if_disable(struct ifnet *, boolean_t); void in6_ifaddr_set_dadprogress(struct in6_ifaddr *ia); #endif /* BSD_KERNEL_PRIVATE */ #ifdef KERNEL /* * @function nd6_lookup_ipv6 * @discussion This function will check the routing table for a cached * neighbor discovery entry or trigger an neighbor discovery query * to resolve the IPv6 address to a link-layer address. * nd entries are stored in the routing table. This function will * lookup the IPv6 destination in the routing table. If the * destination requires forwarding to a gateway, the route of the * gateway will be looked up. The route entry is inspected to * determine if the link layer destination address is known. If * unknown, neighbor discovery will be used to resolve the entry. * @param interface The interface the packet is being sent on. * @param ip6_dest The IPv6 destination of the packet. * @param ll_dest On output, the link-layer destination. * @param ll_dest_len The length of the buffer for ll_dest. * @param hint Any routing hint passed down from the protocol. * @param packet The packet being transmitted. * @result May return an error such as EHOSTDOWN or ENETUNREACH. If * this function returns EJUSTRETURN, the packet has been queued * and will be sent when the address is resolved. If any other * value is returned, the caller is responsible for disposing of * the packet. */ extern errno_t nd6_lookup_ipv6(ifnet_t interface, const struct sockaddr_in6 *ip6_dest, struct sockaddr_dl *ll_dest, size_t ll_dest_len, route_t hint, mbuf_t packet); #endif /* KERNEL */ /* nd6_send.c */ #ifdef BSD_KERNEL_PRIVATE /* * nd6_send_opmode * * value using CGA tx SEND rx SEND * -------- --------- ------- ------- * DISABLED NO NO NO * QUIET YES NO NO */ extern int nd6_send_opstate; #define ND6_SEND_OPMODE_DISABLED 0 #define ND6_SEND_OPMODE_CGA_QUIET 1 #endif /* BSD_KERNEL_PRIVATE */ #endif /* _NETINET6_ND6_H_ */ |