Deleted Added
full compact
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 ---