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