1/* $FreeBSD: head/sys/netinet6/icmp6.c 169664 2007-05-17 21:20:24Z jinmei $ */ |
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 --- 651 unchanged lines hidden (view full) --- 661 if (n) 662 n = ni6_input(n, off); 663 /* XXX meaningless if n == NULL */ 664 noff = sizeof(struct ip6_hdr); 665 } else { 666 u_char *p; 667 int maxlen, maxhlen; 668 |
669 /* 670 * XXX: this combination of flags is pointless, 671 * but should we keep this for compatibility? 672 */ |
673 if ((icmp6_nodeinfo & 5) != 5) 674 break; 675 676 if (code != 0) 677 goto badcode; 678 maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4; 679 if (maxlen >= MCLBYTES) { 680 /* Give up remote */ --- 502 unchanged lines hidden (view full) --- 1183 IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6)); 1184 if (ni6 == NULL) { 1185 /* m is already reclaimed */ 1186 return (NULL); 1187 } 1188#endif 1189 1190 /* |
1191 * Validate IPv6 source address. 1192 * The default configuration MUST be to refuse answering queries from 1193 * global-scope addresses according to RFC4602. 1194 * Notes: 1195 * - it's not very clear what "refuse" means; this implementation 1196 * simply drops it. 1197 * - it's not very easy to identify global-scope (unicast) addresses 1198 * since there are many prefixes for them. It should be safer 1199 * and in practice sufficient to check "all" but loopback and 1200 * link-local (note that site-local unicast was deprecated and 1201 * ULA is defined as global scope-wise) 1202 */ 1203 if ((icmp6_nodeinfo & ICMP6_NODEINFO_GLOBALOK) == 0 && 1204 !IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) && 1205 !IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) 1206 goto bad; 1207 1208 /* |
1209 * Validate IPv6 destination address. 1210 * 1211 * The Responder must discard the Query without further processing 1212 * unless it is one of the Responder's unicast or anycast addresses, or 1213 * a link-local scope multicast address which the Responder has joined. |
1214 * [RFC4602, Section 5.] |
1215 */ 1216 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 1217 if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) 1218 goto bad; 1219 /* else it's a link-local multicast, fine */ 1220 } else { /* unicast or anycast */ 1221 if ((ia6 = ip6_getdstifaddr(m)) == NULL) 1222 goto bad; /* XXX impossible */ 1223 1224 if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) && |
1225 !(icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) { |
1226 nd6log((LOG_DEBUG, "ni6_input: ignore node info to " 1227 "a temporary address in %s:%d", 1228 __FILE__, __LINE__)); 1229 goto bad; 1230 } 1231 } 1232 1233 /* validate query Subject field. */ --- 98 unchanged lines hidden (view full) --- 1332 goto bad; 1333 } 1334 break; 1335 } 1336 1337 /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */ 1338 switch (qtype) { 1339 case NI_QTYPE_FQDN: |
1340 if ((icmp6_nodeinfo & ICMP6_NODEINFO_FQDNOK) == 0) |
1341 goto bad; 1342 break; 1343 case NI_QTYPE_NODEADDR: 1344 case NI_QTYPE_IPV4ADDR: |
1345 if ((icmp6_nodeinfo & ICMP6_NODEINFO_NODEADDROK) == 0) |
1346 goto bad; 1347 break; 1348 } 1349 1350 /* guess reply length */ 1351 switch (qtype) { 1352 case NI_QTYPE_NOOP: 1353 break; /* no reply data */ --- 361 unchanged lines hidden (view full) --- 1715 /* 1716 * check if anycast is okay. 1717 * XXX: just experimental. not in the spec. 1718 */ 1719 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1720 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1721 continue; /* we need only unicast addresses */ 1722 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && |
1723 (icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) { |
1724 continue; 1725 } 1726 addrsofif++; /* count the address */ 1727 } 1728 if (iffound) { 1729 *ifpp = ifp; 1730 IFNET_RUNLOCK(); 1731 return (addrsofif); --- 71 unchanged lines hidden (view full) --- 1803 /* 1804 * check if anycast is okay. 1805 * XXX: just experimental. not in the spec. 1806 */ 1807 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1808 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1809 continue; 1810 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && |
1811 (icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK) == 0) { |
1812 continue; 1813 } 1814 1815 /* now we can copy the address */ 1816 if (resid < sizeof(struct in6_addr) + 1817 sizeof(u_int32_t)) { 1818 /* 1819 * We give up much more copy. --- 998 unchanged lines hidden --- |