Fri Oct 3 09:21:02 2008 UTC ()
Pull up revision 1.150 (requested by adrianp in ticket #1966).

Fix for CVE-2008-3530 from matt@
Implement improved checking for MTU values on ICMP 'Packet Too Big Messages'


(jdc)
diff -r1.108 -r1.108.8.1 src/sys/netinet6/icmp6.c

cvs diff -r1.108 -r1.108.8.1 src/sys/netinet6/icmp6.c (switch to unified diff)

--- src/sys/netinet6/icmp6.c 2005/01/17 10:16:07 1.108
+++ src/sys/netinet6/icmp6.c 2008/10/03 09:21:02 1.108.8.1
@@ -1,2109 +1,2126 @@ @@ -1,2109 +1,2126 @@
1/* $NetBSD: icmp6.c,v 1.108 2005/01/17 10:16:07 itojun Exp $ */ 1/* $NetBSD: icmp6.c,v 1.108.8.1 2008/10/03 09:21:02 jdc Exp $ */
2/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ 2/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors 16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software 17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission. 18 * without specific prior written permission.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1982, 1986, 1988, 1993 34 * Copyright (c) 1982, 1986, 1988, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors 45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software 46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission. 47 * without specific prior written permission.
48 * 48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 61 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.108 2005/01/17 10:16:07 itojun Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.108.8.1 2008/10/03 09:21:02 jdc Exp $");
66 66
67#include "opt_inet.h" 67#include "opt_inet.h"
68#include "opt_ipsec.h" 68#include "opt_ipsec.h"
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/systm.h> 71#include <sys/systm.h>
72#include <sys/malloc.h> 72#include <sys/malloc.h>
73#include <sys/mbuf.h> 73#include <sys/mbuf.h>
74#include <sys/protosw.h> 74#include <sys/protosw.h>
75#include <sys/socket.h> 75#include <sys/socket.h>
76#include <sys/socketvar.h> 76#include <sys/socketvar.h>
77#include <sys/time.h> 77#include <sys/time.h>
78#include <sys/kernel.h> 78#include <sys/kernel.h>
79#include <sys/syslog.h> 79#include <sys/syslog.h>
80#include <sys/domain.h> 80#include <sys/domain.h>
81#include <sys/sysctl.h> 81#include <sys/sysctl.h>
82 82
83#include <net/if.h> 83#include <net/if.h>
84#include <net/route.h> 84#include <net/route.h>
85#include <net/if_dl.h> 85#include <net/if_dl.h>
86#include <net/if_types.h> 86#include <net/if_types.h>
87 87
88#include <netinet/in.h> 88#include <netinet/in.h>
89#include <netinet/in_var.h> 89#include <netinet/in_var.h>
90#include <netinet/ip6.h> 90#include <netinet/ip6.h>
91#include <netinet6/ip6_var.h> 91#include <netinet6/ip6_var.h>
92#include <netinet/icmp6.h> 92#include <netinet/icmp6.h>
93#include <netinet6/mld6_var.h> 93#include <netinet6/mld6_var.h>
94#include <netinet6/in6_pcb.h> 94#include <netinet6/in6_pcb.h>
95#include <netinet6/nd6.h> 95#include <netinet6/nd6.h>
96#include <netinet6/in6_ifattach.h> 96#include <netinet6/in6_ifattach.h>
97#include <netinet6/ip6protosw.h> 97#include <netinet6/ip6protosw.h>
98 98
99#ifdef IPSEC 99#ifdef IPSEC
100#include <netinet6/ipsec.h> 100#include <netinet6/ipsec.h>
101#include <netkey/key.h> 101#include <netkey/key.h>
102#endif 102#endif
103 103
104#include "faith.h" 104#include "faith.h"
105#if defined(NFAITH) && 0 < NFAITH 105#if defined(NFAITH) && 0 < NFAITH
106#include <net/if_faith.h> 106#include <net/if_faith.h>
107#endif 107#endif
108 108
109#include <net/net_osdep.h> 109#include <net/net_osdep.h>
110 110
111extern struct domain inet6domain; 111extern struct domain inet6domain;
112 112
113struct icmp6stat icmp6stat; 113struct icmp6stat icmp6stat;
114 114
115extern struct inpcbtable raw6cbtable; 115extern struct inpcbtable raw6cbtable;
116extern int icmp6errppslim; 116extern int icmp6errppslim;
117static int icmp6errpps_count = 0; 117static int icmp6errpps_count = 0;
118static struct timeval icmp6errppslim_last; 118static struct timeval icmp6errppslim_last;
119extern int icmp6_nodeinfo; 119extern int icmp6_nodeinfo;
120 120
121/* 121/*
122 * List of callbacks to notify when Path MTU changes are made. 122 * List of callbacks to notify when Path MTU changes are made.
123 */ 123 */
124struct icmp6_mtudisc_callback { 124struct icmp6_mtudisc_callback {
125 LIST_ENTRY(icmp6_mtudisc_callback) mc_list; 125 LIST_ENTRY(icmp6_mtudisc_callback) mc_list;
126 void (*mc_func) __P((struct in6_addr *)); 126 void (*mc_func) __P((struct in6_addr *));
127}; 127};
128 128
129LIST_HEAD(, icmp6_mtudisc_callback) icmp6_mtudisc_callbacks = 129LIST_HEAD(, icmp6_mtudisc_callback) icmp6_mtudisc_callbacks =
130 LIST_HEAD_INITIALIZER(&icmp6_mtudisc_callbacks); 130 LIST_HEAD_INITIALIZER(&icmp6_mtudisc_callbacks);
131 131
132static struct rttimer_queue *icmp6_mtudisc_timeout_q = NULL; 132static struct rttimer_queue *icmp6_mtudisc_timeout_q = NULL;
133extern int pmtu_expire; 133extern int pmtu_expire;
134 134
135/* XXX do these values make any sense? */ 135/* XXX do these values make any sense? */
136static int icmp6_mtudisc_hiwat = 1280; 136static int icmp6_mtudisc_hiwat = 1280;
137static int icmp6_mtudisc_lowat = 256; 137static int icmp6_mtudisc_lowat = 256;
138 138
139/* 139/*
140 * keep track of # of redirect routes. 140 * keep track of # of redirect routes.
141 */ 141 */
142static struct rttimer_queue *icmp6_redirect_timeout_q = NULL; 142static struct rttimer_queue *icmp6_redirect_timeout_q = NULL;
143 143
144/* XXX experimental, turned off */ 144/* XXX experimental, turned off */
145static int icmp6_redirect_hiwat = -1; 145static int icmp6_redirect_hiwat = -1;
146static int icmp6_redirect_lowat = -1; 146static int icmp6_redirect_lowat = -1;
147 147
148static void icmp6_errcount __P((struct icmp6errstat *, int, int)); 148static void icmp6_errcount __P((struct icmp6errstat *, int, int));
149static int icmp6_rip6_input __P((struct mbuf **, int)); 149static int icmp6_rip6_input __P((struct mbuf **, int));
150static int icmp6_ratelimit __P((const struct in6_addr *, const int, const int)); 150static int icmp6_ratelimit __P((const struct in6_addr *, const int, const int));
151static const char *icmp6_redirect_diag __P((struct in6_addr *, 151static const char *icmp6_redirect_diag __P((struct in6_addr *,
152 struct in6_addr *, struct in6_addr *)); 152 struct in6_addr *, struct in6_addr *));
153static struct mbuf *ni6_input __P((struct mbuf *, int)); 153static struct mbuf *ni6_input __P((struct mbuf *, int));
154static struct mbuf *ni6_nametodns __P((const char *, int, int)); 154static struct mbuf *ni6_nametodns __P((const char *, int, int));
155static int ni6_dnsmatch __P((const char *, int, const char *, int)); 155static int ni6_dnsmatch __P((const char *, int, const char *, int));
156static int ni6_addrs __P((struct icmp6_nodeinfo *, struct mbuf *, 156static int ni6_addrs __P((struct icmp6_nodeinfo *, struct mbuf *,
157 struct ifnet **, char *)); 157 struct ifnet **, char *));
158static int ni6_store_addrs __P((struct icmp6_nodeinfo *, struct icmp6_nodeinfo *, 158static int ni6_store_addrs __P((struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
159 struct ifnet *, int)); 159 struct ifnet *, int));
160static int icmp6_notify_error __P((struct mbuf *, int, int, int)); 160static int icmp6_notify_error __P((struct mbuf *, int, int, int));
161static struct rtentry *icmp6_mtudisc_clone __P((struct sockaddr *)); 161static struct rtentry *icmp6_mtudisc_clone __P((struct sockaddr *));
162static void icmp6_mtudisc_timeout __P((struct rtentry *, struct rttimer *)); 162static void icmp6_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
163static void icmp6_redirect_timeout __P((struct rtentry *, struct rttimer *)); 163static void icmp6_redirect_timeout __P((struct rtentry *, struct rttimer *));
164 164
165void 165void
166icmp6_init() 166icmp6_init()
167{ 167{
168 mld6_init(); 168 mld6_init();
169 icmp6_mtudisc_timeout_q = rt_timer_queue_create(pmtu_expire); 169 icmp6_mtudisc_timeout_q = rt_timer_queue_create(pmtu_expire);
170 icmp6_redirect_timeout_q = rt_timer_queue_create(icmp6_redirtimeout); 170 icmp6_redirect_timeout_q = rt_timer_queue_create(icmp6_redirtimeout);
171} 171}
172 172
173static void 173static void
174icmp6_errcount(stat, type, code) 174icmp6_errcount(stat, type, code)
175 struct icmp6errstat *stat; 175 struct icmp6errstat *stat;
176 int type, code; 176 int type, code;
177{ 177{
178 switch (type) { 178 switch (type) {
179 case ICMP6_DST_UNREACH: 179 case ICMP6_DST_UNREACH:
180 switch (code) { 180 switch (code) {
181 case ICMP6_DST_UNREACH_NOROUTE: 181 case ICMP6_DST_UNREACH_NOROUTE:
182 stat->icp6errs_dst_unreach_noroute++; 182 stat->icp6errs_dst_unreach_noroute++;
183 return; 183 return;
184 case ICMP6_DST_UNREACH_ADMIN: 184 case ICMP6_DST_UNREACH_ADMIN:
185 stat->icp6errs_dst_unreach_admin++; 185 stat->icp6errs_dst_unreach_admin++;
186 return; 186 return;
187 case ICMP6_DST_UNREACH_BEYONDSCOPE: 187 case ICMP6_DST_UNREACH_BEYONDSCOPE:
188 stat->icp6errs_dst_unreach_beyondscope++; 188 stat->icp6errs_dst_unreach_beyondscope++;
189 return; 189 return;
190 case ICMP6_DST_UNREACH_ADDR: 190 case ICMP6_DST_UNREACH_ADDR:
191 stat->icp6errs_dst_unreach_addr++; 191 stat->icp6errs_dst_unreach_addr++;
192 return; 192 return;
193 case ICMP6_DST_UNREACH_NOPORT: 193 case ICMP6_DST_UNREACH_NOPORT:
194 stat->icp6errs_dst_unreach_noport++; 194 stat->icp6errs_dst_unreach_noport++;
195 return; 195 return;
196 } 196 }
197 break; 197 break;
198 case ICMP6_PACKET_TOO_BIG: 198 case ICMP6_PACKET_TOO_BIG:
199 stat->icp6errs_packet_too_big++; 199 stat->icp6errs_packet_too_big++;
200 return; 200 return;
201 case ICMP6_TIME_EXCEEDED: 201 case ICMP6_TIME_EXCEEDED:
202 switch (code) { 202 switch (code) {
203 case ICMP6_TIME_EXCEED_TRANSIT: 203 case ICMP6_TIME_EXCEED_TRANSIT:
204 stat->icp6errs_time_exceed_transit++; 204 stat->icp6errs_time_exceed_transit++;
205 return; 205 return;
206 case ICMP6_TIME_EXCEED_REASSEMBLY: 206 case ICMP6_TIME_EXCEED_REASSEMBLY:
207 stat->icp6errs_time_exceed_reassembly++; 207 stat->icp6errs_time_exceed_reassembly++;
208 return; 208 return;
209 } 209 }
210 break; 210 break;
211 case ICMP6_PARAM_PROB: 211 case ICMP6_PARAM_PROB:
212 switch (code) { 212 switch (code) {
213 case ICMP6_PARAMPROB_HEADER: 213 case ICMP6_PARAMPROB_HEADER:
214 stat->icp6errs_paramprob_header++; 214 stat->icp6errs_paramprob_header++;
215 return; 215 return;
216 case ICMP6_PARAMPROB_NEXTHEADER: 216 case ICMP6_PARAMPROB_NEXTHEADER:
217 stat->icp6errs_paramprob_nextheader++; 217 stat->icp6errs_paramprob_nextheader++;
218 return; 218 return;
219 case ICMP6_PARAMPROB_OPTION: 219 case ICMP6_PARAMPROB_OPTION:
220 stat->icp6errs_paramprob_option++; 220 stat->icp6errs_paramprob_option++;
221 return; 221 return;
222 } 222 }
223 break; 223 break;
224 case ND_REDIRECT: 224 case ND_REDIRECT:
225 stat->icp6errs_redirect++; 225 stat->icp6errs_redirect++;
226 return; 226 return;
227 } 227 }
228 stat->icp6errs_unknown++; 228 stat->icp6errs_unknown++;
229} 229}
230 230
231/* 231/*
232 * Register a Path MTU Discovery callback. 232 * Register a Path MTU Discovery callback.
233 */ 233 */
234void 234void
235icmp6_mtudisc_callback_register(func) 235icmp6_mtudisc_callback_register(func)
236 void (*func) __P((struct in6_addr *)); 236 void (*func) __P((struct in6_addr *));
237{ 237{
238 struct icmp6_mtudisc_callback *mc; 238 struct icmp6_mtudisc_callback *mc;
239 239
240 for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL; 240 for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL;
241 mc = LIST_NEXT(mc, mc_list)) { 241 mc = LIST_NEXT(mc, mc_list)) {
242 if (mc->mc_func == func) 242 if (mc->mc_func == func)
243 return; 243 return;
244 } 244 }
245 245
246 mc = malloc(sizeof(*mc), M_PCB, M_NOWAIT); 246 mc = malloc(sizeof(*mc), M_PCB, M_NOWAIT);
247 if (mc == NULL) 247 if (mc == NULL)
248 panic("icmp6_mtudisc_callback_register"); 248 panic("icmp6_mtudisc_callback_register");
249 249
250 mc->mc_func = func; 250 mc->mc_func = func;
251 LIST_INSERT_HEAD(&icmp6_mtudisc_callbacks, mc, mc_list); 251 LIST_INSERT_HEAD(&icmp6_mtudisc_callbacks, mc, mc_list);
252} 252}
253 253
254/* 254/*
255 * Generate an error packet of type error in response to bad IP6 packet. 255 * Generate an error packet of type error in response to bad IP6 packet.
256 */ 256 */
257void 257void
258icmp6_error(m, type, code, param) 258icmp6_error(m, type, code, param)
259 struct mbuf *m; 259 struct mbuf *m;
260 int type, code, param; 260 int type, code, param;
261{ 261{
262 struct ip6_hdr *oip6, *nip6; 262 struct ip6_hdr *oip6, *nip6;
263 struct icmp6_hdr *icmp6; 263 struct icmp6_hdr *icmp6;
264 u_int preplen; 264 u_int preplen;
265 int off; 265 int off;
266 int nxt; 266 int nxt;
267 267
268 icmp6stat.icp6s_error++; 268 icmp6stat.icp6s_error++;
269 269
270 /* count per-type-code statistics */ 270 /* count per-type-code statistics */
271 icmp6_errcount(&icmp6stat.icp6s_outerrhist, type, code); 271 icmp6_errcount(&icmp6stat.icp6s_outerrhist, type, code);
272 272
273 if (m->m_flags & M_DECRYPTED) { 273 if (m->m_flags & M_DECRYPTED) {
274 icmp6stat.icp6s_canterror++; 274 icmp6stat.icp6s_canterror++;
275 goto freeit; 275 goto freeit;
276 } 276 }
277 277
278 if (m->m_len < sizeof(struct ip6_hdr)) { 278 if (m->m_len < sizeof(struct ip6_hdr)) {
279 m = m_pullup(m, sizeof(struct ip6_hdr)); 279 m = m_pullup(m, sizeof(struct ip6_hdr));
280 if (m == NULL) 280 if (m == NULL)
281 return; 281 return;
282 } 282 }
283 oip6 = mtod(m, struct ip6_hdr *); 283 oip6 = mtod(m, struct ip6_hdr *);
284 284
285 /* 285 /*
286 * If the destination address of the erroneous packet is a multicast 286 * If the destination address of the erroneous packet is a multicast
287 * address, or the packet was sent using link-layer multicast, 287 * address, or the packet was sent using link-layer multicast,
288 * we should basically suppress sending an error (RFC 2463, Section 288 * we should basically suppress sending an error (RFC 2463, Section
289 * 2.4). 289 * 2.4).
290 * We have two exceptions (the item e.2 in that section): 290 * We have two exceptions (the item e.2 in that section):
291 * - the Pakcet Too Big message can be sent for path MTU discovery. 291 * - the Pakcet Too Big message can be sent for path MTU discovery.
292 * - the Parameter Problem Message that can be allowed an icmp6 error 292 * - the Parameter Problem Message that can be allowed an icmp6 error
293 * in the option type field. This check has been done in 293 * in the option type field. This check has been done in
294 * ip6_unknown_opt(), so we can just check the type and code. 294 * ip6_unknown_opt(), so we can just check the type and code.
295 */ 295 */
296 if ((m->m_flags & (M_BCAST|M_MCAST) || 296 if ((m->m_flags & (M_BCAST|M_MCAST) ||
297 IN6_IS_ADDR_MULTICAST(&oip6->ip6_dst)) && 297 IN6_IS_ADDR_MULTICAST(&oip6->ip6_dst)) &&
298 (type != ICMP6_PACKET_TOO_BIG && 298 (type != ICMP6_PACKET_TOO_BIG &&
299 (type != ICMP6_PARAM_PROB || 299 (type != ICMP6_PARAM_PROB ||
300 code != ICMP6_PARAMPROB_OPTION))) 300 code != ICMP6_PARAMPROB_OPTION)))
301 goto freeit; 301 goto freeit;
302 302
303 /* 303 /*
304 * RFC 2463, 2.4 (e.5): source address check. 304 * RFC 2463, 2.4 (e.5): source address check.
305 * XXX: the case of anycast source? 305 * XXX: the case of anycast source?
306 */ 306 */
307 if (IN6_IS_ADDR_UNSPECIFIED(&oip6->ip6_src) || 307 if (IN6_IS_ADDR_UNSPECIFIED(&oip6->ip6_src) ||
308 IN6_IS_ADDR_MULTICAST(&oip6->ip6_src)) 308 IN6_IS_ADDR_MULTICAST(&oip6->ip6_src))
309 goto freeit; 309 goto freeit;
310 310
311 /* 311 /*
312 * If we are about to send ICMPv6 against ICMPv6 error/redirect, 312 * If we are about to send ICMPv6 against ICMPv6 error/redirect,
313 * don't do it. 313 * don't do it.
314 */ 314 */
315 nxt = -1; 315 nxt = -1;
316 off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt); 316 off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
317 if (off >= 0 && nxt == IPPROTO_ICMPV6) { 317 if (off >= 0 && nxt == IPPROTO_ICMPV6) {
318 struct icmp6_hdr *icp; 318 struct icmp6_hdr *icp;
319 319
320 IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off, 320 IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off,
321 sizeof(*icp)); 321 sizeof(*icp));
322 if (icp == NULL) { 322 if (icp == NULL) {
323 icmp6stat.icp6s_tooshort++; 323 icmp6stat.icp6s_tooshort++;
324 return; 324 return;
325 } 325 }
326 if (icp->icmp6_type < ICMP6_ECHO_REQUEST || 326 if (icp->icmp6_type < ICMP6_ECHO_REQUEST ||
327 icp->icmp6_type == ND_REDIRECT) { 327 icp->icmp6_type == ND_REDIRECT) {
328 /* 328 /*
329 * ICMPv6 error 329 * ICMPv6 error
330 * Special case: for redirect (which is 330 * Special case: for redirect (which is
331 * informational) we must not send icmp6 error. 331 * informational) we must not send icmp6 error.
332 */ 332 */
333 icmp6stat.icp6s_canterror++; 333 icmp6stat.icp6s_canterror++;
334 goto freeit; 334 goto freeit;
335 } else { 335 } else {
336 /* ICMPv6 informational - send the error */ 336 /* ICMPv6 informational - send the error */
337 } 337 }
338 } 338 }
339#if 0 /* controversial */ 339#if 0 /* controversial */
340 else if (off >= 0 && nxt == IPPROTO_ESP) { 340 else if (off >= 0 && nxt == IPPROTO_ESP) {
341 /* 341 /*
342 * It could be ICMPv6 error inside ESP. Take a safer side, 342 * It could be ICMPv6 error inside ESP. Take a safer side,
343 * don't respond. 343 * don't respond.
344 */ 344 */
345 icmp6stat.icp6s_canterror++; 345 icmp6stat.icp6s_canterror++;
346 goto freeit; 346 goto freeit;
347 } 347 }
348#endif 348#endif
349 else { 349 else {
350 /* non-ICMPv6 - send the error */ 350 /* non-ICMPv6 - send the error */
351 } 351 }
352 352
353 oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */ 353 oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */
354 354
355 /* Finally, do rate limitation check. */ 355 /* Finally, do rate limitation check. */
356 if (icmp6_ratelimit(&oip6->ip6_src, type, code)) { 356 if (icmp6_ratelimit(&oip6->ip6_src, type, code)) {
357 icmp6stat.icp6s_toofreq++; 357 icmp6stat.icp6s_toofreq++;
358 goto freeit; 358 goto freeit;
359 } 359 }
360 360
361 /* 361 /*
362 * OK, ICMP6 can be generated. 362 * OK, ICMP6 can be generated.
363 */ 363 */
364 364
365 if (m->m_pkthdr.len >= ICMPV6_PLD_MAXLEN) 365 if (m->m_pkthdr.len >= ICMPV6_PLD_MAXLEN)
366 m_adj(m, ICMPV6_PLD_MAXLEN - m->m_pkthdr.len); 366 m_adj(m, ICMPV6_PLD_MAXLEN - m->m_pkthdr.len);
367 367
368 preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); 368 preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
369 M_PREPEND(m, preplen, M_DONTWAIT); 369 M_PREPEND(m, preplen, M_DONTWAIT);
370 if (m && m->m_len < preplen) 370 if (m && m->m_len < preplen)
371 m = m_pullup(m, preplen); 371 m = m_pullup(m, preplen);
372 if (m == NULL) { 372 if (m == NULL) {
373 nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__)); 373 nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__));
374 return; 374 return;
375 } 375 }
376 376
377 nip6 = mtod(m, struct ip6_hdr *); 377 nip6 = mtod(m, struct ip6_hdr *);
378 nip6->ip6_src = oip6->ip6_src; 378 nip6->ip6_src = oip6->ip6_src;
379 nip6->ip6_dst = oip6->ip6_dst; 379 nip6->ip6_dst = oip6->ip6_dst;
380 380
381 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src)) 381 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src))
382 oip6->ip6_src.s6_addr16[1] = 0; 382 oip6->ip6_src.s6_addr16[1] = 0;
383 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst)) 383 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst))
384 oip6->ip6_dst.s6_addr16[1] = 0; 384 oip6->ip6_dst.s6_addr16[1] = 0;
385 385
386 icmp6 = (struct icmp6_hdr *)(nip6 + 1); 386 icmp6 = (struct icmp6_hdr *)(nip6 + 1);
387 icmp6->icmp6_type = type; 387 icmp6->icmp6_type = type;
388 icmp6->icmp6_code = code; 388 icmp6->icmp6_code = code;
389 icmp6->icmp6_pptr = htonl((u_int32_t)param); 389 icmp6->icmp6_pptr = htonl((u_int32_t)param);
390 390
391 /* 391 /*
392 * icmp6_reflect() is designed to be in the input path. 392 * icmp6_reflect() is designed to be in the input path.
393 * icmp6_error() can be called from both input and outut path, 393 * icmp6_error() can be called from both input and outut path,
394 * and if we are in output path rcvif could contain bogus value. 394 * and if we are in output path rcvif could contain bogus value.
395 * clear m->m_pkthdr.rcvif for safety, we should have enough scope 395 * clear m->m_pkthdr.rcvif for safety, we should have enough scope
396 * information in ip header (nip6). 396 * information in ip header (nip6).
397 */ 397 */
398 m->m_pkthdr.rcvif = NULL; 398 m->m_pkthdr.rcvif = NULL;
399 399
400 icmp6stat.icp6s_outhist[type]++; 400 icmp6stat.icp6s_outhist[type]++;
401 icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */ 401 icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */
402 402
403 return; 403 return;
404 404
405 freeit: 405 freeit:
406 /* 406 /*
407 * If we can't tell wheter or not we can generate ICMP6, free it. 407 * If we can't tell wheter or not we can generate ICMP6, free it.
408 */ 408 */
409 m_freem(m); 409 m_freem(m);
410} 410}
411 411
412/* 412/*
413 * Process a received ICMP6 message. 413 * Process a received ICMP6 message.
414 */ 414 */
415int 415int
416icmp6_input(mp, offp, proto) 416icmp6_input(mp, offp, proto)
417 struct mbuf **mp; 417 struct mbuf **mp;
418 int *offp, proto; 418 int *offp, proto;
419{ 419{
420 struct mbuf *m = *mp, *n; 420 struct mbuf *m = *mp, *n;
421 struct ip6_hdr *ip6, *nip6; 421 struct ip6_hdr *ip6, *nip6;
422 struct icmp6_hdr *icmp6, *nicmp6; 422 struct icmp6_hdr *icmp6, *nicmp6;
423 int off = *offp; 423 int off = *offp;
424 int icmp6len = m->m_pkthdr.len - *offp; 424 int icmp6len = m->m_pkthdr.len - *offp;
425 int code, sum, noff; 425 int code, sum, noff;
426 426
427 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_msg); 427 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_msg);
428 428
429 /* 429 /*
430 * Locate icmp6 structure in mbuf, and check 430 * Locate icmp6 structure in mbuf, and check
431 * that not corrupted and of at least minimum length 431 * that not corrupted and of at least minimum length
432 */ 432 */
433 433
434 ip6 = mtod(m, struct ip6_hdr *); 434 ip6 = mtod(m, struct ip6_hdr *);
435 if (icmp6len < sizeof(struct icmp6_hdr)) { 435 if (icmp6len < sizeof(struct icmp6_hdr)) {
436 icmp6stat.icp6s_tooshort++; 436 icmp6stat.icp6s_tooshort++;
437 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error); 437 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error);
438 goto freeit; 438 goto freeit;
439 } 439 }
440 440
441 /* 441 /*
442 * calculate the checksum 442 * calculate the checksum
443 */ 443 */
444 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); 444 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
445 if (icmp6 == NULL) { 445 if (icmp6 == NULL) {
446 icmp6stat.icp6s_tooshort++; 446 icmp6stat.icp6s_tooshort++;
447 /* m is invalid */ 447 /* m is invalid */
448 /*icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error);*/ 448 /*icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error);*/
449 return IPPROTO_DONE; 449 return IPPROTO_DONE;
450 } 450 }
451 KASSERT(IP6_HDR_ALIGNED_P(icmp6)); 451 KASSERT(IP6_HDR_ALIGNED_P(icmp6));
452 code = icmp6->icmp6_code; 452 code = icmp6->icmp6_code;
453 453
454 if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { 454 if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) {
455 nd6log((LOG_ERR, 455 nd6log((LOG_ERR,
456 "ICMP6 checksum error(%d|%x) %s\n", 456 "ICMP6 checksum error(%d|%x) %s\n",
457 icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src))); 457 icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src)));
458 icmp6stat.icp6s_checksum++; 458 icmp6stat.icp6s_checksum++;
459 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error); 459 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error);
460 goto freeit; 460 goto freeit;
461 } 461 }
462 462
463#if defined(NFAITH) && 0 < NFAITH 463#if defined(NFAITH) && 0 < NFAITH
464 if (faithprefix(&ip6->ip6_dst)) { 464 if (faithprefix(&ip6->ip6_dst)) {
465 /* 465 /*
466 * Deliver very specific ICMP6 type only. 466 * Deliver very specific ICMP6 type only.
467 * This is important to deilver TOOBIG. Otherwise PMTUD 467 * This is important to deilver TOOBIG. Otherwise PMTUD
468 * will not work. 468 * will not work.
469 */ 469 */
470 switch (icmp6->icmp6_type) { 470 switch (icmp6->icmp6_type) {
471 case ICMP6_DST_UNREACH: 471 case ICMP6_DST_UNREACH:
472 case ICMP6_PACKET_TOO_BIG: 472 case ICMP6_PACKET_TOO_BIG:
473 case ICMP6_TIME_EXCEEDED: 473 case ICMP6_TIME_EXCEEDED:
474 break; 474 break;
475 default: 475 default:
476 goto freeit; 476 goto freeit;
477 } 477 }
478 } 478 }
479#endif 479#endif
480 480
481 icmp6stat.icp6s_inhist[icmp6->icmp6_type]++; 481 icmp6stat.icp6s_inhist[icmp6->icmp6_type]++;
482 482
483 switch (icmp6->icmp6_type) { 483 switch (icmp6->icmp6_type) {
484 case ICMP6_DST_UNREACH: 484 case ICMP6_DST_UNREACH:
485 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_dstunreach); 485 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_dstunreach);
486 switch (code) { 486 switch (code) {
487 case ICMP6_DST_UNREACH_NOROUTE: 487 case ICMP6_DST_UNREACH_NOROUTE:
488 code = PRC_UNREACH_NET; 488 code = PRC_UNREACH_NET;
489 break; 489 break;
490 case ICMP6_DST_UNREACH_ADMIN: 490 case ICMP6_DST_UNREACH_ADMIN:
491 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_adminprohib); 491 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_adminprohib);
492 code = PRC_UNREACH_PROTOCOL; /* is this a good code? */ 492 code = PRC_UNREACH_PROTOCOL; /* is this a good code? */
493 break; 493 break;
494 case ICMP6_DST_UNREACH_ADDR: 494 case ICMP6_DST_UNREACH_ADDR:
495 code = PRC_HOSTDEAD; 495 code = PRC_HOSTDEAD;
496 break; 496 break;
497#ifdef COMPAT_RFC1885 497#ifdef COMPAT_RFC1885
498 case ICMP6_DST_UNREACH_NOTNEIGHBOR: 498 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
499 code = PRC_UNREACH_SRCFAIL; 499 code = PRC_UNREACH_SRCFAIL;
500 break; 500 break;
501#else 501#else
502 case ICMP6_DST_UNREACH_BEYONDSCOPE: 502 case ICMP6_DST_UNREACH_BEYONDSCOPE:
503 /* I mean "source address was incorrect." */ 503 /* I mean "source address was incorrect." */
504 code = PRC_UNREACH_NET; 504 code = PRC_UNREACH_NET;
505 break; 505 break;
506#endif 506#endif
507 case ICMP6_DST_UNREACH_NOPORT: 507 case ICMP6_DST_UNREACH_NOPORT:
508 code = PRC_UNREACH_PORT; 508 code = PRC_UNREACH_PORT;
509 break; 509 break;
510 default: 510 default:
511 goto badcode; 511 goto badcode;
512 } 512 }
513 goto deliver; 513 goto deliver;
514 514
515 case ICMP6_PACKET_TOO_BIG: 515 case ICMP6_PACKET_TOO_BIG:
516 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_pkttoobig); 516 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_pkttoobig);
517 517
 518 /*
 519 * MTU is checked in icmp6_mtudisc.
 520 */
518 code = PRC_MSGSIZE; 521 code = PRC_MSGSIZE;
519 522
520 /* 523 /*
521 * Updating the path MTU will be done after examining 524 * Updating the path MTU will be done after examining
522 * intermediate extension headers. 525 * intermediate extension headers.
523 */ 526 */
524 goto deliver; 527 goto deliver;
525 528
526 case ICMP6_TIME_EXCEEDED: 529 case ICMP6_TIME_EXCEEDED:
527 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_timeexceed); 530 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_timeexceed);
528 switch (code) { 531 switch (code) {
529 case ICMP6_TIME_EXCEED_TRANSIT: 532 case ICMP6_TIME_EXCEED_TRANSIT:
530 code = PRC_TIMXCEED_INTRANS; 533 code = PRC_TIMXCEED_INTRANS;
531 break; 534 break;
532 case ICMP6_TIME_EXCEED_REASSEMBLY: 535 case ICMP6_TIME_EXCEED_REASSEMBLY:
533 code = PRC_TIMXCEED_REASS; 536 code = PRC_TIMXCEED_REASS;
534 break; 537 break;
535 default: 538 default:
536 goto badcode; 539 goto badcode;
537 } 540 }
538 goto deliver; 541 goto deliver;
539 542
540 case ICMP6_PARAM_PROB: 543 case ICMP6_PARAM_PROB:
541 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_paramprob); 544 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_paramprob);
542 switch (code) { 545 switch (code) {
543 case ICMP6_PARAMPROB_NEXTHEADER: 546 case ICMP6_PARAMPROB_NEXTHEADER:
544 code = PRC_UNREACH_PROTOCOL; 547 code = PRC_UNREACH_PROTOCOL;
545 break; 548 break;
546 case ICMP6_PARAMPROB_HEADER: 549 case ICMP6_PARAMPROB_HEADER:
547 case ICMP6_PARAMPROB_OPTION: 550 case ICMP6_PARAMPROB_OPTION:
548 code = PRC_PARAMPROB; 551 code = PRC_PARAMPROB;
549 break; 552 break;
550 default: 553 default:
551 goto badcode; 554 goto badcode;
552 } 555 }
553 goto deliver; 556 goto deliver;
554 557
555 case ICMP6_ECHO_REQUEST: 558 case ICMP6_ECHO_REQUEST:
556 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echo); 559 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echo);
557 if (code != 0) 560 if (code != 0)
558 goto badcode; 561 goto badcode;
559 /* 562 /*
560 * Copy mbuf to send to two data paths: userland socket(s), 563 * Copy mbuf to send to two data paths: userland socket(s),
561 * and to the querier (echo reply). 564 * and to the querier (echo reply).
562 * m: a copy for socket, n: a copy for querier 565 * m: a copy for socket, n: a copy for querier
563 */ 566 */
564 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 567 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
565 /* Give up local */ 568 /* Give up local */
566 n = m; 569 n = m;
567 m = NULL; 570 m = NULL;
568 goto deliverecho; 571 goto deliverecho;
569 } 572 }
570 /* 573 /*
571 * If the first mbuf is shared, or the first mbuf is too short, 574 * If the first mbuf is shared, or the first mbuf is too short,
572 * copy the first part of the data into a fresh mbuf. 575 * copy the first part of the data into a fresh mbuf.
573 * Otherwise, we will wrongly overwrite both copies. 576 * Otherwise, we will wrongly overwrite both copies.
574 */ 577 */
575 if ((n->m_flags & M_EXT) != 0 || 578 if ((n->m_flags & M_EXT) != 0 ||
576 n->m_len < off + sizeof(struct icmp6_hdr)) { 579 n->m_len < off + sizeof(struct icmp6_hdr)) {
577 struct mbuf *n0 = n; 580 struct mbuf *n0 = n;
578 const int maxlen = sizeof(*nip6) + sizeof(*nicmp6); 581 const int maxlen = sizeof(*nip6) + sizeof(*nicmp6);
579 582
580 /* 583 /*
581 * Prepare an internal mbuf. m_pullup() doesn't 584 * Prepare an internal mbuf. m_pullup() doesn't
582 * always copy the length we specified. 585 * always copy the length we specified.
583 */ 586 */
584 if (maxlen >= MCLBYTES) { 587 if (maxlen >= MCLBYTES) {
585 /* Give up remote */ 588 /* Give up remote */
586 m_freem(n0); 589 m_freem(n0);
587 break; 590 break;
588 } 591 }
589 MGETHDR(n, M_DONTWAIT, n0->m_type); 592 MGETHDR(n, M_DONTWAIT, n0->m_type);
590 if (n && maxlen >= MHLEN) { 593 if (n && maxlen >= MHLEN) {
591 MCLGET(n, M_DONTWAIT); 594 MCLGET(n, M_DONTWAIT);
592 if ((n->m_flags & M_EXT) == 0) { 595 if ((n->m_flags & M_EXT) == 0) {
593 m_free(n); 596 m_free(n);
594 n = NULL; 597 n = NULL;
595 } 598 }
596 } 599 }
597 if (n == NULL) { 600 if (n == NULL) {
598 /* Give up local */ 601 /* Give up local */
599 m_freem(n0); 602 m_freem(n0);
600 n = m; 603 n = m;
601 m = NULL; 604 m = NULL;
602 goto deliverecho; 605 goto deliverecho;
603 } 606 }
604 M_COPY_PKTHDR(n, n0); 607 M_COPY_PKTHDR(n, n0);
605 /* 608 /*
606 * Copy IPv6 and ICMPv6 only. 609 * Copy IPv6 and ICMPv6 only.
607 */ 610 */
608 nip6 = mtod(n, struct ip6_hdr *); 611 nip6 = mtod(n, struct ip6_hdr *);
609 bcopy(ip6, nip6, sizeof(struct ip6_hdr)); 612 bcopy(ip6, nip6, sizeof(struct ip6_hdr));
610 nicmp6 = (struct icmp6_hdr *)(nip6 + 1); 613 nicmp6 = (struct icmp6_hdr *)(nip6 + 1);
611 bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr)); 614 bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
612 noff = sizeof(struct ip6_hdr); 615 noff = sizeof(struct ip6_hdr);
613 n->m_len = noff + sizeof(struct icmp6_hdr); 616 n->m_len = noff + sizeof(struct icmp6_hdr);
614 /* 617 /*
615 * Adjust mbuf. ip6_plen will be adjusted in 618 * Adjust mbuf. ip6_plen will be adjusted in
616 * ip6_output(). 619 * ip6_output().
617 * n->m_pkthdr.len == n0->m_pkthdr.len at this point. 620 * n->m_pkthdr.len == n0->m_pkthdr.len at this point.
618 */ 621 */
619 n->m_pkthdr.len += noff + sizeof(struct icmp6_hdr); 622 n->m_pkthdr.len += noff + sizeof(struct icmp6_hdr);
620 n->m_pkthdr.len -= (off + sizeof(struct icmp6_hdr)); 623 n->m_pkthdr.len -= (off + sizeof(struct icmp6_hdr));
621 m_adj(n0, off + sizeof(struct icmp6_hdr)); 624 m_adj(n0, off + sizeof(struct icmp6_hdr));
622 n->m_next = n0; 625 n->m_next = n0;
623 n0->m_flags &= ~M_PKTHDR; 626 n0->m_flags &= ~M_PKTHDR;
624 } else { 627 } else {
625 deliverecho: 628 deliverecho:
626 nip6 = mtod(n, struct ip6_hdr *); 629 nip6 = mtod(n, struct ip6_hdr *);
627 nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off); 630 nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off);
628 noff = off; 631 noff = off;
629 } 632 }
630 nicmp6->icmp6_type = ICMP6_ECHO_REPLY; 633 nicmp6->icmp6_type = ICMP6_ECHO_REPLY;
631 nicmp6->icmp6_code = 0; 634 nicmp6->icmp6_code = 0;
632 if (n) { 635 if (n) {
633 icmp6stat.icp6s_reflect++; 636 icmp6stat.icp6s_reflect++;
634 icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++; 637 icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++;
635 icmp6_reflect(n, noff); 638 icmp6_reflect(n, noff);
636 } 639 }
637 if (!m) 640 if (!m)
638 goto freeit; 641 goto freeit;
639 break; 642 break;
640 643
641 case ICMP6_ECHO_REPLY: 644 case ICMP6_ECHO_REPLY:
642 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echoreply); 645 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echoreply);
643 if (code != 0) 646 if (code != 0)
644 goto badcode; 647 goto badcode;
645 break; 648 break;
646 649
647 case MLD_LISTENER_QUERY: 650 case MLD_LISTENER_QUERY:
648 case MLD_LISTENER_REPORT: 651 case MLD_LISTENER_REPORT:
649 if (icmp6len < sizeof(struct mld_hdr)) 652 if (icmp6len < sizeof(struct mld_hdr))
650 goto badlen; 653 goto badlen;
651 if (icmp6->icmp6_type == MLD_LISTENER_QUERY) /* XXX: ugly... */ 654 if (icmp6->icmp6_type == MLD_LISTENER_QUERY) /* XXX: ugly... */
652 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldquery); 655 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldquery);
653 else 656 else
654 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldreport); 657 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldreport);
655 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 658 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
656 /* give up local */ 659 /* give up local */
657 mld6_input(m, off); 660 mld6_input(m, off);
658 m = NULL; 661 m = NULL;
659 goto freeit; 662 goto freeit;
660 } 663 }
661 mld6_input(n, off); 664 mld6_input(n, off);
662 /* m stays. */ 665 /* m stays. */
663 break; 666 break;
664 667
665 case MLD_LISTENER_DONE: 668 case MLD_LISTENER_DONE:
666 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mlddone); 669 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mlddone);
667 if (icmp6len < sizeof(struct mld_hdr)) /* necessary? */ 670 if (icmp6len < sizeof(struct mld_hdr)) /* necessary? */
668 goto badlen; 671 goto badlen;
669 break; /* nothing to be done in kernel */ 672 break; /* nothing to be done in kernel */
670 673
671 case MLD_MTRACE_RESP: 674 case MLD_MTRACE_RESP:
672 case MLD_MTRACE: 675 case MLD_MTRACE:
673 /* XXX: these two are experimental. not officially defined. */ 676 /* XXX: these two are experimental. not officially defined. */
674 /* XXX: per-interface statistics? */ 677 /* XXX: per-interface statistics? */
675 break; /* just pass it to applications */ 678 break; /* just pass it to applications */
676 679
677 case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */ 680 case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */
678 { 681 {
679 enum { WRU, FQDN } mode; 682 enum { WRU, FQDN } mode;
680 683
681 if (!icmp6_nodeinfo) 684 if (!icmp6_nodeinfo)
682 break; 685 break;
683 686
684 if (icmp6len == sizeof(struct icmp6_hdr) + 4) 687 if (icmp6len == sizeof(struct icmp6_hdr) + 4)
685 mode = WRU; 688 mode = WRU;
686 else if (icmp6len >= sizeof(struct icmp6_nodeinfo)) 689 else if (icmp6len >= sizeof(struct icmp6_nodeinfo))
687 mode = FQDN; 690 mode = FQDN;
688 else 691 else
689 goto badlen; 692 goto badlen;
690 693
691 if (mode == FQDN) { 694 if (mode == FQDN) {
692 n = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 695 n = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
693 if (n) 696 if (n)
694 n = ni6_input(n, off); 697 n = ni6_input(n, off);
695 /* XXX meaningless if n == NULL */ 698 /* XXX meaningless if n == NULL */
696 noff = sizeof(struct ip6_hdr); 699 noff = sizeof(struct ip6_hdr);
697 } else { 700 } else {
698 u_char *p; 701 u_char *p;
699 int maxlen, maxhlen; 702 int maxlen, maxhlen;
700 703
701 if ((icmp6_nodeinfo & 5) != 5) 704 if ((icmp6_nodeinfo & 5) != 5)
702 break; 705 break;
703 706
704 if (code != 0) 707 if (code != 0)
705 goto badcode; 708 goto badcode;
706 maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4; 709 maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4;
707 if (maxlen >= MCLBYTES) { 710 if (maxlen >= MCLBYTES) {
708 /* Give up remote */ 711 /* Give up remote */
709 break; 712 break;
710 } 713 }
711 MGETHDR(n, M_DONTWAIT, m->m_type); 714 MGETHDR(n, M_DONTWAIT, m->m_type);
712 if (n && maxlen > MHLEN) { 715 if (n && maxlen > MHLEN) {
713 MCLGET(n, M_DONTWAIT); 716 MCLGET(n, M_DONTWAIT);
714 if ((n->m_flags & M_EXT) == 0) { 717 if ((n->m_flags & M_EXT) == 0) {
715 m_free(n); 718 m_free(n);
716 n = NULL; 719 n = NULL;
717 } 720 }
718 } 721 }
719 if (n == NULL) { 722 if (n == NULL) {
720 /* Give up remote */ 723 /* Give up remote */
721 break; 724 break;
722 } 725 }
723 n->m_pkthdr.rcvif = NULL; 726 n->m_pkthdr.rcvif = NULL;
724 n->m_len = 0; 727 n->m_len = 0;
725 maxhlen = M_TRAILINGSPACE(n) - maxlen; 728 maxhlen = M_TRAILINGSPACE(n) - maxlen;
726 if (maxhlen > hostnamelen) 729 if (maxhlen > hostnamelen)
727 maxhlen = hostnamelen; 730 maxhlen = hostnamelen;
728 /* 731 /*
729 * Copy IPv6 and ICMPv6 only. 732 * Copy IPv6 and ICMPv6 only.
730 */ 733 */
731 nip6 = mtod(n, struct ip6_hdr *); 734 nip6 = mtod(n, struct ip6_hdr *);
732 bcopy(ip6, nip6, sizeof(struct ip6_hdr)); 735 bcopy(ip6, nip6, sizeof(struct ip6_hdr));
733 nicmp6 = (struct icmp6_hdr *)(nip6 + 1); 736 nicmp6 = (struct icmp6_hdr *)(nip6 + 1);
734 bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr)); 737 bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
735 p = (u_char *)(nicmp6 + 1); 738 p = (u_char *)(nicmp6 + 1);
736 bzero(p, 4); 739 bzero(p, 4);
737 bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */ 740 bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */
738 noff = sizeof(struct ip6_hdr); 741 noff = sizeof(struct ip6_hdr);
739 M_COPY_PKTHDR(n, m); /* just for rcvif */ 742 M_COPY_PKTHDR(n, m); /* just for rcvif */
740 n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 743 n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
741 sizeof(struct icmp6_hdr) + 4 + maxhlen; 744 sizeof(struct icmp6_hdr) + 4 + maxhlen;
742 nicmp6->icmp6_type = ICMP6_WRUREPLY; 745 nicmp6->icmp6_type = ICMP6_WRUREPLY;
743 nicmp6->icmp6_code = 0; 746 nicmp6->icmp6_code = 0;
744 } 747 }
745#undef hostnamelen 748#undef hostnamelen
746 if (n) { 749 if (n) {
747 icmp6stat.icp6s_reflect++; 750 icmp6stat.icp6s_reflect++;
748 icmp6stat.icp6s_outhist[ICMP6_WRUREPLY]++; 751 icmp6stat.icp6s_outhist[ICMP6_WRUREPLY]++;
749 icmp6_reflect(n, noff); 752 icmp6_reflect(n, noff);
750 } 753 }
751 break; 754 break;
752 } 755 }
753 756
754 case ICMP6_WRUREPLY: 757 case ICMP6_WRUREPLY:
755 if (code != 0) 758 if (code != 0)
756 goto badcode; 759 goto badcode;
757 break; 760 break;
758 761
759 case ND_ROUTER_SOLICIT: 762 case ND_ROUTER_SOLICIT:
760 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_routersolicit); 763 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_routersolicit);
761 if (code != 0) 764 if (code != 0)
762 goto badcode; 765 goto badcode;
763 if (icmp6len < sizeof(struct nd_router_solicit)) 766 if (icmp6len < sizeof(struct nd_router_solicit))
764 goto badlen; 767 goto badlen;
765 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 768 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
766 /* give up local */ 769 /* give up local */
767 nd6_rs_input(m, off, icmp6len); 770 nd6_rs_input(m, off, icmp6len);
768 m = NULL; 771 m = NULL;
769 goto freeit; 772 goto freeit;
770 } 773 }
771 nd6_rs_input(n, off, icmp6len); 774 nd6_rs_input(n, off, icmp6len);
772 /* m stays. */ 775 /* m stays. */
773 break; 776 break;
774 777
775 case ND_ROUTER_ADVERT: 778 case ND_ROUTER_ADVERT:
776 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_routeradvert); 779 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_routeradvert);
777 if (code != 0) 780 if (code != 0)
778 goto badcode; 781 goto badcode;
779 if (icmp6len < sizeof(struct nd_router_advert)) 782 if (icmp6len < sizeof(struct nd_router_advert))
780 goto badlen; 783 goto badlen;
781 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 784 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
782 /* give up local */ 785 /* give up local */
783 nd6_ra_input(m, off, icmp6len); 786 nd6_ra_input(m, off, icmp6len);
784 m = NULL; 787 m = NULL;
785 goto freeit; 788 goto freeit;
786 } 789 }
787 nd6_ra_input(n, off, icmp6len); 790 nd6_ra_input(n, off, icmp6len);
788 /* m stays. */ 791 /* m stays. */
789 break; 792 break;
790 793
791 case ND_NEIGHBOR_SOLICIT: 794 case ND_NEIGHBOR_SOLICIT:
792 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_neighborsolicit); 795 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_neighborsolicit);
793 if (code != 0) 796 if (code != 0)
794 goto badcode; 797 goto badcode;
795 if (icmp6len < sizeof(struct nd_neighbor_solicit)) 798 if (icmp6len < sizeof(struct nd_neighbor_solicit))
796 goto badlen; 799 goto badlen;
797 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 800 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
798 /* give up local */ 801 /* give up local */
799 nd6_ns_input(m, off, icmp6len); 802 nd6_ns_input(m, off, icmp6len);
800 m = NULL; 803 m = NULL;
801 goto freeit; 804 goto freeit;
802 } 805 }
803 nd6_ns_input(n, off, icmp6len); 806 nd6_ns_input(n, off, icmp6len);
804 /* m stays. */ 807 /* m stays. */
805 break; 808 break;
806 809
807 case ND_NEIGHBOR_ADVERT: 810 case ND_NEIGHBOR_ADVERT:
808 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_neighboradvert); 811 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_neighboradvert);
809 if (code != 0) 812 if (code != 0)
810 goto badcode; 813 goto badcode;
811 if (icmp6len < sizeof(struct nd_neighbor_advert)) 814 if (icmp6len < sizeof(struct nd_neighbor_advert))
812 goto badlen; 815 goto badlen;
813 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 816 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
814 /* give up local */ 817 /* give up local */
815 nd6_na_input(m, off, icmp6len); 818 nd6_na_input(m, off, icmp6len);
816 m = NULL; 819 m = NULL;
817 goto freeit; 820 goto freeit;
818 } 821 }
819 nd6_na_input(n, off, icmp6len); 822 nd6_na_input(n, off, icmp6len);
820 /* m stays. */ 823 /* m stays. */
821 break; 824 break;
822 825
823 case ND_REDIRECT: 826 case ND_REDIRECT:
824 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_redirect); 827 icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_redirect);
825 if (code != 0) 828 if (code != 0)
826 goto badcode; 829 goto badcode;
827 if (icmp6len < sizeof(struct nd_redirect)) 830 if (icmp6len < sizeof(struct nd_redirect))
828 goto badlen; 831 goto badlen;
829 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 832 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
830 /* give up local */ 833 /* give up local */
831 icmp6_redirect_input(m, off); 834 icmp6_redirect_input(m, off);
832 m = NULL; 835 m = NULL;
833 goto freeit; 836 goto freeit;
834 } 837 }
835 icmp6_redirect_input(n, off); 838 icmp6_redirect_input(n, off);
836 /* m stays. */ 839 /* m stays. */
837 break; 840 break;
838 841
839 case ICMP6_ROUTER_RENUMBERING: 842 case ICMP6_ROUTER_RENUMBERING:
840 if (code != ICMP6_ROUTER_RENUMBERING_COMMAND && 843 if (code != ICMP6_ROUTER_RENUMBERING_COMMAND &&
841 code != ICMP6_ROUTER_RENUMBERING_RESULT) 844 code != ICMP6_ROUTER_RENUMBERING_RESULT)
842 goto badcode; 845 goto badcode;
843 if (icmp6len < sizeof(struct icmp6_router_renum)) 846 if (icmp6len < sizeof(struct icmp6_router_renum))
844 goto badlen; 847 goto badlen;
845 break; 848 break;
846 849
847 default: 850 default:
848 nd6log((LOG_DEBUG, 851 nd6log((LOG_DEBUG,
849 "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n", 852 "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n",
850 icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src), 853 icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src),
851 ip6_sprintf(&ip6->ip6_dst), 854 ip6_sprintf(&ip6->ip6_dst),
852 m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0)); 855 m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0));
853 if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) { 856 if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) {
854 /* ICMPv6 error: MUST deliver it by spec... */ 857 /* ICMPv6 error: MUST deliver it by spec... */
855 code = PRC_NCMDS; 858 code = PRC_NCMDS;
856 /* deliver */ 859 /* deliver */
857 } else { 860 } else {
858 /* ICMPv6 informational: MUST not deliver */ 861 /* ICMPv6 informational: MUST not deliver */
859 break; 862 break;
860 } 863 }
861 deliver: 864 deliver:
862 if (icmp6_notify_error(m, off, icmp6len, code)) { 865 if (icmp6_notify_error(m, off, icmp6len, code)) {
863 /* In this case, m should've been freed. */ 866 /* In this case, m should've been freed. */
864 return (IPPROTO_DONE); 867 return (IPPROTO_DONE);
865 } 868 }
866 break; 869 break;
867 870
868 badcode: 871 badcode:
869 icmp6stat.icp6s_badcode++; 872 icmp6stat.icp6s_badcode++;
870 break; 873 break;
871 874
872 badlen: 875 badlen:
873 icmp6stat.icp6s_badlen++; 876 icmp6stat.icp6s_badlen++;
874 break; 877 break;
875 } 878 }
876 879
877 /* deliver the packet to appropriate sockets */ 880 /* deliver the packet to appropriate sockets */
878 icmp6_rip6_input(&m, *offp); 881 icmp6_rip6_input(&m, *offp);
879 882
880 return IPPROTO_DONE; 883 return IPPROTO_DONE;
881 884
882 freeit: 885 freeit:
883 m_freem(m); 886 m_freem(m);
884 return IPPROTO_DONE; 887 return IPPROTO_DONE;
885} 888}
886 889
887static int 890static int
888icmp6_notify_error(m, off, icmp6len, code) 891icmp6_notify_error(m, off, icmp6len, code)
889 struct mbuf *m; 892 struct mbuf *m;
890 int off, icmp6len; 893 int off, icmp6len;
891{ 894{
892 struct icmp6_hdr *icmp6; 895 struct icmp6_hdr *icmp6;
893 struct ip6_hdr *eip6; 896 struct ip6_hdr *eip6;
894 u_int32_t notifymtu; 897 u_int32_t notifymtu;
895 struct sockaddr_in6 icmp6src, icmp6dst; 898 struct sockaddr_in6 icmp6src, icmp6dst;
896 899
897 if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) { 900 if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) {
898 icmp6stat.icp6s_tooshort++; 901 icmp6stat.icp6s_tooshort++;
899 goto freeit; 902 goto freeit;
900 } 903 }
901 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 904 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
902 sizeof(*icmp6) + sizeof(struct ip6_hdr)); 905 sizeof(*icmp6) + sizeof(struct ip6_hdr));
903 if (icmp6 == NULL) { 906 if (icmp6 == NULL) {
904 icmp6stat.icp6s_tooshort++; 907 icmp6stat.icp6s_tooshort++;
905 return (-1); 908 return (-1);
906 } 909 }
907 eip6 = (struct ip6_hdr *)(icmp6 + 1); 910 eip6 = (struct ip6_hdr *)(icmp6 + 1);
908 911
909 /* Detect the upper level protocol */ 912 /* Detect the upper level protocol */
910 { 913 {
911 void (*ctlfunc) __P((int, struct sockaddr *, void *)); 914 void (*ctlfunc) __P((int, struct sockaddr *, void *));
912 u_int8_t nxt = eip6->ip6_nxt; 915 u_int8_t nxt = eip6->ip6_nxt;
913 int eoff = off + sizeof(struct icmp6_hdr) + 916 int eoff = off + sizeof(struct icmp6_hdr) +
914 sizeof(struct ip6_hdr); 917 sizeof(struct ip6_hdr);
915 struct ip6ctlparam ip6cp; 918 struct ip6ctlparam ip6cp;
916 struct in6_addr *finaldst = NULL; 919 struct in6_addr *finaldst = NULL;
917 int icmp6type = icmp6->icmp6_type; 920 int icmp6type = icmp6->icmp6_type;
918 struct ip6_frag *fh; 921 struct ip6_frag *fh;
919 struct ip6_rthdr *rth; 922 struct ip6_rthdr *rth;
920 struct ip6_rthdr0 *rth0; 923 struct ip6_rthdr0 *rth0;
921 int rthlen; 924 int rthlen;
922 925
923 while (1) { /* XXX: should avoid infinite loop explicitly? */ 926 while (1) { /* XXX: should avoid infinite loop explicitly? */
924 struct ip6_ext *eh; 927 struct ip6_ext *eh;
925 928
926 switch (nxt) { 929 switch (nxt) {
927 case IPPROTO_HOPOPTS: 930 case IPPROTO_HOPOPTS:
928 case IPPROTO_DSTOPTS: 931 case IPPROTO_DSTOPTS:
929 case IPPROTO_AH: 932 case IPPROTO_AH:
930 IP6_EXTHDR_GET(eh, struct ip6_ext *, m, 933 IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
931 eoff, sizeof(*eh)); 934 eoff, sizeof(*eh));
932 if (eh == NULL) { 935 if (eh == NULL) {
933 icmp6stat.icp6s_tooshort++; 936 icmp6stat.icp6s_tooshort++;
934 return (-1); 937 return (-1);
935 } 938 }
936 939
937 if (nxt == IPPROTO_AH) 940 if (nxt == IPPROTO_AH)
938 eoff += (eh->ip6e_len + 2) << 2; 941 eoff += (eh->ip6e_len + 2) << 2;
939 else 942 else
940 eoff += (eh->ip6e_len + 1) << 3; 943 eoff += (eh->ip6e_len + 1) << 3;
941 nxt = eh->ip6e_nxt; 944 nxt = eh->ip6e_nxt;
942 break; 945 break;
943 case IPPROTO_ROUTING: 946 case IPPROTO_ROUTING:
944 /* 947 /*
945 * When the erroneous packet contains a 948 * When the erroneous packet contains a
946 * routing header, we should examine the 949 * routing header, we should examine the
947 * header to determine the final destination. 950 * header to determine the final destination.
948 * Otherwise, we can't properly update 951 * Otherwise, we can't properly update
949 * information that depends on the final 952 * information that depends on the final
950 * destination (e.g. path MTU). 953 * destination (e.g. path MTU).
951 */ 954 */
952 IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m, 955 IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
953 eoff, sizeof(*rth)); 956 eoff, sizeof(*rth));
954 if (rth == NULL) { 957 if (rth == NULL) {
955 icmp6stat.icp6s_tooshort++; 958 icmp6stat.icp6s_tooshort++;
956 return (-1); 959 return (-1);
957 } 960 }
958 rthlen = (rth->ip6r_len + 1) << 3; 961 rthlen = (rth->ip6r_len + 1) << 3;
959 /* 962 /*
960 * XXX: currently there is no 963 * XXX: currently there is no
961 * officially defined type other 964 * officially defined type other
962 * than type-0. 965 * than type-0.
963 * Note that if the segment left field 966 * Note that if the segment left field
964 * is 0, all intermediate hops must 967 * is 0, all intermediate hops must
965 * have been passed. 968 * have been passed.
966 */ 969 */
967 if (rth->ip6r_segleft && 970 if (rth->ip6r_segleft &&
968 rth->ip6r_type == IPV6_RTHDR_TYPE_0) { 971 rth->ip6r_type == IPV6_RTHDR_TYPE_0) {
969 int hops; 972 int hops;
970 973
971 IP6_EXTHDR_GET(rth0, 974 IP6_EXTHDR_GET(rth0,
972 struct ip6_rthdr0 *, m, 975 struct ip6_rthdr0 *, m,
973 eoff, rthlen); 976 eoff, rthlen);
974 if (rth0 == NULL) { 977 if (rth0 == NULL) {
975 icmp6stat.icp6s_tooshort++; 978 icmp6stat.icp6s_tooshort++;
976 return (-1); 979 return (-1);
977 } 980 }
978 /* just ignore a bogus header */ 981 /* just ignore a bogus header */
979 if ((rth0->ip6r0_len % 2) == 0 && 982 if ((rth0->ip6r0_len % 2) == 0 &&
980 (hops = rth0->ip6r0_len/2)) 983 (hops = rth0->ip6r0_len/2))
981 finaldst = (struct in6_addr *)(rth0 + 1) + (hops - 1); 984 finaldst = (struct in6_addr *)(rth0 + 1) + (hops - 1);
982 } 985 }
983 eoff += rthlen; 986 eoff += rthlen;
984 nxt = rth->ip6r_nxt; 987 nxt = rth->ip6r_nxt;
985 break; 988 break;
986 case IPPROTO_FRAGMENT: 989 case IPPROTO_FRAGMENT:
987 IP6_EXTHDR_GET(fh, struct ip6_frag *, m, 990 IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
988 eoff, sizeof(*fh)); 991 eoff, sizeof(*fh));
989 if (fh == NULL) { 992 if (fh == NULL) {
990 icmp6stat.icp6s_tooshort++; 993 icmp6stat.icp6s_tooshort++;
991 return (-1); 994 return (-1);
992 } 995 }
993 /* 996 /*
994 * Data after a fragment header is meaningless 997 * Data after a fragment header is meaningless
995 * unless it is the first fragment, but 998 * unless it is the first fragment, but
996 * we'll go to the notify label for path MTU 999 * we'll go to the notify label for path MTU
997 * discovery. 1000 * discovery.
998 */ 1001 */
999 if (fh->ip6f_offlg & IP6F_OFF_MASK) 1002 if (fh->ip6f_offlg & IP6F_OFF_MASK)
1000 goto notify; 1003 goto notify;
1001 1004
1002 eoff += sizeof(struct ip6_frag); 1005 eoff += sizeof(struct ip6_frag);
1003 nxt = fh->ip6f_nxt; 1006 nxt = fh->ip6f_nxt;
1004 break; 1007 break;
1005 default: 1008 default:
1006 /* 1009 /*
1007 * This case includes ESP and the No Next 1010 * This case includes ESP and the No Next
1008 * Header. In such cases going to the notify 1011 * Header. In such cases going to the notify
1009 * label does not have any meaning 1012 * label does not have any meaning
1010 * (i.e. ctlfunc will be NULL), but we go 1013 * (i.e. ctlfunc will be NULL), but we go
1011 * anyway since we might have to update 1014 * anyway since we might have to update
1012 * path MTU information. 1015 * path MTU information.
1013 */ 1016 */
1014 goto notify; 1017 goto notify;
1015 } 1018 }
1016 } 1019 }
1017 notify: 1020 notify:
1018 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 1021 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
1019 sizeof(*icmp6) + sizeof(struct ip6_hdr)); 1022 sizeof(*icmp6) + sizeof(struct ip6_hdr));
1020 if (icmp6 == NULL) { 1023 if (icmp6 == NULL) {
1021 icmp6stat.icp6s_tooshort++; 1024 icmp6stat.icp6s_tooshort++;
1022 return (-1); 1025 return (-1);
1023 } 1026 }
1024 1027
1025 eip6 = (struct ip6_hdr *)(icmp6 + 1); 1028 eip6 = (struct ip6_hdr *)(icmp6 + 1);
1026 bzero(&icmp6dst, sizeof(icmp6dst)); 1029 bzero(&icmp6dst, sizeof(icmp6dst));
1027 icmp6dst.sin6_len = sizeof(struct sockaddr_in6); 1030 icmp6dst.sin6_len = sizeof(struct sockaddr_in6);
1028 icmp6dst.sin6_family = AF_INET6; 1031 icmp6dst.sin6_family = AF_INET6;
1029 if (finaldst == NULL) 1032 if (finaldst == NULL)
1030 icmp6dst.sin6_addr = eip6->ip6_dst; 1033 icmp6dst.sin6_addr = eip6->ip6_dst;
1031 else 1034 else
1032 icmp6dst.sin6_addr = *finaldst; 1035 icmp6dst.sin6_addr = *finaldst;
1033 icmp6dst.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, 1036 icmp6dst.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
1034 &icmp6dst.sin6_addr); 1037 &icmp6dst.sin6_addr);
1035#ifndef SCOPEDROUTING 1038#ifndef SCOPEDROUTING
1036 if (in6_embedscope(&icmp6dst.sin6_addr, &icmp6dst, 1039 if (in6_embedscope(&icmp6dst.sin6_addr, &icmp6dst,
1037 NULL, NULL)) { 1040 NULL, NULL)) {
1038 /* should be impossbile */ 1041 /* should be impossbile */
1039 nd6log((LOG_DEBUG, 1042 nd6log((LOG_DEBUG,
1040 "icmp6_notify_error: in6_embedscope failed\n")); 1043 "icmp6_notify_error: in6_embedscope failed\n"));
1041 goto freeit; 1044 goto freeit;
1042 } 1045 }
1043#endif 1046#endif
1044 1047
1045 /* 1048 /*
1046 * retrieve parameters from the inner IPv6 header, and convert 1049 * retrieve parameters from the inner IPv6 header, and convert
1047 * them into sockaddr structures. 1050 * them into sockaddr structures.
1048 */ 1051 */
1049 bzero(&icmp6src, sizeof(icmp6src)); 1052 bzero(&icmp6src, sizeof(icmp6src));
1050 icmp6src.sin6_len = sizeof(struct sockaddr_in6); 1053 icmp6src.sin6_len = sizeof(struct sockaddr_in6);
1051 icmp6src.sin6_family = AF_INET6; 1054 icmp6src.sin6_family = AF_INET6;
1052 icmp6src.sin6_addr = eip6->ip6_src; 1055 icmp6src.sin6_addr = eip6->ip6_src;
1053 icmp6src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, 1056 icmp6src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
1054 &icmp6src.sin6_addr); 1057 &icmp6src.sin6_addr);
1055#ifndef SCOPEDROUTING 1058#ifndef SCOPEDROUTING
1056 if (in6_embedscope(&icmp6src.sin6_addr, &icmp6src, 1059 if (in6_embedscope(&icmp6src.sin6_addr, &icmp6src,
1057 NULL, NULL)) { 1060 NULL, NULL)) {
1058 /* should be impossbile */ 1061 /* should be impossbile */
1059 nd6log((LOG_DEBUG, 1062 nd6log((LOG_DEBUG,
1060 "icmp6_notify_error: in6_embedscope failed\n")); 1063 "icmp6_notify_error: in6_embedscope failed\n"));
1061 goto freeit; 1064 goto freeit;
1062 } 1065 }
1063#endif 1066#endif
1064 icmp6src.sin6_flowinfo = 1067 icmp6src.sin6_flowinfo =
1065 (eip6->ip6_flow & IPV6_FLOWLABEL_MASK); 1068 (eip6->ip6_flow & IPV6_FLOWLABEL_MASK);
1066 1069
1067 if (finaldst == NULL) 1070 if (finaldst == NULL)
1068 finaldst = &eip6->ip6_dst; 1071 finaldst = &eip6->ip6_dst;
1069 ip6cp.ip6c_m = m; 1072 ip6cp.ip6c_m = m;
1070 ip6cp.ip6c_icmp6 = icmp6; 1073 ip6cp.ip6c_icmp6 = icmp6;
1071 ip6cp.ip6c_ip6 = (struct ip6_hdr *)(icmp6 + 1); 1074 ip6cp.ip6c_ip6 = (struct ip6_hdr *)(icmp6 + 1);
1072 ip6cp.ip6c_off = eoff; 1075 ip6cp.ip6c_off = eoff;
1073 ip6cp.ip6c_finaldst = finaldst; 1076 ip6cp.ip6c_finaldst = finaldst;
1074 ip6cp.ip6c_src = &icmp6src; 1077 ip6cp.ip6c_src = &icmp6src;
1075 ip6cp.ip6c_nxt = nxt; 1078 ip6cp.ip6c_nxt = nxt;
1076 1079
1077 if (icmp6type == ICMP6_PACKET_TOO_BIG) { 1080 if (icmp6type == ICMP6_PACKET_TOO_BIG) {
1078 notifymtu = ntohl(icmp6->icmp6_mtu); 1081 notifymtu = ntohl(icmp6->icmp6_mtu);
1079 ip6cp.ip6c_cmdarg = (void *)&notifymtu; 1082 ip6cp.ip6c_cmdarg = (void *)&notifymtu;
1080 } 1083 }
1081 1084
1082 ctlfunc = (void (*) __P((int, struct sockaddr *, void *))) 1085 ctlfunc = (void (*) __P((int, struct sockaddr *, void *)))
1083 (inet6sw[ip6_protox[nxt]].pr_ctlinput); 1086 (inet6sw[ip6_protox[nxt]].pr_ctlinput);
1084 if (ctlfunc) { 1087 if (ctlfunc) {
1085 (void) (*ctlfunc)(code, (struct sockaddr *)&icmp6dst, 1088 (void) (*ctlfunc)(code, (struct sockaddr *)&icmp6dst,
1086 &ip6cp); 1089 &ip6cp);
1087 } 1090 }
1088 } 1091 }
1089 return (0); 1092 return (0);
1090 1093
1091 freeit: 1094 freeit:
1092 m_freem(m); 1095 m_freem(m);
1093 return (-1); 1096 return (-1);
1094} 1097}
1095 1098
1096void 1099void
1097icmp6_mtudisc_update(ip6cp, validated) 1100icmp6_mtudisc_update(ip6cp, validated)
1098 struct ip6ctlparam *ip6cp; 1101 struct ip6ctlparam *ip6cp;
1099 int validated; 1102 int validated;
1100{ 1103{
1101 unsigned long rtcount; 1104 unsigned long rtcount;
1102 struct icmp6_mtudisc_callback *mc; 1105 struct icmp6_mtudisc_callback *mc;
1103 struct in6_addr *dst = ip6cp->ip6c_finaldst; 1106 struct in6_addr *dst = ip6cp->ip6c_finaldst;
1104 struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6; 1107 struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6;
1105 struct mbuf *m = ip6cp->ip6c_m; /* will be necessary for scope issue */ 1108 struct mbuf *m = ip6cp->ip6c_m; /* will be necessary for scope issue */
1106 u_int mtu = ntohl(icmp6->icmp6_mtu); 1109 u_int mtu = ntohl(icmp6->icmp6_mtu);
1107 struct rtentry *rt = NULL; 1110 struct rtentry *rt = NULL;
1108 struct sockaddr_in6 sin6; 1111 struct sockaddr_in6 sin6;
1109 1112
1110 /* 1113 /*
 1114 * The MTU should not be less than the minimal IPv6 MTU except for the
 1115 * hack in ip6_output/ip6_setpmtu where we always include a frag header.
 1116 * In that one case, the MTU might be less than 1280.
 1117 */
 1118 if (__predict_false(mtu < IPV6_MMTU - sizeof(struct ip6_frag))) {
 1119 /* is the mtu even sane? */
 1120 if (mtu < sizeof(struct ip6_hdr) + sizeof(struct ip6_frag) + 8)
 1121 return;
 1122 if (!validated)
 1123 return;
 1124 mtu = IPV6_MMTU - sizeof(struct ip6_frag);
 1125 }
 1126
 1127 /*
1111 * allow non-validated cases if memory is plenty, to make traffic 1128 * allow non-validated cases if memory is plenty, to make traffic
1112 * from non-connected pcb happy. 1129 * from non-connected pcb happy.
1113 */ 1130 */
1114 rtcount = rt_timer_count(icmp6_mtudisc_timeout_q); 1131 rtcount = rt_timer_count(icmp6_mtudisc_timeout_q);
1115 if (validated) { 1132 if (validated) {
1116 if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat) 1133 if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat)
1117 return; 1134 return;
1118 else if (0 <= icmp6_mtudisc_lowat && 1135 else if (0 <= icmp6_mtudisc_lowat &&
1119 rtcount > icmp6_mtudisc_lowat) { 1136 rtcount > icmp6_mtudisc_lowat) {
1120 /* 1137 /*
1121 * XXX nuke a victim, install the new one. 1138 * XXX nuke a victim, install the new one.
1122 */ 1139 */
1123 } 1140 }
1124 } else { 1141 } else {
1125 if (0 <= icmp6_mtudisc_lowat && rtcount > icmp6_mtudisc_lowat) 1142 if (0 <= icmp6_mtudisc_lowat && rtcount > icmp6_mtudisc_lowat)
1126 return; 1143 return;
1127 } 1144 }
1128 1145
1129 bzero(&sin6, sizeof(sin6)); 1146 bzero(&sin6, sizeof(sin6));
1130 sin6.sin6_family = PF_INET6; 1147 sin6.sin6_family = PF_INET6;
1131 sin6.sin6_len = sizeof(struct sockaddr_in6); 1148 sin6.sin6_len = sizeof(struct sockaddr_in6);
1132 sin6.sin6_addr = *dst; 1149 sin6.sin6_addr = *dst;
1133 /* XXX normally, this won't happen */ 1150 /* XXX normally, this won't happen */
1134 if (IN6_IS_ADDR_LINKLOCAL(dst)) { 1151 if (IN6_IS_ADDR_LINKLOCAL(dst)) {
1135 sin6.sin6_addr.s6_addr16[1] = 1152 sin6.sin6_addr.s6_addr16[1] =
1136 htons(m->m_pkthdr.rcvif->if_index); 1153 htons(m->m_pkthdr.rcvif->if_index);
1137 } 1154 }
1138 /* sin6.sin6_scope_id = XXX: should be set if DST is a scoped addr */ 1155 /* sin6.sin6_scope_id = XXX: should be set if DST is a scoped addr */
1139 rt = icmp6_mtudisc_clone((struct sockaddr *)&sin6); 1156 rt = icmp6_mtudisc_clone((struct sockaddr *)&sin6);
1140 1157
1141 if (rt && (rt->rt_flags & RTF_HOST) && 1158 if (rt && (rt->rt_flags & RTF_HOST) &&
1142 !(rt->rt_rmx.rmx_locks & RTV_MTU) && 1159 !(rt->rt_rmx.rmx_locks & RTV_MTU) &&
1143 (rt->rt_rmx.rmx_mtu > mtu || rt->rt_rmx.rmx_mtu == 0)) { 1160 (rt->rt_rmx.rmx_mtu > mtu || rt->rt_rmx.rmx_mtu == 0)) {
1144 if (mtu < IN6_LINKMTU(rt->rt_ifp)) { 1161 if (mtu < IN6_LINKMTU(rt->rt_ifp)) {
1145 icmp6stat.icp6s_pmtuchg++; 1162 icmp6stat.icp6s_pmtuchg++;
1146 rt->rt_rmx.rmx_mtu = mtu; 1163 rt->rt_rmx.rmx_mtu = mtu;
1147 } 1164 }
1148 } 1165 }
1149 if (rt) { /* XXX: need braces to avoid conflict with else in RTFREE. */ 1166 if (rt) { /* XXX: need braces to avoid conflict with else in RTFREE. */
1150 RTFREE(rt); 1167 RTFREE(rt);
1151 } 1168 }
1152 1169
1153 /* 1170 /*
1154 * Notify protocols that the MTU for this destination 1171 * Notify protocols that the MTU for this destination
1155 * has changed. 1172 * has changed.
1156 */ 1173 */
1157 for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL; 1174 for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL;
1158 mc = LIST_NEXT(mc, mc_list)) 1175 mc = LIST_NEXT(mc, mc_list))
1159 (*mc->mc_func)(&sin6.sin6_addr); 1176 (*mc->mc_func)(&sin6.sin6_addr);
1160} 1177}
1161 1178
1162/* 1179/*
1163 * Process a Node Information Query packet, based on 1180 * Process a Node Information Query packet, based on
1164 * draft-ietf-ipngwg-icmp-name-lookups-07. 1181 * draft-ietf-ipngwg-icmp-name-lookups-07.
1165 * 1182 *
1166 * Spec incompatibilities: 1183 * Spec incompatibilities:
1167 * - IPv6 Subject address handling 1184 * - IPv6 Subject address handling
1168 * - IPv4 Subject address handling support missing 1185 * - IPv4 Subject address handling support missing
1169 * - Proxy reply (answer even if it's not for me) 1186 * - Proxy reply (answer even if it's not for me)
1170 * - joins NI group address at in6_ifattach() time only, does not cope 1187 * - joins NI group address at in6_ifattach() time only, does not cope
1171 * with hostname changes by sethostname(3) 1188 * with hostname changes by sethostname(3)
1172 */ 1189 */
1173#ifndef offsetof /* XXX */ 1190#ifndef offsetof /* XXX */
1174#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 1191#define offsetof(type, member) ((size_t)(&((type *)0)->member))
1175#endif 1192#endif
1176static struct mbuf * 1193static struct mbuf *
1177ni6_input(m, off) 1194ni6_input(m, off)
1178 struct mbuf *m; 1195 struct mbuf *m;
1179 int off; 1196 int off;
1180{ 1197{
1181 struct icmp6_nodeinfo *ni6, *nni6; 1198 struct icmp6_nodeinfo *ni6, *nni6;
1182 struct mbuf *n = NULL; 1199 struct mbuf *n = NULL;
1183 u_int16_t qtype; 1200 u_int16_t qtype;
1184 int subjlen; 1201 int subjlen;
1185 int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo); 1202 int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
1186 struct ni_reply_fqdn *fqdn; 1203 struct ni_reply_fqdn *fqdn;
1187 int addrs; /* for NI_QTYPE_NODEADDR */ 1204 int addrs; /* for NI_QTYPE_NODEADDR */
1188 struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */ 1205 struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */
1189 struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */ 1206 struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */
1190 struct ip6_hdr *ip6; 1207 struct ip6_hdr *ip6;
1191 int oldfqdn = 0; /* if 1, return pascal string (03 draft) */ 1208 int oldfqdn = 0; /* if 1, return pascal string (03 draft) */
1192 char *subj = NULL; 1209 char *subj = NULL;
1193 1210
1194 ip6 = mtod(m, struct ip6_hdr *); 1211 ip6 = mtod(m, struct ip6_hdr *);
1195 IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6)); 1212 IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6));
1196 if (ni6 == NULL) { 1213 if (ni6 == NULL) {
1197 /* m is already reclaimed */ 1214 /* m is already reclaimed */
1198 return NULL; 1215 return NULL;
1199 } 1216 }
1200 1217
1201 /* 1218 /*
1202 * Validate IPv6 destination address. 1219 * Validate IPv6 destination address.
1203 * 1220 *
1204 * The Responder must discard the Query without further processing 1221 * The Responder must discard the Query without further processing
1205 * unless it is one of the Responder's unicast or anycast addresses, or 1222 * unless it is one of the Responder's unicast or anycast addresses, or
1206 * a link-local scope multicast address which the Responder has joined. 1223 * a link-local scope multicast address which the Responder has joined.
1207 * [icmp-name-lookups-07, Section 4.] 1224 * [icmp-name-lookups-07, Section 4.]
1208 */ 1225 */
1209 bzero(&sin6, sizeof(sin6)); 1226 bzero(&sin6, sizeof(sin6));
1210 sin6.sin6_family = AF_INET6; 1227 sin6.sin6_family = AF_INET6;
1211 sin6.sin6_len = sizeof(struct sockaddr_in6); 1228 sin6.sin6_len = sizeof(struct sockaddr_in6);
1212 bcopy(&ip6->ip6_dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); 1229 bcopy(&ip6->ip6_dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
1213 /* XXX scopeid */ 1230 /* XXX scopeid */
1214 if (ifa_ifwithaddr((struct sockaddr *)&sin6)) 1231 if (ifa_ifwithaddr((struct sockaddr *)&sin6))
1215 ; /* unicast/anycast, fine */ 1232 ; /* unicast/anycast, fine */
1216 else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) 1233 else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr))
1217 ; /* link-local multicast, fine */ 1234 ; /* link-local multicast, fine */
1218 else 1235 else
1219 goto bad; 1236 goto bad;
1220 1237
1221 /* validate query Subject field. */ 1238 /* validate query Subject field. */
1222 qtype = ntohs(ni6->ni_qtype); 1239 qtype = ntohs(ni6->ni_qtype);
1223 subjlen = m->m_pkthdr.len - off - sizeof(struct icmp6_nodeinfo); 1240 subjlen = m->m_pkthdr.len - off - sizeof(struct icmp6_nodeinfo);
1224 switch (qtype) { 1241 switch (qtype) {
1225 case NI_QTYPE_NOOP: 1242 case NI_QTYPE_NOOP:
1226 case NI_QTYPE_SUPTYPES: 1243 case NI_QTYPE_SUPTYPES:
1227 /* 07 draft */ 1244 /* 07 draft */
1228 if (ni6->ni_code == ICMP6_NI_SUBJ_FQDN && subjlen == 0) 1245 if (ni6->ni_code == ICMP6_NI_SUBJ_FQDN && subjlen == 0)
1229 break; 1246 break;
1230 /* FALLTHROUGH */ 1247 /* FALLTHROUGH */
1231 case NI_QTYPE_FQDN: 1248 case NI_QTYPE_FQDN:
1232 case NI_QTYPE_NODEADDR: 1249 case NI_QTYPE_NODEADDR:
1233 switch (ni6->ni_code) { 1250 switch (ni6->ni_code) {
1234 case ICMP6_NI_SUBJ_IPV6: 1251 case ICMP6_NI_SUBJ_IPV6:
1235#if ICMP6_NI_SUBJ_IPV6 != 0 1252#if ICMP6_NI_SUBJ_IPV6 != 0
1236 case 0: 1253 case 0:
1237#endif 1254#endif
1238 /* 1255 /*
1239 * backward compatibility - try to accept 03 draft 1256 * backward compatibility - try to accept 03 draft
1240 * format, where no Subject is present. 1257 * format, where no Subject is present.
1241 */ 1258 */
1242 if (qtype == NI_QTYPE_FQDN && ni6->ni_code == 0 && 1259 if (qtype == NI_QTYPE_FQDN && ni6->ni_code == 0 &&
1243 subjlen == 0) { 1260 subjlen == 0) {
1244 oldfqdn++; 1261 oldfqdn++;
1245 break; 1262 break;
1246 } 1263 }
1247#if ICMP6_NI_SUBJ_IPV6 != 0 1264#if ICMP6_NI_SUBJ_IPV6 != 0
1248 if (ni6->ni_code != ICMP6_NI_SUBJ_IPV6) 1265 if (ni6->ni_code != ICMP6_NI_SUBJ_IPV6)
1249 goto bad; 1266 goto bad;
1250#endif 1267#endif
1251 1268
1252 if (subjlen != sizeof(sin6.sin6_addr)) 1269 if (subjlen != sizeof(sin6.sin6_addr))
1253 goto bad; 1270 goto bad;
1254 1271
1255 /* 1272 /*
1256 * Validate Subject address. 1273 * Validate Subject address.
1257 * 1274 *
1258 * Not sure what exactly "address belongs to the node" 1275 * Not sure what exactly "address belongs to the node"
1259 * means in the spec, is it just unicast, or what? 1276 * means in the spec, is it just unicast, or what?
1260 * 1277 *
1261 * At this moment we consider Subject address as 1278 * At this moment we consider Subject address as
1262 * "belong to the node" if the Subject address equals 1279 * "belong to the node" if the Subject address equals
1263 * to the IPv6 destination address; validation for 1280 * to the IPv6 destination address; validation for
1264 * IPv6 destination address should have done enough 1281 * IPv6 destination address should have done enough
1265 * check for us. 1282 * check for us.
1266 * 1283 *
1267 * We do not do proxy at this moment. 1284 * We do not do proxy at this moment.
1268 */ 1285 */
1269 /* m_pulldown instead of copy? */ 1286 /* m_pulldown instead of copy? */
1270 m_copydata(m, off + sizeof(struct icmp6_nodeinfo), 1287 m_copydata(m, off + sizeof(struct icmp6_nodeinfo),
1271 subjlen, (caddr_t)&sin6.sin6_addr); 1288 subjlen, (caddr_t)&sin6.sin6_addr);
1272 /* XXX kame scope hack */ 1289 /* XXX kame scope hack */
1273 if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) { 1290 if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) {
1274 if ((m->m_flags & M_PKTHDR) != 0 && 1291 if ((m->m_flags & M_PKTHDR) != 0 &&
1275 m->m_pkthdr.rcvif) { 1292 m->m_pkthdr.rcvif) {
1276 sin6.sin6_addr.s6_addr16[1] = 1293 sin6.sin6_addr.s6_addr16[1] =
1277 htons(m->m_pkthdr.rcvif->if_index); 1294 htons(m->m_pkthdr.rcvif->if_index);
1278 } 1295 }
1279 } 1296 }
1280 subj = (char *)&sin6; 1297 subj = (char *)&sin6;
1281 if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &sin6.sin6_addr)) 1298 if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &sin6.sin6_addr))
1282 break; 1299 break;
1283 1300
1284 /* 1301 /*
1285 * XXX if we are to allow other cases, we should really 1302 * XXX if we are to allow other cases, we should really
1286 * be careful about scope here. 1303 * be careful about scope here.
1287 * basically, we should disallow queries toward IPv6 1304 * basically, we should disallow queries toward IPv6
1288 * destination X with subject Y, if scope(X) > scope(Y). 1305 * destination X with subject Y, if scope(X) > scope(Y).
1289 * if we allow scope(X) > scope(Y), it will result in 1306 * if we allow scope(X) > scope(Y), it will result in
1290 * information leakage across scope boundary. 1307 * information leakage across scope boundary.
1291 */ 1308 */
1292 goto bad; 1309 goto bad;
1293 1310
1294 case ICMP6_NI_SUBJ_FQDN: 1311 case ICMP6_NI_SUBJ_FQDN:
1295 /* 1312 /*
1296 * Validate Subject name with gethostname(3). 1313 * Validate Subject name with gethostname(3).
1297 * 1314 *
1298 * The behavior may need some debate, since: 1315 * The behavior may need some debate, since:
1299 * - we are not sure if the node has FQDN as 1316 * - we are not sure if the node has FQDN as
1300 * hostname (returned by gethostname(3)). 1317 * hostname (returned by gethostname(3)).
1301 * - the code does wildcard match for truncated names. 1318 * - the code does wildcard match for truncated names.
1302 * however, we are not sure if we want to perform 1319 * however, we are not sure if we want to perform
1303 * wildcard match, if gethostname(3) side has 1320 * wildcard match, if gethostname(3) side has
1304 * truncated hostname. 1321 * truncated hostname.
1305 */ 1322 */
1306 n = ni6_nametodns(hostname, hostnamelen, 0); 1323 n = ni6_nametodns(hostname, hostnamelen, 0);
1307 if (!n || n->m_next || n->m_len == 0) 1324 if (!n || n->m_next || n->m_len == 0)
1308 goto bad; 1325 goto bad;
1309 IP6_EXTHDR_GET(subj, char *, m, 1326 IP6_EXTHDR_GET(subj, char *, m,
1310 off + sizeof(struct icmp6_nodeinfo), subjlen); 1327 off + sizeof(struct icmp6_nodeinfo), subjlen);
1311 if (subj == NULL) 1328 if (subj == NULL)
1312 goto bad; 1329 goto bad;
1313 if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *), 1330 if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *),
1314 n->m_len)) { 1331 n->m_len)) {
1315 goto bad; 1332 goto bad;
1316 } 1333 }
1317 m_freem(n); 1334 m_freem(n);
1318 n = NULL; 1335 n = NULL;
1319 break; 1336 break;
1320 1337
1321 case ICMP6_NI_SUBJ_IPV4: /* XXX: to be implemented? */ 1338 case ICMP6_NI_SUBJ_IPV4: /* XXX: to be implemented? */
1322 default: 1339 default:
1323 goto bad; 1340 goto bad;
1324 } 1341 }
1325 break; 1342 break;
1326 } 1343 }
1327 1344
1328 /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */ 1345 /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */
1329 switch (qtype) { 1346 switch (qtype) {
1330 case NI_QTYPE_FQDN: 1347 case NI_QTYPE_FQDN:
1331 if ((icmp6_nodeinfo & 1) == 0) 1348 if ((icmp6_nodeinfo & 1) == 0)
1332 goto bad; 1349 goto bad;
1333 break; 1350 break;
1334 case NI_QTYPE_NODEADDR: 1351 case NI_QTYPE_NODEADDR:
1335 if ((icmp6_nodeinfo & 2) == 0) 1352 if ((icmp6_nodeinfo & 2) == 0)
1336 goto bad; 1353 goto bad;
1337 break; 1354 break;
1338 } 1355 }
1339 1356
1340 /* guess reply length */ 1357 /* guess reply length */
1341 switch (qtype) { 1358 switch (qtype) {
1342 case NI_QTYPE_NOOP: 1359 case NI_QTYPE_NOOP:
1343 break; /* no reply data */ 1360 break; /* no reply data */
1344 case NI_QTYPE_SUPTYPES: 1361 case NI_QTYPE_SUPTYPES:
1345 replylen += sizeof(u_int32_t); 1362 replylen += sizeof(u_int32_t);
1346 break; 1363 break;
1347 case NI_QTYPE_FQDN: 1364 case NI_QTYPE_FQDN:
1348 /* XXX will append an mbuf */ 1365 /* XXX will append an mbuf */
1349 replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen); 1366 replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen);
1350 break; 1367 break;
1351 case NI_QTYPE_NODEADDR: 1368 case NI_QTYPE_NODEADDR:
1352 addrs = ni6_addrs(ni6, m, &ifp, subj); 1369 addrs = ni6_addrs(ni6, m, &ifp, subj);
1353 if ((replylen += addrs * (sizeof(struct in6_addr) + 1370 if ((replylen += addrs * (sizeof(struct in6_addr) +
1354 sizeof(u_int32_t))) > MCLBYTES) 1371 sizeof(u_int32_t))) > MCLBYTES)
1355 replylen = MCLBYTES; /* XXX: will truncate pkt later */ 1372 replylen = MCLBYTES; /* XXX: will truncate pkt later */
1356 break; 1373 break;
1357 default: 1374 default:
1358 /* 1375 /*
1359 * XXX: We must return a reply with the ICMP6 code 1376 * XXX: We must return a reply with the ICMP6 code
1360 * `unknown Qtype' in this case. However we regard the case 1377 * `unknown Qtype' in this case. However we regard the case
1361 * as an FQDN query for backward compatibility. 1378 * as an FQDN query for backward compatibility.
1362 * Older versions set a random value to this field, 1379 * Older versions set a random value to this field,
1363 * so it rarely varies in the defined qtypes. 1380 * so it rarely varies in the defined qtypes.
1364 * But the mechanism is not reliable... 1381 * But the mechanism is not reliable...
1365 * maybe we should obsolete older versions. 1382 * maybe we should obsolete older versions.
1366 */ 1383 */
1367 qtype = NI_QTYPE_FQDN; 1384 qtype = NI_QTYPE_FQDN;
1368 /* XXX will append an mbuf */ 1385 /* XXX will append an mbuf */
1369 replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen); 1386 replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen);
1370 oldfqdn++; 1387 oldfqdn++;
1371 break; 1388 break;
1372 } 1389 }
1373 1390
1374 /* allocate an mbuf to reply. */ 1391 /* allocate an mbuf to reply. */
1375 MGETHDR(n, M_DONTWAIT, m->m_type); 1392 MGETHDR(n, M_DONTWAIT, m->m_type);
1376 if (n == NULL) { 1393 if (n == NULL) {
1377 m_freem(m); 1394 m_freem(m);
1378 return (NULL); 1395 return (NULL);
1379 } 1396 }
1380 M_COPY_PKTHDR(n, m); /* just for rcvif */ 1397 M_COPY_PKTHDR(n, m); /* just for rcvif */
1381 if (replylen > MHLEN) { 1398 if (replylen > MHLEN) {
1382 if (replylen > MCLBYTES) { 1399 if (replylen > MCLBYTES) {
1383 /* 1400 /*
1384 * XXX: should we try to allocate more? But MCLBYTES 1401 * XXX: should we try to allocate more? But MCLBYTES
1385 * is probably much larger than IPV6_MMTU... 1402 * is probably much larger than IPV6_MMTU...
1386 */ 1403 */
1387 goto bad; 1404 goto bad;
1388 } 1405 }
1389 MCLGET(n, M_DONTWAIT); 1406 MCLGET(n, M_DONTWAIT);
1390 if ((n->m_flags & M_EXT) == 0) { 1407 if ((n->m_flags & M_EXT) == 0) {
1391 goto bad; 1408 goto bad;
1392 } 1409 }
1393 } 1410 }
1394 n->m_pkthdr.len = n->m_len = replylen; 1411 n->m_pkthdr.len = n->m_len = replylen;
1395 1412
1396 /* copy mbuf header and IPv6 + Node Information base headers */ 1413 /* copy mbuf header and IPv6 + Node Information base headers */
1397 bcopy(mtod(m, caddr_t), mtod(n, caddr_t), sizeof(struct ip6_hdr)); 1414 bcopy(mtod(m, caddr_t), mtod(n, caddr_t), sizeof(struct ip6_hdr));
1398 nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1); 1415 nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1);
1399 bcopy((caddr_t)ni6, (caddr_t)nni6, sizeof(struct icmp6_nodeinfo)); 1416 bcopy((caddr_t)ni6, (caddr_t)nni6, sizeof(struct icmp6_nodeinfo));
1400 1417
1401 /* qtype dependent procedure */ 1418 /* qtype dependent procedure */
1402 switch (qtype) { 1419 switch (qtype) {
1403 case NI_QTYPE_NOOP: 1420 case NI_QTYPE_NOOP:
1404 nni6->ni_code = ICMP6_NI_SUCCESS; 1421 nni6->ni_code = ICMP6_NI_SUCCESS;
1405 nni6->ni_flags = 0; 1422 nni6->ni_flags = 0;
1406 break; 1423 break;
1407 case NI_QTYPE_SUPTYPES: 1424 case NI_QTYPE_SUPTYPES:
1408 { 1425 {
1409 u_int32_t v; 1426 u_int32_t v;
1410 nni6->ni_code = ICMP6_NI_SUCCESS; 1427 nni6->ni_code = ICMP6_NI_SUCCESS;
1411 nni6->ni_flags = htons(0x0000); /* raw bitmap */ 1428 nni6->ni_flags = htons(0x0000); /* raw bitmap */
1412 /* supports NOOP, SUPTYPES, FQDN, and NODEADDR */ 1429 /* supports NOOP, SUPTYPES, FQDN, and NODEADDR */
1413 v = (u_int32_t)htonl(0x0000000f); 1430 v = (u_int32_t)htonl(0x0000000f);
1414 bcopy(&v, nni6 + 1, sizeof(u_int32_t)); 1431 bcopy(&v, nni6 + 1, sizeof(u_int32_t));
1415 break; 1432 break;
1416 } 1433 }
1417 case NI_QTYPE_FQDN: 1434 case NI_QTYPE_FQDN:
1418 nni6->ni_code = ICMP6_NI_SUCCESS; 1435 nni6->ni_code = ICMP6_NI_SUCCESS;
1419 fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) + 1436 fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) +
1420 sizeof(struct ip6_hdr) + 1437 sizeof(struct ip6_hdr) +
1421 sizeof(struct icmp6_nodeinfo)); 1438 sizeof(struct icmp6_nodeinfo));
1422 nni6->ni_flags = 0; /* XXX: meaningless TTL */ 1439 nni6->ni_flags = 0; /* XXX: meaningless TTL */
1423 fqdn->ni_fqdn_ttl = 0; /* ditto. */ 1440 fqdn->ni_fqdn_ttl = 0; /* ditto. */
1424 /* 1441 /*
1425 * XXX do we really have FQDN in variable "hostname"? 1442 * XXX do we really have FQDN in variable "hostname"?
1426 */ 1443 */
1427 n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn); 1444 n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn);
1428 if (n->m_next == NULL) 1445 if (n->m_next == NULL)
1429 goto bad; 1446 goto bad;
1430 /* XXX we assume that n->m_next is not a chain */ 1447 /* XXX we assume that n->m_next is not a chain */
1431 if (n->m_next->m_next != NULL) 1448 if (n->m_next->m_next != NULL)
1432 goto bad; 1449 goto bad;
1433 n->m_pkthdr.len += n->m_next->m_len; 1450 n->m_pkthdr.len += n->m_next->m_len;
1434 break; 1451 break;
1435 case NI_QTYPE_NODEADDR: 1452 case NI_QTYPE_NODEADDR:
1436 { 1453 {
1437 int lenlim, copied; 1454 int lenlim, copied;
1438 1455
1439 nni6->ni_code = ICMP6_NI_SUCCESS; 1456 nni6->ni_code = ICMP6_NI_SUCCESS;
1440 n->m_pkthdr.len = n->m_len = 1457 n->m_pkthdr.len = n->m_len =
1441 sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo); 1458 sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
1442 lenlim = M_TRAILINGSPACE(n); 1459 lenlim = M_TRAILINGSPACE(n);
1443 copied = ni6_store_addrs(ni6, nni6, ifp, lenlim); 1460 copied = ni6_store_addrs(ni6, nni6, ifp, lenlim);
1444 /* XXX: reset mbuf length */ 1461 /* XXX: reset mbuf length */
1445 n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 1462 n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
1446 sizeof(struct icmp6_nodeinfo) + copied; 1463 sizeof(struct icmp6_nodeinfo) + copied;
1447 break; 1464 break;
1448 } 1465 }
1449 default: 1466 default:
1450 break; /* XXX impossible! */ 1467 break; /* XXX impossible! */
1451 } 1468 }
1452 1469
1453 nni6->ni_type = ICMP6_NI_REPLY; 1470 nni6->ni_type = ICMP6_NI_REPLY;
1454 m_freem(m); 1471 m_freem(m);
1455 return (n); 1472 return (n);
1456 1473
1457 bad: 1474 bad:
1458 m_freem(m); 1475 m_freem(m);
1459 if (n) 1476 if (n)
1460 m_freem(n); 1477 m_freem(n);
1461 return (NULL); 1478 return (NULL);
1462} 1479}
1463#undef hostnamelen 1480#undef hostnamelen
1464 1481
1465#define isupper(x) ('A' <= (x) && (x) <= 'Z') 1482#define isupper(x) ('A' <= (x) && (x) <= 'Z')
1466#define isalpha(x) (('A' <= (x) && (x) <= 'Z') || ('a' <= (x) && (x) <= 'z')) 1483#define isalpha(x) (('A' <= (x) && (x) <= 'Z') || ('a' <= (x) && (x) <= 'z'))
1467#define isalnum(x) (isalpha(x) || ('0' <= (x) && (x) <= '9')) 1484#define isalnum(x) (isalpha(x) || ('0' <= (x) && (x) <= '9'))
1468#define tolower(x) (isupper(x) ? (x) + 'a' - 'A' : (x)) 1485#define tolower(x) (isupper(x) ? (x) + 'a' - 'A' : (x))
1469 1486
1470/* 1487/*
1471 * make a mbuf with DNS-encoded string. no compression support. 1488 * make a mbuf with DNS-encoded string. no compression support.
1472 * 1489 *
1473 * XXX names with less than 2 dots (like "foo" or "foo.section") will be 1490 * XXX names with less than 2 dots (like "foo" or "foo.section") will be
1474 * treated as truncated name (two \0 at the end). this is a wild guess. 1491 * treated as truncated name (two \0 at the end). this is a wild guess.
1475 */ 1492 */
1476static struct mbuf * 1493static struct mbuf *
1477ni6_nametodns(name, namelen, old) 1494ni6_nametodns(name, namelen, old)
1478 const char *name; 1495 const char *name;
1479 int namelen; 1496 int namelen;
1480 int old; /* return pascal string if non-zero */ 1497 int old; /* return pascal string if non-zero */
1481{ 1498{
1482 struct mbuf *m; 1499 struct mbuf *m;
1483 char *cp, *ep; 1500 char *cp, *ep;
1484 const char *p, *q; 1501 const char *p, *q;
1485 int i, len, nterm; 1502 int i, len, nterm;
1486 1503
1487 if (old) 1504 if (old)
1488 len = namelen + 1; 1505 len = namelen + 1;
1489 else 1506 else
1490 len = MCLBYTES; 1507 len = MCLBYTES;
1491 1508
1492 /* because MAXHOSTNAMELEN is usually 256, we use cluster mbuf */ 1509 /* because MAXHOSTNAMELEN is usually 256, we use cluster mbuf */
1493 MGET(m, M_DONTWAIT, MT_DATA); 1510 MGET(m, M_DONTWAIT, MT_DATA);
1494 if (m && len > MLEN) { 1511 if (m && len > MLEN) {
1495 MCLGET(m, M_DONTWAIT); 1512 MCLGET(m, M_DONTWAIT);
1496 if ((m->m_flags & M_EXT) == 0) 1513 if ((m->m_flags & M_EXT) == 0)
1497 goto fail; 1514 goto fail;
1498 } 1515 }
1499 if (!m) 1516 if (!m)
1500 goto fail; 1517 goto fail;
1501 m->m_next = NULL; 1518 m->m_next = NULL;
1502 1519
1503 if (old) { 1520 if (old) {
1504 m->m_len = len; 1521 m->m_len = len;
1505 *mtod(m, char *) = namelen; 1522 *mtod(m, char *) = namelen;
1506 bcopy(name, mtod(m, char *) + 1, namelen); 1523 bcopy(name, mtod(m, char *) + 1, namelen);
1507 return m; 1524 return m;
1508 } else { 1525 } else {
1509 m->m_len = 0; 1526 m->m_len = 0;
1510 cp = mtod(m, char *); 1527 cp = mtod(m, char *);
1511 ep = mtod(m, char *) + M_TRAILINGSPACE(m); 1528 ep = mtod(m, char *) + M_TRAILINGSPACE(m);
1512 1529
1513 /* if not certain about my name, return empty buffer */ 1530 /* if not certain about my name, return empty buffer */
1514 if (namelen == 0) 1531 if (namelen == 0)
1515 return m; 1532 return m;
1516 1533
1517 /* 1534 /*
1518 * guess if it looks like shortened hostname, or FQDN. 1535 * guess if it looks like shortened hostname, or FQDN.
1519 * shortened hostname needs two trailing "\0". 1536 * shortened hostname needs two trailing "\0".
1520 */ 1537 */
1521 i = 0; 1538 i = 0;
1522 for (p = name; p < name + namelen; p++) { 1539 for (p = name; p < name + namelen; p++) {
1523 if (*p && *p == '.') 1540 if (*p && *p == '.')
1524 i++; 1541 i++;
1525 } 1542 }
1526 if (i < 2) 1543 if (i < 2)
1527 nterm = 2; 1544 nterm = 2;
1528 else 1545 else
1529 nterm = 1; 1546 nterm = 1;
1530 1547
1531 p = name; 1548 p = name;
1532 while (cp < ep && p < name + namelen) { 1549 while (cp < ep && p < name + namelen) {
1533 i = 0; 1550 i = 0;
1534 for (q = p; q < name + namelen && *q && *q != '.'; q++) 1551 for (q = p; q < name + namelen && *q && *q != '.'; q++)
1535 i++; 1552 i++;
1536 /* result does not fit into mbuf */ 1553 /* result does not fit into mbuf */
1537 if (cp + i + 1 >= ep) 1554 if (cp + i + 1 >= ep)
1538 goto fail; 1555 goto fail;
1539 /* 1556 /*
1540 * DNS label length restriction, RFC1035 page 8. 1557 * DNS label length restriction, RFC1035 page 8.
1541 * "i == 0" case is included here to avoid returning 1558 * "i == 0" case is included here to avoid returning
1542 * 0-length label on "foo..bar". 1559 * 0-length label on "foo..bar".
1543 */ 1560 */
1544 if (i <= 0 || i >= 64) 1561 if (i <= 0 || i >= 64)
1545 goto fail; 1562 goto fail;
1546 *cp++ = i; 1563 *cp++ = i;
1547 if (!isalpha(p[0]) || !isalnum(p[i - 1])) 1564 if (!isalpha(p[0]) || !isalnum(p[i - 1]))
1548 goto fail; 1565 goto fail;
1549 while (i > 0) { 1566 while (i > 0) {
1550 if (!isalnum(*p) && *p != '-') 1567 if (!isalnum(*p) && *p != '-')
1551 goto fail; 1568 goto fail;
1552 if (isupper(*p)) { 1569 if (isupper(*p)) {
1553 *cp++ = tolower(*p); 1570 *cp++ = tolower(*p);
1554 p++; 1571 p++;
1555 } else 1572 } else
1556 *cp++ = *p++; 1573 *cp++ = *p++;
1557 i--; 1574 i--;
1558 } 1575 }
1559 p = q; 1576 p = q;
1560 if (p < name + namelen && *p == '.') 1577 if (p < name + namelen && *p == '.')
1561 p++; 1578 p++;
1562 } 1579 }
1563 /* termination */ 1580 /* termination */
1564 if (cp + nterm >= ep) 1581 if (cp + nterm >= ep)
1565 goto fail; 1582 goto fail;
1566 while (nterm-- > 0) 1583 while (nterm-- > 0)
1567 *cp++ = '\0'; 1584 *cp++ = '\0';
1568 m->m_len = cp - mtod(m, char *); 1585 m->m_len = cp - mtod(m, char *);
1569 return m; 1586 return m;
1570 } 1587 }
1571 1588
1572 panic("should not reach here"); 1589 panic("should not reach here");
1573 /* NOTREACHED */ 1590 /* NOTREACHED */
1574 1591
1575 fail: 1592 fail:
1576 if (m) 1593 if (m)
1577 m_freem(m); 1594 m_freem(m);
1578 return NULL; 1595 return NULL;
1579} 1596}
1580 1597
1581/* 1598/*
1582 * check if two DNS-encoded string matches. takes care of truncated 1599 * check if two DNS-encoded string matches. takes care of truncated
1583 * form (with \0\0 at the end). no compression support. 1600 * form (with \0\0 at the end). no compression support.
1584 * XXX upper/lowercase match (see RFC2065) 1601 * XXX upper/lowercase match (see RFC2065)
1585 */ 1602 */
1586static int 1603static int
1587ni6_dnsmatch(a, alen, b, blen) 1604ni6_dnsmatch(a, alen, b, blen)
1588 const char *a; 1605 const char *a;
1589 int alen; 1606 int alen;
1590 const char *b; 1607 const char *b;
1591 int blen; 1608 int blen;
1592{ 1609{
1593 const char *a0, *b0; 1610 const char *a0, *b0;
1594 int l; 1611 int l;
1595 1612
1596 /* simplest case - need validation? */ 1613 /* simplest case - need validation? */
1597 if (alen == blen && bcmp(a, b, alen) == 0) 1614 if (alen == blen && bcmp(a, b, alen) == 0)
1598 return 1; 1615 return 1;
1599 1616
1600 a0 = a; 1617 a0 = a;
1601 b0 = b; 1618 b0 = b;
1602 1619
1603 /* termination is mandatory */ 1620 /* termination is mandatory */
1604 if (alen < 2 || blen < 2) 1621 if (alen < 2 || blen < 2)
1605 return 0; 1622 return 0;
1606 if (a0[alen - 1] != '\0' || b0[blen - 1] != '\0') 1623 if (a0[alen - 1] != '\0' || b0[blen - 1] != '\0')
1607 return 0; 1624 return 0;
1608 alen--; 1625 alen--;
1609 blen--; 1626 blen--;
1610 1627
1611 while (a - a0 < alen && b - b0 < blen) { 1628 while (a - a0 < alen && b - b0 < blen) {
1612 if (a - a0 + 1 > alen || b - b0 + 1 > blen) 1629 if (a - a0 + 1 > alen || b - b0 + 1 > blen)
1613 return 0; 1630 return 0;
1614 1631
1615 if ((signed char)a[0] < 0 || (signed char)b[0] < 0) 1632 if ((signed char)a[0] < 0 || (signed char)b[0] < 0)
1616 return 0; 1633 return 0;
1617 /* we don't support compression yet */ 1634 /* we don't support compression yet */
1618 if (a[0] >= 64 || b[0] >= 64) 1635 if (a[0] >= 64 || b[0] >= 64)
1619 return 0; 1636 return 0;
1620 1637
1621 /* truncated case */ 1638 /* truncated case */
1622 if (a[0] == 0 && a - a0 == alen - 1) 1639 if (a[0] == 0 && a - a0 == alen - 1)
1623 return 1; 1640 return 1;
1624 if (b[0] == 0 && b - b0 == blen - 1) 1641 if (b[0] == 0 && b - b0 == blen - 1)
1625 return 1; 1642 return 1;
1626 if (a[0] == 0 || b[0] == 0) 1643 if (a[0] == 0 || b[0] == 0)
1627 return 0; 1644 return 0;
1628 1645
1629 if (a[0] != b[0]) 1646 if (a[0] != b[0])
1630 return 0; 1647 return 0;
1631 l = a[0]; 1648 l = a[0];
1632 if (a - a0 + 1 + l > alen || b - b0 + 1 + l > blen) 1649 if (a - a0 + 1 + l > alen || b - b0 + 1 + l > blen)
1633 return 0; 1650 return 0;
1634 if (bcmp(a + 1, b + 1, l) != 0) 1651 if (bcmp(a + 1, b + 1, l) != 0)
1635 return 0; 1652 return 0;
1636 1653
1637 a += 1 + l; 1654 a += 1 + l;
1638 b += 1 + l; 1655 b += 1 + l;
1639 } 1656 }
1640 1657
1641 if (a - a0 == alen && b - b0 == blen) 1658 if (a - a0 == alen && b - b0 == blen)
1642 return 1; 1659 return 1;
1643 else 1660 else
1644 return 0; 1661 return 0;
1645} 1662}
1646 1663
1647/* 1664/*
1648 * calculate the number of addresses to be returned in the node info reply. 1665 * calculate the number of addresses to be returned in the node info reply.
1649 */ 1666 */
1650static int 1667static int
1651ni6_addrs(ni6, m, ifpp, subj) 1668ni6_addrs(ni6, m, ifpp, subj)
1652 struct icmp6_nodeinfo *ni6; 1669 struct icmp6_nodeinfo *ni6;
1653 struct mbuf *m; 1670 struct mbuf *m;
1654 struct ifnet **ifpp; 1671 struct ifnet **ifpp;
1655 char *subj; 1672 char *subj;
1656{ 1673{
1657 struct ifnet *ifp; 1674 struct ifnet *ifp;
1658 struct in6_ifaddr *ifa6; 1675 struct in6_ifaddr *ifa6;
1659 struct ifaddr *ifa; 1676 struct ifaddr *ifa;
1660 struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */ 1677 struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
1661 int addrs = 0, addrsofif, iffound = 0; 1678 int addrs = 0, addrsofif, iffound = 0;
1662 int niflags = ni6->ni_flags; 1679 int niflags = ni6->ni_flags;
1663 1680
1664 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) { 1681 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) {
1665 switch (ni6->ni_code) { 1682 switch (ni6->ni_code) {
1666 case ICMP6_NI_SUBJ_IPV6: 1683 case ICMP6_NI_SUBJ_IPV6:
1667 if (subj == NULL) /* must be impossible... */ 1684 if (subj == NULL) /* must be impossible... */
1668 return (0); 1685 return (0);
1669 subj_ip6 = (struct sockaddr_in6 *)subj; 1686 subj_ip6 = (struct sockaddr_in6 *)subj;
1670 break; 1687 break;
1671 default: 1688 default:
1672 /* 1689 /*
1673 * XXX: we only support IPv6 subject address for 1690 * XXX: we only support IPv6 subject address for
1674 * this Qtype. 1691 * this Qtype.
1675 */ 1692 */
1676 return (0); 1693 return (0);
1677 } 1694 }
1678 } 1695 }
1679 1696
1680 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) 1697 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
1681 { 1698 {
1682 addrsofif = 0; 1699 addrsofif = 0;
1683 for (ifa = ifp->if_addrlist.tqh_first; ifa; 1700 for (ifa = ifp->if_addrlist.tqh_first; ifa;
1684 ifa = ifa->ifa_list.tqe_next) 1701 ifa = ifa->ifa_list.tqe_next)
1685 { 1702 {
1686 if (ifa->ifa_addr->sa_family != AF_INET6) 1703 if (ifa->ifa_addr->sa_family != AF_INET6)
1687 continue; 1704 continue;
1688 ifa6 = (struct in6_ifaddr *)ifa; 1705 ifa6 = (struct in6_ifaddr *)ifa;
1689 1706
1690 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 && 1707 if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 &&
1691 IN6_ARE_ADDR_EQUAL(&subj_ip6->sin6_addr, 1708 IN6_ARE_ADDR_EQUAL(&subj_ip6->sin6_addr,
1692 &ifa6->ia_addr.sin6_addr)) 1709 &ifa6->ia_addr.sin6_addr))
1693 iffound = 1; 1710 iffound = 1;
1694 1711
1695 /* 1712 /*
1696 * IPv4-mapped addresses can only be returned by a 1713 * IPv4-mapped addresses can only be returned by a
1697 * Node Information proxy, since they represent 1714 * Node Information proxy, since they represent
1698 * addresses of IPv4-only nodes, which perforce do 1715 * addresses of IPv4-only nodes, which perforce do
1699 * not implement this protocol. 1716 * not implement this protocol.
1700 * [icmp-name-lookups-07, Section 5.4] 1717 * [icmp-name-lookups-07, Section 5.4]
1701 * So we don't support NI_NODEADDR_FLAG_COMPAT in 1718 * So we don't support NI_NODEADDR_FLAG_COMPAT in
1702 * this function at this moment. 1719 * this function at this moment.
1703 */ 1720 */
1704 1721
1705 /* What do we have to do about ::1? */ 1722 /* What do we have to do about ::1? */
1706 switch (in6_addrscope(&ifa6->ia_addr.sin6_addr)) { 1723 switch (in6_addrscope(&ifa6->ia_addr.sin6_addr)) {
1707 case IPV6_ADDR_SCOPE_LINKLOCAL: 1724 case IPV6_ADDR_SCOPE_LINKLOCAL:
1708 if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) 1725 if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0)
1709 continue; 1726 continue;
1710 break; 1727 break;
1711 case IPV6_ADDR_SCOPE_SITELOCAL: 1728 case IPV6_ADDR_SCOPE_SITELOCAL:
1712 if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) 1729 if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0)
1713 continue; 1730 continue;
1714 break; 1731 break;
1715 case IPV6_ADDR_SCOPE_GLOBAL: 1732 case IPV6_ADDR_SCOPE_GLOBAL:
1716 if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) 1733 if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0)
1717 continue; 1734 continue;
1718 break; 1735 break;
1719 default: 1736 default:
1720 continue; 1737 continue;
1721 } 1738 }
1722 1739
1723 /* 1740 /*
1724 * check if anycast is okay. 1741 * check if anycast is okay.
1725 * XXX: just experimental. not in the spec. 1742 * XXX: just experimental. not in the spec.
1726 */ 1743 */
1727 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1744 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
1728 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1745 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0)
1729 continue; /* we need only unicast addresses */ 1746 continue; /* we need only unicast addresses */
1730 1747
1731 addrsofif++; /* count the address */ 1748 addrsofif++; /* count the address */
1732 } 1749 }
1733 if (iffound) { 1750 if (iffound) {
1734 *ifpp = ifp; 1751 *ifpp = ifp;
1735 return (addrsofif); 1752 return (addrsofif);
1736 } 1753 }
1737 1754
1738 addrs += addrsofif; 1755 addrs += addrsofif;
1739 } 1756 }
1740 1757
1741 return (addrs); 1758 return (addrs);
1742} 1759}
1743 1760
1744static int 1761static int
1745ni6_store_addrs(ni6, nni6, ifp0, resid) 1762ni6_store_addrs(ni6, nni6, ifp0, resid)
1746 struct icmp6_nodeinfo *ni6, *nni6; 1763 struct icmp6_nodeinfo *ni6, *nni6;
1747 struct ifnet *ifp0; 1764 struct ifnet *ifp0;
1748 int resid; 1765 int resid;
1749{ 1766{
1750 struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet); 1767 struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
1751 struct in6_ifaddr *ifa6; 1768 struct in6_ifaddr *ifa6;
1752 struct ifaddr *ifa; 1769 struct ifaddr *ifa;
1753 struct ifnet *ifp_dep = NULL; 1770 struct ifnet *ifp_dep = NULL;
1754 int copied = 0, allow_deprecated = 0; 1771 int copied = 0, allow_deprecated = 0;
1755 u_char *cp = (u_char *)(nni6 + 1); 1772 u_char *cp = (u_char *)(nni6 + 1);
1756 int niflags = ni6->ni_flags; 1773 int niflags = ni6->ni_flags;
1757 u_int32_t ltime; 1774 u_int32_t ltime;
1758 1775
1759 if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL)) 1776 if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL))
1760 return (0); /* needless to copy */ 1777 return (0); /* needless to copy */
1761 1778
1762 again: 1779 again:
1763 1780
1764 for (; ifp; ifp = TAILQ_NEXT(ifp, if_list)) 1781 for (; ifp; ifp = TAILQ_NEXT(ifp, if_list))
1765 { 1782 {
1766 for (ifa = ifp->if_addrlist.tqh_first; ifa; 1783 for (ifa = ifp->if_addrlist.tqh_first; ifa;
1767 ifa = ifa->ifa_list.tqe_next) 1784 ifa = ifa->ifa_list.tqe_next)
1768 { 1785 {
1769 if (ifa->ifa_addr->sa_family != AF_INET6) 1786 if (ifa->ifa_addr->sa_family != AF_INET6)
1770 continue; 1787 continue;
1771 ifa6 = (struct in6_ifaddr *)ifa; 1788 ifa6 = (struct in6_ifaddr *)ifa;
1772 1789
1773 if ((ifa6->ia6_flags & IN6_IFF_DEPRECATED) != 0 && 1790 if ((ifa6->ia6_flags & IN6_IFF_DEPRECATED) != 0 &&
1774 allow_deprecated == 0) { 1791 allow_deprecated == 0) {
1775 /* 1792 /*
1776 * prefererred address should be put before 1793 * prefererred address should be put before
1777 * deprecated addresses. 1794 * deprecated addresses.
1778 */ 1795 */
1779 1796
1780 /* record the interface for later search */ 1797 /* record the interface for later search */
1781 if (ifp_dep == NULL) 1798 if (ifp_dep == NULL)
1782 ifp_dep = ifp; 1799 ifp_dep = ifp;
1783 1800
1784 continue; 1801 continue;
1785 } 1802 }
1786 else if ((ifa6->ia6_flags & IN6_IFF_DEPRECATED) == 0 && 1803 else if ((ifa6->ia6_flags & IN6_IFF_DEPRECATED) == 0 &&
1787 allow_deprecated != 0) 1804 allow_deprecated != 0)
1788 continue; /* we now collect deprecated addrs */ 1805 continue; /* we now collect deprecated addrs */
1789 1806
1790 /* What do we have to do about ::1? */ 1807 /* What do we have to do about ::1? */
1791 switch (in6_addrscope(&ifa6->ia_addr.sin6_addr)) { 1808 switch (in6_addrscope(&ifa6->ia_addr.sin6_addr)) {
1792 case IPV6_ADDR_SCOPE_LINKLOCAL: 1809 case IPV6_ADDR_SCOPE_LINKLOCAL:
1793 if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) 1810 if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0)
1794 continue; 1811 continue;
1795 break; 1812 break;
1796 case IPV6_ADDR_SCOPE_SITELOCAL: 1813 case IPV6_ADDR_SCOPE_SITELOCAL:
1797 if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) 1814 if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0)
1798 continue; 1815 continue;
1799 break; 1816 break;
1800 case IPV6_ADDR_SCOPE_GLOBAL: 1817 case IPV6_ADDR_SCOPE_GLOBAL:
1801 if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) 1818 if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0)
1802 continue; 1819 continue;
1803 break; 1820 break;
1804 default: 1821 default:
1805 continue; 1822 continue;
1806 } 1823 }
1807 1824
1808 /* 1825 /*
1809 * check if anycast is okay. 1826 * check if anycast is okay.
1810 * XXX: just experimental. not in the spec. 1827 * XXX: just experimental. not in the spec.
1811 */ 1828 */
1812 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1829 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
1813 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1830 (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0)
1814 continue; 1831 continue;
1815 1832
1816 /* now we can copy the address */ 1833 /* now we can copy the address */
1817 if (resid < sizeof(struct in6_addr) + 1834 if (resid < sizeof(struct in6_addr) +
1818 sizeof(u_int32_t)) { 1835 sizeof(u_int32_t)) {
1819 /* 1836 /*
1820 * We give up much more copy. 1837 * We give up much more copy.
1821 * Set the truncate flag and return. 1838 * Set the truncate flag and return.
1822 */ 1839 */
1823 nni6->ni_flags |= 1840 nni6->ni_flags |=
1824 NI_NODEADDR_FLAG_TRUNCATE; 1841 NI_NODEADDR_FLAG_TRUNCATE;
1825 return (copied); 1842 return (copied);
1826 } 1843 }
1827 1844
1828 /* 1845 /*
1829 * Set the TTL of the address. 1846 * Set the TTL of the address.
1830 * The TTL value should be one of the following 1847 * The TTL value should be one of the following
1831 * according to the specification: 1848 * according to the specification:
1832 * 1849 *
1833 * 1. The remaining lifetime of a DHCP lease on the 1850 * 1. The remaining lifetime of a DHCP lease on the
1834 * address, or 1851 * address, or
1835 * 2. The remaining Valid Lifetime of a prefix from 1852 * 2. The remaining Valid Lifetime of a prefix from
1836 * which the address was derived through Stateless 1853 * which the address was derived through Stateless
1837 * Autoconfiguration. 1854 * Autoconfiguration.
1838 * 1855 *
1839 * Note that we currently do not support stateful 1856 * Note that we currently do not support stateful
1840 * address configuration by DHCPv6, so the former 1857 * address configuration by DHCPv6, so the former
1841 * case can't happen. 1858 * case can't happen.
1842 * 1859 *
1843 * TTL must be 2^31 > TTL >= 0. 1860 * TTL must be 2^31 > TTL >= 0.
1844 */ 1861 */
1845 if (ifa6->ia6_lifetime.ia6t_expire == 0) 1862 if (ifa6->ia6_lifetime.ia6t_expire == 0)
1846 ltime = ND6_INFINITE_LIFETIME; 1863 ltime = ND6_INFINITE_LIFETIME;
1847 else { 1864 else {
1848 if (ifa6->ia6_lifetime.ia6t_expire > 1865 if (ifa6->ia6_lifetime.ia6t_expire >
1849 time.tv_sec) 1866 time.tv_sec)
1850 ltime = ifa6->ia6_lifetime.ia6t_expire - time.tv_sec; 1867 ltime = ifa6->ia6_lifetime.ia6t_expire - time.tv_sec;
1851 else 1868 else
1852 ltime = 0; 1869 ltime = 0;
1853 } 1870 }
1854 if (ltime > 0x7fffffff) 1871 if (ltime > 0x7fffffff)
1855 ltime = 0x7fffffff; 1872 ltime = 0x7fffffff;
1856 ltime = htonl(ltime); 1873 ltime = htonl(ltime);
1857 1874
1858 bcopy(&ltime, cp, sizeof(u_int32_t)); 1875 bcopy(&ltime, cp, sizeof(u_int32_t));
1859 cp += sizeof(u_int32_t); 1876 cp += sizeof(u_int32_t);
1860 1877
1861 /* copy the address itself */ 1878 /* copy the address itself */
1862 bcopy(&ifa6->ia_addr.sin6_addr, cp, 1879 bcopy(&ifa6->ia_addr.sin6_addr, cp,
1863 sizeof(struct in6_addr)); 1880 sizeof(struct in6_addr));
1864 /* XXX: KAME link-local hack; remove ifindex */ 1881 /* XXX: KAME link-local hack; remove ifindex */
1865 if (IN6_IS_ADDR_LINKLOCAL(&ifa6->ia_addr.sin6_addr)) 1882 if (IN6_IS_ADDR_LINKLOCAL(&ifa6->ia_addr.sin6_addr))
1866 ((struct in6_addr *)cp)->s6_addr16[1] = 0; 1883 ((struct in6_addr *)cp)->s6_addr16[1] = 0;
1867 cp += sizeof(struct in6_addr); 1884 cp += sizeof(struct in6_addr);
1868 1885
1869 resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t)); 1886 resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t));
1870 copied += (sizeof(struct in6_addr) + 1887 copied += (sizeof(struct in6_addr) +
1871 sizeof(u_int32_t)); 1888 sizeof(u_int32_t));
1872 } 1889 }
1873 if (ifp0) /* we need search only on the specified IF */ 1890 if (ifp0) /* we need search only on the specified IF */
1874 break; 1891 break;
1875 } 1892 }
1876 1893
1877 if (allow_deprecated == 0 && ifp_dep != NULL) { 1894 if (allow_deprecated == 0 && ifp_dep != NULL) {
1878 ifp = ifp_dep; 1895 ifp = ifp_dep;
1879 allow_deprecated = 1; 1896 allow_deprecated = 1;
1880 1897
1881 goto again; 1898 goto again;
1882 } 1899 }
1883 1900
1884 return (copied); 1901 return (copied);
1885} 1902}
1886 1903
1887/* 1904/*
1888 * XXX almost dup'ed code with rip6_input. 1905 * XXX almost dup'ed code with rip6_input.
1889 */ 1906 */
1890static int 1907static int
1891icmp6_rip6_input(mp, off) 1908icmp6_rip6_input(mp, off)
1892 struct mbuf **mp; 1909 struct mbuf **mp;
1893 int off; 1910 int off;
1894{ 1911{
1895 struct mbuf *m = *mp; 1912 struct mbuf *m = *mp;
1896 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1913 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1897 struct inpcb_hdr *inph; 1914 struct inpcb_hdr *inph;
1898 struct in6pcb *in6p; 1915 struct in6pcb *in6p;
1899 struct in6pcb *last = NULL; 1916 struct in6pcb *last = NULL;
1900 struct sockaddr_in6 rip6src; 1917 struct sockaddr_in6 rip6src;
1901 struct icmp6_hdr *icmp6; 1918 struct icmp6_hdr *icmp6;
1902 struct mbuf *opts = NULL; 1919 struct mbuf *opts = NULL;
1903 1920
1904 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); 1921 IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
1905 if (icmp6 == NULL) { 1922 if (icmp6 == NULL) {
1906 /* m is already reclaimed */ 1923 /* m is already reclaimed */
1907 return IPPROTO_DONE; 1924 return IPPROTO_DONE;
1908 } 1925 }
1909 1926
1910 bzero(&rip6src, sizeof(rip6src)); 1927 bzero(&rip6src, sizeof(rip6src));
1911 rip6src.sin6_len = sizeof(struct sockaddr_in6); 1928 rip6src.sin6_len = sizeof(struct sockaddr_in6);
1912 rip6src.sin6_family = AF_INET6; 1929 rip6src.sin6_family = AF_INET6;
1913 /* KAME hack: recover scopeid */ 1930 /* KAME hack: recover scopeid */
1914 (void)in6_recoverscope(&rip6src, &ip6->ip6_src, m->m_pkthdr.rcvif); 1931 (void)in6_recoverscope(&rip6src, &ip6->ip6_src, m->m_pkthdr.rcvif);
1915 1932
1916 CIRCLEQ_FOREACH(inph, &raw6cbtable.inpt_queue, inph_queue) { 1933 CIRCLEQ_FOREACH(inph, &raw6cbtable.inpt_queue, inph_queue) {
1917 in6p = (struct in6pcb *)inph; 1934 in6p = (struct in6pcb *)inph;
1918 if (in6p->in6p_af != AF_INET6) 1935 if (in6p->in6p_af != AF_INET6)
1919 continue; 1936 continue;
1920 if (in6p->in6p_ip6.ip6_nxt != IPPROTO_ICMPV6) 1937 if (in6p->in6p_ip6.ip6_nxt != IPPROTO_ICMPV6)
1921 continue; 1938 continue;
1922 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && 1939 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
1923 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) 1940 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
1924 continue; 1941 continue;
1925 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && 1942 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
1926 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) 1943 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
1927 continue; 1944 continue;
1928 if (in6p->in6p_icmp6filt 1945 if (in6p->in6p_icmp6filt
1929 && ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, 1946 && ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type,
1930 in6p->in6p_icmp6filt)) 1947 in6p->in6p_icmp6filt))
1931 continue; 1948 continue;
1932 if (last) { 1949 if (last) {
1933 struct mbuf *n; 1950 struct mbuf *n;
1934 if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { 1951 if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
1935 if (last->in6p_flags & IN6P_CONTROLOPTS) 1952 if (last->in6p_flags & IN6P_CONTROLOPTS)
1936 ip6_savecontrol(last, &opts, ip6, n); 1953 ip6_savecontrol(last, &opts, ip6, n);
1937 /* strip intermediate headers */ 1954 /* strip intermediate headers */
1938 m_adj(n, off); 1955 m_adj(n, off);
1939 if (sbappendaddr(&last->in6p_socket->so_rcv, 1956 if (sbappendaddr(&last->in6p_socket->so_rcv,
1940 (struct sockaddr *)&rip6src, 1957 (struct sockaddr *)&rip6src,
1941 n, opts) == 0) { 1958 n, opts) == 0) {
1942 /* should notify about lost packet */ 1959 /* should notify about lost packet */
1943 m_freem(n); 1960 m_freem(n);
1944 if (opts) 1961 if (opts)
1945 m_freem(opts); 1962 m_freem(opts);
1946 } else 1963 } else
1947 sorwakeup(last->in6p_socket); 1964 sorwakeup(last->in6p_socket);
1948 opts = NULL; 1965 opts = NULL;
1949 } 1966 }
1950 } 1967 }
1951 last = in6p; 1968 last = in6p;
1952 } 1969 }
1953 if (last) { 1970 if (last) {
1954 if (last->in6p_flags & IN6P_CONTROLOPTS) 1971 if (last->in6p_flags & IN6P_CONTROLOPTS)
1955 ip6_savecontrol(last, &opts, ip6, m); 1972 ip6_savecontrol(last, &opts, ip6, m);
1956 /* strip intermediate headers */ 1973 /* strip intermediate headers */
1957 m_adj(m, off); 1974 m_adj(m, off);
1958 if (sbappendaddr(&last->in6p_socket->so_rcv, 1975 if (sbappendaddr(&last->in6p_socket->so_rcv,
1959 (struct sockaddr *)&rip6src, m, opts) == 0) { 1976 (struct sockaddr *)&rip6src, m, opts) == 0) {
1960 m_freem(m); 1977 m_freem(m);
1961 if (opts) 1978 if (opts)
1962 m_freem(opts); 1979 m_freem(opts);
1963 } else 1980 } else
1964 sorwakeup(last->in6p_socket); 1981 sorwakeup(last->in6p_socket);
1965 } else { 1982 } else {
1966 m_freem(m); 1983 m_freem(m);
1967 ip6stat.ip6s_delivered--; 1984 ip6stat.ip6s_delivered--;
1968 } 1985 }
1969 return IPPROTO_DONE; 1986 return IPPROTO_DONE;
1970} 1987}
1971 1988
1972/* 1989/*
1973 * Reflect the ip6 packet back to the source. 1990 * Reflect the ip6 packet back to the source.
1974 * OFF points to the icmp6 header, counted from the top of the mbuf. 1991 * OFF points to the icmp6 header, counted from the top of the mbuf.
1975 * 1992 *
1976 * Note: RFC 1885 required that an echo reply should be truncated if it 1993 * Note: RFC 1885 required that an echo reply should be truncated if it
1977 * did not fit in with (return) path MTU, and KAME code supported the 1994 * did not fit in with (return) path MTU, and KAME code supported the
1978 * behavior. However, as a clarification after the RFC, this limitation 1995 * behavior. However, as a clarification after the RFC, this limitation
1979 * was removed in a revised version of the spec, RFC 2463. We had kept the 1996 * was removed in a revised version of the spec, RFC 2463. We had kept the
1980 * old behavior, with a (non-default) ifdef block, while the new version of 1997 * old behavior, with a (non-default) ifdef block, while the new version of
1981 * the spec was an internet-draft status, and even after the new RFC was 1998 * the spec was an internet-draft status, and even after the new RFC was
1982 * published. But it would rather make sense to clean the obsoleted part 1999 * published. But it would rather make sense to clean the obsoleted part
1983 * up, and to make the code simpler at this stage. 2000 * up, and to make the code simpler at this stage.
1984 */ 2001 */
1985void 2002void
1986icmp6_reflect(m, off) 2003icmp6_reflect(m, off)
1987 struct mbuf *m; 2004 struct mbuf *m;
1988 size_t off; 2005 size_t off;
1989{ 2006{
1990 struct ip6_hdr *ip6; 2007 struct ip6_hdr *ip6;
1991 struct icmp6_hdr *icmp6; 2008 struct icmp6_hdr *icmp6;
1992 struct in6_ifaddr *ia; 2009 struct in6_ifaddr *ia;
1993 struct in6_addr t, *src = 0; 2010 struct in6_addr t, *src = 0;
1994 int plen; 2011 int plen;
1995 int type, code; 2012 int type, code;
1996 struct ifnet *outif = NULL; 2013 struct ifnet *outif = NULL;
1997 struct sockaddr_in6 sa6_src, sa6_dst; 2014 struct sockaddr_in6 sa6_src, sa6_dst;
1998 2015
1999 /* too short to reflect */ 2016 /* too short to reflect */
2000 if (off < sizeof(struct ip6_hdr)) { 2017 if (off < sizeof(struct ip6_hdr)) {
2001 nd6log((LOG_DEBUG, 2018 nd6log((LOG_DEBUG,
2002 "sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n", 2019 "sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n",
2003 (u_long)off, (u_long)sizeof(struct ip6_hdr), 2020 (u_long)off, (u_long)sizeof(struct ip6_hdr),
2004 __FILE__, __LINE__)); 2021 __FILE__, __LINE__));
2005 goto bad; 2022 goto bad;
2006 } 2023 }
2007 2024
2008 /* 2025 /*
2009 * If there are extra headers between IPv6 and ICMPv6, strip 2026 * If there are extra headers between IPv6 and ICMPv6, strip
2010 * off that header first. 2027 * off that header first.
2011 */ 2028 */
2012#ifdef DIAGNOSTIC 2029#ifdef DIAGNOSTIC
2013 if (sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) > MHLEN) 2030 if (sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) > MHLEN)
2014 panic("assumption failed in icmp6_reflect"); 2031 panic("assumption failed in icmp6_reflect");
2015#endif 2032#endif
2016 if (off > sizeof(struct ip6_hdr)) { 2033 if (off > sizeof(struct ip6_hdr)) {
2017 size_t l; 2034 size_t l;
2018 struct ip6_hdr nip6; 2035 struct ip6_hdr nip6;
2019 2036
2020 l = off - sizeof(struct ip6_hdr); 2037 l = off - sizeof(struct ip6_hdr);
2021 m_copydata(m, 0, sizeof(nip6), (caddr_t)&nip6); 2038 m_copydata(m, 0, sizeof(nip6), (caddr_t)&nip6);
2022 m_adj(m, l); 2039 m_adj(m, l);
2023 l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); 2040 l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
2024 if (m->m_len < l) { 2041 if (m->m_len < l) {
2025 if ((m = m_pullup(m, l)) == NULL) 2042 if ((m = m_pullup(m, l)) == NULL)
2026 return; 2043 return;
2027 } 2044 }
2028 bcopy((caddr_t)&nip6, mtod(m, caddr_t), sizeof(nip6)); 2045 bcopy((caddr_t)&nip6, mtod(m, caddr_t), sizeof(nip6));
2029 } else /* off == sizeof(struct ip6_hdr) */ { 2046 } else /* off == sizeof(struct ip6_hdr) */ {
2030 size_t l; 2047 size_t l;
2031 l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); 2048 l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
2032 if (m->m_len < l) { 2049 if (m->m_len < l) {
2033 if ((m = m_pullup(m, l)) == NULL) 2050 if ((m = m_pullup(m, l)) == NULL)
2034 return; 2051 return;
2035 } 2052 }
2036 } 2053 }
2037 plen = m->m_pkthdr.len - sizeof(struct ip6_hdr); 2054 plen = m->m_pkthdr.len - sizeof(struct ip6_hdr);
2038 ip6 = mtod(m, struct ip6_hdr *); 2055 ip6 = mtod(m, struct ip6_hdr *);
2039 ip6->ip6_nxt = IPPROTO_ICMPV6; 2056 ip6->ip6_nxt = IPPROTO_ICMPV6;
2040 icmp6 = (struct icmp6_hdr *)(ip6 + 1); 2057 icmp6 = (struct icmp6_hdr *)(ip6 + 1);
2041 type = icmp6->icmp6_type; /* keep type for statistics */ 2058 type = icmp6->icmp6_type; /* keep type for statistics */
2042 code = icmp6->icmp6_code; /* ditto. */ 2059 code = icmp6->icmp6_code; /* ditto. */
2043 2060
2044 t = ip6->ip6_dst; 2061 t = ip6->ip6_dst;
2045 /* 2062 /*
2046 * ip6_input() drops a packet if its src is multicast. 2063 * ip6_input() drops a packet if its src is multicast.
2047 * So, the src is never multicast. 2064 * So, the src is never multicast.
2048 */ 2065 */
2049 ip6->ip6_dst = ip6->ip6_src; 2066 ip6->ip6_dst = ip6->ip6_src;
2050 2067
2051 /* 2068 /*
2052 * XXX: make sure to embed scope zone information, using 2069 * XXX: make sure to embed scope zone information, using
2053 * already embedded IDs or the received interface (if any). 2070 * already embedded IDs or the received interface (if any).
2054 * Note that rcvif may be NULL. 2071 * Note that rcvif may be NULL.
2055 * TODO: scoped routing case (XXX). 2072 * TODO: scoped routing case (XXX).
2056 */ 2073 */
2057 bzero(&sa6_src, sizeof(sa6_src)); 2074 bzero(&sa6_src, sizeof(sa6_src));
2058 sa6_src.sin6_family = AF_INET6; 2075 sa6_src.sin6_family = AF_INET6;
2059 sa6_src.sin6_len = sizeof(sa6_src); 2076 sa6_src.sin6_len = sizeof(sa6_src);
2060 sa6_src.sin6_addr = ip6->ip6_dst; 2077 sa6_src.sin6_addr = ip6->ip6_dst;
2061 in6_recoverscope(&sa6_src, &ip6->ip6_dst, m->m_pkthdr.rcvif); 2078 in6_recoverscope(&sa6_src, &ip6->ip6_dst, m->m_pkthdr.rcvif);
2062 in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL, NULL); 2079 in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL, NULL);
2063 ip6->ip6_dst = sa6_src.sin6_addr; 2080 ip6->ip6_dst = sa6_src.sin6_addr;
2064 2081
2065 bzero(&sa6_dst, sizeof(sa6_dst)); 2082 bzero(&sa6_dst, sizeof(sa6_dst));
2066 sa6_dst.sin6_family = AF_INET6; 2083 sa6_dst.sin6_family = AF_INET6;
2067 sa6_dst.sin6_len = sizeof(sa6_dst); 2084 sa6_dst.sin6_len = sizeof(sa6_dst);
2068 sa6_dst.sin6_addr = t; 2085 sa6_dst.sin6_addr = t;
2069 in6_recoverscope(&sa6_dst, &t, m->m_pkthdr.rcvif); 2086 in6_recoverscope(&sa6_dst, &t, m->m_pkthdr.rcvif);
2070 in6_embedscope(&t, &sa6_dst, NULL, NULL); 2087 in6_embedscope(&t, &sa6_dst, NULL, NULL);
2071 2088
2072 /* 2089 /*
2073 * If the incoming packet was addressed directly to us (i.e. unicast), 2090 * If the incoming packet was addressed directly to us (i.e. unicast),
2074 * use dst as the src for the reply. 2091 * use dst as the src for the reply.
2075 * The IN6_IFF_NOTREADY case would be VERY rare, but is possible 2092 * The IN6_IFF_NOTREADY case would be VERY rare, but is possible
2076 * (for example) when we encounter an error while forwarding procedure 2093 * (for example) when we encounter an error while forwarding procedure
2077 * destined to a duplicated address of ours. 2094 * destined to a duplicated address of ours.
2078 */ 2095 */
2079 for (ia = in6_ifaddr; ia; ia = ia->ia_next) 2096 for (ia = in6_ifaddr; ia; ia = ia->ia_next)
2080 if (IN6_ARE_ADDR_EQUAL(&t, &ia->ia_addr.sin6_addr) && 2097 if (IN6_ARE_ADDR_EQUAL(&t, &ia->ia_addr.sin6_addr) &&
2081 (ia->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)) == 0) { 2098 (ia->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)) == 0) {
2082 src = &t; 2099 src = &t;
2083 break; 2100 break;
2084 } 2101 }
2085 if (ia == NULL && IN6_IS_ADDR_LINKLOCAL(&t) && (m->m_flags & M_LOOP)) { 2102 if (ia == NULL && IN6_IS_ADDR_LINKLOCAL(&t) && (m->m_flags & M_LOOP)) {
2086 /* 2103 /*
2087 * This is the case if the dst is our link-local address 2104 * This is the case if the dst is our link-local address
2088 * and the sender is also ourselves. 2105 * and the sender is also ourselves.
2089 */ 2106 */
2090 src = &t; 2107 src = &t;
2091 } 2108 }
2092 2109
2093 if (src == 0) { 2110 if (src == 0) {
2094 int e; 2111 int e;
2095 struct route_in6 ro; 2112 struct route_in6 ro;
2096 2113
2097 /* 2114 /*
2098 * This case matches to multicasts, our anycast, or unicasts 2115 * This case matches to multicasts, our anycast, or unicasts
2099 * that we do not own. Select a source address based on the 2116 * that we do not own. Select a source address based on the
2100 * source address of the erroneous packet. 2117 * source address of the erroneous packet.
2101 */ 2118 */
2102 bzero(&ro, sizeof(ro)); 2119 bzero(&ro, sizeof(ro));
2103 src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e); 2120 src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e);
2104 if (ro.ro_rt) { /* XXX: see comments in icmp6_mtudisc_update */ 2121 if (ro.ro_rt) { /* XXX: see comments in icmp6_mtudisc_update */
2105 RTFREE(ro.ro_rt); /* XXX: we could use this */ 2122 RTFREE(ro.ro_rt); /* XXX: we could use this */
2106 } 2123 }
2107 if (src == NULL) { 2124 if (src == NULL) {
2108 nd6log((LOG_DEBUG, 2125 nd6log((LOG_DEBUG,
2109 "icmp6_reflect: source can't be determined: " 2126 "icmp6_reflect: source can't be determined: "