route6.c (174510) | route6.c (181803) |
---|---|
1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $KAME: route6.c,v 1.24 2001/03/14 03:07:05 itojun Exp $ 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $KAME: route6.c,v 1.24 2001/03/14 03:07:05 itojun Exp $ 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/netinet6/route6.c 174510 2007-12-10 16:03:40Z obrien $"); | 33__FBSDID("$FreeBSD: head/sys/netinet6/route6.c 181803 2008-08-17 23:27:27Z bz $"); |
34 35#include "opt_inet.h" 36#include "opt_inet6.h" 37 38#include <sys/param.h> 39#include <sys/mbuf.h> 40#include <sys/socket.h> 41#include <sys/systm.h> 42#include <sys/queue.h> | 34 35#include "opt_inet.h" 36#include "opt_inet6.h" 37 38#include <sys/param.h> 39#include <sys/mbuf.h> 40#include <sys/socket.h> 41#include <sys/systm.h> 42#include <sys/queue.h> |
43#include <sys/vimage.h> |
|
43 44#include <net/if.h> 45 46#include <netinet/in.h> 47#include <netinet6/in6_var.h> 48#include <netinet/ip6.h> 49#include <netinet6/ip6_var.h> 50#include <netinet6/scope6_var.h> --- 18 unchanged lines hidden (view full) --- 69 struct ip6_rthdr *rh; 70 int off = *offp, rhlen; 71 struct ip6aux *ip6a; 72 73 ip6a = ip6_findaux(m); 74 if (ip6a) { 75 /* XXX reject home-address option before rthdr */ 76 if (ip6a->ip6a_flags & IP6A_SWAP) { | 44 45#include <net/if.h> 46 47#include <netinet/in.h> 48#include <netinet6/in6_var.h> 49#include <netinet/ip6.h> 50#include <netinet6/ip6_var.h> 51#include <netinet6/scope6_var.h> --- 18 unchanged lines hidden (view full) --- 70 struct ip6_rthdr *rh; 71 int off = *offp, rhlen; 72 struct ip6aux *ip6a; 73 74 ip6a = ip6_findaux(m); 75 if (ip6a) { 76 /* XXX reject home-address option before rthdr */ 77 if (ip6a->ip6a_flags & IP6A_SWAP) { |
77 ip6stat.ip6s_badoptions++; | 78 V_ip6stat.ip6s_badoptions++; |
78 m_freem(m); 79 return IPPROTO_DONE; 80 } 81 } 82 83#ifndef PULLDOWN_TEST 84 IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE); 85 ip6 = mtod(m, struct ip6_hdr *); 86 rh = (struct ip6_rthdr *)((caddr_t)ip6 + off); 87#else 88 ip6 = mtod(m, struct ip6_hdr *); 89 IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh)); 90 if (rh == NULL) { | 79 m_freem(m); 80 return IPPROTO_DONE; 81 } 82 } 83 84#ifndef PULLDOWN_TEST 85 IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE); 86 ip6 = mtod(m, struct ip6_hdr *); 87 rh = (struct ip6_rthdr *)((caddr_t)ip6 + off); 88#else 89 ip6 = mtod(m, struct ip6_hdr *); 90 IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh)); 91 if (rh == NULL) { |
91 ip6stat.ip6s_tooshort++; | 92 V_ip6stat.ip6s_tooshort++; |
92 return IPPROTO_DONE; 93 } 94#endif 95 96 switch (rh->ip6r_type) { 97#if 0 98 case IPV6_RTHDR_TYPE_0: 99 rhlen = (rh->ip6r_len + 1) << 3; --- 10 unchanged lines hidden (view full) --- 110 * maximum rhlen: 2048 111 * max mbuf m_pulldown can handle: MCLBYTES == usually 2048 112 * so, here we are assuming that m_pulldown can handle 113 * rhlen == 2048 case. this may not be a good thing to 114 * assume - we may want to avoid pulling it up altogether. 115 */ 116 IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, rhlen); 117 if (rh == NULL) { | 93 return IPPROTO_DONE; 94 } 95#endif 96 97 switch (rh->ip6r_type) { 98#if 0 99 case IPV6_RTHDR_TYPE_0: 100 rhlen = (rh->ip6r_len + 1) << 3; --- 10 unchanged lines hidden (view full) --- 111 * maximum rhlen: 2048 112 * max mbuf m_pulldown can handle: MCLBYTES == usually 2048 113 * so, here we are assuming that m_pulldown can handle 114 * rhlen == 2048 case. this may not be a good thing to 115 * assume - we may want to avoid pulling it up altogether. 116 */ 117 IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, rhlen); 118 if (rh == NULL) { |
118 ip6stat.ip6s_tooshort++; | 119 V_ip6stat.ip6s_tooshort++; |
119 return IPPROTO_DONE; 120 } 121#endif 122 if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh)) 123 return (IPPROTO_DONE); 124 break; 125#endif /* Disable route header 0 */ 126 default: 127 /* unknown routing type */ 128 if (rh->ip6r_segleft == 0) { 129 rhlen = (rh->ip6r_len + 1) << 3; 130 break; /* Final dst. Just ignore the header. */ 131 } | 120 return IPPROTO_DONE; 121 } 122#endif 123 if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh)) 124 return (IPPROTO_DONE); 125 break; 126#endif /* Disable route header 0 */ 127 default: 128 /* unknown routing type */ 129 if (rh->ip6r_segleft == 0) { 130 rhlen = (rh->ip6r_len + 1) << 3; 131 break; /* Final dst. Just ignore the header. */ 132 } |
132 ip6stat.ip6s_badoptions++; | 133 V_ip6stat.ip6s_badoptions++; |
133 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 134 (caddr_t)&rh->ip6r_type - (caddr_t)ip6); 135 return (IPPROTO_DONE); 136 } 137 138 *offp += rhlen; 139 return (rh->ip6r_nxt); 140} --- 20 unchanged lines hidden (view full) --- 161 || rh0->ip6r0_len > 46 162#endif 163 ) { 164 /* 165 * Type 0 routing header can't contain more than 23 addresses. 166 * RFC 2462: this limitation was removed since strict/loose 167 * bitmap field was deleted. 168 */ | 134 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 135 (caddr_t)&rh->ip6r_type - (caddr_t)ip6); 136 return (IPPROTO_DONE); 137 } 138 139 *offp += rhlen; 140 return (rh->ip6r_nxt); 141} --- 20 unchanged lines hidden (view full) --- 162 || rh0->ip6r0_len > 46 163#endif 164 ) { 165 /* 166 * Type 0 routing header can't contain more than 23 addresses. 167 * RFC 2462: this limitation was removed since strict/loose 168 * bitmap field was deleted. 169 */ |
169 ip6stat.ip6s_badoptions++; | 170 V_ip6stat.ip6s_badoptions++; |
170 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 171 (caddr_t)&rh0->ip6r0_len - (caddr_t)ip6); 172 return (-1); 173 } 174 175 if ((addrs = rh0->ip6r0_len / 2) < rh0->ip6r0_segleft) { | 171 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 172 (caddr_t)&rh0->ip6r0_len - (caddr_t)ip6); 173 return (-1); 174 } 175 176 if ((addrs = rh0->ip6r0_len / 2) < rh0->ip6r0_segleft) { |
176 ip6stat.ip6s_badoptions++; | 177 V_ip6stat.ip6s_badoptions++; |
177 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 178 (caddr_t)&rh0->ip6r0_segleft - (caddr_t)ip6); 179 return (-1); 180 } 181 182 index = addrs - rh0->ip6r0_segleft; 183 rh0->ip6r0_segleft--; 184 nextaddr = ((struct in6_addr *)(rh0 + 1)) + index; 185 186 /* 187 * reject invalid addresses. be proactive about malicious use of 188 * IPv4 mapped/compat address. 189 * XXX need more checks? 190 */ 191 if (IN6_IS_ADDR_MULTICAST(nextaddr) || 192 IN6_IS_ADDR_UNSPECIFIED(nextaddr) || 193 IN6_IS_ADDR_V4MAPPED(nextaddr) || 194 IN6_IS_ADDR_V4COMPAT(nextaddr)) { | 178 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 179 (caddr_t)&rh0->ip6r0_segleft - (caddr_t)ip6); 180 return (-1); 181 } 182 183 index = addrs - rh0->ip6r0_segleft; 184 rh0->ip6r0_segleft--; 185 nextaddr = ((struct in6_addr *)(rh0 + 1)) + index; 186 187 /* 188 * reject invalid addresses. be proactive about malicious use of 189 * IPv4 mapped/compat address. 190 * XXX need more checks? 191 */ 192 if (IN6_IS_ADDR_MULTICAST(nextaddr) || 193 IN6_IS_ADDR_UNSPECIFIED(nextaddr) || 194 IN6_IS_ADDR_V4MAPPED(nextaddr) || 195 IN6_IS_ADDR_V4COMPAT(nextaddr)) { |
195 ip6stat.ip6s_badoptions++; | 196 V_ip6stat.ip6s_badoptions++; |
196 m_freem(m); 197 return (-1); 198 } 199 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 200 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst) || 201 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst) || 202 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { | 197 m_freem(m); 198 return (-1); 199 } 200 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 201 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst) || 202 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst) || 203 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { |
203 ip6stat.ip6s_badoptions++; | 204 V_ip6stat.ip6s_badoptions++; |
204 m_freem(m); 205 return (-1); 206 } 207 208 /* 209 * Determine the scope zone of the next hop, based on the interface 210 * of the current hop. [RFC4007, Section 9] 211 * Then disambiguate the scope zone for the next hop (if necessary). 212 */ 213 if ((ifa = ip6_getdstifaddr(m)) == NULL) 214 goto bad; 215 if (in6_setscope(nextaddr, ifa->ia_ifp, NULL) != 0) { | 205 m_freem(m); 206 return (-1); 207 } 208 209 /* 210 * Determine the scope zone of the next hop, based on the interface 211 * of the current hop. [RFC4007, Section 9] 212 * Then disambiguate the scope zone for the next hop (if necessary). 213 */ 214 if ((ifa = ip6_getdstifaddr(m)) == NULL) 215 goto bad; 216 if (in6_setscope(nextaddr, ifa->ia_ifp, NULL) != 0) { |
216 ip6stat.ip6s_badscope++; | 217 V_ip6stat.ip6s_badscope++; |
217 goto bad; 218 } 219 220 /* 221 * Swap the IPv6 destination address and nextaddr. Forward the packet. 222 */ 223 tmpaddr = *nextaddr; 224 *nextaddr = ip6->ip6_dst; --- 19 unchanged lines hidden --- | 218 goto bad; 219 } 220 221 /* 222 * Swap the IPv6 destination address and nextaddr. Forward the packet. 223 */ 224 tmpaddr = *nextaddr; 225 *nextaddr = ip6->ip6_dst; --- 19 unchanged lines hidden --- |