1/* $FreeBSD: head/sys/netinet6/icmp6.c 165118 2006-12-12 12:17:58Z bz $ */ |
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 --- 389 unchanged lines hidden (view full) --- 399 int *offp, proto; 400{ 401 struct mbuf *m = *mp, *n; 402 struct ip6_hdr *ip6, *nip6; 403 struct icmp6_hdr *icmp6, *nicmp6; 404 int off = *offp; 405 int icmp6len = m->m_pkthdr.len - *offp; 406 int code, sum, noff; |
407 char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; |
408 409#ifndef PULLDOWN_TEST 410 IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE); 411 /* m might change if M_LOOP. So, call mtod after this */ 412#endif 413 414 /* 415 * Locate icmp6 structure in mbuf, and check --- 18 unchanged lines hidden (view full) --- 434 return IPPROTO_DONE; 435 } 436#endif 437 code = icmp6->icmp6_code; 438 439 if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { 440 nd6log((LOG_ERR, 441 "ICMP6 checksum error(%d|%x) %s\n", |
442 icmp6->icmp6_type, sum, 443 ip6_sprintf(ip6bufs, &ip6->ip6_src))); |
444 icmp6stat.icp6s_checksum++; 445 goto freeit; 446 } 447 448 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { 449 /* 450 * Deliver very specific ICMP6 type only. 451 * This is important to deliver TOOBIG. Otherwise PMTUD --- 367 unchanged lines hidden (view full) --- 819 goto badcode; 820 if (icmp6len < sizeof(struct icmp6_router_renum)) 821 goto badlen; 822 break; 823 824 default: 825 nd6log((LOG_DEBUG, 826 "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n", |
827 icmp6->icmp6_type, ip6_sprintf(ip6bufs, &ip6->ip6_src), 828 ip6_sprintf(ip6bufd, &ip6->ip6_dst), |
829 m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0)); 830 if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) { 831 /* ICMPv6 error: MUST deliver it by spec... */ 832 code = PRC_NCMDS; 833 /* deliver */ 834 } else { 835 /* ICMPv6 informational: MUST not deliver */ 836 break; --- 1296 unchanged lines hidden (view full) --- 2133 sin6.sin6_len = sizeof(sin6); 2134 sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */ 2135 2136 bzero(&ro, sizeof(ro)); 2137 src = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &e); 2138 if (ro.ro_rt) 2139 RTFREE(ro.ro_rt); /* XXX: we could use this */ 2140 if (src == NULL) { |
2141 char ip6buf[INET6_ADDRSTRLEN]; |
2142 nd6log((LOG_DEBUG, 2143 "icmp6_reflect: source can't be determined: " 2144 "dst=%s, error=%d\n", |
2145 ip6_sprintf(ip6buf, &sin6.sin6_addr), e)); |
2146 goto bad; 2147 } 2148 } 2149 2150 ip6->ip6_src = *src; 2151 ip6->ip6_flow = 0; 2152 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 2153 ip6->ip6_vfc |= IPV6_VERSION; --- 36 unchanged lines hidden (view full) --- 2190 2191static const char * 2192icmp6_redirect_diag(src6, dst6, tgt6) 2193 struct in6_addr *src6; 2194 struct in6_addr *dst6; 2195 struct in6_addr *tgt6; 2196{ 2197 static char buf[1024]; |
2198 char ip6bufs[INET6_ADDRSTRLEN]; 2199 char ip6bufd[INET6_ADDRSTRLEN]; 2200 char ip6buft[INET6_ADDRSTRLEN]; |
2201 snprintf(buf, sizeof(buf), "(src=%s dst=%s tgt=%s)", |
2202 ip6_sprintf(ip6bufs, src6), ip6_sprintf(ip6bufd, dst6), 2203 ip6_sprintf(ip6buft, tgt6)); |
2204 return buf; 2205} 2206 2207void 2208icmp6_redirect_input(m, off) 2209 struct mbuf *m; 2210 int off; 2211{ --- 7 unchanged lines hidden (view full) --- 2219 int redirhdrlen = 0; 2220 struct rtentry *rt = NULL; 2221 int is_router; 2222 int is_onlink; 2223 struct in6_addr src6 = ip6->ip6_src; 2224 struct in6_addr redtgt6; 2225 struct in6_addr reddst6; 2226 union nd_opts ndopts; |
2227 char ip6buf[INET6_ADDRSTRLEN]; |
2228 2229 if (!m || !ifp) 2230 return; 2231 2232 /* XXX if we are router, we don't update route by icmp6 redirect */ 2233 if (ip6_forwarding) 2234 goto freeit; 2235 if (!icmp6_rediraccept) --- 17 unchanged lines hidden (view full) --- 2253 goto freeit; 2254 } 2255 2256 /* validation */ 2257 if (!IN6_IS_ADDR_LINKLOCAL(&src6)) { 2258 nd6log((LOG_ERR, 2259 "ICMP6 redirect sent from %s rejected; " 2260 "must be from linklocal\n", |
2261 ip6_sprintf(ip6buf, &src6))); |
2262 goto bad; 2263 } 2264 if (ip6->ip6_hlim != 255) { 2265 nd6log((LOG_ERR, 2266 "ICMP6 redirect sent from %s rejected; " 2267 "hlim=%d (must be 255)\n", |
2268 ip6_sprintf(ip6buf, &src6), ip6->ip6_hlim)); |
2269 goto bad; 2270 } 2271 { 2272 /* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */ 2273 struct sockaddr_in6 sin6; 2274 struct in6_addr *gw6; 2275 2276 bzero(&sin6, sizeof(sin6)); --- 13 unchanged lines hidden (view full) --- 2290 } 2291 2292 gw6 = &(((struct sockaddr_in6 *)rt->rt_gateway)->sin6_addr); 2293 if (bcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) { 2294 nd6log((LOG_ERR, 2295 "ICMP6 redirect rejected; " 2296 "not equal to gw-for-src=%s (must be same): " 2297 "%s\n", |
2298 ip6_sprintf(ip6buf, gw6), |
2299 icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); 2300 RTFREE_LOCKED(rt); 2301 goto bad; 2302 } 2303 } else { 2304 nd6log((LOG_ERR, 2305 "ICMP6 redirect rejected; " 2306 "no route found for redirect dst: %s\n", --- 44 unchanged lines hidden (view full) --- 2351 redirhdrlen = ndopts.nd_opts_rh->nd_opt_rh_len; 2352 redirhdr = (u_char *)(ndopts.nd_opts_rh + 1); /* xxx */ 2353 } 2354 2355 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 2356 nd6log((LOG_INFO, 2357 "icmp6_redirect_input: lladdrlen mismatch for %s " 2358 "(if %d, icmp6 packet %d): %s\n", |
2359 ip6_sprintf(ip6buf, &redtgt6), 2360 ifp->if_addrlen, lladdrlen - 2, |
2361 icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); 2362 goto bad; 2363 } 2364 2365 /* RFC 2461 8.3 */ 2366 nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT, 2367 is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER); 2368 --- 426 unchanged lines hidden --- |