icmp6.c (180968) | icmp6.c (181803) |
---|---|
1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 47 unchanged lines hidden (view full) --- 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 61 */ 62 63#include <sys/cdefs.h> | 1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 47 unchanged lines hidden (view full) --- 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 61 */ 62 63#include <sys/cdefs.h> |
64__FBSDID("$FreeBSD: head/sys/netinet6/icmp6.c 180968 2008-07-29 19:37:16Z rwatson $"); | 64__FBSDID("$FreeBSD: head/sys/netinet6/icmp6.c 181803 2008-08-17 23:27:27Z bz $"); |
65 66#include "opt_inet.h" 67#include "opt_inet6.h" 68#include "opt_ipsec.h" 69 70#include <sys/param.h> 71#include <sys/domain.h> 72#include <sys/kernel.h> 73#include <sys/lock.h> 74#include <sys/malloc.h> 75#include <sys/mbuf.h> 76#include <sys/protosw.h> 77#include <sys/signalvar.h> 78#include <sys/socket.h> 79#include <sys/socketvar.h> 80#include <sys/sx.h> 81#include <sys/syslog.h> 82#include <sys/systm.h> 83#include <sys/time.h> | 65 66#include "opt_inet.h" 67#include "opt_inet6.h" 68#include "opt_ipsec.h" 69 70#include <sys/param.h> 71#include <sys/domain.h> 72#include <sys/kernel.h> 73#include <sys/lock.h> 74#include <sys/malloc.h> 75#include <sys/mbuf.h> 76#include <sys/protosw.h> 77#include <sys/signalvar.h> 78#include <sys/socket.h> 79#include <sys/socketvar.h> 80#include <sys/sx.h> 81#include <sys/syslog.h> 82#include <sys/systm.h> 83#include <sys/time.h> |
84#include <sys/vimage.h> |
|
84 85#include <net/if.h> 86#include <net/if_dl.h> 87#include <net/if_types.h> 88#include <net/route.h> 89 90#include <netinet/in.h> 91#include <netinet/in_pcb.h> --- 143 unchanged lines hidden (view full) --- 235icmp6_error(struct mbuf *m, int type, int code, int param) 236{ 237 struct ip6_hdr *oip6, *nip6; 238 struct icmp6_hdr *icmp6; 239 u_int preplen; 240 int off; 241 int nxt; 242 | 85 86#include <net/if.h> 87#include <net/if_dl.h> 88#include <net/if_types.h> 89#include <net/route.h> 90 91#include <netinet/in.h> 92#include <netinet/in_pcb.h> --- 143 unchanged lines hidden (view full) --- 236icmp6_error(struct mbuf *m, int type, int code, int param) 237{ 238 struct ip6_hdr *oip6, *nip6; 239 struct icmp6_hdr *icmp6; 240 u_int preplen; 241 int off; 242 int nxt; 243 |
243 icmp6stat.icp6s_error++; | 244 V_icmp6stat.icp6s_error++; |
244 245 /* count per-type-code statistics */ | 245 246 /* count per-type-code statistics */ |
246 icmp6_errcount(&icmp6stat.icp6s_outerrhist, type, code); | 247 icmp6_errcount(&V_icmp6stat.icp6s_outerrhist, type, code); |
247 248#ifdef M_DECRYPTED /*not openbsd*/ 249 if (m->m_flags & M_DECRYPTED) { | 248 249#ifdef M_DECRYPTED /*not openbsd*/ 250 if (m->m_flags & M_DECRYPTED) { |
250 icmp6stat.icp6s_canterror++; | 251 V_icmp6stat.icp6s_canterror++; |
251 goto freeit; 252 } 253#endif 254 255#ifndef PULLDOWN_TEST 256 IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), ); 257#else 258 if (m->m_len < sizeof(struct ip6_hdr)) { --- 41 unchanged lines hidden (view full) --- 300 301#ifndef PULLDOWN_TEST 302 IP6_EXTHDR_CHECK(m, 0, off + sizeof(struct icmp6_hdr), ); 303 icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); 304#else 305 IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off, 306 sizeof(*icp)); 307 if (icp == NULL) { | 252 goto freeit; 253 } 254#endif 255 256#ifndef PULLDOWN_TEST 257 IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), ); 258#else 259 if (m->m_len < sizeof(struct ip6_hdr)) { --- 41 unchanged lines hidden (view full) --- 301 302#ifndef PULLDOWN_TEST 303 IP6_EXTHDR_CHECK(m, 0, off + sizeof(struct icmp6_hdr), ); 304 icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); 305#else 306 IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off, 307 sizeof(*icp)); 308 if (icp == NULL) { |
308 icmp6stat.icp6s_tooshort++; | 309 V_icmp6stat.icp6s_tooshort++; |
309 return; 310 } 311#endif 312 if (icp->icmp6_type < ICMP6_ECHO_REQUEST || 313 icp->icmp6_type == ND_REDIRECT) { 314 /* 315 * ICMPv6 error 316 * Special case: for redirect (which is 317 * informational) we must not send icmp6 error. 318 */ | 310 return; 311 } 312#endif 313 if (icp->icmp6_type < ICMP6_ECHO_REQUEST || 314 icp->icmp6_type == ND_REDIRECT) { 315 /* 316 * ICMPv6 error 317 * Special case: for redirect (which is 318 * informational) we must not send icmp6 error. 319 */ |
319 icmp6stat.icp6s_canterror++; | 320 V_icmp6stat.icp6s_canterror++; |
320 goto freeit; 321 } else { 322 /* ICMPv6 informational - send the error */ 323 } 324 } else { 325 /* non-ICMPv6 - send the error */ 326 } 327 328 oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */ 329 330 /* Finally, do rate limitation check. */ 331 if (icmp6_ratelimit(&oip6->ip6_src, type, code)) { | 321 goto freeit; 322 } else { 323 /* ICMPv6 informational - send the error */ 324 } 325 } else { 326 /* non-ICMPv6 - send the error */ 327 } 328 329 oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */ 330 331 /* Finally, do rate limitation check. */ 332 if (icmp6_ratelimit(&oip6->ip6_src, type, code)) { |
332 icmp6stat.icp6s_toofreq++; | 333 V_icmp6stat.icp6s_toofreq++; |
333 goto freeit; 334 } 335 336 /* 337 * OK, ICMP6 can be generated. 338 */ 339 340 if (m->m_pkthdr.len >= ICMPV6_PLD_MAXLEN) --- 24 unchanged lines hidden (view full) --- 365 * icmp6_reflect() is designed to be in the input path. 366 * icmp6_error() can be called from both input and output path, 367 * and if we are in output path rcvif could contain bogus value. 368 * clear m->m_pkthdr.rcvif for safety, we should have enough scope 369 * information in ip header (nip6). 370 */ 371 m->m_pkthdr.rcvif = NULL; 372 | 334 goto freeit; 335 } 336 337 /* 338 * OK, ICMP6 can be generated. 339 */ 340 341 if (m->m_pkthdr.len >= ICMPV6_PLD_MAXLEN) --- 24 unchanged lines hidden (view full) --- 366 * icmp6_reflect() is designed to be in the input path. 367 * icmp6_error() can be called from both input and output path, 368 * and if we are in output path rcvif could contain bogus value. 369 * clear m->m_pkthdr.rcvif for safety, we should have enough scope 370 * information in ip header (nip6). 371 */ 372 m->m_pkthdr.rcvif = NULL; 373 |
373 icmp6stat.icp6s_outhist[type]++; | 374 V_icmp6stat.icp6s_outhist[type]++; |
374 icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */ 375 376 return; 377 378 freeit: 379 /* 380 * If we can't tell whether or not we can generate ICMP6, free it. 381 */ --- 21 unchanged lines hidden (view full) --- 403 404 /* 405 * Locate icmp6 structure in mbuf, and check 406 * that not corrupted and of at least minimum length 407 */ 408 409 ip6 = mtod(m, struct ip6_hdr *); 410 if (icmp6len < sizeof(struct icmp6_hdr)) { | 375 icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */ 376 377 return; 378 379 freeit: 380 /* 381 * If we can't tell whether or not we can generate ICMP6, free it. 382 */ --- 21 unchanged lines hidden (view full) --- 404 405 /* 406 * Locate icmp6 structure in mbuf, and check 407 * that not corrupted and of at least minimum length 408 */ 409 410 ip6 = mtod(m, struct ip6_hdr *); 411 if (icmp6len < sizeof(struct icmp6_hdr)) { |
411 icmp6stat.icp6s_tooshort++; | 412 V_icmp6stat.icp6s_tooshort++; |
412 goto freeit; 413 } 414 415 /* 416 * calculate the checksum 417 */ 418#ifndef PULLDOWN_TEST 419 icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off); 420#else 421 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); 422 if (icmp6 == NULL) { | 413 goto freeit; 414 } 415 416 /* 417 * calculate the checksum 418 */ 419#ifndef PULLDOWN_TEST 420 icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off); 421#else 422 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); 423 if (icmp6 == NULL) { |
423 icmp6stat.icp6s_tooshort++; | 424 V_icmp6stat.icp6s_tooshort++; |
424 return IPPROTO_DONE; 425 } 426#endif 427 code = icmp6->icmp6_code; 428 429 if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { 430 nd6log((LOG_ERR, 431 "ICMP6 checksum error(%d|%x) %s\n", 432 icmp6->icmp6_type, sum, 433 ip6_sprintf(ip6bufs, &ip6->ip6_src))); | 425 return IPPROTO_DONE; 426 } 427#endif 428 code = icmp6->icmp6_code; 429 430 if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { 431 nd6log((LOG_ERR, 432 "ICMP6 checksum error(%d|%x) %s\n", 433 icmp6->icmp6_type, sum, 434 ip6_sprintf(ip6bufs, &ip6->ip6_src))); |
434 icmp6stat.icp6s_checksum++; | 435 V_icmp6stat.icp6s_checksum++; |
435 goto freeit; 436 } 437 438 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { 439 /* 440 * Deliver very specific ICMP6 type only. 441 * This is important to deliver TOOBIG. Otherwise PMTUD 442 * will not work. 443 */ 444 switch (icmp6->icmp6_type) { 445 case ICMP6_DST_UNREACH: 446 case ICMP6_PACKET_TOO_BIG: 447 case ICMP6_TIME_EXCEEDED: 448 break; 449 default: 450 goto freeit; 451 } 452 } 453 | 436 goto freeit; 437 } 438 439 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { 440 /* 441 * Deliver very specific ICMP6 type only. 442 * This is important to deliver TOOBIG. Otherwise PMTUD 443 * will not work. 444 */ 445 switch (icmp6->icmp6_type) { 446 case ICMP6_DST_UNREACH: 447 case ICMP6_PACKET_TOO_BIG: 448 case ICMP6_TIME_EXCEEDED: 449 break; 450 default: 451 goto freeit; 452 } 453 } 454 |
454 icmp6stat.icp6s_inhist[icmp6->icmp6_type]++; | 455 V_icmp6stat.icp6s_inhist[icmp6->icmp6_type]++; |
455 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_msg); 456 if (icmp6->icmp6_type < ICMP6_INFOMSG_MASK) 457 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error); 458 459 switch (icmp6->icmp6_type) { 460 case ICMP6_DST_UNREACH: 461 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_dstunreach); 462 switch (code) { --- 117 unchanged lines hidden (view full) --- 580 nip6 = mtod(n, struct ip6_hdr *); 581 IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off, 582 sizeof(*nicmp6)); 583 noff = off; 584 } 585 nicmp6->icmp6_type = ICMP6_ECHO_REPLY; 586 nicmp6->icmp6_code = 0; 587 if (n) { | 456 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_msg); 457 if (icmp6->icmp6_type < ICMP6_INFOMSG_MASK) 458 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error); 459 460 switch (icmp6->icmp6_type) { 461 case ICMP6_DST_UNREACH: 462 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_dstunreach); 463 switch (code) { --- 117 unchanged lines hidden (view full) --- 581 nip6 = mtod(n, struct ip6_hdr *); 582 IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off, 583 sizeof(*nicmp6)); 584 noff = off; 585 } 586 nicmp6->icmp6_type = ICMP6_ECHO_REPLY; 587 nicmp6->icmp6_code = 0; 588 if (n) { |
588 icmp6stat.icp6s_reflect++; 589 icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++; | 589 V_icmp6stat.icp6s_reflect++; 590 V_icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++; |
590 icmp6_reflect(n, noff); 591 } 592 break; 593 594 case ICMP6_ECHO_REPLY: 595 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echoreply); 596 if (code != 0) 597 goto badcode; --- 28 unchanged lines hidden (view full) --- 626 /* XXX: these two are experimental. not officially defined. */ 627 /* XXX: per-interface statistics? */ 628 break; /* just pass it to applications */ 629 630 case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */ 631 { 632 enum { WRU, FQDN } mode; 633 | 591 icmp6_reflect(n, noff); 592 } 593 break; 594 595 case ICMP6_ECHO_REPLY: 596 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echoreply); 597 if (code != 0) 598 goto badcode; --- 28 unchanged lines hidden (view full) --- 627 /* XXX: these two are experimental. not officially defined. */ 628 /* XXX: per-interface statistics? */ 629 break; /* just pass it to applications */ 630 631 case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */ 632 { 633 enum { WRU, FQDN } mode; 634 |
634 if (!icmp6_nodeinfo) | 635 if (!V_icmp6_nodeinfo) |
635 break; 636 637 if (icmp6len == sizeof(struct icmp6_hdr) + 4) 638 mode = WRU; 639 else if (icmp6len >= sizeof(struct icmp6_nodeinfo)) 640 mode = FQDN; 641 else 642 goto badlen; 643 | 636 break; 637 638 if (icmp6len == sizeof(struct icmp6_hdr) + 4) 639 mode = WRU; 640 else if (icmp6len >= sizeof(struct icmp6_nodeinfo)) 641 mode = FQDN; 642 else 643 goto badlen; 644 |
644#define hostnamelen strlen(hostname) | 645#define hostnamelen strlen(V_hostname) |
645 if (mode == FQDN) { 646#ifndef PULLDOWN_TEST 647 IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo), 648 IPPROTO_DONE); 649#endif 650 n = m_copy(m, 0, M_COPYALL); 651 if (n) 652 n = ni6_input(n, off); 653 /* XXX meaningless if n == NULL */ 654 noff = sizeof(struct ip6_hdr); 655 } else { 656 u_char *p; 657 int maxlen, maxhlen; 658 659 /* 660 * XXX: this combination of flags is pointless, 661 * but should we keep this for compatibility? 662 */ | 646 if (mode == FQDN) { 647#ifndef PULLDOWN_TEST 648 IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo), 649 IPPROTO_DONE); 650#endif 651 n = m_copy(m, 0, M_COPYALL); 652 if (n) 653 n = ni6_input(n, off); 654 /* XXX meaningless if n == NULL */ 655 noff = sizeof(struct ip6_hdr); 656 } else { 657 u_char *p; 658 int maxlen, maxhlen; 659 660 /* 661 * XXX: this combination of flags is pointless, 662 * but should we keep this for compatibility? 663 */ |
663 if ((icmp6_nodeinfo & 5) != 5) | 664 if ((V_icmp6_nodeinfo & 5) != 5) |
664 break; 665 666 if (code != 0) 667 goto badcode; 668 maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4; 669 if (maxlen >= MCLBYTES) { 670 /* Give up remote */ 671 break; --- 31 unchanged lines hidden (view full) --- 703 * Copy IPv6 and ICMPv6 only. 704 */ 705 nip6 = mtod(n, struct ip6_hdr *); 706 bcopy(ip6, nip6, sizeof(struct ip6_hdr)); 707 nicmp6 = (struct icmp6_hdr *)(nip6 + 1); 708 bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr)); 709 p = (u_char *)(nicmp6 + 1); 710 bzero(p, 4); | 665 break; 666 667 if (code != 0) 668 goto badcode; 669 maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4; 670 if (maxlen >= MCLBYTES) { 671 /* Give up remote */ 672 break; --- 31 unchanged lines hidden (view full) --- 704 * Copy IPv6 and ICMPv6 only. 705 */ 706 nip6 = mtod(n, struct ip6_hdr *); 707 bcopy(ip6, nip6, sizeof(struct ip6_hdr)); 708 nicmp6 = (struct icmp6_hdr *)(nip6 + 1); 709 bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr)); 710 p = (u_char *)(nicmp6 + 1); 711 bzero(p, 4); |
711 bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */ | 712 bcopy(V_hostname, p + 4, maxhlen); /* meaningless TTL */ |
712 mtx_unlock(&hostname_mtx); 713 noff = sizeof(struct ip6_hdr); 714 n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 715 sizeof(struct icmp6_hdr) + 4 + maxhlen; 716 nicmp6->icmp6_type = ICMP6_WRUREPLY; 717 nicmp6->icmp6_code = 0; 718 } 719#undef hostnamelen 720 if (n) { | 713 mtx_unlock(&hostname_mtx); 714 noff = sizeof(struct ip6_hdr); 715 n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 716 sizeof(struct icmp6_hdr) + 4 + maxhlen; 717 nicmp6->icmp6_type = ICMP6_WRUREPLY; 718 nicmp6->icmp6_code = 0; 719 } 720#undef hostnamelen 721 if (n) { |
721 icmp6stat.icp6s_reflect++; 722 icmp6stat.icp6s_outhist[ICMP6_WRUREPLY]++; | 722 V_icmp6stat.icp6s_reflect++; 723 V_icmp6stat.icp6s_outhist[ICMP6_WRUREPLY]++; |
723 icmp6_reflect(n, noff); 724 } 725 break; 726 } 727 728 case ICMP6_WRUREPLY: 729 if (code != 0) 730 goto badcode; --- 104 unchanged lines hidden (view full) --- 835 deliver: 836 if (icmp6_notify_error(&m, off, icmp6len, code)) { 837 /* In this case, m should've been freed. */ 838 return (IPPROTO_DONE); 839 } 840 break; 841 842 badcode: | 724 icmp6_reflect(n, noff); 725 } 726 break; 727 } 728 729 case ICMP6_WRUREPLY: 730 if (code != 0) 731 goto badcode; --- 104 unchanged lines hidden (view full) --- 836 deliver: 837 if (icmp6_notify_error(&m, off, icmp6len, code)) { 838 /* In this case, m should've been freed. */ 839 return (IPPROTO_DONE); 840 } 841 break; 842 843 badcode: |
843 icmp6stat.icp6s_badcode++; | 844 V_icmp6stat.icp6s_badcode++; |
844 break; 845 846 badlen: | 845 break; 846 847 badlen: |
847 icmp6stat.icp6s_badlen++; | 848 V_icmp6stat.icp6s_badlen++; |
848 break; 849 } 850 851 /* deliver the packet to appropriate sockets */ 852 icmp6_rip6_input(&m, *offp); 853 854 return IPPROTO_DONE; 855 --- 7 unchanged lines hidden (view full) --- 863{ 864 struct mbuf *m = *mp; 865 struct icmp6_hdr *icmp6; 866 struct ip6_hdr *eip6; 867 u_int32_t notifymtu; 868 struct sockaddr_in6 icmp6src, icmp6dst; 869 870 if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) { | 849 break; 850 } 851 852 /* deliver the packet to appropriate sockets */ 853 icmp6_rip6_input(&m, *offp); 854 855 return IPPROTO_DONE; 856 --- 7 unchanged lines hidden (view full) --- 864{ 865 struct mbuf *m = *mp; 866 struct icmp6_hdr *icmp6; 867 struct ip6_hdr *eip6; 868 u_int32_t notifymtu; 869 struct sockaddr_in6 icmp6src, icmp6dst; 870 871 if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) { |
871 icmp6stat.icp6s_tooshort++; | 872 V_icmp6stat.icp6s_tooshort++; |
872 goto freeit; 873 } 874#ifndef PULLDOWN_TEST 875 IP6_EXTHDR_CHECK(m, off, 876 sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr), -1); 877 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); 878#else 879 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 880 sizeof(*icmp6) + sizeof(struct ip6_hdr)); 881 if (icmp6 == NULL) { | 873 goto freeit; 874 } 875#ifndef PULLDOWN_TEST 876 IP6_EXTHDR_CHECK(m, off, 877 sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr), -1); 878 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); 879#else 880 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 881 sizeof(*icmp6) + sizeof(struct ip6_hdr)); 882 if (icmp6 == NULL) { |
882 icmp6stat.icp6s_tooshort++; | 883 V_icmp6stat.icp6s_tooshort++; |
883 return (-1); 884 } 885#endif 886 eip6 = (struct ip6_hdr *)(icmp6 + 1); 887 888 /* Detect the upper level protocol */ 889 { 890 void (*ctlfunc)(int, struct sockaddr *, void *); --- 18 unchanged lines hidden (view full) --- 909#ifndef PULLDOWN_TEST 910 IP6_EXTHDR_CHECK(m, 0, 911 eoff + sizeof(struct ip6_ext), -1); 912 eh = (struct ip6_ext *)(mtod(m, caddr_t) + eoff); 913#else 914 IP6_EXTHDR_GET(eh, struct ip6_ext *, m, 915 eoff, sizeof(*eh)); 916 if (eh == NULL) { | 884 return (-1); 885 } 886#endif 887 eip6 = (struct ip6_hdr *)(icmp6 + 1); 888 889 /* Detect the upper level protocol */ 890 { 891 void (*ctlfunc)(int, struct sockaddr *, void *); --- 18 unchanged lines hidden (view full) --- 910#ifndef PULLDOWN_TEST 911 IP6_EXTHDR_CHECK(m, 0, 912 eoff + sizeof(struct ip6_ext), -1); 913 eh = (struct ip6_ext *)(mtod(m, caddr_t) + eoff); 914#else 915 IP6_EXTHDR_GET(eh, struct ip6_ext *, m, 916 eoff, sizeof(*eh)); 917 if (eh == NULL) { |
917 icmp6stat.icp6s_tooshort++; | 918 V_icmp6stat.icp6s_tooshort++; |
918 return (-1); 919 } 920#endif 921 922 if (nxt == IPPROTO_AH) 923 eoff += (eh->ip6e_len + 2) << 2; 924 else 925 eoff += (eh->ip6e_len + 1) << 3; --- 11 unchanged lines hidden (view full) --- 937#ifndef PULLDOWN_TEST 938 IP6_EXTHDR_CHECK(m, 0, eoff + sizeof(*rth), -1); 939 rth = (struct ip6_rthdr *) 940 (mtod(m, caddr_t) + eoff); 941#else 942 IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m, 943 eoff, sizeof(*rth)); 944 if (rth == NULL) { | 919 return (-1); 920 } 921#endif 922 923 if (nxt == IPPROTO_AH) 924 eoff += (eh->ip6e_len + 2) << 2; 925 else 926 eoff += (eh->ip6e_len + 1) << 3; --- 11 unchanged lines hidden (view full) --- 938#ifndef PULLDOWN_TEST 939 IP6_EXTHDR_CHECK(m, 0, eoff + sizeof(*rth), -1); 940 rth = (struct ip6_rthdr *) 941 (mtod(m, caddr_t) + eoff); 942#else 943 IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m, 944 eoff, sizeof(*rth)); 945 if (rth == NULL) { |
945 icmp6stat.icp6s_tooshort++; | 946 V_icmp6stat.icp6s_tooshort++; |
946 return (-1); 947 } 948#endif 949 rthlen = (rth->ip6r_len + 1) << 3; 950 /* 951 * XXX: currently there is no 952 * officially defined type other 953 * than type-0. --- 9 unchanged lines hidden (view full) --- 963 IP6_EXTHDR_CHECK(m, 0, eoff + rthlen, -1); 964 rth0 = (struct ip6_rthdr0 *) 965 (mtod(m, caddr_t) + eoff); 966#else 967 IP6_EXTHDR_GET(rth0, 968 struct ip6_rthdr0 *, m, 969 eoff, rthlen); 970 if (rth0 == NULL) { | 947 return (-1); 948 } 949#endif 950 rthlen = (rth->ip6r_len + 1) << 3; 951 /* 952 * XXX: currently there is no 953 * officially defined type other 954 * than type-0. --- 9 unchanged lines hidden (view full) --- 964 IP6_EXTHDR_CHECK(m, 0, eoff + rthlen, -1); 965 rth0 = (struct ip6_rthdr0 *) 966 (mtod(m, caddr_t) + eoff); 967#else 968 IP6_EXTHDR_GET(rth0, 969 struct ip6_rthdr0 *, m, 970 eoff, rthlen); 971 if (rth0 == NULL) { |
971 icmp6stat.icp6s_tooshort++; | 972 V_icmp6stat.icp6s_tooshort++; |
972 return (-1); 973 } 974#endif 975 /* just ignore a bogus header */ 976 if ((rth0->ip6r0_len % 2) == 0 && 977 (hops = rth0->ip6r0_len/2)) 978 finaldst = (struct in6_addr *)(rth0 + 1) + (hops - 1); 979 } --- 5 unchanged lines hidden (view full) --- 985 IP6_EXTHDR_CHECK(m, 0, eoff + 986 sizeof(struct ip6_frag), -1); 987 fh = (struct ip6_frag *)(mtod(m, caddr_t) + 988 eoff); 989#else 990 IP6_EXTHDR_GET(fh, struct ip6_frag *, m, 991 eoff, sizeof(*fh)); 992 if (fh == NULL) { | 973 return (-1); 974 } 975#endif 976 /* just ignore a bogus header */ 977 if ((rth0->ip6r0_len % 2) == 0 && 978 (hops = rth0->ip6r0_len/2)) 979 finaldst = (struct in6_addr *)(rth0 + 1) + (hops - 1); 980 } --- 5 unchanged lines hidden (view full) --- 986 IP6_EXTHDR_CHECK(m, 0, eoff + 987 sizeof(struct ip6_frag), -1); 988 fh = (struct ip6_frag *)(mtod(m, caddr_t) + 989 eoff); 990#else 991 IP6_EXTHDR_GET(fh, struct ip6_frag *, m, 992 eoff, sizeof(*fh)); 993 if (fh == NULL) { |
993 icmp6stat.icp6s_tooshort++; | 994 V_icmp6stat.icp6s_tooshort++; |
994 return (-1); 995 } 996#endif 997 /* 998 * Data after a fragment header is meaningless 999 * unless it is the first fragment, but 1000 * we'll go to the notify label for path MTU 1001 * discovery. --- 18 unchanged lines hidden (view full) --- 1020 } 1021 notify: 1022#ifndef PULLDOWN_TEST 1023 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); 1024#else 1025 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 1026 sizeof(*icmp6) + sizeof(struct ip6_hdr)); 1027 if (icmp6 == NULL) { | 995 return (-1); 996 } 997#endif 998 /* 999 * Data after a fragment header is meaningless 1000 * unless it is the first fragment, but 1001 * we'll go to the notify label for path MTU 1002 * discovery. --- 18 unchanged lines hidden (view full) --- 1021 } 1022 notify: 1023#ifndef PULLDOWN_TEST 1024 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); 1025#else 1026 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 1027 sizeof(*icmp6) + sizeof(struct ip6_hdr)); 1028 if (icmp6 == NULL) { |
1028 icmp6stat.icp6s_tooshort++; | 1029 V_icmp6stat.icp6s_tooshort++; |
1029 return (-1); 1030 } 1031#endif 1032 1033 /* 1034 * retrieve parameters from the inner IPv6 header, and convert 1035 * them into sockaddr structures. 1036 * XXX: there is no guarantee that the source or destination --- 87 unchanged lines hidden (view full) --- 1124 bzero(&inc, sizeof(inc)); 1125 inc.inc_flags = 1; /* IPv6 */ 1126 inc.inc6_faddr = *dst; 1127 if (in6_setscope(&inc.inc6_faddr, m->m_pkthdr.rcvif, NULL)) 1128 return; 1129 1130 if (mtu < tcp_maxmtu6(&inc, NULL)) { 1131 tcp_hc_updatemtu(&inc, mtu); | 1030 return (-1); 1031 } 1032#endif 1033 1034 /* 1035 * retrieve parameters from the inner IPv6 header, and convert 1036 * them into sockaddr structures. 1037 * XXX: there is no guarantee that the source or destination --- 87 unchanged lines hidden (view full) --- 1125 bzero(&inc, sizeof(inc)); 1126 inc.inc_flags = 1; /* IPv6 */ 1127 inc.inc6_faddr = *dst; 1128 if (in6_setscope(&inc.inc6_faddr, m->m_pkthdr.rcvif, NULL)) 1129 return; 1130 1131 if (mtu < tcp_maxmtu6(&inc, NULL)) { 1132 tcp_hc_updatemtu(&inc, mtu); |
1132 icmp6stat.icp6s_pmtuchg++; | 1133 V_icmp6stat.icp6s_pmtuchg++; |
1133 } 1134} 1135 1136/* 1137 * Process a Node Information Query packet, based on 1138 * draft-ietf-ipngwg-icmp-name-lookups-07. 1139 * 1140 * Spec incompatibilities: 1141 * - IPv6 Subject address handling 1142 * - IPv4 Subject address handling support missing 1143 * - Proxy reply (answer even if it's not for me) 1144 * - joins NI group address at in6_ifattach() time only, does not cope 1145 * with hostname changes by sethostname(3) 1146 */ | 1134 } 1135} 1136 1137/* 1138 * Process a Node Information Query packet, based on 1139 * draft-ietf-ipngwg-icmp-name-lookups-07. 1140 * 1141 * Spec incompatibilities: 1142 * - IPv6 Subject address handling 1143 * - IPv4 Subject address handling support missing 1144 * - Proxy reply (answer even if it's not for me) 1145 * - joins NI group address at in6_ifattach() time only, does not cope 1146 * with hostname changes by sethostname(3) 1147 */ |
1147#define hostnamelen strlen(hostname) | 1148#define hostnamelen strlen(V_hostname) |
1148static struct mbuf * 1149ni6_input(struct mbuf *m, int off) 1150{ 1151 struct icmp6_nodeinfo *ni6, *nni6; 1152 struct mbuf *n = NULL; 1153 u_int16_t qtype; 1154 int subjlen; 1155 int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo); --- 25 unchanged lines hidden (view full) --- 1181 * - it's not very clear what "refuse" means; this implementation 1182 * simply drops it. 1183 * - it's not very easy to identify global-scope (unicast) addresses 1184 * since there are many prefixes for them. It should be safer 1185 * and in practice sufficient to check "all" but loopback and 1186 * link-local (note that site-local unicast was deprecated and 1187 * ULA is defined as global scope-wise) 1188 */ | 1149static struct mbuf * 1150ni6_input(struct mbuf *m, int off) 1151{ 1152 struct icmp6_nodeinfo *ni6, *nni6; 1153 struct mbuf *n = NULL; 1154 u_int16_t qtype; 1155 int subjlen; 1156 int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo); --- 25 unchanged lines hidden (view full) --- 1182 * - it's not very clear what "refuse" means; this implementation 1183 * simply drops it. 1184 * - it's not very easy to identify global-scope (unicast) addresses 1185 * since there are many prefixes for them. It should be safer 1186 * and in practice sufficient to check "all" but loopback and 1187 * link-local (note that site-local unicast was deprecated and 1188 * ULA is defined as global scope-wise) 1189 */ |
1189 if ((icmp6_nodeinfo & ICMP6_NODEINFO_GLOBALOK) == 0 && | 1190 if ((V_icmp6_nodeinfo & ICMP6_NODEINFO_GLOBALOK) == 0 && |
1190 !IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) && 1191 !IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) 1192 goto bad; 1193 1194 /* 1195 * Validate IPv6 destination address. 1196 * 1197 * The Responder must discard the Query without further processing --- 5 unchanged lines hidden (view full) --- 1203 if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) 1204 goto bad; 1205 /* else it's a link-local multicast, fine */ 1206 } else { /* unicast or anycast */ 1207 if ((ia6 = ip6_getdstifaddr(m)) == NULL) 1208 goto bad; /* XXX impossible */ 1209 1210 if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) && | 1191 !IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) && 1192 !IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) 1193 goto bad; 1194 1195 /* 1196 * Validate IPv6 destination address. 1197 * 1198 * The Responder must discard the Query without further processing --- 5 unchanged lines hidden (view full) --- 1204 if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) 1205 goto bad; 1206 /* else it's a link-local multicast, fine */ 1207 } else { /* unicast or anycast */ 1208 if ((ia6 = ip6_getdstifaddr(m)) == NULL) 1209 goto bad; /* XXX impossible */ 1210 1211 if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) && |
1211 !(icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) { | 1212 !(V_icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) { |
1212 nd6log((LOG_DEBUG, "ni6_input: ignore node info to " 1213 "a temporary address in %s:%d", 1214 __FILE__, __LINE__)); 1215 goto bad; 1216 } 1217 } 1218 1219 /* validate query Subject field. */ --- 74 unchanged lines hidden (view full) --- 1294 * - we are not sure if the node has FQDN as 1295 * hostname (returned by gethostname(3)). 1296 * - the code does wildcard match for truncated names. 1297 * however, we are not sure if we want to perform 1298 * wildcard match, if gethostname(3) side has 1299 * truncated hostname. 1300 */ 1301 mtx_lock(&hostname_mtx); | 1213 nd6log((LOG_DEBUG, "ni6_input: ignore node info to " 1214 "a temporary address in %s:%d", 1215 __FILE__, __LINE__)); 1216 goto bad; 1217 } 1218 } 1219 1220 /* validate query Subject field. */ --- 74 unchanged lines hidden (view full) --- 1295 * - we are not sure if the node has FQDN as 1296 * hostname (returned by gethostname(3)). 1297 * - the code does wildcard match for truncated names. 1298 * however, we are not sure if we want to perform 1299 * wildcard match, if gethostname(3) side has 1300 * truncated hostname. 1301 */ 1302 mtx_lock(&hostname_mtx); |
1302 n = ni6_nametodns(hostname, hostnamelen, 0); | 1303 n = ni6_nametodns(V_hostname, hostnamelen, 0); |
1303 mtx_unlock(&hostname_mtx); 1304 if (!n || n->m_next || n->m_len == 0) 1305 goto bad; 1306 IP6_EXTHDR_GET(subj, char *, m, 1307 off + sizeof(struct icmp6_nodeinfo), subjlen); 1308 if (subj == NULL) 1309 goto bad; 1310 if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *), --- 9 unchanged lines hidden (view full) --- 1320 goto bad; 1321 } 1322 break; 1323 } 1324 1325 /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */ 1326 switch (qtype) { 1327 case NI_QTYPE_FQDN: | 1304 mtx_unlock(&hostname_mtx); 1305 if (!n || n->m_next || n->m_len == 0) 1306 goto bad; 1307 IP6_EXTHDR_GET(subj, char *, m, 1308 off + sizeof(struct icmp6_nodeinfo), subjlen); 1309 if (subj == NULL) 1310 goto bad; 1311 if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *), --- 9 unchanged lines hidden (view full) --- 1321 goto bad; 1322 } 1323 break; 1324 } 1325 1326 /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */ 1327 switch (qtype) { 1328 case NI_QTYPE_FQDN: |
1328 if ((icmp6_nodeinfo & ICMP6_NODEINFO_FQDNOK) == 0) | 1329 if ((V_icmp6_nodeinfo & ICMP6_NODEINFO_FQDNOK) == 0) |
1329 goto bad; 1330 break; 1331 case NI_QTYPE_NODEADDR: 1332 case NI_QTYPE_IPV4ADDR: | 1330 goto bad; 1331 break; 1332 case NI_QTYPE_NODEADDR: 1333 case NI_QTYPE_IPV4ADDR: |
1333 if ((icmp6_nodeinfo & ICMP6_NODEINFO_NODEADDROK) == 0) | 1334 if ((V_icmp6_nodeinfo & ICMP6_NODEINFO_NODEADDROK) == 0) |
1334 goto bad; 1335 break; 1336 } 1337 1338 /* guess reply length */ 1339 switch (qtype) { 1340 case NI_QTYPE_NOOP: 1341 break; /* no reply data */ --- 78 unchanged lines hidden (view full) --- 1420 fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) + 1421 sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo)); 1422 nni6->ni_flags = 0; /* XXX: meaningless TTL */ 1423 fqdn->ni_fqdn_ttl = 0; /* ditto. */ 1424 /* 1425 * XXX do we really have FQDN in variable "hostname"? 1426 */ 1427 mtx_lock(&hostname_mtx); | 1335 goto bad; 1336 break; 1337 } 1338 1339 /* guess reply length */ 1340 switch (qtype) { 1341 case NI_QTYPE_NOOP: 1342 break; /* no reply data */ --- 78 unchanged lines hidden (view full) --- 1421 fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) + 1422 sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo)); 1423 nni6->ni_flags = 0; /* XXX: meaningless TTL */ 1424 fqdn->ni_fqdn_ttl = 0; /* ditto. */ 1425 /* 1426 * XXX do we really have FQDN in variable "hostname"? 1427 */ 1428 mtx_lock(&hostname_mtx); |
1428 n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn); | 1429 n->m_next = ni6_nametodns(V_hostname, hostnamelen, oldfqdn); |
1429 mtx_unlock(&hostname_mtx); 1430 if (n->m_next == NULL) 1431 goto bad; 1432 /* XXX we assume that n->m_next is not a chain */ 1433 if (n->m_next->m_next != NULL) 1434 goto bad; 1435 n->m_pkthdr.len += n->m_next->m_len; 1436 break; --- 213 unchanged lines hidden (view full) --- 1650 * XXX: we only support IPv6 subject address for 1651 * this Qtype. 1652 */ 1653 return (0); 1654 } 1655 } 1656 1657 IFNET_RLOCK(); | 1430 mtx_unlock(&hostname_mtx); 1431 if (n->m_next == NULL) 1432 goto bad; 1433 /* XXX we assume that n->m_next is not a chain */ 1434 if (n->m_next->m_next != NULL) 1435 goto bad; 1436 n->m_pkthdr.len += n->m_next->m_len; 1437 break; --- 213 unchanged lines hidden (view full) --- 1651 * XXX: we only support IPv6 subject address for 1652 * this Qtype. 1653 */ 1654 return (0); 1655 } 1656 } 1657 1658 IFNET_RLOCK(); |
1658 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { | 1659 for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { |
1659 addrsofif = 0; 1660 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1661 if (ifa->ifa_addr->sa_family != AF_INET6) 1662 continue; 1663 ifa6 = (struct in6_ifaddr *)ifa; 1664 1665 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 && 1666 IN6_ARE_ADDR_EQUAL(subj, &ifa6->ia_addr.sin6_addr)) --- 30 unchanged lines hidden (view full) --- 1697 /* 1698 * check if anycast is okay. 1699 * XXX: just experimental. not in the spec. 1700 */ 1701 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1702 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1703 continue; /* we need only unicast addresses */ 1704 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && | 1660 addrsofif = 0; 1661 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1662 if (ifa->ifa_addr->sa_family != AF_INET6) 1663 continue; 1664 ifa6 = (struct in6_ifaddr *)ifa; 1665 1666 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 && 1667 IN6_ARE_ADDR_EQUAL(subj, &ifa6->ia_addr.sin6_addr)) --- 30 unchanged lines hidden (view full) --- 1698 /* 1699 * check if anycast is okay. 1700 * XXX: just experimental. not in the spec. 1701 */ 1702 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1703 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1704 continue; /* we need only unicast addresses */ 1705 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && |
1705 (icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) { | 1706 (V_icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) { |
1706 continue; 1707 } 1708 addrsofif++; /* count the address */ 1709 } 1710 if (iffound) { 1711 *ifpp = ifp; 1712 IFNET_RUNLOCK(); 1713 return (addrsofif); --- 5 unchanged lines hidden (view full) --- 1719 1720 return (addrs); 1721} 1722 1723static int 1724ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, 1725 struct ifnet *ifp0, int resid) 1726{ | 1707 continue; 1708 } 1709 addrsofif++; /* count the address */ 1710 } 1711 if (iffound) { 1712 *ifpp = ifp; 1713 IFNET_RUNLOCK(); 1714 return (addrsofif); --- 5 unchanged lines hidden (view full) --- 1720 1721 return (addrs); 1722} 1723 1724static int 1725ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, 1726 struct ifnet *ifp0, int resid) 1727{ |
1727 struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet); | 1728 struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&V_ifnet); |
1728 struct in6_ifaddr *ifa6; 1729 struct ifaddr *ifa; 1730 struct ifnet *ifp_dep = NULL; 1731 int copied = 0, allow_deprecated = 0; 1732 u_char *cp = (u_char *)(nni6 + 1); 1733 int niflags = ni6->ni_flags; 1734 u_int32_t ltime; 1735 --- 47 unchanged lines hidden (view full) --- 1783 /* 1784 * check if anycast is okay. 1785 * XXX: just experimental. not in the spec. 1786 */ 1787 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1788 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1789 continue; 1790 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && | 1729 struct in6_ifaddr *ifa6; 1730 struct ifaddr *ifa; 1731 struct ifnet *ifp_dep = NULL; 1732 int copied = 0, allow_deprecated = 0; 1733 u_char *cp = (u_char *)(nni6 + 1); 1734 int niflags = ni6->ni_flags; 1735 u_int32_t ltime; 1736 --- 47 unchanged lines hidden (view full) --- 1784 /* 1785 * check if anycast is okay. 1786 * XXX: just experimental. not in the spec. 1787 */ 1788 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1789 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1790 continue; 1791 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && |
1791 (icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) { | 1792 (V_icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) { |
1792 continue; 1793 } 1794 1795 /* now we can copy the address */ 1796 if (resid < sizeof(struct in6_addr) + 1797 sizeof(u_int32_t)) { 1798 /* 1799 * We give up much more copy. --- 90 unchanged lines hidden (view full) --- 1890 fromsa.sin6_family = AF_INET6; 1891 fromsa.sin6_len = sizeof(struct sockaddr_in6); 1892 fromsa.sin6_addr = ip6->ip6_src; 1893 if (sa6_recoverscope(&fromsa)) { 1894 m_freem(m); 1895 return (IPPROTO_DONE); 1896 } 1897 | 1793 continue; 1794 } 1795 1796 /* now we can copy the address */ 1797 if (resid < sizeof(struct in6_addr) + 1798 sizeof(u_int32_t)) { 1799 /* 1800 * We give up much more copy. --- 90 unchanged lines hidden (view full) --- 1891 fromsa.sin6_family = AF_INET6; 1892 fromsa.sin6_len = sizeof(struct sockaddr_in6); 1893 fromsa.sin6_addr = ip6->ip6_src; 1894 if (sa6_recoverscope(&fromsa)) { 1895 m_freem(m); 1896 return (IPPROTO_DONE); 1897 } 1898 |
1898 INP_INFO_RLOCK(&ripcbinfo); 1899 LIST_FOREACH(in6p, &ripcb, inp_list) { | 1899 INP_INFO_RLOCK(&V_ripcbinfo); 1900 LIST_FOREACH(in6p, &V_ripcb, inp_list) { |
1900 if ((in6p->inp_vflag & INP_IPV6) == 0) 1901 continue; 1902 if (in6p->in6p_ip6_nxt != IPPROTO_ICMPV6) 1903 continue; 1904 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && 1905 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) 1906 continue; 1907 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && --- 60 unchanged lines hidden (view full) --- 1968 } else 1969 sorwakeup_locked(last->in6p_socket); 1970 opts = NULL; 1971 } 1972 INP_RUNLOCK(last); 1973 } 1974 last = in6p; 1975 } | 1901 if ((in6p->inp_vflag & INP_IPV6) == 0) 1902 continue; 1903 if (in6p->in6p_ip6_nxt != IPPROTO_ICMPV6) 1904 continue; 1905 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && 1906 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) 1907 continue; 1908 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && --- 60 unchanged lines hidden (view full) --- 1969 } else 1970 sorwakeup_locked(last->in6p_socket); 1971 opts = NULL; 1972 } 1973 INP_RUNLOCK(last); 1974 } 1975 last = in6p; 1976 } |
1976 INP_INFO_RUNLOCK(&ripcbinfo); | 1977 INP_INFO_RUNLOCK(&V_ripcbinfo); |
1977 if (last) { 1978 if (last->in6p_flags & IN6P_CONTROLOPTS) 1979 ip6_savecontrol(last, m, &opts); 1980 /* strip intermediate headers */ 1981 m_adj(m, off); 1982 1983 /* avoid using mbuf clusters if possible (see above) */ 1984 if ((m->m_flags & M_EXT) && m->m_next == NULL && --- 21 unchanged lines hidden (view full) --- 2006 if (opts) 2007 m_freem(opts); 2008 SOCKBUF_UNLOCK(&last->in6p_socket->so_rcv); 2009 } else 2010 sorwakeup_locked(last->in6p_socket); 2011 INP_RUNLOCK(last); 2012 } else { 2013 m_freem(m); | 1978 if (last) { 1979 if (last->in6p_flags & IN6P_CONTROLOPTS) 1980 ip6_savecontrol(last, m, &opts); 1981 /* strip intermediate headers */ 1982 m_adj(m, off); 1983 1984 /* avoid using mbuf clusters if possible (see above) */ 1985 if ((m->m_flags & M_EXT) && m->m_next == NULL && --- 21 unchanged lines hidden (view full) --- 2007 if (opts) 2008 m_freem(opts); 2009 SOCKBUF_UNLOCK(&last->in6p_socket->so_rcv); 2010 } else 2011 sorwakeup_locked(last->in6p_socket); 2012 INP_RUNLOCK(last); 2013 } else { 2014 m_freem(m); |
2014 ip6stat.ip6s_delivered--; | 2015 V_ip6stat.ip6s_delivered--; |
2015 } 2016 return IPPROTO_DONE; 2017} 2018 2019/* 2020 * Reflect the ip6 packet back to the source. 2021 * OFF points to the icmp6 header, counted from the top of the mbuf. 2022 */ --- 127 unchanged lines hidden (view full) --- 2150 ip6->ip6_vfc |= IPV6_VERSION; 2151 ip6->ip6_nxt = IPPROTO_ICMPV6; 2152 if (outif) 2153 ip6->ip6_hlim = ND_IFINFO(outif)->chlim; 2154 else if (m->m_pkthdr.rcvif) { 2155 /* XXX: This may not be the outgoing interface */ 2156 ip6->ip6_hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim; 2157 } else | 2016 } 2017 return IPPROTO_DONE; 2018} 2019 2020/* 2021 * Reflect the ip6 packet back to the source. 2022 * OFF points to the icmp6 header, counted from the top of the mbuf. 2023 */ --- 127 unchanged lines hidden (view full) --- 2151 ip6->ip6_vfc |= IPV6_VERSION; 2152 ip6->ip6_nxt = IPPROTO_ICMPV6; 2153 if (outif) 2154 ip6->ip6_hlim = ND_IFINFO(outif)->chlim; 2155 else if (m->m_pkthdr.rcvif) { 2156 /* XXX: This may not be the outgoing interface */ 2157 ip6->ip6_hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim; 2158 } else |
2158 ip6->ip6_hlim = ip6_defhlim; | 2159 ip6->ip6_hlim = V_ip6_defhlim; |
2159 2160 icmp6->icmp6_cksum = 0; 2161 icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6, 2162 sizeof(struct ip6_hdr), plen); 2163 2164 /* 2165 * XXX option handling 2166 */ --- 56 unchanged lines hidden (view full) --- 2223 return; 2224 2225 ifp = m->m_pkthdr.rcvif; 2226 2227 if (!ifp) 2228 return; 2229 2230 /* XXX if we are router, we don't update route by icmp6 redirect */ | 2160 2161 icmp6->icmp6_cksum = 0; 2162 icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6, 2163 sizeof(struct ip6_hdr), plen); 2164 2165 /* 2166 * XXX option handling 2167 */ --- 56 unchanged lines hidden (view full) --- 2224 return; 2225 2226 ifp = m->m_pkthdr.rcvif; 2227 2228 if (!ifp) 2229 return; 2230 2231 /* XXX if we are router, we don't update route by icmp6 redirect */ |
2231 if (ip6_forwarding) | 2232 if (V_ip6_forwarding) |
2232 goto freeit; | 2233 goto freeit; |
2233 if (!icmp6_rediraccept) | 2234 if (!V_icmp6_rediraccept) |
2234 goto freeit; 2235 2236#ifndef PULLDOWN_TEST 2237 IP6_EXTHDR_CHECK(m, off, icmp6len,); 2238 nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off); 2239#else 2240 IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len); 2241 if (nd_rd == NULL) { | 2235 goto freeit; 2236 2237#ifndef PULLDOWN_TEST 2238 IP6_EXTHDR_CHECK(m, off, icmp6len,); 2239 nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off); 2240#else 2241 IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len); 2242 if (nd_rd == NULL) { |
2242 icmp6stat.icp6s_tooshort++; | 2243 V_icmp6stat.icp6s_tooshort++; |
2243 return; 2244 } 2245#endif 2246 redtgt6 = nd_rd->nd_rd_target; 2247 reddst6 = nd_rd->nd_rd_dst; 2248 2249 if (in6_setscope(&redtgt6, m->m_pkthdr.rcvif, NULL) || 2250 in6_setscope(&reddst6, m->m_pkthdr.rcvif, NULL)) { --- 146 unchanged lines hidden (view full) --- 2397#endif /* IPSEC */ 2398 } 2399 2400 freeit: 2401 m_freem(m); 2402 return; 2403 2404 bad: | 2244 return; 2245 } 2246#endif 2247 redtgt6 = nd_rd->nd_rd_target; 2248 reddst6 = nd_rd->nd_rd_dst; 2249 2250 if (in6_setscope(&redtgt6, m->m_pkthdr.rcvif, NULL) || 2251 in6_setscope(&reddst6, m->m_pkthdr.rcvif, NULL)) { --- 146 unchanged lines hidden (view full) --- 2398#endif /* IPSEC */ 2399 } 2400 2401 freeit: 2402 m_freem(m); 2403 return; 2404 2405 bad: |
2405 icmp6stat.icp6s_badredirect++; | 2406 V_icmp6stat.icp6s_badredirect++; |
2406 m_freem(m); 2407} 2408 2409void 2410icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) 2411{ 2412 struct ifnet *ifp; /* my outgoing interface */ 2413 struct in6_addr *ifp_ll6; 2414 struct in6_addr *router_ll6; 2415 struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */ 2416 struct mbuf *m = NULL; /* newly allocated one */ 2417 struct ip6_hdr *ip6; /* m as struct ip6_hdr */ 2418 struct nd_redirect *nd_rd; 2419 size_t maxlen; 2420 u_char *p; 2421 struct ifnet *outif = NULL; 2422 struct sockaddr_in6 src_sa; 2423 | 2407 m_freem(m); 2408} 2409 2410void 2411icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) 2412{ 2413 struct ifnet *ifp; /* my outgoing interface */ 2414 struct in6_addr *ifp_ll6; 2415 struct in6_addr *router_ll6; 2416 struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */ 2417 struct mbuf *m = NULL; /* newly allocated one */ 2418 struct ip6_hdr *ip6; /* m as struct ip6_hdr */ 2419 struct nd_redirect *nd_rd; 2420 size_t maxlen; 2421 u_char *p; 2422 struct ifnet *outif = NULL; 2423 struct sockaddr_in6 src_sa; 2424 |
2424 icmp6_errcount(&icmp6stat.icp6s_outerrhist, ND_REDIRECT, 0); | 2425 icmp6_errcount(&V_icmp6stat.icp6s_outerrhist, ND_REDIRECT, 0); |
2425 2426 /* if we are not router, we don't send icmp6 redirect */ | 2426 2427 /* if we are not router, we don't send icmp6 redirect */ |
2427 if (!ip6_forwarding) | 2428 if (!V_ip6_forwarding) |
2428 goto fail; 2429 2430 /* sanity check */ 2431 if (!m0 || !rt || !(rt->rt_flags & RTF_UP) || !(ifp = rt->rt_ifp)) 2432 goto fail; 2433 2434 /* 2435 * Address check: --- 235 unchanged lines hidden (view full) --- 2671 sizeof(*ip6), ntohs(ip6->ip6_plen)); 2672 2673 /* send the packet to outside... */ 2674 ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL); 2675 if (outif) { 2676 icmp6_ifstat_inc(outif, ifs6_out_msg); 2677 icmp6_ifstat_inc(outif, ifs6_out_redirect); 2678 } | 2429 goto fail; 2430 2431 /* sanity check */ 2432 if (!m0 || !rt || !(rt->rt_flags & RTF_UP) || !(ifp = rt->rt_ifp)) 2433 goto fail; 2434 2435 /* 2436 * Address check: --- 235 unchanged lines hidden (view full) --- 2672 sizeof(*ip6), ntohs(ip6->ip6_plen)); 2673 2674 /* send the packet to outside... */ 2675 ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL); 2676 if (outif) { 2677 icmp6_ifstat_inc(outif, ifs6_out_msg); 2678 icmp6_ifstat_inc(outif, ifs6_out_redirect); 2679 } |
2679 icmp6stat.icp6s_outhist[ND_REDIRECT]++; | 2680 V_icmp6stat.icp6s_outhist[ND_REDIRECT]++; |
2680 2681 return; 2682 2683fail: 2684 if (m) 2685 m_freem(m); 2686 if (m0) 2687 m_freem(m0); --- 87 unchanged lines hidden (view full) --- 2775icmp6_ratelimit(const struct in6_addr *dst, const int type, 2776 const int code) 2777{ 2778 int ret; 2779 2780 ret = 0; /* okay to send */ 2781 2782 /* PPS limit */ | 2681 2682 return; 2683 2684fail: 2685 if (m) 2686 m_freem(m); 2687 if (m0) 2688 m_freem(m0); --- 87 unchanged lines hidden (view full) --- 2776icmp6_ratelimit(const struct in6_addr *dst, const int type, 2777 const int code) 2778{ 2779 int ret; 2780 2781 ret = 0; /* okay to send */ 2782 2783 /* PPS limit */ |
2783 if (!ppsratecheck(&icmp6errppslim_last, &icmp6errpps_count, 2784 icmp6errppslim)) { | 2784 if (!ppsratecheck(&V_icmp6errppslim_last, &V_icmp6errpps_count, 2785 V_icmp6errppslim)) { |
2785 /* The packet is subject to rate limit */ 2786 ret++; 2787 } 2788 2789 return ret; 2790} | 2786 /* The packet is subject to rate limit */ 2787 ret++; 2788 } 2789 2790 return ret; 2791} |