]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/route6.c
1 /* $KAME: route6.c,v 1.10 2000/02/22 14:04:34 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/param.h>
34 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <netinet6/in6_var.h>
40 #include <netinet/ip6.h>
41 #include <netinet6/ip6_var.h>
43 #include <netinet/icmp6.h>
46 #include <netinet6/mip6.h>
47 #include <net/if_types.h>
50 static int ip6_rthdr0
__P((struct mbuf
*, struct ip6_hdr
*,
51 struct ip6_rthdr0
*));
55 route6_input(mp
, offp
, proto
)
57 int *offp
, proto
; /* proto is unused */
59 register struct ip6_hdr
*ip6
;
60 register struct mbuf
*m
= *mp
;
61 register struct ip6_rthdr
*rh
;
62 int off
= *offp
, rhlen
;
65 IP6_EXTHDR_CHECK(m
, off
, sizeof(*rh
), IPPROTO_DONE
);
66 ip6
= mtod(m
, struct ip6_hdr
*);
67 rh
= (struct ip6_rthdr
*)((caddr_t
)ip6
+ off
);
69 ip6
= mtod(m
, struct ip6_hdr
*);
70 IP6_EXTHDR_GET(rh
, struct ip6_rthdr
*, m
, off
, sizeof(*rh
));
72 ip6stat
.ip6s_tooshort
++;
77 switch(rh
->ip6r_type
) {
78 case IPV6_RTHDR_TYPE_0
:
79 rhlen
= (rh
->ip6r_len
+ 1) << 3;
81 IP6_EXTHDR_CHECK(m
, off
, rhlen
, IPPROTO_DONE
);
83 IP6_EXTHDR_GET(rh
, struct ip6_rthdr
*, m
, off
, rhlen
);
85 ip6stat
.ip6s_tooshort
++;
89 if (ip6_rthdr0(m
, ip6
, (struct ip6_rthdr0
*)rh
))
93 /* unknown routing type */
94 if (rh
->ip6r_segleft
== 0) {
95 rhlen
= (rh
->ip6r_len
+ 1) << 3;
96 break; /* Final dst. Just ignore the header. */
98 ip6stat
.ip6s_badoptions
++;
99 icmp6_error(m
, ICMP6_PARAM_PROB
, ICMP6_PARAMPROB_HEADER
,
100 (caddr_t
)&rh
->ip6r_type
- (caddr_t
)ip6
);
101 return(IPPROTO_DONE
);
105 return(rh
->ip6r_nxt
);
109 * Type0 routing header processing
112 ip6_rthdr0(m
, ip6
, rh0
)
115 struct ip6_rthdr0
*rh0
;
118 struct in6_addr
*nextaddr
, tmpaddr
;
120 if (rh0
->ip6r0_segleft
== 0)
123 if (rh0
->ip6r0_len
% 2
125 || rh0
->ip6r0_len
> 46
129 * Type 0 routing header can't contain more than 23 addresses.
130 * RFC 2462: this limitation was removed since stict/loose
131 * bitmap field was deleted.
133 ip6stat
.ip6s_badoptions
++;
134 icmp6_error(m
, ICMP6_PARAM_PROB
, ICMP6_PARAMPROB_HEADER
,
135 (caddr_t
)&rh0
->ip6r0_len
- (caddr_t
)ip6
);
139 if ((addrs
= rh0
->ip6r0_len
/ 2) < rh0
->ip6r0_segleft
) {
140 ip6stat
.ip6s_badoptions
++;
141 icmp6_error(m
, ICMP6_PARAM_PROB
, ICMP6_PARAMPROB_HEADER
,
142 (caddr_t
)&rh0
->ip6r0_segleft
- (caddr_t
)ip6
);
146 index
= addrs
- rh0
->ip6r0_segleft
;
147 rh0
->ip6r0_segleft
--;
148 nextaddr
= ((struct in6_addr
*)(rh0
+ 1)) + index
;
151 * reject invalid addresses. be proactive about malicious use of
152 * IPv4 mapped/compat address.
153 * XXX need more checks?
155 if (IN6_IS_ADDR_MULTICAST(nextaddr
) ||
156 IN6_IS_ADDR_UNSPECIFIED(nextaddr
) ||
157 IN6_IS_ADDR_V4MAPPED(nextaddr
) ||
158 IN6_IS_ADDR_V4COMPAT(nextaddr
)) {
159 ip6stat
.ip6s_badoptions
++;
163 if (IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
) ||
164 IN6_IS_ADDR_UNSPECIFIED(&ip6
->ip6_dst
) ||
165 IN6_IS_ADDR_V4MAPPED(&ip6
->ip6_dst
) ||
166 IN6_IS_ADDR_V4COMPAT(nextaddr
)) {
167 ip6stat
.ip6s_badoptions
++;
173 * Swap the IPv6 destination address and nextaddr. Forward the packet.
176 *nextaddr
= ip6
->ip6_dst
;
177 if (IN6_IS_ADDR_LINKLOCAL(nextaddr
))
178 nextaddr
->s6_addr16
[1] = 0;
179 ip6
->ip6_dst
= tmpaddr
;
180 if (IN6_IS_ADDR_LINKLOCAL(&ip6
->ip6_dst
))
181 ip6
->ip6_dst
.s6_addr16
[1] = htons(m
->m_pkthdr
.rcvif
->if_index
);
184 if (rh0
->ip6r0_slmap
[index
/ 8] & (1 << (7 - (index
% 8))))
185 ip6_forward(m
, IPV6_SRCRT_NEIGHBOR
);
187 ip6_forward(m
, IPV6_SRCRT_NOTNEIGHBOR
);
192 return(-1); /* m would be freed in ip6_forward() */