in6_ifattach.c (37f878f56c07f3c298351acae5fe0c9afe936d79) | in6_ifattach.c (1272577e22d8f1c1c5b5e88f2624836e93aecb17) |
---|---|
1/* $FreeBSD$ */ 2/* $KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 81 unchanged lines hidden (view full) --- 90#define IFID_UNIVERSAL(in6) (!EUI64_UNIVERSAL(in6)) 91 92/* 93 * Generate a last-resort interface identifier, when the machine has no 94 * IEEE802/EUI64 address sources. 95 * The goal here is to get an interface identifier that is 96 * (1) random enough and (2) does not change across reboot. 97 * We currently use MD5(hostname) for it. | 1/* $FreeBSD$ */ 2/* $KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 81 unchanged lines hidden (view full) --- 90#define IFID_UNIVERSAL(in6) (!EUI64_UNIVERSAL(in6)) 91 92/* 93 * Generate a last-resort interface identifier, when the machine has no 94 * IEEE802/EUI64 address sources. 95 * The goal here is to get an interface identifier that is 96 * (1) random enough and (2) does not change across reboot. 97 * We currently use MD5(hostname) for it. |
98 * 99 * in6 - upper 64bits are preserved |
|
98 */ 99static int | 100 */ 101static int |
100get_rand_ifid(ifp, in6) 101 struct ifnet *ifp; 102 struct in6_addr *in6; /* upper 64bits are preserved */ | 102get_rand_ifid(struct ifnet *ifp, struct in6_addr *in6) |
103{ 104 MD5_CTX ctxt; 105 u_int8_t digest[16]; 106 int hostnamelen = strlen(hostname); 107 108#if 0 109 /* we need at least several letters as seed for ifid */ 110 if (hostnamelen < 3) --- 15 unchanged lines hidden (view full) --- 126 127 /* convert EUI64 into IPv6 interface identifier */ 128 EUI64_TO_IFID(in6); 129 130 return 0; 131} 132 133static int | 103{ 104 MD5_CTX ctxt; 105 u_int8_t digest[16]; 106 int hostnamelen = strlen(hostname); 107 108#if 0 109 /* we need at least several letters as seed for ifid */ 110 if (hostnamelen < 3) --- 15 unchanged lines hidden (view full) --- 126 127 /* convert EUI64 into IPv6 interface identifier */ 128 EUI64_TO_IFID(in6); 129 130 return 0; 131} 132 133static int |
134generate_tmp_ifid(seed0, seed1, ret) 135 u_int8_t *seed0, *ret; 136 const u_int8_t *seed1; | 134generate_tmp_ifid(u_int8_t *seed0, const u_int8_t *seed1, u_int8_t *ret) |
137{ 138 MD5_CTX ctxt; 139 u_int8_t seed[16], digest[16], nullbuf[8]; 140 u_int32_t val32; 141 | 135{ 136 MD5_CTX ctxt; 137 u_int8_t seed[16], digest[16], nullbuf[8]; 138 u_int32_t val32; 139 |
142 /* If there's no hisotry, start with a random seed. */ | 140 /* If there's no history, start with a random seed. */ |
143 bzero(nullbuf, sizeof(nullbuf)); 144 if (bcmp(nullbuf, seed0, sizeof(nullbuf)) == 0) { 145 int i; 146 147 for (i = 0; i < 2; i++) { 148 val32 = arc4random(); 149 bcopy(&val32, seed + sizeof(val32) * i, sizeof(val32)); 150 } --- 58 unchanged lines hidden (view full) --- 209 } 210 211 return 0; 212} 213 214/* 215 * Get interface identifier for the specified interface. 216 * XXX assumes single sockaddr_dl (AF_LINK address) per an interface | 141 bzero(nullbuf, sizeof(nullbuf)); 142 if (bcmp(nullbuf, seed0, sizeof(nullbuf)) == 0) { 143 int i; 144 145 for (i = 0; i < 2; i++) { 146 val32 = arc4random(); 147 bcopy(&val32, seed + sizeof(val32) * i, sizeof(val32)); 148 } --- 58 unchanged lines hidden (view full) --- 207 } 208 209 return 0; 210} 211 212/* 213 * Get interface identifier for the specified interface. 214 * XXX assumes single sockaddr_dl (AF_LINK address) per an interface |
215 * 216 * in6 - upper 64bits are preserved |
|
217 */ 218int | 217 */ 218int |
219in6_get_hw_ifid(ifp, in6) 220 struct ifnet *ifp; 221 struct in6_addr *in6; /* upper 64bits are preserved */ | 219in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6) |
222{ 223 struct ifaddr *ifa; 224 struct sockaddr_dl *sdl; 225 u_int8_t *addr; 226 size_t addrlen; 227 static u_int8_t allzero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 228 static u_int8_t allone[8] = 229 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; --- 112 unchanged lines hidden (view full) --- 342 343 return 0; 344} 345 346/* 347 * Get interface identifier for the specified interface. If it is not 348 * available on ifp0, borrow interface identifier from other information 349 * sources. | 220{ 221 struct ifaddr *ifa; 222 struct sockaddr_dl *sdl; 223 u_int8_t *addr; 224 size_t addrlen; 225 static u_int8_t allzero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 226 static u_int8_t allone[8] = 227 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; --- 112 unchanged lines hidden (view full) --- 340 341 return 0; 342} 343 344/* 345 * Get interface identifier for the specified interface. If it is not 346 * available on ifp0, borrow interface identifier from other information 347 * sources. |
348 * 349 * altifp - secondary EUI64 source |
|
350 */ 351static int | 350 */ 351static int |
352get_ifid(ifp0, altifp, in6) 353 struct ifnet *ifp0; 354 struct ifnet *altifp; /* secondary EUI64 source */ 355 struct in6_addr *in6; | 352get_ifid(struct ifnet *ifp0, struct ifnet *altifp, 353 struct in6_addr *in6) |
356{ 357 struct ifnet *ifp; 358 359 /* first, try to get it from the interface itself */ 360 if (in6_get_hw_ifid(ifp0, in6) == 0) { 361 nd6log((LOG_DEBUG, "%s: got interface identifier from itself\n", 362 if_name(ifp0))); 363 goto success; --- 42 unchanged lines hidden (view full) --- 406success: 407 nd6log((LOG_INFO, "%s: ifid: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 408 if_name(ifp0), in6->s6_addr[8], in6->s6_addr[9], in6->s6_addr[10], 409 in6->s6_addr[11], in6->s6_addr[12], in6->s6_addr[13], 410 in6->s6_addr[14], in6->s6_addr[15])); 411 return 0; 412} 413 | 354{ 355 struct ifnet *ifp; 356 357 /* first, try to get it from the interface itself */ 358 if (in6_get_hw_ifid(ifp0, in6) == 0) { 359 nd6log((LOG_DEBUG, "%s: got interface identifier from itself\n", 360 if_name(ifp0))); 361 goto success; --- 42 unchanged lines hidden (view full) --- 404success: 405 nd6log((LOG_INFO, "%s: ifid: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 406 if_name(ifp0), in6->s6_addr[8], in6->s6_addr[9], in6->s6_addr[10], 407 in6->s6_addr[11], in6->s6_addr[12], in6->s6_addr[13], 408 in6->s6_addr[14], in6->s6_addr[15])); 409 return 0; 410} 411 |
412/* 413 * altifp - secondary EUI64 source 414 */ |
|
414static int | 415static int |
415in6_ifattach_linklocal(ifp, altifp) 416 struct ifnet *ifp; 417 struct ifnet *altifp; /* secondary EUI64 source */ | 416in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) |
418{ 419 struct in6_ifaddr *ia; 420 struct in6_aliasreq ifra; 421 struct nd_prefixctl pr0; 422 int i, error; 423 424 /* 425 * configure link-local address. --- 95 unchanged lines hidden (view full) --- 521 if (nd6_prefix_lookup(&pr0) == NULL) { 522 if ((error = nd6_prelist_add(&pr0, NULL, NULL)) != 0) 523 return (error); 524 } 525 526 return 0; 527} 528 | 417{ 418 struct in6_ifaddr *ia; 419 struct in6_aliasreq ifra; 420 struct nd_prefixctl pr0; 421 int i, error; 422 423 /* 424 * configure link-local address. --- 95 unchanged lines hidden (view full) --- 520 if (nd6_prefix_lookup(&pr0) == NULL) { 521 if ((error = nd6_prelist_add(&pr0, NULL, NULL)) != 0) 522 return (error); 523 } 524 525 return 0; 526} 527 |
528/* 529 * ifp - must be IFT_LOOP 530 */ |
|
529static int | 531static int |
530in6_ifattach_loopback(ifp) 531 struct ifnet *ifp; /* must be IFT_LOOP */ | 532in6_ifattach_loopback(struct ifnet *ifp) |
532{ 533 struct in6_aliasreq ifra; 534 int error; 535 536 bzero(&ifra, sizeof(ifra)); 537 538 /* 539 * in6_update_ifa() does not use ifra_name, but we accurately set it --- 43 unchanged lines hidden (view full) --- 583 584/* 585 * compute NI group address, based on the current hostname setting. 586 * see draft-ietf-ipngwg-icmp-name-lookup-* (04 and later). 587 * 588 * when ifp == NULL, the caller is responsible for filling scopeid. 589 */ 590int | 533{ 534 struct in6_aliasreq ifra; 535 int error; 536 537 bzero(&ifra, sizeof(ifra)); 538 539 /* 540 * in6_update_ifa() does not use ifra_name, but we accurately set it --- 43 unchanged lines hidden (view full) --- 584 585/* 586 * compute NI group address, based on the current hostname setting. 587 * see draft-ietf-ipngwg-icmp-name-lookup-* (04 and later). 588 * 589 * when ifp == NULL, the caller is responsible for filling scopeid. 590 */ 591int |
591in6_nigroup(ifp, name, namelen, in6) 592 struct ifnet *ifp; 593 const char *name; 594 int namelen; 595 struct in6_addr *in6; | 592in6_nigroup(struct ifnet *ifp, const char *name, int namelen, 593 struct in6_addr *in6) |
596{ 597 const char *p; 598 u_char *q; 599 MD5_CTX ctxt; 600 u_int8_t digest[16]; 601 char l; 602 char n[64]; /* a single label must not exceed 63 chars */ 603 --- 29 unchanged lines hidden (view full) --- 633 634 return 0; 635} 636 637/* 638 * XXX multiple loopback interface needs more care. for instance, 639 * nodelocal address needs to be configured onto only one of them. 640 * XXX multiple link-local address case | 594{ 595 const char *p; 596 u_char *q; 597 MD5_CTX ctxt; 598 u_int8_t digest[16]; 599 char l; 600 char n[64]; /* a single label must not exceed 63 chars */ 601 --- 29 unchanged lines hidden (view full) --- 631 632 return 0; 633} 634 635/* 636 * XXX multiple loopback interface needs more care. for instance, 637 * nodelocal address needs to be configured onto only one of them. 638 * XXX multiple link-local address case |
639 * 640 * altifp - secondary EUI64 source |
|
641 */ 642void | 641 */ 642void |
643in6_ifattach(ifp, altifp) 644 struct ifnet *ifp; 645 struct ifnet *altifp; /* secondary EUI64 source */ | 643in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) |
646{ 647 struct in6_ifaddr *ia; 648 struct in6_addr in6; 649 650 /* some of the interfaces are inherently not IPv6 capable */ 651 switch (ifp->if_type) { 652 case IFT_PFLOG: 653 case IFT_PFSYNC: --- 65 unchanged lines hidden (view full) --- 719} 720 721/* 722 * NOTE: in6_ifdetach() does not support loopback if at this moment. 723 * We don't need this function in bsdi, because interfaces are never removed 724 * from the ifnet list in bsdi. 725 */ 726void | 644{ 645 struct in6_ifaddr *ia; 646 struct in6_addr in6; 647 648 /* some of the interfaces are inherently not IPv6 capable */ 649 switch (ifp->if_type) { 650 case IFT_PFLOG: 651 case IFT_PFSYNC: --- 65 unchanged lines hidden (view full) --- 717} 718 719/* 720 * NOTE: in6_ifdetach() does not support loopback if at this moment. 721 * We don't need this function in bsdi, because interfaces are never removed 722 * from the ifnet list in bsdi. 723 */ 724void |
727in6_ifdetach(ifp) 728 struct ifnet *ifp; | 725in6_ifdetach(struct ifnet *ifp) |
729{ 730 struct in6_ifaddr *ia, *oia; 731 struct ifaddr *ifa, *next; 732 struct rtentry *rt; 733 short rtflags; 734 struct sockaddr_in6 sin6; 735 struct in6_multi_mship *imm; 736 --- 93 unchanged lines hidden (view full) --- 830 rtexpunge(rt); 831 RTFREE_LOCKED(rt); 832 } 833 RADIX_NODE_HEAD_UNLOCK(rt_tables[AF_INET6]); 834 } 835} 836 837int | 726{ 727 struct in6_ifaddr *ia, *oia; 728 struct ifaddr *ifa, *next; 729 struct rtentry *rt; 730 short rtflags; 731 struct sockaddr_in6 sin6; 732 struct in6_multi_mship *imm; 733 --- 93 unchanged lines hidden (view full) --- 827 rtexpunge(rt); 828 RTFREE_LOCKED(rt); 829 } 830 RADIX_NODE_HEAD_UNLOCK(rt_tables[AF_INET6]); 831 } 832} 833 834int |
838in6_get_tmpifid(ifp, retbuf, baseid, generate) 839 struct ifnet *ifp; 840 u_int8_t *retbuf; 841 const u_int8_t *baseid; 842 int generate; | 835in6_get_tmpifid(struct ifnet *ifp, u_int8_t *retbuf, 836 const u_int8_t *baseid, int generate) |
843{ 844 u_int8_t nullbuf[8]; 845 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 846 847 bzero(nullbuf, sizeof(nullbuf)); 848 if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) == 0) { 849 /* we've never created a random ID. Create a new one. */ 850 generate = 1; --- 7 unchanged lines hidden (view full) --- 858 ndi->randomid); 859 } 860 bcopy(ndi->randomid, retbuf, 8); 861 862 return (0); 863} 864 865void | 837{ 838 u_int8_t nullbuf[8]; 839 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 840 841 bzero(nullbuf, sizeof(nullbuf)); 842 if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) == 0) { 843 /* we've never created a random ID. Create a new one. */ 844 generate = 1; --- 7 unchanged lines hidden (view full) --- 852 ndi->randomid); 853 } 854 bcopy(ndi->randomid, retbuf, 8); 855 856 return (0); 857} 858 859void |
866in6_tmpaddrtimer(ignored_arg) 867 void *ignored_arg; | 860in6_tmpaddrtimer(void *ignored_arg) |
868{ 869 struct nd_ifinfo *ndi; 870 u_int8_t nullbuf[8]; 871 struct ifnet *ifp; 872 int s = splnet(); 873 874 callout_reset(&in6_tmpaddrtimer_ch, 875 (ip6_temp_preferred_lifetime - ip6_desync_factor - --- 11 unchanged lines hidden (view full) --- 887 ndi->randomseed1, ndi->randomid); 888 } 889 } 890 891 splx(s); 892} 893 894static void | 861{ 862 struct nd_ifinfo *ndi; 863 u_int8_t nullbuf[8]; 864 struct ifnet *ifp; 865 int s = splnet(); 866 867 callout_reset(&in6_tmpaddrtimer_ch, 868 (ip6_temp_preferred_lifetime - ip6_desync_factor - --- 11 unchanged lines hidden (view full) --- 880 ndi->randomseed1, ndi->randomid); 881 } 882 } 883 884 splx(s); 885} 886 887static void |
895in6_purgemaddrs(ifp) 896 struct ifnet *ifp; | 888in6_purgemaddrs(struct ifnet *ifp) |
897{ 898 struct in6_multi *in6m; 899 struct in6_multi *oin6m; 900 901#ifdef DIAGNOSTIC 902 printf("%s: purging ifp %p\n", __func__, ifp); 903#endif 904 905 IFF_LOCKGIANT(ifp); 906 LIST_FOREACH_SAFE(in6m, &in6_multihead, in6m_entry, oin6m) { 907 if (in6m->in6m_ifp == ifp) 908 in6_delmulti(in6m); 909 } 910 IFF_UNLOCKGIANT(ifp); 911} | 889{ 890 struct in6_multi *in6m; 891 struct in6_multi *oin6m; 892 893#ifdef DIAGNOSTIC 894 printf("%s: purging ifp %p\n", __func__, ifp); 895#endif 896 897 IFF_LOCKGIANT(ifp); 898 LIST_FOREACH_SAFE(in6m, &in6_multihead, in6m_entry, oin6m) { 899 if (in6m->in6m_ifp == ifp) 900 in6_delmulti(in6m); 901 } 902 IFF_UNLOCKGIANT(ifp); 903} |