Deleted Added
full compact
icmp6.c (120727) icmp6.c (120856)
1/* $FreeBSD: head/sys/netinet6/icmp6.c 120727 2003-10-04 03:44:50Z sam $ */
1/* $FreeBSD: head/sys/netinet6/icmp6.c 120856 2003-10-06 14:02:09Z ume $ */
2/* $KAME: icmp6.c,v 1.211 2001/04/04 05:56:20 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
9 * modification, are permitted provided that the following conditions

--- 833 unchanged lines hidden (view full) ---

843 /* deliver */
844 } else {
845 /* ICMPv6 informational: MUST not deliver */
846 break;
847 }
848 deliver:
849 if (icmp6_notify_error(m, off, icmp6len, code)) {
850 /* In this case, m should've been freed. */
2/* $KAME: icmp6.c,v 1.211 2001/04/04 05:56:20 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
9 * modification, are permitted provided that the following conditions

--- 833 unchanged lines hidden (view full) ---

843 /* deliver */
844 } else {
845 /* ICMPv6 informational: MUST not deliver */
846 break;
847 }
848 deliver:
849 if (icmp6_notify_error(m, off, icmp6len, code)) {
850 /* In this case, m should've been freed. */
851 return(IPPROTO_DONE);
851 return (IPPROTO_DONE);
852 }
853 break;
854
855 badcode:
856 icmp6stat.icp6s_badcode++;
857 break;
858
859 badlen:

--- 30 unchanged lines hidden (view full) ---

890 sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr),
891 -1);
892 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
893#else
894 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
895 sizeof(*icmp6) + sizeof(struct ip6_hdr));
896 if (icmp6 == NULL) {
897 icmp6stat.icp6s_tooshort++;
852 }
853 break;
854
855 badcode:
856 icmp6stat.icp6s_badcode++;
857 break;
858
859 badlen:

--- 30 unchanged lines hidden (view full) ---

890 sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr),
891 -1);
892 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
893#else
894 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
895 sizeof(*icmp6) + sizeof(struct ip6_hdr));
896 if (icmp6 == NULL) {
897 icmp6stat.icp6s_tooshort++;
898 return(-1);
898 return (-1);
899 }
900#endif
901 eip6 = (struct ip6_hdr *)(icmp6 + 1);
902
903 /* Detect the upper level protocol */
904 {
905 void (*ctlfunc) __P((int, struct sockaddr *, void *));
906 u_int8_t nxt = eip6->ip6_nxt;

--- 20 unchanged lines hidden (view full) ---

927 -1);
928 eh = (struct ip6_ext *)(mtod(m, caddr_t)
929 + eoff);
930#else
931 IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
932 eoff, sizeof(*eh));
933 if (eh == NULL) {
934 icmp6stat.icp6s_tooshort++;
899 }
900#endif
901 eip6 = (struct ip6_hdr *)(icmp6 + 1);
902
903 /* Detect the upper level protocol */
904 {
905 void (*ctlfunc) __P((int, struct sockaddr *, void *));
906 u_int8_t nxt = eip6->ip6_nxt;

--- 20 unchanged lines hidden (view full) ---

927 -1);
928 eh = (struct ip6_ext *)(mtod(m, caddr_t)
929 + eoff);
930#else
931 IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
932 eoff, sizeof(*eh));
933 if (eh == NULL) {
934 icmp6stat.icp6s_tooshort++;
935 return(-1);
935 return (-1);
936 }
937#endif
938
939 if (nxt == IPPROTO_AH)
940 eoff += (eh->ip6e_len + 2) << 2;
941 else
942 eoff += (eh->ip6e_len + 1) << 3;
943 nxt = eh->ip6e_nxt;

--- 12 unchanged lines hidden (view full) ---

956 -1);
957 rth = (struct ip6_rthdr *)(mtod(m, caddr_t)
958 + eoff);
959#else
960 IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
961 eoff, sizeof(*rth));
962 if (rth == NULL) {
963 icmp6stat.icp6s_tooshort++;
936 }
937#endif
938
939 if (nxt == IPPROTO_AH)
940 eoff += (eh->ip6e_len + 2) << 2;
941 else
942 eoff += (eh->ip6e_len + 1) << 3;
943 nxt = eh->ip6e_nxt;

--- 12 unchanged lines hidden (view full) ---

956 -1);
957 rth = (struct ip6_rthdr *)(mtod(m, caddr_t)
958 + eoff);
959#else
960 IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
961 eoff, sizeof(*rth));
962 if (rth == NULL) {
963 icmp6stat.icp6s_tooshort++;
964 return(-1);
964 return (-1);
965 }
966#endif
967 rthlen = (rth->ip6r_len + 1) << 3;
968 /*
969 * XXX: currently there is no
970 * officially defined type other
971 * than type-0.
972 * Note that if the segment left field

--- 9 unchanged lines hidden (view full) ---

982 -1);
983 rth0 = (struct ip6_rthdr0 *)(mtod(m, caddr_t) + eoff);
984#else
985 IP6_EXTHDR_GET(rth0,
986 struct ip6_rthdr0 *, m,
987 eoff, rthlen);
988 if (rth0 == NULL) {
989 icmp6stat.icp6s_tooshort++;
965 }
966#endif
967 rthlen = (rth->ip6r_len + 1) << 3;
968 /*
969 * XXX: currently there is no
970 * officially defined type other
971 * than type-0.
972 * Note that if the segment left field

--- 9 unchanged lines hidden (view full) ---

982 -1);
983 rth0 = (struct ip6_rthdr0 *)(mtod(m, caddr_t) + eoff);
984#else
985 IP6_EXTHDR_GET(rth0,
986 struct ip6_rthdr0 *, m,
987 eoff, rthlen);
988 if (rth0 == NULL) {
989 icmp6stat.icp6s_tooshort++;
990 return(-1);
990 return (-1);
991 }
992#endif
993 /* just ignore a bogus header */
994 if ((rth0->ip6r0_len % 2) == 0 &&
995 (hops = rth0->ip6r0_len/2))
996 finaldst = (struct in6_addr *)(rth0 + 1) + (hops - 1);
997 }
998 eoff += rthlen;

--- 6 unchanged lines hidden (view full) ---

1005 -1);
1006 fh = (struct ip6_frag *)(mtod(m, caddr_t)
1007 + eoff);
1008#else
1009 IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
1010 eoff, sizeof(*fh));
1011 if (fh == NULL) {
1012 icmp6stat.icp6s_tooshort++;
991 }
992#endif
993 /* just ignore a bogus header */
994 if ((rth0->ip6r0_len % 2) == 0 &&
995 (hops = rth0->ip6r0_len/2))
996 finaldst = (struct in6_addr *)(rth0 + 1) + (hops - 1);
997 }
998 eoff += rthlen;

--- 6 unchanged lines hidden (view full) ---

1005 -1);
1006 fh = (struct ip6_frag *)(mtod(m, caddr_t)
1007 + eoff);
1008#else
1009 IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
1010 eoff, sizeof(*fh));
1011 if (fh == NULL) {
1012 icmp6stat.icp6s_tooshort++;
1013 return(-1);
1013 return (-1);
1014 }
1015#endif
1016 /*
1017 * Data after a fragment header is meaningless
1018 * unless it is the first fragment, but
1019 * we'll go to the notify label for path MTU
1020 * discovery.
1021 */

--- 18 unchanged lines hidden (view full) ---

1040 notify:
1041#ifndef PULLDOWN_TEST
1042 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
1043#else
1044 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
1045 sizeof(*icmp6) + sizeof(struct ip6_hdr));
1046 if (icmp6 == NULL) {
1047 icmp6stat.icp6s_tooshort++;
1014 }
1015#endif
1016 /*
1017 * Data after a fragment header is meaningless
1018 * unless it is the first fragment, but
1019 * we'll go to the notify label for path MTU
1020 * discovery.
1021 */

--- 18 unchanged lines hidden (view full) ---

1040 notify:
1041#ifndef PULLDOWN_TEST
1042 icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
1043#else
1044 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
1045 sizeof(*icmp6) + sizeof(struct ip6_hdr));
1046 if (icmp6 == NULL) {
1047 icmp6stat.icp6s_tooshort++;
1048 return(-1);
1048 return (-1);
1049 }
1050#endif
1051
1052 eip6 = (struct ip6_hdr *)(icmp6 + 1);
1053 bzero(&icmp6dst, sizeof(icmp6dst));
1054 icmp6dst.sin6_len = sizeof(struct sockaddr_in6);
1055 icmp6dst.sin6_family = AF_INET6;
1056 if (finaldst == NULL)

--- 52 unchanged lines hidden (view full) ---

1109
1110 ctlfunc = (void (*) __P((int, struct sockaddr *, void *)))
1111 (inet6sw[ip6_protox[nxt]].pr_ctlinput);
1112 if (ctlfunc) {
1113 (void) (*ctlfunc)(code, (struct sockaddr *)&icmp6dst,
1114 &ip6cp);
1115 }
1116 }
1049 }
1050#endif
1051
1052 eip6 = (struct ip6_hdr *)(icmp6 + 1);
1053 bzero(&icmp6dst, sizeof(icmp6dst));
1054 icmp6dst.sin6_len = sizeof(struct sockaddr_in6);
1055 icmp6dst.sin6_family = AF_INET6;
1056 if (finaldst == NULL)

--- 52 unchanged lines hidden (view full) ---

1109
1110 ctlfunc = (void (*) __P((int, struct sockaddr *, void *)))
1111 (inet6sw[ip6_protox[nxt]].pr_ctlinput);
1112 if (ctlfunc) {
1113 (void) (*ctlfunc)(code, (struct sockaddr *)&icmp6dst,
1114 &ip6cp);
1115 }
1116 }
1117 return(0);
1117 return (0);
1118
1119 freeit:
1120 m_freem(m);
1118
1119 freeit:
1120 m_freem(m);
1121 return(-1);
1121 return (-1);
1122}
1123
1124void
1125icmp6_mtudisc_update(ip6cp, validated)
1126 struct ip6ctlparam *ip6cp;
1127 int validated;
1128{
1129 struct in6_addr *dst = ip6cp->ip6c_finaldst;

--- 262 unchanged lines hidden (view full) ---

1392 oldfqdn++;
1393 break;
1394 }
1395
1396 /* allocate an mbuf to reply. */
1397 MGETHDR(n, M_DONTWAIT, m->m_type);
1398 if (n == NULL) {
1399 m_freem(m);
1122}
1123
1124void
1125icmp6_mtudisc_update(ip6cp, validated)
1126 struct ip6ctlparam *ip6cp;
1127 int validated;
1128{
1129 struct in6_addr *dst = ip6cp->ip6c_finaldst;

--- 262 unchanged lines hidden (view full) ---

1392 oldfqdn++;
1393 break;
1394 }
1395
1396 /* allocate an mbuf to reply. */
1397 MGETHDR(n, M_DONTWAIT, m->m_type);
1398 if (n == NULL) {
1399 m_freem(m);
1400 return(NULL);
1400 return (NULL);
1401 }
1402 M_MOVE_PKTHDR(n, m); /* just for recvif */
1403 if (replylen > MHLEN) {
1404 if (replylen > MCLBYTES) {
1405 /*
1406 * XXX: should we try to allocate more? But MCLBYTES
1407 * is probably much larger than IPV6_MMTU...
1408 */

--- 60 unchanged lines hidden (view full) ---

1469 break;
1470 }
1471 default:
1472 break; /* XXX impossible! */
1473 }
1474
1475 nni6->ni_type = ICMP6_NI_REPLY;
1476 m_freem(m);
1401 }
1402 M_MOVE_PKTHDR(n, m); /* just for recvif */
1403 if (replylen > MHLEN) {
1404 if (replylen > MCLBYTES) {
1405 /*
1406 * XXX: should we try to allocate more? But MCLBYTES
1407 * is probably much larger than IPV6_MMTU...
1408 */

--- 60 unchanged lines hidden (view full) ---

1469 break;
1470 }
1471 default:
1472 break; /* XXX impossible! */
1473 }
1474
1475 nni6->ni_type = ICMP6_NI_REPLY;
1476 m_freem(m);
1477 return(n);
1477 return (n);
1478
1479 bad:
1480 m_freem(m);
1481 if (n)
1482 m_freem(n);
1478
1479 bad:
1480 m_freem(m);
1481 if (n)
1482 m_freem(n);
1483 return(NULL);
1483 return (NULL);
1484}
1485#undef hostnamelen
1486
1487/*
1488 * make a mbuf with DNS-encoded string. no compression support.
1489 *
1490 * XXX names with less than 2 dots (like "foo" or "foo.section") will be
1491 * treated as truncated name (two \0 at the end). this is a wild guess.

--- 175 unchanged lines hidden (view full) ---

1667 struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
1668 int addrs = 0, addrsofif, iffound = 0;
1669 int niflags = ni6->ni_flags;
1670
1671 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) {
1672 switch (ni6->ni_code) {
1673 case ICMP6_NI_SUBJ_IPV6:
1674 if (subj == NULL) /* must be impossible... */
1484}
1485#undef hostnamelen
1486
1487/*
1488 * make a mbuf with DNS-encoded string. no compression support.
1489 *
1490 * XXX names with less than 2 dots (like "foo" or "foo.section") will be
1491 * treated as truncated name (two \0 at the end). this is a wild guess.

--- 175 unchanged lines hidden (view full) ---

1667 struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
1668 int addrs = 0, addrsofif, iffound = 0;
1669 int niflags = ni6->ni_flags;
1670
1671 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) {
1672 switch (ni6->ni_code) {
1673 case ICMP6_NI_SUBJ_IPV6:
1674 if (subj == NULL) /* must be impossible... */
1675 return(0);
1675 return (0);
1676 subj_ip6 = (struct sockaddr_in6 *)subj;
1677 break;
1678 default:
1679 /*
1680 * XXX: we only support IPv6 subject address for
1681 * this Qtype.
1682 */
1676 subj_ip6 = (struct sockaddr_in6 *)subj;
1677 break;
1678 default:
1679 /*
1680 * XXX: we only support IPv6 subject address for
1681 * this Qtype.
1682 */
1683 return(0);
1683 return (0);
1684 }
1685 }
1686
1687 IFNET_RLOCK();
1688 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
1689 {
1690 addrsofif = 0;
1691 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)

--- 46 unchanged lines hidden (view full) ---

1738 (icmp6_nodeinfo & 4) == 0) {
1739 continue;
1740 }
1741 addrsofif++; /* count the address */
1742 }
1743 if (iffound) {
1744 *ifpp = ifp;
1745 IFNET_RUNLOCK();
1684 }
1685 }
1686
1687 IFNET_RLOCK();
1688 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
1689 {
1690 addrsofif = 0;
1691 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)

--- 46 unchanged lines hidden (view full) ---

1738 (icmp6_nodeinfo & 4) == 0) {
1739 continue;
1740 }
1741 addrsofif++; /* count the address */
1742 }
1743 if (iffound) {
1744 *ifpp = ifp;
1745 IFNET_RUNLOCK();
1746 return(addrsofif);
1746 return (addrsofif);
1747 }
1748
1749 addrs += addrsofif;
1750 }
1751 IFNET_RUNLOCK();
1752
1747 }
1748
1749 addrs += addrsofif;
1750 }
1751 IFNET_RUNLOCK();
1752
1753 return(addrs);
1753 return (addrs);
1754}
1755
1756static int
1757ni6_store_addrs(ni6, nni6, ifp0, resid)
1758 struct icmp6_nodeinfo *ni6, *nni6;
1759 struct ifnet *ifp0;
1760 int resid;
1761{
1762 struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
1763 struct in6_ifaddr *ifa6;
1764 struct ifaddr *ifa;
1765 struct ifnet *ifp_dep = NULL;
1766 int copied = 0, allow_deprecated = 0;
1767 u_char *cp = (u_char *)(nni6 + 1);
1768 int niflags = ni6->ni_flags;
1769 u_int32_t ltime;
1770
1771 if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL))
1754}
1755
1756static int
1757ni6_store_addrs(ni6, nni6, ifp0, resid)
1758 struct icmp6_nodeinfo *ni6, *nni6;
1759 struct ifnet *ifp0;
1760 int resid;
1761{
1762 struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
1763 struct in6_ifaddr *ifa6;
1764 struct ifaddr *ifa;
1765 struct ifnet *ifp_dep = NULL;
1766 int copied = 0, allow_deprecated = 0;
1767 u_char *cp = (u_char *)(nni6 + 1);
1768 int niflags = ni6->ni_flags;
1769 u_int32_t ltime;
1770
1771 if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL))
1772 return(0); /* needless to copy */
1772 return (0); /* needless to copy */
1773
1774 IFNET_RLOCK();
1775 again:
1776 for (; ifp; ifp = TAILQ_NEXT(ifp, if_list))
1777 {
1778 for (ifa = ifp->if_addrlist.tqh_first; ifa;
1779 ifa = ifa->ifa_list.tqe_next)
1780 {

--- 53 unchanged lines hidden (view full) ---

1834 sizeof(u_int32_t)) {
1835 /*
1836 * We give up much more copy.
1837 * Set the truncate flag and return.
1838 */
1839 nni6->ni_flags |=
1840 NI_NODEADDR_FLAG_TRUNCATE;
1841 IFNET_RUNLOCK();
1773
1774 IFNET_RLOCK();
1775 again:
1776 for (; ifp; ifp = TAILQ_NEXT(ifp, if_list))
1777 {
1778 for (ifa = ifp->if_addrlist.tqh_first; ifa;
1779 ifa = ifa->ifa_list.tqe_next)
1780 {

--- 53 unchanged lines hidden (view full) ---

1834 sizeof(u_int32_t)) {
1835 /*
1836 * We give up much more copy.
1837 * Set the truncate flag and return.
1838 */
1839 nni6->ni_flags |=
1840 NI_NODEADDR_FLAG_TRUNCATE;
1841 IFNET_RUNLOCK();
1842 return(copied);
1842 return (copied);
1843 }
1844
1845 /*
1846 * Set the TTL of the address.
1847 * The TTL value should be one of the following
1848 * according to the specification:
1849 *
1850 * 1. The remaining lifetime of a DHCP lease on the

--- 39 unchanged lines hidden (view full) ---

1890 ifp = ifp_dep;
1891 allow_deprecated = 1;
1892
1893 goto again;
1894 }
1895
1896 IFNET_RUNLOCK();
1897
1843 }
1844
1845 /*
1846 * Set the TTL of the address.
1847 * The TTL value should be one of the following
1848 * according to the specification:
1849 *
1850 * 1. The remaining lifetime of a DHCP lease on the

--- 39 unchanged lines hidden (view full) ---

1890 ifp = ifp_dep;
1891 allow_deprecated = 1;
1892
1893 goto again;
1894 }
1895
1896 IFNET_RUNLOCK();
1897
1898 return(copied);
1898 return (copied);
1899}
1900
1901/*
1902 * XXX almost dup'ed code with rip6_input.
1903 */
1904static int
1905icmp6_rip6_input(mp, off)
1906 struct mbuf **mp;

--- 873 unchanged lines hidden (view full) ---

2780
2781 default:
2782 error = ENOPROTOOPT;
2783 break;
2784 }
2785 break;
2786 }
2787
1899}
1900
1901/*
1902 * XXX almost dup'ed code with rip6_input.
1903 */
1904static int
1905icmp6_rip6_input(mp, off)
1906 struct mbuf **mp;

--- 873 unchanged lines hidden (view full) ---

2780
2781 default:
2782 error = ENOPROTOOPT;
2783 break;
2784 }
2785 break;
2786 }
2787
2788 return(error);
2788 return (error);
2789}
2790#ifdef HAVE_NRL_INPCB
2791#undef sotoin6pcb
2792#undef in6pcb
2793#undef in6p_icmp6filt
2794#endif
2795
2796#ifndef HAVE_PPSRATECHECK

--- 96 unchanged lines hidden ---
2789}
2790#ifdef HAVE_NRL_INPCB
2791#undef sotoin6pcb
2792#undef in6pcb
2793#undef in6p_icmp6filt
2794#endif
2795
2796#ifndef HAVE_PPSRATECHECK

--- 96 unchanged lines hidden ---