icmp6.c (162084) | icmp6.c (165118) |
---|---|
1/* $FreeBSD: head/sys/netinet6/icmp6.c 162084 2006-09-06 21:51:59Z andre $ */ | 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; | 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]; |
|
407 408#ifndef PULLDOWN_TEST 409 IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE); 410 /* m might change if M_LOOP. So, call mtod after this */ 411#endif 412 413 /* 414 * Locate icmp6 structure in mbuf, and check --- 18 unchanged lines hidden (view full) --- 433 return IPPROTO_DONE; 434 } 435#endif 436 code = icmp6->icmp6_code; 437 438 if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { 439 nd6log((LOG_ERR, 440 "ICMP6 checksum error(%d|%x) %s\n", | 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", |
441 icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src))); | 442 icmp6->icmp6_type, sum, 443 ip6_sprintf(ip6bufs, &ip6->ip6_src))); |
442 icmp6stat.icp6s_checksum++; 443 goto freeit; 444 } 445 446 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { 447 /* 448 * Deliver very specific ICMP6 type only. 449 * This is important to deliver TOOBIG. Otherwise PMTUD --- 367 unchanged lines hidden (view full) --- 817 goto badcode; 818 if (icmp6len < sizeof(struct icmp6_router_renum)) 819 goto badlen; 820 break; 821 822 default: 823 nd6log((LOG_DEBUG, 824 "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n", | 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", |
825 icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src), 826 ip6_sprintf(&ip6->ip6_dst), | 827 icmp6->icmp6_type, ip6_sprintf(ip6bufs, &ip6->ip6_src), 828 ip6_sprintf(ip6bufd, &ip6->ip6_dst), |
827 m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0)); 828 if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) { 829 /* ICMPv6 error: MUST deliver it by spec... */ 830 code = PRC_NCMDS; 831 /* deliver */ 832 } else { 833 /* ICMPv6 informational: MUST not deliver */ 834 break; --- 1296 unchanged lines hidden (view full) --- 2131 sin6.sin6_len = sizeof(sin6); 2132 sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */ 2133 2134 bzero(&ro, sizeof(ro)); 2135 src = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &e); 2136 if (ro.ro_rt) 2137 RTFREE(ro.ro_rt); /* XXX: we could use this */ 2138 if (src == NULL) { | 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]; |
|
2139 nd6log((LOG_DEBUG, 2140 "icmp6_reflect: source can't be determined: " 2141 "dst=%s, error=%d\n", | 2142 nd6log((LOG_DEBUG, 2143 "icmp6_reflect: source can't be determined: " 2144 "dst=%s, error=%d\n", |
2142 ip6_sprintf(&sin6.sin6_addr), e)); | 2145 ip6_sprintf(ip6buf, &sin6.sin6_addr), e)); |
2143 goto bad; 2144 } 2145 } 2146 2147 ip6->ip6_src = *src; 2148 ip6->ip6_flow = 0; 2149 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 2150 ip6->ip6_vfc |= IPV6_VERSION; --- 36 unchanged lines hidden (view full) --- 2187 2188static const char * 2189icmp6_redirect_diag(src6, dst6, tgt6) 2190 struct in6_addr *src6; 2191 struct in6_addr *dst6; 2192 struct in6_addr *tgt6; 2193{ 2194 static char buf[1024]; | 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]; |
|
2195 snprintf(buf, sizeof(buf), "(src=%s dst=%s tgt=%s)", | 2201 snprintf(buf, sizeof(buf), "(src=%s dst=%s tgt=%s)", |
2196 ip6_sprintf(src6), ip6_sprintf(dst6), ip6_sprintf(tgt6)); | 2202 ip6_sprintf(ip6bufs, src6), ip6_sprintf(ip6bufd, dst6), 2203 ip6_sprintf(ip6buft, tgt6)); |
2197 return buf; 2198} 2199 2200void 2201icmp6_redirect_input(m, off) 2202 struct mbuf *m; 2203 int off; 2204{ --- 7 unchanged lines hidden (view full) --- 2212 int redirhdrlen = 0; 2213 struct rtentry *rt = NULL; 2214 int is_router; 2215 int is_onlink; 2216 struct in6_addr src6 = ip6->ip6_src; 2217 struct in6_addr redtgt6; 2218 struct in6_addr reddst6; 2219 union nd_opts ndopts; | 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]; |
|
2220 2221 if (!m || !ifp) 2222 return; 2223 2224 /* XXX if we are router, we don't update route by icmp6 redirect */ 2225 if (ip6_forwarding) 2226 goto freeit; 2227 if (!icmp6_rediraccept) --- 17 unchanged lines hidden (view full) --- 2245 goto freeit; 2246 } 2247 2248 /* validation */ 2249 if (!IN6_IS_ADDR_LINKLOCAL(&src6)) { 2250 nd6log((LOG_ERR, 2251 "ICMP6 redirect sent from %s rejected; " 2252 "must be from linklocal\n", | 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", |
2253 ip6_sprintf(&src6))); | 2261 ip6_sprintf(ip6buf, &src6))); |
2254 goto bad; 2255 } 2256 if (ip6->ip6_hlim != 255) { 2257 nd6log((LOG_ERR, 2258 "ICMP6 redirect sent from %s rejected; " 2259 "hlim=%d (must be 255)\n", | 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", |
2260 ip6_sprintf(&src6), ip6->ip6_hlim)); | 2268 ip6_sprintf(ip6buf, &src6), ip6->ip6_hlim)); |
2261 goto bad; 2262 } 2263 { 2264 /* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */ 2265 struct sockaddr_in6 sin6; 2266 struct in6_addr *gw6; 2267 2268 bzero(&sin6, sizeof(sin6)); --- 13 unchanged lines hidden (view full) --- 2282 } 2283 2284 gw6 = &(((struct sockaddr_in6 *)rt->rt_gateway)->sin6_addr); 2285 if (bcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) { 2286 nd6log((LOG_ERR, 2287 "ICMP6 redirect rejected; " 2288 "not equal to gw-for-src=%s (must be same): " 2289 "%s\n", | 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", |
2290 ip6_sprintf(gw6), | 2298 ip6_sprintf(ip6buf, gw6), |
2291 icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); 2292 RTFREE_LOCKED(rt); 2293 goto bad; 2294 } 2295 } else { 2296 nd6log((LOG_ERR, 2297 "ICMP6 redirect rejected; " 2298 "no route found for redirect dst: %s\n", --- 44 unchanged lines hidden (view full) --- 2343 redirhdrlen = ndopts.nd_opts_rh->nd_opt_rh_len; 2344 redirhdr = (u_char *)(ndopts.nd_opts_rh + 1); /* xxx */ 2345 } 2346 2347 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 2348 nd6log((LOG_INFO, 2349 "icmp6_redirect_input: lladdrlen mismatch for %s " 2350 "(if %d, icmp6 packet %d): %s\n", | 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", |
2351 ip6_sprintf(&redtgt6), ifp->if_addrlen, lladdrlen - 2, | 2359 ip6_sprintf(ip6buf, &redtgt6), 2360 ifp->if_addrlen, lladdrlen - 2, |
2352 icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); 2353 goto bad; 2354 } 2355 2356 /* RFC 2461 8.3 */ 2357 nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT, 2358 is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER); 2359 --- 426 unchanged lines hidden --- | 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 --- |