Sat Dec 10 19:14:29 2011 UTC ()
Add RDNSS and DNSSL support, RFC6106.
Replace custom lists with TAILQ lists.
Clean up plently of signed vs unsigned warnings and set WARNS=4.

Adapted from FreeBSD.


(roy)
diff -r1.43 -r1.44 src/sys/netinet/icmp6.h
diff -r1.15 -r1.16 src/usr.sbin/rtadvd/Makefile
diff -r1.12 -r1.13 src/usr.sbin/rtadvd/advcap.c
diff -r1.6 -r1.7 src/usr.sbin/rtadvd/advcap.h
diff -r1.6 -r1.7 src/usr.sbin/rtadvd/config.h
diff -r1.6 -r1.7 src/usr.sbin/rtadvd/timer.h
diff -r1.25 -r1.26 src/usr.sbin/rtadvd/config.c
diff -r1.8 -r1.9 src/usr.sbin/rtadvd/dump.c
diff -r1.1 -r1.2 src/usr.sbin/rtadvd/dump.h
diff -r1.18 -r1.19 src/usr.sbin/rtadvd/if.c
diff -r1.7 -r1.8 src/usr.sbin/rtadvd/if.h
diff -r1.13 -r1.14 src/usr.sbin/rtadvd/rrenum.c
diff -r1.4 -r1.5 src/usr.sbin/rtadvd/rrenum.h
diff -r1.35 -r1.36 src/usr.sbin/rtadvd/rtadvd.c
diff -r1.14 -r1.15 src/usr.sbin/rtadvd/rtadvd.conf.5
diff -r1.10 -r1.11 src/usr.sbin/rtadvd/rtadvd.h
diff -r1.9 -r1.10 src/usr.sbin/rtadvd/timer.c

cvs diff -r1.43 -r1.44 src/sys/netinet/icmp6.h (expand / switch to unified diff)

--- src/sys/netinet/icmp6.h 2011/11/11 15:09:32 1.43
+++ src/sys/netinet/icmp6.h 2011/12/10 19:14:29 1.44
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: icmp6.h,v 1.43 2011/11/11 15:09:32 gdt Exp $ */ 1/* $NetBSD: icmp6.h,v 1.44 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */ 2/* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */
3 3
4 4
5/* 5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -290,31 +290,30 @@ struct nd_opt_hdr { /* Neighbor discove @@ -290,31 +290,30 @@ struct nd_opt_hdr { /* Neighbor discove
290 u_int8_t nd_opt_len; 290 u_int8_t nd_opt_len;
291 /* followed by option specific data*/ 291 /* followed by option specific data*/
292} __packed; 292} __packed;
293 293
294#define ND_OPT_SOURCE_LINKADDR 1 294#define ND_OPT_SOURCE_LINKADDR 1
295#define ND_OPT_TARGET_LINKADDR 2 295#define ND_OPT_TARGET_LINKADDR 2
296#define ND_OPT_PREFIX_INFORMATION 3 296#define ND_OPT_PREFIX_INFORMATION 3
297#define ND_OPT_REDIRECTED_HEADER 4 297#define ND_OPT_REDIRECTED_HEADER 4
298#define ND_OPT_MTU 5 298#define ND_OPT_MTU 5
299#define ND_OPT_ADVINTERVAL 7 299#define ND_OPT_ADVINTERVAL 7
300#define ND_OPT_HOMEAGENT_INFO 8 300#define ND_OPT_HOMEAGENT_INFO 8
301#define ND_OPT_SOURCE_ADDRLIST 9 301#define ND_OPT_SOURCE_ADDRLIST 9
302#define ND_OPT_TARGET_ADDRLIST 10 302#define ND_OPT_TARGET_ADDRLIST 10
303/* RFC5380 */ 303#define ND_OPT_MAP 23 /* RFC 5380 */
304#define ND_OPT_MAP 23 304#define ND_OPT_ROUTE_INFO 24 /* RFC 4191 */
305/* RFC4191 */ 305#define ND_OPT_RDNSS 25 /* RFC 6016 */
306#define ND_OPT_ROUTE_INFO 24 306#define ND_OPT_DNSSL 31 /* RFC 6016 */
307#define ND_OPT_RDNSS 25 
308 307
309struct nd_opt_route_info { /* route info */ 308struct nd_opt_route_info { /* route info */
310 u_int8_t nd_opt_rti_type; 309 u_int8_t nd_opt_rti_type;
311 u_int8_t nd_opt_rti_len; 310 u_int8_t nd_opt_rti_len;
312 u_int8_t nd_opt_rti_prefixlen; 311 u_int8_t nd_opt_rti_prefixlen;
313 u_int8_t nd_opt_rti_flags; 312 u_int8_t nd_opt_rti_flags;
314 u_int32_t nd_opt_rti_lifetime; 313 u_int32_t nd_opt_rti_lifetime;
315 /* prefix follows */ 314 /* prefix follows */
316}; 315};
317 316
318struct nd_opt_prefix_info { /* prefix information */ 317struct nd_opt_prefix_info { /* prefix information */
319 u_int8_t nd_opt_pi_type; 318 u_int8_t nd_opt_pi_type;
320 u_int8_t nd_opt_pi_len; 319 u_int8_t nd_opt_pi_len;
@@ -334,34 +333,42 @@ struct nd_opt_rd_hdr { /* redirected he @@ -334,34 +333,42 @@ struct nd_opt_rd_hdr { /* redirected he
334 u_int8_t nd_opt_rh_len; 333 u_int8_t nd_opt_rh_len;
335 u_int16_t nd_opt_rh_reserved1; 334 u_int16_t nd_opt_rh_reserved1;
336 u_int32_t nd_opt_rh_reserved2; 335 u_int32_t nd_opt_rh_reserved2;
337 /* followed by IP header and data */ 336 /* followed by IP header and data */
338} __packed; 337} __packed;
339 338
340struct nd_opt_mtu { /* MTU option */ 339struct nd_opt_mtu { /* MTU option */
341 u_int8_t nd_opt_mtu_type; 340 u_int8_t nd_opt_mtu_type;
342 u_int8_t nd_opt_mtu_len; 341 u_int8_t nd_opt_mtu_len;
343 u_int16_t nd_opt_mtu_reserved; 342 u_int16_t nd_opt_mtu_reserved;
344 u_int32_t nd_opt_mtu_mtu; 343 u_int32_t nd_opt_mtu_mtu;
345} __packed; 344} __packed;
346 345
347struct nd_opt_rdnss { /* RDNSS option RFC 5006 */ 346struct nd_opt_rdnss { /* RDNSS option RFC 6106 */
348 u_int8_t nd_opt_rdnss_type; 347 u_int8_t nd_opt_rdnss_type;
349 u_int8_t nd_opt_rdnss_len; 348 u_int8_t nd_opt_rdnss_len;
350 u_int16_t nd_opt_rdnss_reserved; 349 u_int16_t nd_opt_rdnss_reserved;
351 u_int32_t nd_opt_rdnss_lifetime; 350 u_int32_t nd_opt_rdnss_lifetime;
352 /* followed by list of IP prefixes */ 351 /* followed by list of IP prefixes */
353} __packed; 352} __packed;
354 353
 354struct nd_opt_dnssl { /* DNSSL option RFC 6106 */
 355 u_int8_t nd_opt_dnssl_type;
 356 u_int8_t nd_opt_dnssl_len;
 357 u_int16_t nd_opt_dnssl_reserved;
 358 u_int32_t nd_opt_dnssl_lifetime;
 359 /* followed by list of IP prefixes */
 360} __packed;
 361
355/* 362/*
356 * icmp6 namelookup 363 * icmp6 namelookup
357 */ 364 */
358 365
359struct icmp6_namelookup { 366struct icmp6_namelookup {
360 struct icmp6_hdr icmp6_nl_hdr; 367 struct icmp6_hdr icmp6_nl_hdr;
361 u_int8_t icmp6_nl_nonce[8]; 368 u_int8_t icmp6_nl_nonce[8];
362 int32_t icmp6_nl_ttl; 369 int32_t icmp6_nl_ttl;
363#if 0 370#if 0
364 u_int8_t icmp6_nl_len; 371 u_int8_t icmp6_nl_len;
365 u_int8_t icmp6_nl_name[3]; 372 u_int8_t icmp6_nl_name[3];
366#endif 373#endif
367 /* could be followed by options */ 374 /* could be followed by options */

cvs diff -r1.15 -r1.16 src/usr.sbin/rtadvd/Makefile (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/Makefile 2011/06/20 07:44:04 1.15
+++ src/usr.sbin/rtadvd/Makefile 2011/12/10 19:14:29 1.16
@@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
1# $NetBSD: Makefile,v 1.15 2011/06/20 07:44:04 mrg Exp $ 1# $NetBSD: Makefile,v 1.16 2011/12/10 19:14:29 roy Exp $
2 2
3WARNS?= 2 # XXX -Wcast-qual -Wsign-compare 3WARNS?= 4
4 4
5.include <bsd.own.mk> 5.include <bsd.own.mk>
6 6
7USE_FORT?= yes # network server 7USE_FORT?= yes # network server
8 8
9PROG= rtadvd 9PROG= rtadvd
10SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c 10SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c
11 11
12CPPFLAGS+=-DINET6 -DROUTEINFO 12CPPFLAGS+=-DINET6
13MAN= rtadvd.8 rtadvd.conf.5 13MAN= rtadvd.8 rtadvd.conf.5
14LDADD+= -lutil 14LDADD+= -lutil
15DPADD+= ${LIBUTIL} 15DPADD+= ${LIBUTIL}
16 16
17.if ${MKSHARE} != "no" 17.if ${MKSHARE} != "no"
18FILESDIR= /usr/share/examples/rtadvd 18FILESDIR= /usr/share/examples/rtadvd
19FILES= rtadvd.conf 19FILES= rtadvd.conf
20.endif 20.endif
21 21
22.include <bsd.prog.mk> 22.include <bsd.prog.mk>
23 23
24.if defined(HAVE_GCC) 24.if defined(HAVE_GCC)
25COPTS.dump.c=-fno-strict-aliasing 25COPTS.dump.c=-fno-strict-aliasing

cvs diff -r1.12 -r1.13 src/usr.sbin/rtadvd/advcap.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/advcap.c 2006/03/18 22:07:15 1.12
+++ src/usr.sbin/rtadvd/advcap.c 2011/12/10 19:14:29 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: advcap.c,v 1.12 2006/03/18 22:07:15 dan Exp $ */ 1/* $NetBSD: advcap.c,v 1.13 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: advcap.c,v 1.11 2003/05/19 09:46:50 keiichi Exp $ */ 2/* $KAME: advcap.c,v 1.11 2003/05/19 09:46:50 keiichi Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1983 The Regents of the University of California. 5 * Copyright (c) 1983 The Regents of the University of California.
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
@@ -77,54 +77,52 @@ char *RM; @@ -77,54 +77,52 @@ char *RM;
77 * 77 *
78 * Essentially all the work here is scanning and decoding escapes 78 * Essentially all the work here is scanning and decoding escapes
79 * in string capabilities. We don't use stdio because the editor 79 * in string capabilities. We don't use stdio because the editor
80 * doesn't, and because living w/o it is not hard. 80 * doesn't, and because living w/o it is not hard.
81 */ 81 */
82 82
83static char *tbuf; 83static char *tbuf;
84static int hopcount; /* detect infinite loops in termcap, init 0 */ 84static int hopcount; /* detect infinite loops in termcap, init 0 */
85 85
86static char *remotefile; 86static char *remotefile;
87 87
88extern char *conffile; 88extern char *conffile;
89 89
90int tgetent __P((char *, char *)); 90int tgetent(char *, char *);
91int getent __P((char *, char *, char *)); 91int getent(char *, char *, char *);
92int tnchktc __P((void)); 92int tnchktc(void);
93int tnamatch __P((char *)); 93int tnamatch(char *);
94static char *tskip __P((char *)); 94static char *tskip(char *);
95int64_t tgetnum __P((char *)); 95int64_t tgetnum(char *);
96int tgetflag __P((char *)); 96int tgetflag(char *);
97char *tgetstr __P((char *, char **)); 97char *tgetstr(char *, char **);
98static char *tdecode __P((char *, char **)); 98static char *tdecode(char *, char **);
99 99
100/* 100/*
101 * Get an entry for terminal name in buffer bp, 101 * Get an entry for terminal name in buffer bp,
102 * from the termcap file. Parse is very rudimentary; 102 * from the termcap file. Parse is very rudimentary;
103 * we just notice escaped newlines. 103 * we just notice escaped newlines.
104 */ 104 */
105int 105int
106tgetent(bp, name) 106tgetent(char *bp, char *name)
107 char *bp, *name; 
108{ 107{
109 char *cp; 108 char *cp;
110 109
111 remotefile = cp = conffile ? conffile : _PATH_RTADVDCONF; 110 remotefile = cp = conffile ? conffile : __UNCONST(_PATH_RTADVDCONF);
112 return (getent(bp, name, cp)); 111 return (getent(bp, name, cp));
113} 112}
114 113
115int 114int
116getent(bp, name, cp) 115getent(char *bp, char *name, char *cp)
117 char *bp, *name, *cp; 
118{ 116{
119 int c; 117 int c;
120 int i = 0, cnt = 0; 118 int i = 0, cnt = 0;
121 char ibuf[BUFSIZ]; 119 char ibuf[BUFSIZ];
122 int tf; 120 int tf;
123 121
124 tbuf = bp; 122 tbuf = bp;
125 tf = 0; 123 tf = 0;
126 /* 124 /*
127 * TERMCAP can have one of two things in it. It can be the 125 * TERMCAP can have one of two things in it. It can be the
128 * name of a file to use instead of /etc/termcap. In this 126 * name of a file to use instead of /etc/termcap. In this
129 * case it better start with a "/". Or it can be an entry to 127 * case it better start with a "/". Or it can be an entry to
130 * use so we don't have to read the file. In this case it 128 * use so we don't have to read the file. In this case it
@@ -173,27 +171,27 @@ getent(bp, name, cp) @@ -173,27 +171,27 @@ getent(bp, name, cp)
173 return (tnchktc()); 171 return (tnchktc());
174 } 172 }
175 } 173 }
176} 174}
177 175
178/* 176/*
179 * tnchktc: check the last entry, see if it's tc=xxx. If so, 177 * tnchktc: check the last entry, see if it's tc=xxx. If so,
180 * recursively find xxx and append that entry (minus the names) 178 * recursively find xxx and append that entry (minus the names)
181 * to take the place of the tc=xxx entry. This allows termcap 179 * to take the place of the tc=xxx entry. This allows termcap
182 * entries to say "like an HP2621 but doesn't turn on the labels". 180 * entries to say "like an HP2621 but doesn't turn on the labels".
183 * Note that this works because of the left to right scan. 181 * Note that this works because of the left to right scan.
184 */ 182 */
185int 183int
186tnchktc() 184tnchktc(void)
187{ 185{
188 char *p, *q; 186 char *p, *q;
189 char tcname[16]; /* name of similar terminal */ 187 char tcname[16]; /* name of similar terminal */
190 char tcbuf[BUFSIZ]; 188 char tcbuf[BUFSIZ];
191 char *holdtbuf = tbuf; 189 char *holdtbuf = tbuf;
192 int l; 190 int l;
193 191
194 p = tbuf + strlen(tbuf) - 2; /* before the last colon */ 192 p = tbuf + strlen(tbuf) - 2; /* before the last colon */
195 while (*--p != ':') 193 while (*--p != ':')
196 if (p < tbuf) { 194 if (p < tbuf) {
197 write(2, "Bad remcap entry\n", 18); 195 write(2, "Bad remcap entry\n", 18);
198 return (0); 196 return (0);
199 } 197 }
@@ -222,55 +220,53 @@ tnchktc() @@ -222,55 +220,53 @@ tnchktc()
222 } 220 }
223 strcpy(p, q); 221 strcpy(p, q);
224 tbuf = holdtbuf; 222 tbuf = holdtbuf;
225 return (1); 223 return (1);
226} 224}
227 225
228/* 226/*
229 * Tnamatch deals with name matching. The first field of the termcap 227 * Tnamatch deals with name matching. The first field of the termcap
230 * entry is a sequence of names separated by |'s, so we compare 228 * entry is a sequence of names separated by |'s, so we compare
231 * against each such name. The normal : terminator after the last 229 * against each such name. The normal : terminator after the last
232 * name (before the first field) stops us. 230 * name (before the first field) stops us.
233 */ 231 */
234int 232int
235tnamatch(np) 233tnamatch(char *np)
236 char *np; 
237{ 234{
238 char *Np, *Bp; 235 char *Np, *Bp;
239 236
240 Bp = tbuf; 237 Bp = tbuf;
241 if (*Bp == '#') 238 if (*Bp == '#')
242 return (0); 239 return (0);
243 for (;;) { 240 for (;;) {
244 for (Np = np; *Np && *Bp == *Np; Bp++, Np++) 241 for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
245 continue; 242 continue;
246 if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) 243 if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
247 return (1); 244 return (1);
248 while (*Bp && *Bp != ':' && *Bp != '|') 245 while (*Bp && *Bp != ':' && *Bp != '|')
249 Bp++; 246 Bp++;
250 if (*Bp == 0 || *Bp == ':') 247 if (*Bp == 0 || *Bp == ':')
251 return (0); 248 return (0);
252 Bp++; 249 Bp++;
253 } 250 }
254} 251}
255 252
256/* 253/*
257 * Skip to the next field. Notice that this is very dumb, not 254 * Skip to the next field. Notice that this is very dumb, not
258 * knowing about \: escapes or any such. If necessary, :'s can be put 255 * knowing about \: escapes or any such. If necessary, :'s can be put
259 * into the termcap file in octal. 256 * into the termcap file in octal.
260 */ 257 */
261static char * 258static char *
262tskip(bp) 259tskip(char *bp)
263 char *bp; 
264{ 260{
265 int dquote; 261 int dquote;
266 262
267 dquote = 0; 263 dquote = 0;
268 while (*bp) { 264 while (*bp) {
269 switch (*bp) { 265 switch (*bp) {
270 case ':': 266 case ':':
271 if (!dquote) 267 if (!dquote)
272 goto breakbreak; 268 goto breakbreak;
273 else 269 else
274 bp++; 270 bp++;
275 break; 271 break;
276 case '\\': 272 case '\\':
@@ -294,28 +290,27 @@ breakbreak: @@ -294,28 +290,27 @@ breakbreak:
294 bp++; 290 bp++;
295 return (bp); 291 return (bp);
296} 292}
297 293
298/* 294/*
299 * Return the (numeric) option id. 295 * Return the (numeric) option id.
300 * Numeric options look like 296 * Numeric options look like
301 * li#80 297 * li#80
302 * i.e. the option string is separated from the numeric value by 298 * i.e. the option string is separated from the numeric value by
303 * a # character. If the option is not found we return -1. 299 * a # character. If the option is not found we return -1.
304 * Note that we handle octal numbers beginning with 0. 300 * Note that we handle octal numbers beginning with 0.
305 */ 301 */
306int64_t 302int64_t
307tgetnum(id) 303tgetnum(char *id)
308 char *id; 
309{ 304{
310 int64_t i; 305 int64_t i;
311 int base; 306 int base;
312 char *bp = tbuf; 307 char *bp = tbuf;
313 308
314 for (;;) { 309 for (;;) {
315 bp = tskip(bp); 310 bp = tskip(bp);
316 if (*bp == 0) 311 if (*bp == 0)
317 return (-1); 312 return (-1);
318 if (strncmp(bp, id, strlen(id)) != 0) 313 if (strncmp(bp, id, strlen(id)) != 0)
319 continue; 314 continue;
320 bp += strlen(id); 315 bp += strlen(id);
321 if (*bp == '@') 316 if (*bp == '@')
@@ -330,106 +325,102 @@ tgetnum(id) @@ -330,106 +325,102 @@ tgetnum(id)
330 while (isdigit((unsigned char)*bp)) 325 while (isdigit((unsigned char)*bp))
331 i *= base, i += *bp++ - '0'; 326 i *= base, i += *bp++ - '0';
332 return (i); 327 return (i);
333 } 328 }
334} 329}
335 330
336/* 331/*
337 * Handle a flag option. 332 * Handle a flag option.
338 * Flag options are given "naked", i.e. followed by a : or the end 333 * Flag options are given "naked", i.e. followed by a : or the end
339 * of the buffer. Return 1 if we find the option, or 0 if it is 334 * of the buffer. Return 1 if we find the option, or 0 if it is
340 * not given. 335 * not given.
341 */ 336 */
342int 337int
343tgetflag(id) 338tgetflag(char *id)
344 char *id; 
345{ 339{
346 char *bp = tbuf; 340 char *bp = tbuf;
347 341
348 for (;;) { 342 for (;;) {
349 bp = tskip(bp); 343 bp = tskip(bp);
350 if (!*bp) 344 if (!*bp)
351 return (0); 345 return (0);
352 if (strncmp(bp, id, strlen(id)) == 0) { 346 if (strncmp(bp, id, strlen(id)) == 0) {
353 bp += strlen(id); 347 bp += strlen(id);
354 if (!*bp || *bp == ':') 348 if (!*bp || *bp == ':')
355 return (1); 349 return (1);
356 else if (*bp == '@') 350 else if (*bp == '@')
357 return (0); 351 return (0);
358 } 352 }
359 } 353 }
360} 354}
361 355
362/* 356/*
363 * Get a string valued option. 357 * Get a string valued option.
364 * These are given as 358 * These are given as
365 * cl=^Z 359 * cl=^Z
366 * Much decoding is done on the strings, and the strings are 360 * Much decoding is done on the strings, and the strings are
367 * placed in area, which is a ref parameter which is updated. 361 * placed in area, which is a ref parameter which is updated.
368 * No checking on area overflow. 362 * No checking on area overflow.
369 */ 363 */
370char * 364char *
371tgetstr(id, area) 365tgetstr(char *id, char **area)
372 char *id, **area; 
373{ 366{
374 char *bp = tbuf; 367 char *bp = tbuf;
375 368
376 for (;;) { 369 for (;;) {
377 bp = tskip(bp); 370 bp = tskip(bp);
378 if (!*bp) 371 if (!*bp)
379 return (0); 372 return (0);
380 if (strncmp(bp, id, strlen(id)) != 0) 373 if (strncmp(bp, id, strlen(id)) != 0)
381 continue; 374 continue;
382 bp += strlen(id); 375 bp += strlen(id);
383 if (*bp == '@') 376 if (*bp == '@')
384 return (0); 377 return (0);
385 if (*bp != '=') 378 if (*bp != '=')
386 continue; 379 continue;
387 bp++; 380 bp++;
388 return (tdecode(bp, area)); 381 return (tdecode(bp, area));
389 } 382 }
390} 383}
391 384
392/* 385/*
393 * Tdecode does the grung work to decode the 386 * Tdecode does the grung work to decode the
394 * string capability escapes. 387 * string capability escapes.
395 */ 388 */
396static char * 389static char *
397tdecode(str, area) 390tdecode(char *str, char **area)
398 char *str; 
399 char **area; 
400{ 391{
401 char *cp; 392 char *cp;
402 int c; 393 int c;
403 char *dp; 394 const char *dps = "E\033^^\\\\::n\nr\rt\tb\bf\f\"\"", *dp;
404 int i; 395 int i;
405 char term; 396 char term;
406 397
407 term = ':'; 398 term = ':';
408 cp = *area; 399 cp = *area;
409again: 400again:
410 if (*str == '"') { 401 if (*str == '"') {
411 term = '"'; 402 term = '"';
412 str++; 403 str++;
413 } 404 }
414 while ((c = *str++) && c != term) { 405 while ((c = *str++) && c != term) {
415 switch (c) { 406 switch (c) {
416 407
417 case '^': 408 case '^':
418 c = *str++ & 037; 409 c = *str++ & 037;
419 break; 410 break;
420 411
421 case '\\': 412 case '\\':
422 dp = "E\033^^\\\\::n\nr\rt\tb\bf\f\"\""; 413 dp = dps;
423 c = *str++; 414 c = *str++;
424nextc: 415nextc:
425 if (*dp++ == c) { 416 if (*dp++ == c) {
426 c = *dp++; 417 c = *dp++;
427 break; 418 break;
428 } 419 }
429 dp++; 420 dp++;
430 if (*dp) 421 if (*dp)
431 goto nextc; 422 goto nextc;
432 if (isdigit((unsigned char)c)) { 423 if (isdigit((unsigned char)c)) {
433 c -= '0', i = 2; 424 c -= '0', i = 2;
434 do 425 do
435 c <<= 3, c |= *str++ - '0'; 426 c <<= 3, c |= *str++ - '0';

cvs diff -r1.6 -r1.7 src/usr.sbin/rtadvd/advcap.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/advcap.h 2006/03/05 23:47:08 1.6
+++ src/usr.sbin/rtadvd/advcap.h 2011/12/10 19:14:29 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: advcap.h,v 1.6 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: advcap.h,v 1.7 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: advcap.h,v 1.5 2003/06/09 05:40:54 t-momose Exp $ */ 2/* $KAME: advcap.h,v 1.5 2003/06/09 05:40:54 t-momose Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia. 5 * Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia.
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
@@ -26,21 +26,21 @@ @@ -26,21 +26,21 @@
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30/* Based on Id: termcap.h,v 1.8 1996/09/10 12:42:10 peter Exp */ 30/* Based on Id: termcap.h,v 1.8 1996/09/10 12:42:10 peter Exp */
31 31
32#ifndef _ADVCAP_H_ 32#ifndef _ADVCAP_H_
33#define _ADVCAP_H_ 33#define _ADVCAP_H_
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36 36
37__BEGIN_DECLS 37__BEGIN_DECLS
38 38
39extern int agetent __P((char *, const char *)); 39extern int agetent(char *, const char *);
40extern int agetflag __P((const char *)); 40extern int agetflag(const char *);
41extern int64_t agetnum __P((const char *)); 41extern int64_t agetnum(const char *);
42extern char *agetstr __P((const char *, char **)); 42extern char *agetstr(const char *, char **);
43 43
44__END_DECLS 44__END_DECLS
45 45
46#endif /* _ADVCAP_H_ */ 46#endif /* _ADVCAP_H_ */

cvs diff -r1.6 -r1.7 src/usr.sbin/rtadvd/config.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/config.h 2006/03/05 23:47:08 1.6
+++ src/usr.sbin/rtadvd/config.h 2011/12/10 19:14:29 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: config.h,v 1.6 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: config.h,v 1.7 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: config.h,v 1.9 2003/08/06 04:19:40 ono Exp $ */ 2/* $KAME: config.h,v 1.9 2003/08/06 04:19:40 ono Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 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
@@ -20,28 +20,29 @@ @@ -20,28 +20,29 @@
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
33extern void getconfig __P((char *)); 33extern void getconfig(char *);
34extern void delete_prefix __P((struct prefix *)); 34extern void delete_prefix(struct prefix *);
35extern void invalidate_prefix __P((struct prefix *)); 35extern void invalidate_prefix(struct prefix *);
36extern void update_prefix __P((struct prefix *)); 36extern void update_prefix(struct prefix *);
37extern void make_prefix __P((struct rainfo *, int, struct in6_addr *, int)); 37extern void make_prefix(struct rainfo *, int, struct in6_addr *, int);
38extern void make_packet __P((struct rainfo *)); 38extern void make_packet(struct rainfo *);
39extern void get_prefix __P((struct rainfo *)); 39extern void get_prefix(struct rainfo *);
40 
41 40
42/* 41/*
43 * it is highly unlikely to have 100 prefix information options, 42 * it is highly unlikely to have 100 information options,
44 * so it should be okay to limit it 43 * so it should be okay to limit it
45 */ 44 */
46#define MAXPREFIX 100 45#define MAXPREFIX 100
47#define MAXROUTE 100 46#define MAXROUTE 100
 47#define MAXRDNSS 100
 48#define MAXDNSSL 100

cvs diff -r1.6 -r1.7 src/usr.sbin/rtadvd/timer.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/timer.h 2006/03/05 23:47:08 1.6
+++ src/usr.sbin/rtadvd/timer.h 2011/12/10 19:14:29 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: timer.h,v 1.6 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: timer.h,v 1.7 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: timer.h,v 1.5 2002/05/31 13:30:38 jinmei Exp $ */ 2/* $KAME: timer.h,v 1.5 2002/05/31 13:30:38 jinmei Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1998 WIDE Project. 5 * Copyright (C) 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
@@ -30,36 +30,36 @@ @@ -30,36 +30,36 @@
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33/* a < b */ 33/* a < b */
34#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ 34#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\
35 (((a).tv_sec == (b).tv_sec) && \ 35 (((a).tv_sec == (b).tv_sec) && \
36 ((a).tv_usec < (b).tv_usec))) 36 ((a).tv_usec < (b).tv_usec)))
37 37
38/* a <= b */ 38/* a <= b */
39#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\ 39#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\
40 (((a).tv_sec == (b).tv_sec) &&\ 40 (((a).tv_sec == (b).tv_sec) &&\
41 ((a).tv_usec <= (b).tv_usec))) 41 ((a).tv_usec <= (b).tv_usec)))
42 42
 43extern TAILQ_HEAD(rtadvd_timer_head_t, rtadvd_timer) ra_timer;
43struct rtadvd_timer { 44struct rtadvd_timer {
44 struct rtadvd_timer *next; 45 TAILQ_ENTRY(rtadvd_timer) next;
45 struct rtadvd_timer *prev; 
46 struct rainfo *rai; 46 struct rainfo *rai;
47 struct timeval tm; 47 struct timeval tm;
48 48
49 struct rtadvd_timer *(*expire) __P((void *)); /* expiration function */ 49 struct rtadvd_timer *(*expire) (void *); /* expiration function */
50 void *expire_data; 50 void *expire_data;
51 void (*update) __P((void *, struct timeval *)); /* update function */ 51 void (*update) __P((void *, struct timeval *)); /* update function */
52 void *update_data; 52 void *update_data;
53}; 53};
54 54
55void rtadvd_timer_init __P((void)); 55void rtadvd_timer_init(void);
56struct rtadvd_timer *rtadvd_add_timer __P((struct rtadvd_timer *(*) __P((void *)), 56struct rtadvd_timer *rtadvd_add_timer(struct rtadvd_timer *(*) (void *),
57 void (*) __P((void *, struct timeval *)), void *, void *)); 57 void (*) (void *, struct timeval *), void *, void *);
58void rtadvd_set_timer __P((struct timeval *, struct rtadvd_timer *)); 58void rtadvd_set_timer(struct timeval *, struct rtadvd_timer *);
59void rtadvd_remove_timer __P((struct rtadvd_timer **)); 59void rtadvd_remove_timer(struct rtadvd_timer **);
60struct timeval * rtadvd_check_timer __P((void)); 60struct timeval * rtadvd_check_timer(void);
61struct timeval * rtadvd_timer_rest __P((struct rtadvd_timer *)); 61struct timeval * rtadvd_timer_rest(struct rtadvd_timer *);
62void TIMEVAL_ADD __P((struct timeval *, struct timeval *, 62void TIMEVAL_ADD(struct timeval *, struct timeval *,
63 struct timeval *)); 63 struct timeval *);
64void TIMEVAL_SUB __P((struct timeval *, struct timeval *, 64void TIMEVAL_SUB(struct timeval *, struct timeval *,
65 struct timeval *)); 65 struct timeval *);

cvs diff -r1.25 -r1.26 src/usr.sbin/rtadvd/config.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/config.c 2006/05/11 08:35:47 1.25
+++ src/usr.sbin/rtadvd/config.c 2011/12/10 19:14:29 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: config.c,v 1.25 2006/05/11 08:35:47 mrg Exp $ */ 1/* $NetBSD: config.c,v 1.26 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: config.c,v 1.93 2005/10/17 14:40:02 suz Exp $ */ 2/* $KAME: config.c,v 1.93 2005/10/17 14:40:02 suz Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1998 WIDE Project. 5 * Copyright (C) 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
@@ -56,82 +56,104 @@ @@ -56,82 +56,104 @@
56#include <stdlib.h> 56#include <stdlib.h>
57#include <search.h> 57#include <search.h>
58#include <unistd.h> 58#include <unistd.h>
59#include <ifaddrs.h> 59#include <ifaddrs.h>
60 60
61#include "rtadvd.h" 61#include "rtadvd.h"
62#include "advcap.h" 62#include "advcap.h"
63#include "timer.h" 63#include "timer.h"
64#include "if.h" 64#include "if.h"
65#include "config.h" 65#include "config.h"
66 66
67static time_t prefix_timo = (60 * 120); /* 2 hours. 67static time_t prefix_timo = (60 * 120); /* 2 hours.
68 * XXX: should be configurable. */ 68 * XXX: should be configurable. */
69extern struct rainfo *ralist; 69static struct rtadvd_timer *prefix_timeout(void *);
 70static void makeentry(char *, size_t, int, const char *);
 71static int getinet6sysctl(int);
70 72
71static struct rtadvd_timer *prefix_timeout __P((void *)); 73static size_t
72static void makeentry __P((char *, size_t, int, char *)); 74encode_domain(char *dst, const char *src)
73static int getinet6sysctl __P((int)); 75{
 76 ssize_t len;
 77 char *odst, *p;
 78
 79 odst = dst;
 80 while (src && (len = strlen(src)) != 0) {
 81 p = strchr(src, '.');
 82 *dst++ = len = MIN(63, p == NULL ? len : p - src);
 83 memcpy(dst, src, len);
 84 dst += len;
 85 if (p == NULL)
 86 break;
 87 src = p + 1;
 88 }
 89 *dst++ = '\0';
 90
 91 return dst - odst;
 92}
74 93
75void 94void
76getconfig(intface) 95getconfig(intface)
77 char *intface; 96 char *intface;
78{ 97{
79 int stat, i; 98 int stat, c, i;
80 char tbuf[BUFSIZ]; 99 char tbuf[BUFSIZ];
81 struct rainfo *tmp; 100 struct rainfo *tmp;
82 long val; 101 int32_t val;
83 int64_t val64; 102 int64_t val64;
84 char buf[BUFSIZ]; 103 char buf[BUFSIZ];
85 char *bp = buf; 104 char *bp = buf;
86 char *addr, *flagstr; 105 char *addr, *flagstr, *ap;
87 static int forwarding = -1; 106 static int forwarding = -1;
 107 char entbuf[256], abuf[256];
88 108
89#define MUSTHAVE(var, cap) \ 109#define MUSTHAVE(var, cap) \
90 do { \ 110 do { \
91 int64_t t; \ 111 int64_t t; \
92 if ((t = agetnum(cap)) < 0) { \ 112 if ((t = agetnum(cap)) < 0) { \
93 fprintf(stderr, "rtadvd: need %s for interface %s\n", \ 113 fprintf(stderr, "rtadvd: need %s for interface %s\n", \
94 cap, intface); \ 114 cap, intface); \
95 exit(1); \ 115 exit(1); \
96 } \ 116 } \
97 var = t; \ 117 var = t; \
98 } while (0) 118 } while (0)
99#define MAYHAVE(var, cap, def) \ 119#define MAYHAVE(var, cap, def) \
100 do { \ 120 do { \
101 if ((var = agetnum(cap)) < 0) \ 121 if ((var = agetnum(cap)) < 0) \
102 var = def; \ 122 var = def; \
103 } while (0) 123 } while (0)
 124#define ELM_MALLOC(p,error_action) \
 125 do { \
 126 p = malloc(sizeof(*p)); \
 127 if (p == NULL) { \
 128 syslog(LOG_ERR, "<%s> malloc failed: %s", \
 129 __func__, strerror(errno)); \
 130 error_action; \
 131 } \
 132 memset(p, 0, sizeof(*p)); \
 133 } while(0)
 134
104 135
105 if ((stat = agetent(tbuf, intface)) <= 0) { 136 if ((stat = agetent(tbuf, intface)) <= 0) {
106 memset(tbuf, 0, sizeof(tbuf)); 137 memset(tbuf, 0, sizeof(tbuf));
107 syslog(LOG_INFO, 138 syslog(LOG_INFO,
108 "<%s> %s isn't defined in the configuration file" 139 "<%s> %s isn't defined in the configuration file"
109 " or the configuration file doesn't exist." 140 " or the configuration file doesn't exist."
110 " Treat it as default", 141 " Treat it as default",
111 __func__, intface); 142 __func__, intface);
112 } 143 }
113 144
114 tmp = (struct rainfo *)malloc(sizeof(*ralist)); 145 ELM_MALLOC(tmp, exit(1));
115 if (tmp == NULL) { 
116 syslog(LOG_INFO, "<%s> %s: can't allocate enough memory", 
117 __func__, intface); 
118 exit(1); 
119 } 
120 memset(tmp, 0, sizeof(*tmp)); 146 memset(tmp, 0, sizeof(*tmp));
121 tmp->prefix.next = tmp->prefix.prev = &tmp->prefix; 
122#ifdef ROUTEINFO 
123 tmp->route.next = tmp->route.prev = &tmp->route; 
124#endif 
125 147
126 /* check if we are allowed to forward packets (if not determined) */ 148 /* check if we are allowed to forward packets (if not determined) */
127 if (forwarding < 0) { 149 if (forwarding < 0) {
128 if ((forwarding = getinet6sysctl(IPV6CTL_FORWARDING)) < 0) 150 if ((forwarding = getinet6sysctl(IPV6CTL_FORWARDING)) < 0)
129 exit(1); 151 exit(1);
130 } 152 }
131 153
132 /* get interface information */ 154 /* get interface information */
133 if (agetflag("nolladdr")) 155 if (agetflag("nolladdr"))
134 tmp->advlinkopt = 0; 156 tmp->advlinkopt = 0;
135 else 157 else
136 tmp->advlinkopt = 1; 158 tmp->advlinkopt = 1;
137 if (tmp->advlinkopt) { 159 if (tmp->advlinkopt) {
@@ -148,42 +170,42 @@ getconfig(intface) @@ -148,42 +170,42 @@ getconfig(intface)
148 if ((tmp->phymtu = if_getmtu(intface)) == 0) { 170 if ((tmp->phymtu = if_getmtu(intface)) == 0) {
149 tmp->phymtu = IPV6_MMTU; 171 tmp->phymtu = IPV6_MMTU;
150 syslog(LOG_WARNING, 172 syslog(LOG_WARNING,
151 "<%s> can't get interface mtu of %s. Treat as %d", 173 "<%s> can't get interface mtu of %s. Treat as %d",
152 __func__, intface, IPV6_MMTU); 174 __func__, intface, IPV6_MMTU);
153 } 175 }
154 176
155 /* 177 /*
156 * set router configuration variables. 178 * set router configuration variables.
157 */ 179 */
158 MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL); 180 MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL);
159 if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) { 181 if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) {
160 syslog(LOG_ERR, 182 syslog(LOG_ERR,
161 "<%s> maxinterval (%ld) on %s is invalid " 183 "<%s> maxinterval (%d) on %s is invalid "
162 "(must be between %u and %u)", __func__, val, 184 "(must be between %u and %u)", __func__, val,
163 intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL); 185 intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
164 exit(1); 186 exit(1);
165 } 187 }
166 tmp->maxinterval = (u_int)val; 188 tmp->maxinterval = val;
167 MAYHAVE(val, "mininterval", tmp->maxinterval/3); 189 MAYHAVE(val, "mininterval", tmp->maxinterval/3);
168 if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) { 190 if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) {
169 syslog(LOG_ERR, 191 syslog(LOG_ERR,
170 "<%s> mininterval (%ld) on %s is invalid " 192 "<%s> mininterval (%d) on %s is invalid "
171 "(must be between %u and %d)", 193 "(must be between %u and %d)",
172 __func__, val, intface, MIN_MININTERVAL, 194 __func__, val, intface, MIN_MININTERVAL,
173 (tmp->maxinterval * 3) / 4); 195 (tmp->maxinterval * 3) / 4);
174 exit(1); 196 exit(1);
175 } 197 }
176 tmp->mininterval = (u_int)val; 198 tmp->mininterval = val;
177 199
178 MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT); 200 MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
179 tmp->hoplimit = val & 0xff; 201 tmp->hoplimit = val & 0xff;
180 202
181 if ((flagstr = (char *)agetstr("raflags", &bp))) { 203 if ((flagstr = (char *)agetstr("raflags", &bp))) {
182 val = 0; 204 val = 0;
183 if (strchr(flagstr, 'm')) 205 if (strchr(flagstr, 'm'))
184 val |= ND_RA_FLAG_MANAGED; 206 val |= ND_RA_FLAG_MANAGED;
185 if (strchr(flagstr, 'o')) 207 if (strchr(flagstr, 'o'))
186 val |= ND_RA_FLAG_OTHER; 208 val |= ND_RA_FLAG_OTHER;
187 if (strchr(flagstr, 'h')) 209 if (strchr(flagstr, 'h'))
188 val |= ND_RA_FLAG_RTPREF_HIGH; 210 val |= ND_RA_FLAG_RTPREF_HIGH;
189 if (strchr(flagstr, 'l')) { 211 if (strchr(flagstr, 'l')) {
@@ -203,133 +225,132 @@ getconfig(intface) @@ -203,133 +225,132 @@ getconfig(intface)
203#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ 225#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
204#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */ 226#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
205#endif 227#endif
206 tmp->rtpref = val & ND_RA_FLAG_RTPREF_MASK; 228 tmp->rtpref = val & ND_RA_FLAG_RTPREF_MASK;
207 if (tmp->rtpref == ND_RA_FLAG_RTPREF_RSV) { 229 if (tmp->rtpref == ND_RA_FLAG_RTPREF_RSV) {
208 syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s", 230 syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s",
209 __func__, tmp->rtpref, intface); 231 __func__, tmp->rtpref, intface);
210 exit(1); 232 exit(1);
211 } 233 }
212 234
213 MAYHAVE(val, "rltime", tmp->maxinterval * 3); 235 MAYHAVE(val, "rltime", tmp->maxinterval * 3);
214 if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) { 236 if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) {
215 syslog(LOG_ERR, 237 syslog(LOG_ERR,
216 "<%s> router lifetime (%ld) on %s is invalid " 238 "<%s> router lifetime (%d) on %s is invalid "
217 "(must be 0 or between %d and %d)", 239 "(must be 0 or between %d and %d)",
218 __func__, val, intface, 240 __func__, val, intface,
219 tmp->maxinterval, MAXROUTERLIFETIME); 241 tmp->maxinterval, MAXROUTERLIFETIME);
220 exit(1); 242 exit(1);
221 } 243 }
222 /* 244 /*
223 * Basically, hosts MUST NOT send Router Advertisement messages at any 245 * Basically, hosts MUST NOT send Router Advertisement messages at any
224 * time (RFC 2461, Section 6.2.3). However, it would sometimes be 246 * time (RFC 2461, Section 6.2.3). However, it would sometimes be
225 * useful to allow hosts to advertise some parameters such as prefix 247 * useful to allow hosts to advertise some parameters such as prefix
226 * information and link MTU. Thus, we allow hosts to invoke rtadvd 248 * information and link MTU. Thus, we allow hosts to invoke rtadvd
227 * only when router lifetime (on every advertising interface) is 249 * only when router lifetime (on every advertising interface) is
228 * explicitly set zero. (see also the above section) 250 * explicitly set zero. (see also the above section)
229 */ 251 */
230 if (val && forwarding == 0) { 252 if (val && forwarding == 0) {
231 syslog(LOG_ERR, 253 syslog(LOG_ERR,
232 "<%s> non zero router lifetime is specified for %s, " 254 "<%s> non zero router lifetime is specified for %s, "
233 "which must not be allowed for hosts. you must " 255 "which must not be allowed for hosts. you must "
234 "change router lifetime or enable IPv6 forwarding.", 256 "change router lifetime or enable IPv6 forwarding.",
235 __func__, intface); 257 __func__, intface);
236 exit(1); 258 exit(1);
237 } 259 }
238 tmp->lifetime = val & 0xffff; 260 tmp->lifetime = val & 0xffff;
239 261
240 MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME); 262 MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME);
241 if (val < 0 || val > MAXREACHABLETIME) { 263 if (val < 0 || val > MAXREACHABLETIME) {
242 syslog(LOG_ERR, 264 syslog(LOG_ERR,
243 "<%s> reachable time (%ld) on %s is invalid " 265 "<%s> reachable time (%d) on %s is invalid "
244 "(must be no greater than %d)", 266 "(must be no greater than %d)",
245 __func__, val, intface, MAXREACHABLETIME); 267 __func__, val, intface, MAXREACHABLETIME);
246 exit(1); 268 exit(1);
247 } 269 }
248 tmp->reachabletime = (u_int32_t)val; 270 tmp->reachabletime = (uint32_t)val;
249 271
250 MAYHAVE(val64, "retrans", DEF_ADVRETRANSTIMER); 272 MAYHAVE(val64, "retrans", DEF_ADVRETRANSTIMER);
251 if (val64 < 0 || val64 > 0xffffffff) { 273 if (val64 < 0 || val64 > 0xffffffff) {
252 syslog(LOG_ERR, "<%s> retrans time (%lld) on %s out of range", 274 syslog(LOG_ERR, "<%s> retrans time (%lld) on %s out of range",
253 __func__, (long long)val64, intface); 275 __func__, (long long)val64, intface);
254 exit(1); 276 exit(1);
255 } 277 }
256 tmp->retranstimer = (u_int32_t)val64; 278 tmp->retranstimer = (uint32_t)val64;
257 279
258 if (agetnum("hapref") != -1 || agetnum("hatime") != -1) { 280 if (agetnum("hapref") != -1 || agetnum("hatime") != -1) {
259 syslog(LOG_ERR, 281 syslog(LOG_ERR,
260 "<%s> mobile-ip6 configuration not supported", 282 "<%s> mobile-ip6 configuration not supported",
261 __func__); 283 __func__);
262 exit(1); 284 exit(1);
263 } 285 }
264 /* prefix information */ 286 /* prefix information */
265 287
266 /* 288 /*
267 * This is an implementation specific parameter to consider 289 * This is an implementation specific parameter to consider
268 * link propagation delays and poorly synchronized clocks when 290 * link propagation delays and poorly synchronized clocks when
269 * checking consistency of advertised lifetimes. 291 * checking consistency of advertised lifetimes.
270 */ 292 */
271 MAYHAVE(val, "clockskew", 0); 293 MAYHAVE(val, "clockskew", 0);
272 tmp->clockskew = val; 294 tmp->clockskew = val;
273 295
274 tmp->pfxs = 0; 296 tmp->pfxs++;
 297 TAILQ_INIT(&tmp->prefix);
275 for (i = -1; i < MAXPREFIX; i++) { 298 for (i = -1; i < MAXPREFIX; i++) {
276 struct prefix *pfx; 299 struct prefix *pfx;
277 char entbuf[256]; 
278 300
279 makeentry(entbuf, sizeof(entbuf), i, "addr"); 301 makeentry(entbuf, sizeof(entbuf), i, "addr");
280 addr = (char *)agetstr(entbuf, &bp); 302 addr = (char *)agetstr(entbuf, &bp);
281 if (addr == NULL) 303 if (addr == NULL)
282 continue; 304 continue;
283 305
284 /* allocate memory to store prefix information */ 306 /* allocate memory to store prefix information */
285 if ((pfx = malloc(sizeof(struct prefix))) == NULL) { 307 if ((pfx = malloc(sizeof(struct prefix))) == NULL) {
286 syslog(LOG_ERR, 308 syslog(LOG_ERR,
287 "<%s> can't allocate enough memory", 309 "<%s> can't allocate enough memory",
288 __func__); 310 __func__);
289 exit(1); 311 exit(1);
290 } 312 }
291 memset(pfx, 0, sizeof(*pfx)); 313 memset(pfx, 0, sizeof(*pfx));
292 314
293 /* link into chain */ 315 TAILQ_INSERT_TAIL(&tmp->prefix, pfx, next);
294 insque(pfx, &tmp->prefix); 
295 pfx->rainfo = tmp; 
296 tmp->pfxs++; 316 tmp->pfxs++;
 317 pfx->rainfo = tmp;
297 318
298 pfx->origin = PREFIX_FROM_CONFIG; 319 pfx->origin = PREFIX_FROM_CONFIG;
299 320
300 if (inet_pton(AF_INET6, addr, &pfx->prefix) != 1) { 321 if (inet_pton(AF_INET6, addr, &pfx->prefix) != 1) {
301 syslog(LOG_ERR, 322 syslog(LOG_ERR,
302 "<%s> inet_pton failed for %s", 323 "<%s> inet_pton failed for %s",
303 __func__, addr); 324 __func__, addr);
304 exit(1); 325 exit(1);
305 } 326 }
306 if (IN6_IS_ADDR_MULTICAST(&pfx->prefix)) { 327 if (IN6_IS_ADDR_MULTICAST(&pfx->prefix)) {
307 syslog(LOG_ERR, 328 syslog(LOG_ERR,
308 "<%s> multicast prefix (%s) must " 329 "<%s> multicast prefix (%s) must "
309 "not be advertised on %s", 330 "not be advertised on %s",
310 __func__, addr, intface); 331 __func__, addr, intface);
311 exit(1); 332 exit(1);
312 } 333 }
313 if (IN6_IS_ADDR_LINKLOCAL(&pfx->prefix)) 334 if (IN6_IS_ADDR_LINKLOCAL(&pfx->prefix))
314 syslog(LOG_NOTICE, 335 syslog(LOG_NOTICE,
315 "<%s> link-local prefix (%s) will be" 336 "<%s> link-local prefix (%s) will be"
316 " advertised on %s", 337 " advertised on %s",
317 __func__, addr, intface); 338 __func__, addr, intface);
318 339
319 makeentry(entbuf, sizeof(entbuf), i, "prefixlen"); 340 makeentry(entbuf, sizeof(entbuf), i, "prefixlen");
320 MAYHAVE(val, entbuf, 64); 341 MAYHAVE(val, entbuf, 64);
321 if (val < 0 || val > 128) { 342 if (val < 0 || val > 128) {
322 syslog(LOG_ERR, "<%s> prefixlen (%ld) for %s " 343 syslog(LOG_ERR, "<%s> prefixlen (%d) for %s "
323 "on %s out of range", 344 "on %s out of range",
324 __func__, val, addr, intface); 345 __func__, val, addr, intface);
325 exit(1); 346 exit(1);
326 } 347 }
327 pfx->prefixlen = (int)val; 348 pfx->prefixlen = (int)val;
328 349
329 makeentry(entbuf, sizeof(entbuf), i, "pinfoflags"); 350 makeentry(entbuf, sizeof(entbuf), i, "pinfoflags");
330 if ((flagstr = (char *)agetstr(entbuf, &bp))) { 351 if ((flagstr = (char *)agetstr(entbuf, &bp))) {
331 val = 0; 352 val = 0;
332 if (strchr(flagstr, 'l')) 353 if (strchr(flagstr, 'l'))
333 val |= ND_OPT_PI_FLAG_ONLINK; 354 val |= ND_OPT_PI_FLAG_ONLINK;
334 if (strchr(flagstr, 'a')) 355 if (strchr(flagstr, 'a'))
335 val |= ND_OPT_PI_FLAG_AUTO; 356 val |= ND_OPT_PI_FLAG_AUTO;
@@ -339,144 +360,136 @@ getconfig(intface) @@ -339,144 +360,136 @@ getconfig(intface)
339 } 360 }
340 pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK; 361 pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
341 pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO; 362 pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
342 363
343 makeentry(entbuf, sizeof(entbuf), i, "vltime"); 364 makeentry(entbuf, sizeof(entbuf), i, "vltime");
344 MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME); 365 MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
345 if (val64 < 0 || val64 > 0xffffffff) { 366 if (val64 < 0 || val64 > 0xffffffff) {
346 syslog(LOG_ERR, "<%s> vltime (%lld) for " 367 syslog(LOG_ERR, "<%s> vltime (%lld) for "
347 "%s/%d on %s is out of range", 368 "%s/%d on %s is out of range",
348 __func__, (long long)val64, 369 __func__, (long long)val64,
349 addr, pfx->prefixlen, intface); 370 addr, pfx->prefixlen, intface);
350 exit(1); 371 exit(1);
351 } 372 }
352 pfx->validlifetime = (u_int32_t)val64; 373 pfx->validlifetime = (uint32_t)val64;
353 374
354 makeentry(entbuf, sizeof(entbuf), i, "vltimedecr"); 375 makeentry(entbuf, sizeof(entbuf), i, "vltimedecr");
355 if (agetflag(entbuf)) { 376 if (agetflag(entbuf)) {
356 struct timeval now; 377 struct timeval now;
357 gettimeofday(&now, 0); 378 gettimeofday(&now, 0);
358 pfx->vltimeexpire = 379 pfx->vltimeexpire =
359 now.tv_sec + pfx->validlifetime; 380 now.tv_sec + pfx->validlifetime;
360 } 381 }
361 382
362 makeentry(entbuf, sizeof(entbuf), i, "pltime"); 383 makeentry(entbuf, sizeof(entbuf), i, "pltime");
363 MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME); 384 MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME);
364 if (val64 < 0 || val64 > 0xffffffff) { 385 if (val64 < 0 || val64 > 0xffffffff) {
365 syslog(LOG_ERR, 386 syslog(LOG_ERR,
366 "<%s> pltime (%lld) for %s/%d on %s " 387 "<%s> pltime (%lld) for %s/%d on %s "
367 "is out of range", 388 "is out of range",
368 __func__, (long long)val64, 389 __func__, (long long)val64,
369 addr, pfx->prefixlen, intface); 390 addr, pfx->prefixlen, intface);
370 exit(1); 391 exit(1);
371 } 392 }
372 pfx->preflifetime = (u_int32_t)val64; 393 pfx->preflifetime = (uint32_t)val64;
373 394
374 makeentry(entbuf, sizeof(entbuf), i, "pltimedecr"); 395 makeentry(entbuf, sizeof(entbuf), i, "pltimedecr");
375 if (agetflag(entbuf)) { 396 if (agetflag(entbuf)) {
376 struct timeval now; 397 struct timeval now;
377 gettimeofday(&now, 0); 398 gettimeofday(&now, 0);
378 pfx->pltimeexpire = 399 pfx->pltimeexpire =
379 now.tv_sec + pfx->preflifetime; 400 now.tv_sec + pfx->preflifetime;
380 } 401 }
381 } 402 }
382 if (tmp->pfxs == 0) 403 if (TAILQ_FIRST(&tmp->prefix) == NULL)
383 get_prefix(tmp); 404 get_prefix(tmp);
384 405
385 MAYHAVE(val, "mtu", 0); 406 MAYHAVE(val64, "mtu", 0);
386 if (val < 0 || val > 0xffffffff) { 407 if (val64 < 0 || val64 > 0xffffffff) {
387 syslog(LOG_ERR, 408 syslog(LOG_ERR,
388 "<%s> mtu (%ld) on %s out of range", 409 "<%s> mtu (%" PRIi64 ") on %s out of range",
389 __func__, val, intface); 410 __func__, val64, intface);
390 exit(1); 411 exit(1);
391 } 412 }
392 tmp->linkmtu = (u_int32_t)val; 413 tmp->linkmtu = (uint32_t)val64;
393 if (tmp->linkmtu == 0) { 414 if (tmp->linkmtu == 0) {
394 char *mtustr; 415 char *mtustr;
395 416
396 if ((mtustr = (char *)agetstr("mtu", &bp)) && 417 if ((mtustr = (char *)agetstr("mtu", &bp)) &&
397 strcmp(mtustr, "auto") == 0) 418 strcmp(mtustr, "auto") == 0)
398 tmp->linkmtu = tmp->phymtu; 419 tmp->linkmtu = tmp->phymtu;
399 } 420 }
400 else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) { 421 else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) {
401 syslog(LOG_ERR, 422 syslog(LOG_ERR,
402 "<%s> advertised link mtu (%lu) on %s is invalid (must " 423 "<%s> advertised link mtu (%d) on %s is invalid (must "
403 "be between least MTU (%d) and physical link MTU (%d)", 424 "be between least MTU (%d) and physical link MTU (%d)",
404 __func__, (unsigned long)tmp->linkmtu, intface, 425 __func__, tmp->linkmtu, intface,
405 IPV6_MMTU, tmp->phymtu); 426 IPV6_MMTU, tmp->phymtu);
406 exit(1); 427 exit(1);
407 } 428 }
408 429
409#ifdef SIOCSIFINFO_IN6 430#ifdef SIOCSIFINFO_IN6
410 { 431 {
411 struct in6_ndireq ndi; 432 struct in6_ndireq ndi;
412 int s; 433 int s;
413 434
414 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 435 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
415 syslog(LOG_ERR, "<%s> socket: %s", __func__, 436 syslog(LOG_ERR, "<%s> socket: %s", __func__,
416 strerror(errno)); 437 strerror(errno));
417 exit(1); 438 exit(1);
418 } 439 }
419 memset(&ndi, 0, sizeof(ndi)); 440 memset(&ndi, 0, sizeof(ndi));
420 strncpy(ndi.ifname, intface, IFNAMSIZ); 441 strncpy(ndi.ifname, intface, IFNAMSIZ);
421 if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&ndi) < 0) { 442 if (ioctl(s, SIOCGIFINFO_IN6, &ndi) < 0) {
422 syslog(LOG_INFO, "<%s> ioctl:SIOCGIFINFO_IN6 at %s: %s", 443 syslog(LOG_INFO, "<%s> ioctl:SIOCGIFINFO_IN6 at %s: %s",
423 __func__, intface, strerror(errno)); 444 __func__, intface, strerror(errno));
424 } 445 }
425 446
426 /* reflect the RA info to the host variables in kernel */ 447 /* reflect the RA info to the host variables in kernel */
427 ndi.ndi.chlim = tmp->hoplimit; 448 ndi.ndi.chlim = tmp->hoplimit;
428 ndi.ndi.retrans = tmp->retranstimer; 449 ndi.ndi.retrans = tmp->retranstimer;
429 ndi.ndi.basereachable = tmp->reachabletime; 450 ndi.ndi.basereachable = tmp->reachabletime;
430 if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&ndi) < 0) { 451 if (ioctl(s, SIOCSIFINFO_IN6, &ndi) < 0) {
431 syslog(LOG_INFO, "<%s> ioctl:SIOCSIFINFO_IN6 at %s: %s", 452 syslog(LOG_INFO, "<%s> ioctl:SIOCSIFINFO_IN6 at %s: %s",
432 __func__, intface, strerror(errno)); 453 __func__, intface, strerror(errno));
433 } 454 }
434 close(s); 455 close(s);
435 } 456 }
436#endif 457#endif
437 458
438 /* route information */ 459 /* route information */
439#ifdef ROUTEINFO 460 TAILQ_INIT(&tmp->route);
440 tmp->routes = 0; 
441 for (i = -1; i < MAXROUTE; i++) { 461 for (i = -1; i < MAXROUTE; i++) {
442 struct rtinfo *rti; 462 struct rtinfo *rti;
443 char entbuf[256], oentbuf[256]; 463 char oentbuf[256];
444 464
445 makeentry(entbuf, sizeof(entbuf), i, "rtprefix"); 465 makeentry(entbuf, sizeof(entbuf), i, "rtprefix");
446 addr = (char *)agetstr(entbuf, &bp); 466 addr = (char *)agetstr(entbuf, &bp);
447 if (addr == NULL) { 467 if (addr == NULL) {
448 makeentry(oentbuf, sizeof(oentbuf), i, "rtrprefix"); 468 makeentry(oentbuf, sizeof(oentbuf), i, "rtrprefix");
449 addr = (char *)agetstr(oentbuf, &bp); 469 addr = (char *)agetstr(oentbuf, &bp);
450 if (addr) { 470 if (addr) {
451 fprintf(stderr, "%s was obsoleted. Use %s.\n", 471 fprintf(stderr, "%s was obsoleted. Use %s.\n",
452 oentbuf, entbuf); 472 oentbuf, entbuf);
453 } 473 }
454 } 474 }
455 if (addr == NULL) 475 if (addr == NULL)
456 continue; 476 continue;
457 477
458 /* allocate memory to store prefix information */ 478 ELM_MALLOC(rti, exit(1));
459 if ((rti = malloc(sizeof(struct rtinfo))) == NULL) { 
460 syslog(LOG_ERR, 
461 "<%s> can't allocate enough memory", 
462 __func__); 
463 exit(1); 
464 } 
465 memset(rti, 0, sizeof(*rti)); 479 memset(rti, 0, sizeof(*rti));
466 480
467 /* link into chain */ 481 /* link into chain */
468 insque(rti, &tmp->route); 482 TAILQ_INSERT_TAIL(&tmp->route, rti, next);
469 tmp->routes++; 
470 483
471 if (inet_pton(AF_INET6, addr, &rti->prefix) != 1) { 484 if (inet_pton(AF_INET6, addr, &rti->prefix) != 1) {
472 syslog(LOG_ERR, "<%s> inet_pton failed for %s", 485 syslog(LOG_ERR, "<%s> inet_pton failed for %s",
473 __func__, addr); 486 __func__, addr);
474 exit(1); 487 exit(1);
475 } 488 }
476#if 0 489#if 0
477 /* 490 /*
478 * XXX: currently there's no restriction in route information 491 * XXX: currently there's no restriction in route information
479 * prefix according to 492 * prefix according to
480 * draft-ietf-ipngwg-router-selection-00.txt. 493 * draft-ietf-ipngwg-router-selection-00.txt.
481 * However, I think the similar restriction be necessary. 494 * However, I think the similar restriction be necessary.
482 */ 495 */
@@ -500,27 +513,27 @@ getconfig(intface) @@ -500,27 +513,27 @@ getconfig(intface)
500 makeentry(entbuf, sizeof(entbuf), i, "rtplen"); 513 makeentry(entbuf, sizeof(entbuf), i, "rtplen");
501 /* XXX: 256 is a magic number for compatibility check. */ 514 /* XXX: 256 is a magic number for compatibility check. */
502 MAYHAVE(val, entbuf, 256); 515 MAYHAVE(val, entbuf, 256);
503 if (val == 256) { 516 if (val == 256) {
504 makeentry(oentbuf, sizeof(oentbuf), i, "rtrplen"); 517 makeentry(oentbuf, sizeof(oentbuf), i, "rtrplen");
505 MAYHAVE(val, oentbuf, 256); 518 MAYHAVE(val, oentbuf, 256);
506 if (val != 256) { 519 if (val != 256) {
507 fprintf(stderr, "%s was obsoleted. Use %s.\n", 520 fprintf(stderr, "%s was obsoleted. Use %s.\n",
508 oentbuf, entbuf); 521 oentbuf, entbuf);
509 } else 522 } else
510 val = 64; 523 val = 64;
511 } 524 }
512 if (val < 0 || val > 128) { 525 if (val < 0 || val > 128) {
513 syslog(LOG_ERR, "<%s> prefixlen (%ld) for %s on %s " 526 syslog(LOG_ERR, "<%s> prefixlen (%d) for %s on %s "
514 "out of range", 527 "out of range",
515 __func__, val, addr, intface); 528 __func__, val, addr, intface);
516 exit(1); 529 exit(1);
517 } 530 }
518 rti->prefixlen = (int)val; 531 rti->prefixlen = (int)val;
519 532
520 makeentry(entbuf, sizeof(entbuf), i, "rtflags"); 533 makeentry(entbuf, sizeof(entbuf), i, "rtflags");
521 if ((flagstr = (char *)agetstr(entbuf, &bp))) { 534 if ((flagstr = (char *)agetstr(entbuf, &bp))) {
522 val = 0; 535 val = 0;
523 if (strchr(flagstr, 'h')) 536 if (strchr(flagstr, 'h'))
524 val |= ND_RA_FLAG_RTPREF_HIGH; 537 val |= ND_RA_FLAG_RTPREF_HIGH;
525 if (strchr(flagstr, 'l')) { 538 if (strchr(flagstr, 'l')) {
526 if ((val & ND_RA_FLAG_RTPREF_HIGH)) { 539 if ((val & ND_RA_FLAG_RTPREF_HIGH)) {
@@ -569,73 +582,149 @@ getconfig(intface) @@ -569,73 +582,149 @@ getconfig(intface)
569 } else { 582 } else {
570 fprintf(stderr, "%s should be specified " 583 fprintf(stderr, "%s should be specified "
571 "for interface %s.\n", 584 "for interface %s.\n",
572 entbuf, intface); 585 entbuf, intface);
573 val64 = tmp->lifetime; 586 val64 = tmp->lifetime;
574 } 587 }
575 } 588 }
576 if (val64 < 0 || val64 > 0xffffffff) { 589 if (val64 < 0 || val64 > 0xffffffff) {
577 syslog(LOG_ERR, "<%s> route lifetime (%lld) for " 590 syslog(LOG_ERR, "<%s> route lifetime (%lld) for "
578 "%s/%d on %s out of range", __func__, 591 "%s/%d on %s out of range", __func__,
579 (long long)val64, addr, rti->prefixlen, intface); 592 (long long)val64, addr, rti->prefixlen, intface);
580 exit(1); 593 exit(1);
581 } 594 }
582 rti->ltime = (u_int32_t)val64; 595 rti->ltime = (uint32_t)val64;
 596 }
 597
 598 /* RDNSS */
 599 TAILQ_INIT(&tmp->rdnss);
 600 for (i = -1; i < MAXRDNSS; i++) {
 601 struct rdnss *rdnss;
 602 struct rdnss_addr *rdnsa;
 603
 604 makeentry(entbuf, sizeof(entbuf), i, "rdnss");
 605 addr = (char *)agetstr(entbuf, &bp);
 606 if (addr == NULL)
 607 continue;
 608
 609 ELM_MALLOC(rdnss, exit(1));
 610 TAILQ_INIT(&rdnss->list);
 611
 612 for (ap = addr; ap - addr < (ssize_t)strlen(addr); ap += c+1) {
 613 c = strcspn(ap, ",");
 614 strncpy(abuf, ap, c);
 615 abuf[c] = '\0';
 616 ELM_MALLOC(rdnsa, exit(1));
 617 if (inet_pton(AF_INET6, abuf, &rdnsa->addr) != 1) {
 618 syslog(LOG_ERR, "<%s> inet_pton failed for %s",
 619 __func__, addr);
 620 exit(1);
 621 }
 622 TAILQ_INSERT_TAIL(&rdnss->list, rdnsa, next);
 623 }
 624
 625 makeentry(entbuf, sizeof(entbuf), i, "rdnssltime");
 626 MAYHAVE(val64, entbuf, tmp->maxinterval * 3 / 2);
 627 if (val64 < tmp->maxinterval ||
 628 val64 > tmp->maxinterval * 2)
 629 {
 630 syslog(LOG_ERR, "<%s> %s (%lld) on %s is invalid",
 631 __func__, entbuf, (long long)val64, intface);
 632 exit(1);
 633 }
 634 rdnss->lifetime = (uint32_t)val64;
 635
 636 TAILQ_INSERT_TAIL(&tmp->rdnss, rdnss, next);
 637 }
 638
 639 /* DNSSL */
 640 TAILQ_INIT(&tmp->dnssl);
 641 for (i = -1; i < MAXDNSSL; i++) {
 642 struct dnssl *dnssl;
 643 struct dnssl_domain *dnsd;
 644
 645 makeentry(entbuf, sizeof(entbuf), i, "dnssl");
 646 addr = (char *)agetstr(entbuf, &bp);
 647 if (addr == NULL)
 648 continue;
 649
 650 ELM_MALLOC(dnssl, exit(1));
 651 TAILQ_INIT(&dnssl->list);
 652
 653 for (ap = addr; ap - addr < (ssize_t)strlen(addr); ap += c+1) {
 654 c = strcspn(ap, ",");
 655 strncpy(abuf, ap, c);
 656 abuf[c] = '\0';
 657 ELM_MALLOC(dnsd, exit(1));
 658 dnsd->len = encode_domain(dnsd->domain, abuf);
 659 TAILQ_INSERT_TAIL(&dnssl->list, dnsd, next);
 660 }
 661
 662 makeentry(entbuf, sizeof(entbuf), i, "dnsslltime");
 663 MAYHAVE(val64, entbuf, tmp->maxinterval * 3 / 2);
 664 if (val64 < tmp->maxinterval ||
 665 val64 > tmp->maxinterval * 2)
 666 {
 667 syslog(LOG_ERR, "<%s> %s (%lld) on %s is invalid",
 668 __func__, entbuf, (long long)val64, intface);
 669 exit(1);
 670 }
 671 dnssl->lifetime = (uint32_t)val64;
 672
 673 TAILQ_INSERT_TAIL(&tmp->dnssl, dnssl, next);
583 } 674 }
584#endif 
585 675
586 /* okey */ 676 /* okey */
587 tmp->next = ralist; 677 TAILQ_INSERT_TAIL(&ralist, tmp, next);
588 ralist = tmp; 
589 678
590 /* construct the sending packet */ 679 /* construct the sending packet */
591 make_packet(tmp); 680 make_packet(tmp);
592 681
593 /* set timer */ 682 /* set timer */
594 tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update, 683 tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
595 tmp, tmp); 684 tmp, tmp);
596 ra_timer_update((void *)tmp, &tmp->timer->tm); 685 ra_timer_update((void *)tmp, &tmp->timer->tm);
597 rtadvd_set_timer(&tmp->timer->tm, tmp->timer); 686 rtadvd_set_timer(&tmp->timer->tm, tmp->timer);
598} 687}
599 688
600void 689void
601get_prefix(struct rainfo *rai) 690get_prefix(struct rainfo *rai)
602{ 691{
603 struct ifaddrs *ifap, *ifa; 692 struct ifaddrs *ifap, *ifa;
604 struct prefix *pp; 693 struct prefix *pp;
605 struct in6_addr *a; 694 struct in6_addr *a;
606 u_char *p, *ep, *m, *lim; 695 unsigned char *p, *ep, *m, *lim;
607 char ntopbuf[INET6_ADDRSTRLEN]; 696 char ntopbuf[INET6_ADDRSTRLEN];
608 697
609 if (getifaddrs(&ifap) < 0) { 698 if (getifaddrs(&ifap) < 0) {
610 syslog(LOG_ERR, 699 syslog(LOG_ERR,
611 "<%s> can't get interface addresses", 700 "<%s> can't get interface addresses",
612 __func__); 701 __func__);
613 exit(1); 702 exit(1);
614 } 703 }
615 704
616 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 705 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
617 int plen; 706 int plen;
618 707
619 if (strcmp(ifa->ifa_name, rai->ifname) != 0) 708 if (strcmp(ifa->ifa_name, rai->ifname) != 0)
620 continue; 709 continue;
621 if (ifa->ifa_addr->sa_family != AF_INET6) 710 if (ifa->ifa_addr->sa_family != AF_INET6)
622 continue; 711 continue;
623 a = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; 712 a = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
624 if (IN6_IS_ADDR_LINKLOCAL(a)) 713 if (IN6_IS_ADDR_LINKLOCAL(a))
625 continue; 714 continue;
626 /* get prefix length */ 715 /* get prefix length */
627 m = (u_char *)&((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; 716 m = (unsigned char *)&((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
628 lim = (u_char *)(ifa->ifa_netmask) + ifa->ifa_netmask->sa_len; 717 lim = (unsigned char *)(ifa->ifa_netmask) + ifa->ifa_netmask->sa_len;
629 plen = prefixlen(m, lim); 718 plen = prefixlen(m, lim);
630 if (plen <= 0 || plen > 128) { 719 if (plen <= 0 || plen > 128) {
631 syslog(LOG_ERR, "<%s> failed to get prefixlen " 720 syslog(LOG_ERR, "<%s> failed to get prefixlen "
632 "or prefix is invalid", 721 "or prefix is invalid",
633 __func__); 722 __func__);
634 exit(1); 723 exit(1);
635 } 724 }
636 if (plen == 128) /* XXX */ 725 if (plen == 128) /* XXX */
637 continue; 726 continue;
638 if (find_prefix(rai, a, plen)) { 727 if (find_prefix(rai, a, plen)) {
639 /* ignore a duplicated prefix. */ 728 /* ignore a duplicated prefix. */
640 continue; 729 continue;
641 } 730 }
@@ -644,66 +733,59 @@ get_prefix(struct rainfo *rai) @@ -644,66 +733,59 @@ get_prefix(struct rainfo *rai)
644 if ((pp = malloc(sizeof(*pp))) == NULL) { 733 if ((pp = malloc(sizeof(*pp))) == NULL) {
645 syslog(LOG_ERR, 734 syslog(LOG_ERR,
646 "<%s> can't get allocate buffer for prefix", 735 "<%s> can't get allocate buffer for prefix",
647 __func__); 736 __func__);
648 exit(1); 737 exit(1);
649 } 738 }
650 memset(pp, 0, sizeof(*pp)); 739 memset(pp, 0, sizeof(*pp));
651 740
652 /* set prefix, sweep bits outside of prefixlen */ 741 /* set prefix, sweep bits outside of prefixlen */
653 pp->prefixlen = plen; 742 pp->prefixlen = plen;
654 memcpy(&pp->prefix, a, sizeof(*a)); 743 memcpy(&pp->prefix, a, sizeof(*a));
655 if (1) 744 if (1)
656 { 745 {
657 p = (u_char *)&pp->prefix; 746 p = (unsigned char *)&pp->prefix;
658 ep = (u_char *)(&pp->prefix + 1); 747 ep = (unsigned char *)(&pp->prefix + 1);
659 while (m < lim && p < ep) 748 while (m < lim && p < ep)
660 *p++ &= *m++; 749 *p++ &= *m++;
661 while (p < ep) 750 while (p < ep)
662 *p++ = 0x00; 751 *p++ = 0x00;
663 } 752 }
664 if (!inet_ntop(AF_INET6, &pp->prefix, ntopbuf, 753 if (!inet_ntop(AF_INET6, &pp->prefix, ntopbuf,
665 sizeof(ntopbuf))) { 754 sizeof(ntopbuf))) {
666 syslog(LOG_ERR, "<%s> inet_ntop failed", __func__); 755 syslog(LOG_ERR, "<%s> inet_ntop failed", __func__);
667 exit(1); 756 exit(1);
668 } 757 }
669 syslog(LOG_DEBUG, 758 syslog(LOG_DEBUG,
670 "<%s> add %s/%d to prefix list on %s", 759 "<%s> add %s/%d to prefix list on %s",
671 __func__, ntopbuf, pp->prefixlen, rai->ifname); 760 __func__, ntopbuf, pp->prefixlen, rai->ifname);
672 761
673 /* set other fields with protocol defaults */ 762 /* set other fields with protocol defaults */
674 pp->validlifetime = DEF_ADVVALIDLIFETIME; 763 pp->validlifetime = DEF_ADVVALIDLIFETIME;
675 pp->preflifetime = DEF_ADVPREFERREDLIFETIME; 764 pp->preflifetime = DEF_ADVPREFERREDLIFETIME;
676 pp->onlinkflg = 1; 765 pp->onlinkflg = 1;
677 pp->autoconfflg = 1; 766 pp->autoconfflg = 1;
678 pp->origin = PREFIX_FROM_KERNEL; 767 pp->origin = PREFIX_FROM_KERNEL;
679 pp->rainfo = rai; 768 pp->rainfo = rai;
680 769
681 /* link into chain */ 770 /* link into chain */
682 insque(pp, &rai->prefix); 771 TAILQ_INSERT_TAIL(&rai->prefix, pp, next);
683 
684 /* counter increment */ 
685 rai->pfxs++; 
686 } 772 }
687 773
688 freeifaddrs(ifap); 774 freeifaddrs(ifap);
689} 775}
690 776
691static void 777static void
692makeentry(buf, len, id, string) 778makeentry(char *buf, size_t len, int id, const char *string)
693 char *buf; 
694 size_t len; 
695 int id; 
696 char *string; 
697{ 779{
698 780
699 if (id < 0) 781 if (id < 0)
700 strlcpy(buf, string, len); 782 strlcpy(buf, string, len);
701 else 783 else
702 snprintf(buf, len, "%s%d", string, id); 784 snprintf(buf, len, "%s%d", string, id);
703} 785}
704 786
705/* 787/*
706 * Add a prefix to the list of specified interface and reconstruct 788 * Add a prefix to the list of specified interface and reconstruct
707 * the outgoing packet. 789 * the outgoing packet.
708 * The prefix must not be in the list. 790 * The prefix must not be in the list.
709 * XXX: other parameters of the prefix(e.g. lifetime) should be 791 * XXX: other parameters of the prefix(e.g. lifetime) should be
@@ -719,63 +801,63 @@ add_prefix(struct rainfo *rai, struct in @@ -719,63 +801,63 @@ add_prefix(struct rainfo *rai, struct in
719 syslog(LOG_ERR, "<%s> memory allocation failed", 801 syslog(LOG_ERR, "<%s> memory allocation failed",
720 __func__); 802 __func__);
721 return; /* XXX: error or exit? */ 803 return; /* XXX: error or exit? */
722 } 804 }
723 memset(prefix, 0, sizeof(*prefix)); 805 memset(prefix, 0, sizeof(*prefix));
724 prefix->prefix = ipr->ipr_prefix.sin6_addr; 806 prefix->prefix = ipr->ipr_prefix.sin6_addr;
725 prefix->prefixlen = ipr->ipr_plen; 807 prefix->prefixlen = ipr->ipr_plen;
726 prefix->validlifetime = ipr->ipr_vltime; 808 prefix->validlifetime = ipr->ipr_vltime;
727 prefix->preflifetime = ipr->ipr_pltime; 809 prefix->preflifetime = ipr->ipr_pltime;
728 prefix->onlinkflg = ipr->ipr_raf_onlink; 810 prefix->onlinkflg = ipr->ipr_raf_onlink;
729 prefix->autoconfflg = ipr->ipr_raf_auto; 811 prefix->autoconfflg = ipr->ipr_raf_auto;
730 prefix->origin = PREFIX_FROM_DYNAMIC; 812 prefix->origin = PREFIX_FROM_DYNAMIC;
731 813
732 insque(prefix, &rai->prefix); 
733 prefix->rainfo = rai; 814 prefix->rainfo = rai;
 815 TAILQ_INSERT_TAIL(&rai->prefix, prefix, next);
 816 rai->pfxs++;
734 817
735 syslog(LOG_DEBUG, "<%s> new prefix %s/%d was added on %s", 818 syslog(LOG_DEBUG, "<%s> new prefix %s/%d was added on %s",
736 __func__, inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr, 819 __func__, inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr,
737 ntopbuf, INET6_ADDRSTRLEN), 820 ntopbuf, INET6_ADDRSTRLEN),
738 ipr->ipr_plen, rai->ifname); 821 ipr->ipr_plen, rai->ifname);
739 822
740 /* free the previous packet */ 823 /* free the previous packet */
741 free(rai->ra_data); 824 free(rai->ra_data);
742 rai->ra_data = NULL; 825 rai->ra_data = NULL;
743 826
744 /* reconstruct the packet */ 827 /* reconstruct the packet */
745 rai->pfxs++; 
746 make_packet(rai); 828 make_packet(rai);
747} 829}
748 830
749/* 831/*
750 * Delete a prefix to the list of specified interface and reconstruct 832 * Delete a prefix to the list of specified interface and reconstruct
751 * the outgoing packet. 833 * the outgoing packet.
752 * The prefix must be in the list. 834 * The prefix must be in the list.
753 */ 835 */
754void 836void
755delete_prefix(struct prefix *prefix) 837delete_prefix(struct prefix *prefix)
756{ 838{
757 char ntopbuf[INET6_ADDRSTRLEN]; 839 char ntopbuf[INET6_ADDRSTRLEN];
758 struct rainfo *rai = prefix->rainfo; 840 struct rainfo *rai = prefix->rainfo;
759 841
760 remque(prefix); 842 TAILQ_REMOVE(&rai->prefix, prefix, next);
 843 rai->pfxs--;
761 syslog(LOG_DEBUG, "<%s> prefix %s/%d was deleted on %s", 844 syslog(LOG_DEBUG, "<%s> prefix %s/%d was deleted on %s",
762 __func__, inet_ntop(AF_INET6, &prefix->prefix, 845 __func__, inet_ntop(AF_INET6, &prefix->prefix,
763 ntopbuf, INET6_ADDRSTRLEN), 846 ntopbuf, INET6_ADDRSTRLEN),
764 prefix->prefixlen, rai->ifname); 847 prefix->prefixlen, rai->ifname);
765 if (prefix->timer) 848 if (prefix->timer)
766 rtadvd_remove_timer(&prefix->timer); 849 rtadvd_remove_timer(&prefix->timer);
767 free(prefix); 850 free(prefix);
768 rai->pfxs--; 
769} 851}
770 852
771void 853void
772invalidate_prefix(struct prefix *prefix) 854invalidate_prefix(struct prefix *prefix)
773{ 855{
774 char ntopbuf[INET6_ADDRSTRLEN]; 856 char ntopbuf[INET6_ADDRSTRLEN];
775 struct timeval timo; 857 struct timeval timo;
776 struct rainfo *rai = prefix->rainfo; 858 struct rainfo *rai = prefix->rainfo;
777 859
778 if (prefix->timer) { /* sanity check */ 860 if (prefix->timer) { /* sanity check */
779 syslog(LOG_ERR, 861 syslog(LOG_ERR,
780 "<%s> assumption failure: timer already exists", 862 "<%s> assumption failure: timer already exists",
781 __func__); 863 __func__);
@@ -837,27 +919,27 @@ update_prefix(struct prefix * prefix) @@ -837,27 +919,27 @@ update_prefix(struct prefix * prefix)
837 */ 919 */
838static int 920static int
839init_prefix(struct in6_prefixreq *ipr) 921init_prefix(struct in6_prefixreq *ipr)
840{ 922{
841#if 0 923#if 0
842 int s; 924 int s;
843 925
844 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 926 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
845 syslog(LOG_ERR, "<%s> socket: %s", __func__, 927 syslog(LOG_ERR, "<%s> socket: %s", __func__,
846 strerror(errno)); 928 strerror(errno));
847 exit(1); 929 exit(1);
848 } 930 }
849 931
850 if (ioctl(s, SIOCGIFPREFIX_IN6, (caddr_t)ipr) < 0) { 932 if (ioctl(s, SIOCGIFPREFIX_IN6, ipr) < 0) {
851 syslog(LOG_INFO, "<%s> ioctl:SIOCGIFPREFIX %s", __func__, 933 syslog(LOG_INFO, "<%s> ioctl:SIOCGIFPREFIX %s", __func__,
852 strerror(errno)); 934 strerror(errno));
853 935
854 ipr->ipr_vltime = DEF_ADVVALIDLIFETIME; 936 ipr->ipr_vltime = DEF_ADVVALIDLIFETIME;
855 ipr->ipr_pltime = DEF_ADVPREFERREDLIFETIME; 937 ipr->ipr_pltime = DEF_ADVPREFERREDLIFETIME;
856 ipr->ipr_raf_onlink = 1; 938 ipr->ipr_raf_onlink = 1;
857 ipr->ipr_raf_auto = 1; 939 ipr->ipr_raf_auto = 1;
858 /* omit other field initialization */ 940 /* omit other field initialization */
859 } 941 }
860 else if (ipr->ipr_origin < PR_ORIG_RR) { 942 else if (ipr->ipr_origin < PR_ORIG_RR) {
861 char ntopbuf[INET6_ADDRSTRLEN]; 943 char ntopbuf[INET6_ADDRSTRLEN];
862 944
863 syslog(LOG_WARNING, "<%s> Added prefix(%s)'s origin %d is" 945 syslog(LOG_WARNING, "<%s> Added prefix(%s)'s origin %d is"
@@ -896,82 +978,99 @@ make_prefix(struct rainfo *rai, int ifin @@ -896,82 +978,99 @@ make_prefix(struct rainfo *rai, int ifin
896 ipr.ipr_prefix.sin6_family = AF_INET6; 978 ipr.ipr_prefix.sin6_family = AF_INET6;
897 ipr.ipr_prefix.sin6_addr = *addr; 979 ipr.ipr_prefix.sin6_addr = *addr;
898 ipr.ipr_plen = plen; 980 ipr.ipr_plen = plen;
899 981
900 if (init_prefix(&ipr)) 982 if (init_prefix(&ipr))
901 return; /* init failed by some error */ 983 return; /* init failed by some error */
902 add_prefix(rai, &ipr); 984 add_prefix(rai, &ipr);
903} 985}
904 986
905void 987void
906make_packet(struct rainfo *rainfo) 988make_packet(struct rainfo *rainfo)
907{ 989{
908 size_t packlen, lladdroptlen = 0; 990 size_t packlen, lladdroptlen = 0;
909 u_char *buf; 991 char *buf;
910 struct nd_router_advert *ra; 992 struct nd_router_advert *ra;
911 struct nd_opt_prefix_info *ndopt_pi; 993 struct nd_opt_prefix_info *ndopt_pi;
912 struct nd_opt_mtu *ndopt_mtu; 994 struct nd_opt_mtu *ndopt_mtu;
913 struct prefix *pfx; 995 struct prefix *pfx;
914#ifdef ROUTEINFO 
915 struct nd_opt_route_info *ndopt_rti; 996 struct nd_opt_route_info *ndopt_rti;
916 struct rtinfo *rti; 997 struct rtinfo *rti;
917#endif 998 struct nd_opt_rdnss *ndopt_rdnss;
 999 struct rdnss *rdns;
 1000 struct rdnss_addr *rdnsa;
 1001 struct nd_opt_dnssl *ndopt_dnssl;
 1002 struct dnssl *dnsl;
 1003 struct dnssl_domain *dnsd;
 1004 size_t len, plen;
918 1005
919 /* calculate total length */ 1006 /* calculate total length */
920 packlen = sizeof(struct nd_router_advert); 1007 packlen = sizeof(struct nd_router_advert);
921 if (rainfo->advlinkopt) { 1008 if (rainfo->advlinkopt) {
922 if ((lladdroptlen = lladdropt_length(rainfo->sdl)) == 0) { 1009 if ((lladdroptlen = lladdropt_length(rainfo->sdl)) == 0) {
923 syslog(LOG_INFO, 1010 syslog(LOG_INFO,
924 "<%s> link-layer address option has" 1011 "<%s> link-layer address option has"
925 " null length on %s. Treat as not included.", 1012 " null length on %s. Treat as not included.",
926 __func__, rainfo->ifname); 1013 __func__, rainfo->ifname);
927 rainfo->advlinkopt = 0; 1014 rainfo->advlinkopt = 0;
928 } 1015 }
929 packlen += lladdroptlen; 1016 packlen += lladdroptlen;
930 } 1017 }
931 if (rainfo->pfxs) 1018 if (TAILQ_FIRST(&rainfo->prefix) != NULL)
932 packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs; 1019 packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs;
933 if (rainfo->linkmtu) 1020 if (rainfo->linkmtu)
934 packlen += sizeof(struct nd_opt_mtu); 1021 packlen += sizeof(struct nd_opt_mtu);
935#ifdef ROUTEINFO 1022 TAILQ_FOREACH(rti, &rainfo->route, next)
936 for (rti = rainfo->route.next; rti != &rainfo->route; rti = rti->next) 
937 packlen += sizeof(struct nd_opt_route_info) +  1023 packlen += sizeof(struct nd_opt_route_info) +
938 ((rti->prefixlen + 0x3f) >> 6) * 8; 1024 ((rti->prefixlen + 0x3f) >> 6) * 8;
939#endif 1025
 1026 TAILQ_FOREACH(rdns, &rainfo->rdnss, next) {
 1027 packlen += sizeof(struct nd_opt_rdnss);
 1028 TAILQ_FOREACH(rdnsa, &rdns->list, next)
 1029 packlen += sizeof(rdnsa->addr);
 1030 }
 1031 TAILQ_FOREACH(dnsl, &rainfo->dnssl, next) {
 1032 packlen += sizeof(struct nd_opt_dnssl);
 1033 len = 0;
 1034 TAILQ_FOREACH(dnsd, &dnsl->list, next)
 1035 len += dnsd->len;
 1036 len += len % 8 ? 8 - len % 8 : 0;
 1037 packlen += len;
 1038 }
940 1039
941 /* allocate memory for the packet */ 1040 /* allocate memory for the packet */
942 if ((buf = malloc(packlen)) == NULL) { 1041 if ((buf = malloc(packlen)) == NULL) {
943 syslog(LOG_ERR, 1042 syslog(LOG_ERR,
944 "<%s> can't get enough memory for an RA packet", 1043 "<%s> can't get enough memory for an RA packet",
945 __func__); 1044 __func__);
946 exit(1); 1045 exit(1);
947 } 1046 }
948 if (rainfo->ra_data) { 1047 if (rainfo->ra_data) {
949 /* free the previous packet */ 1048 /* free the previous packet */
950 free(rainfo->ra_data); 1049 free(rainfo->ra_data);
951 rainfo->ra_data = NULL; 1050 rainfo->ra_data = NULL;
952 } 1051 }
953 rainfo->ra_data = buf; 1052 rainfo->ra_data = buf;
954 /* XXX: what if packlen > 576? */ 1053 /* XXX: what if packlen > 576? */
955 rainfo->ra_datalen = packlen; 1054 rainfo->ra_datalen = packlen;
956 1055
957 /* 1056 /*
958 * construct the packet 1057 * construct the packet
959 */ 1058 */
960 ra = (struct nd_router_advert *)buf; 1059 ra = (struct nd_router_advert *)buf;
961 ra->nd_ra_type = ND_ROUTER_ADVERT; 1060 ra->nd_ra_type = ND_ROUTER_ADVERT;
962 ra->nd_ra_code = 0; 1061 ra->nd_ra_code = 0;
963 ra->nd_ra_cksum = 0; 1062 ra->nd_ra_cksum = 0;
964 ra->nd_ra_curhoplimit = (u_int8_t)(0xff & rainfo->hoplimit); 1063 ra->nd_ra_curhoplimit = (uint8_t)(0xff & rainfo->hoplimit);
965 ra->nd_ra_flags_reserved = 0; /* just in case */ 1064 ra->nd_ra_flags_reserved = 0; /* just in case */
966 /* 1065 /*
967 * XXX: the router preference field, which is a 2-bit field, should be 1066 * XXX: the router preference field, which is a 2-bit field, should be
968 * initialized before other fields. 1067 * initialized before other fields.
969 */ 1068 */
970 ra->nd_ra_flags_reserved = 0xff & rainfo->rtpref; 1069 ra->nd_ra_flags_reserved = 0xff & rainfo->rtpref;
971 ra->nd_ra_flags_reserved |= 1070 ra->nd_ra_flags_reserved |=
972 rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0; 1071 rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0;
973 ra->nd_ra_flags_reserved |= 1072 ra->nd_ra_flags_reserved |=
974 rainfo->otherflg ? ND_RA_FLAG_OTHER : 0; 1073 rainfo->otherflg ? ND_RA_FLAG_OTHER : 0;
975 ra->nd_ra_router_lifetime = htons(rainfo->lifetime); 1074 ra->nd_ra_router_lifetime = htons(rainfo->lifetime);
976 ra->nd_ra_reachable = htonl(rainfo->reachabletime); 1075 ra->nd_ra_reachable = htonl(rainfo->reachabletime);
977 ra->nd_ra_retransmit = htonl(rainfo->retranstimer); 1076 ra->nd_ra_retransmit = htonl(rainfo->retranstimer);
@@ -981,31 +1080,28 @@ make_packet(struct rainfo *rainfo) @@ -981,31 +1080,28 @@ make_packet(struct rainfo *rainfo)
981 lladdropt_fill(rainfo->sdl, (struct nd_opt_hdr *)buf); 1080 lladdropt_fill(rainfo->sdl, (struct nd_opt_hdr *)buf);
982 buf += lladdroptlen; 1081 buf += lladdroptlen;
983 } 1082 }
984 1083
985 if (rainfo->linkmtu) { 1084 if (rainfo->linkmtu) {
986 ndopt_mtu = (struct nd_opt_mtu *)buf; 1085 ndopt_mtu = (struct nd_opt_mtu *)buf;
987 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU; 1086 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU;
988 ndopt_mtu->nd_opt_mtu_len = 1; 1087 ndopt_mtu->nd_opt_mtu_len = 1;
989 ndopt_mtu->nd_opt_mtu_reserved = 0; 1088 ndopt_mtu->nd_opt_mtu_reserved = 0;
990 ndopt_mtu->nd_opt_mtu_mtu = htonl(rainfo->linkmtu); 1089 ndopt_mtu->nd_opt_mtu_mtu = htonl(rainfo->linkmtu);
991 buf += sizeof(struct nd_opt_mtu); 1090 buf += sizeof(struct nd_opt_mtu);
992 } 1091 }
993 1092
994  1093 TAILQ_FOREACH(pfx, &rainfo->prefix, next) {
995  1094 uint32_t vltime, pltime;
996 for (pfx = rainfo->prefix.next; 
997 pfx != &rainfo->prefix; pfx = pfx->next) { 
998 u_int32_t vltime, pltime; 
999 struct timeval now; 1095 struct timeval now;
1000 1096
1001 ndopt_pi = (struct nd_opt_prefix_info *)buf; 1097 ndopt_pi = (struct nd_opt_prefix_info *)buf;
1002 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; 1098 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1003 ndopt_pi->nd_opt_pi_len = 4; 1099 ndopt_pi->nd_opt_pi_len = 4;
1004 ndopt_pi->nd_opt_pi_prefix_len = pfx->prefixlen; 1100 ndopt_pi->nd_opt_pi_prefix_len = pfx->prefixlen;
1005 ndopt_pi->nd_opt_pi_flags_reserved = 0; 1101 ndopt_pi->nd_opt_pi_flags_reserved = 0;
1006 if (pfx->onlinkflg) 1102 if (pfx->onlinkflg)
1007 ndopt_pi->nd_opt_pi_flags_reserved |= 1103 ndopt_pi->nd_opt_pi_flags_reserved |=
1008 ND_OPT_PI_FLAG_ONLINK; 1104 ND_OPT_PI_FLAG_ONLINK;
1009 if (pfx->autoconfflg) 1105 if (pfx->autoconfflg)
1010 ndopt_pi->nd_opt_pi_flags_reserved |= 1106 ndopt_pi->nd_opt_pi_flags_reserved |=
1011 ND_OPT_PI_FLAG_AUTO; 1107 ND_OPT_PI_FLAG_AUTO;
@@ -1034,42 +1130,73 @@ make_packet(struct rainfo *rainfo) @@ -1034,42 +1130,73 @@ make_packet(struct rainfo *rainfo)
1034 * this can happen if vltime is decrement but pltime 1130 * this can happen if vltime is decrement but pltime
1035 * is not. 1131 * is not.
1036 */ 1132 */
1037 pltime = vltime; 1133 pltime = vltime;
1038 } 1134 }
1039 ndopt_pi->nd_opt_pi_valid_time = htonl(vltime); 1135 ndopt_pi->nd_opt_pi_valid_time = htonl(vltime);
1040 ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime); 1136 ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime);
1041 ndopt_pi->nd_opt_pi_reserved2 = 0; 1137 ndopt_pi->nd_opt_pi_reserved2 = 0;
1042 ndopt_pi->nd_opt_pi_prefix = pfx->prefix; 1138 ndopt_pi->nd_opt_pi_prefix = pfx->prefix;
1043 1139
1044 buf += sizeof(struct nd_opt_prefix_info); 1140 buf += sizeof(struct nd_opt_prefix_info);
1045 } 1141 }
1046 1142
1047#ifdef ROUTEINFO 1143 TAILQ_FOREACH(rti, &rainfo->route, next) {
1048 for (rti = rainfo->route.next; rti != &rainfo->route; rti = rti->next) { 1144 uint8_t psize = (rti->prefixlen + 0x3f) >> 6;
1049 u_int8_t psize = (rti->prefixlen + 0x3f) >> 6; 
1050 1145
1051 ndopt_rti = (struct nd_opt_route_info *)buf; 1146 ndopt_rti = (struct nd_opt_route_info *)buf;
1052 ndopt_rti->nd_opt_rti_type = ND_OPT_ROUTE_INFO; 1147 ndopt_rti->nd_opt_rti_type = ND_OPT_ROUTE_INFO;
1053 ndopt_rti->nd_opt_rti_len = 1 + psize; 1148 ndopt_rti->nd_opt_rti_len = 1 + psize;
1054 ndopt_rti->nd_opt_rti_prefixlen = rti->prefixlen; 1149 ndopt_rti->nd_opt_rti_prefixlen = rti->prefixlen;
1055 ndopt_rti->nd_opt_rti_flags = 0xff & rti->rtpref; 1150 ndopt_rti->nd_opt_rti_flags = 0xff & rti->rtpref;
1056 ndopt_rti->nd_opt_rti_lifetime = htonl(rti->ltime); 1151 ndopt_rti->nd_opt_rti_lifetime = htonl(rti->ltime);
1057 memcpy(ndopt_rti + 1, &rti->prefix, psize * 8); 1152 memcpy(ndopt_rti + 1, &rti->prefix, psize * 8);
1058 buf += sizeof(struct nd_opt_route_info) + psize * 8; 1153 buf += sizeof(struct nd_opt_route_info) + psize * 8;
1059 } 1154 }
1060#endif 
1061 1155
1062 return; 1156 TAILQ_FOREACH(rdns, &rainfo->rdnss, next) {
 1157 ndopt_rdnss = (struct nd_opt_rdnss *)buf;
 1158 ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS;
 1159 ndopt_rdnss->nd_opt_rdnss_len = 1;
 1160 ndopt_rdnss->nd_opt_rdnss_reserved = 0;
 1161 ndopt_rdnss->nd_opt_rdnss_lifetime = htonl(rdns->lifetime);
 1162 buf += sizeof(*ndopt_rdnss);
 1163
 1164 TAILQ_FOREACH(rdnsa, &rdns->list, next) {
 1165 memcpy(buf, &rdnsa->addr, sizeof(rdnsa->addr));
 1166 ndopt_rdnss->nd_opt_rdnss_len += 2;
 1167 buf += sizeof(rdnsa->addr);
 1168 }
 1169 }
 1170
 1171 TAILQ_FOREACH(dnsl, &rainfo->dnssl, next) {
 1172 ndopt_dnssl = (struct nd_opt_dnssl *)buf;
 1173 ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL;
 1174 ndopt_dnssl->nd_opt_dnssl_len = 0;
 1175 ndopt_dnssl->nd_opt_dnssl_reserved = 0;
 1176 ndopt_dnssl->nd_opt_dnssl_lifetime = htonl(dnsl->lifetime);
 1177 buf += sizeof(*ndopt_dnssl);
 1178
 1179 TAILQ_FOREACH(dnsd, &dnsl->list, next) {
 1180 memcpy(buf, dnsd->domain, dnsd->len);
 1181 buf += dnsd->len;
 1182 }
 1183 /* Ensure our length is padded correctly */
 1184 len = buf - (char *)ndopt_dnssl;
 1185 plen = len % 8 ? 8 - len % 8 : 0;
 1186 memset(buf, 0, plen);
 1187 buf += plen;
 1188 ndopt_dnssl->nd_opt_dnssl_len = (len + plen) / 8;
 1189 }
1063} 1190}
1064 1191
1065static int 1192static int
1066getinet6sysctl(int code) 1193getinet6sysctl(int code)
1067{ 1194{
1068 int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 }; 1195 int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 };
1069 int value; 1196 int value;
1070 size_t size; 1197 size_t size;
1071 1198
1072 mib[3] = code; 1199 mib[3] = code;
1073 size = sizeof(value); 1200 size = sizeof(value);
1074 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0) 1201 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0)
1075 < 0) { 1202 < 0) {

cvs diff -r1.8 -r1.9 src/usr.sbin/rtadvd/dump.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/dump.c 2008/12/29 04:01:21 1.8
+++ src/usr.sbin/rtadvd/dump.c 2011/12/10 19:14:29 1.9
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dump.c,v 1.8 2008/12/29 04:01:21 christos Exp $ */ 1/* $NetBSD: dump.c,v 1.9 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: dump.c,v 1.34 2004/06/14 05:35:59 itojun Exp $ */ 2/* $KAME: dump.c,v 1.34 2004/06/14 05:35:59 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 2000 WIDE Project. 5 * Copyright (C) 2000 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
@@ -49,68 +49,67 @@ @@ -49,68 +49,67 @@
49#include <stdarg.h> 49#include <stdarg.h>
50#include <syslog.h> 50#include <syslog.h>
51#include <string.h> 51#include <string.h>
52#include <errno.h> 52#include <errno.h>
53#include <netdb.h> 53#include <netdb.h>
54 54
55#include "rtadvd.h" 55#include "rtadvd.h"
56#include "timer.h" 56#include "timer.h"
57#include "if.h" 57#include "if.h"
58#include "dump.h" 58#include "dump.h"
59 59
60static FILE *fp; 60static FILE *fp;
61 61
62extern struct rainfo *ralist; 62static char *ether_str(struct sockaddr_dl *);
 63static void if_dump(void);
63 64
64static char *ether_str __P((struct sockaddr_dl *)); 65static const char *rtpref_str[] = {
65static void if_dump __P((void)); 
66 
67static char *rtpref_str[] = { 
68 "medium", /* 00 */ 66 "medium", /* 00 */
69 "high", /* 01 */ 67 "high", /* 01 */
70 "rsv", /* 10 */ 68 "rsv", /* 10 */
71 "low" /* 11 */ 69 "low" /* 11 */
72}; 70};
73 71
74static char * 72static char *
75ether_str(sdl) 73ether_str(struct sockaddr_dl *sdl)
76 struct sockaddr_dl *sdl; 
77{ 74{
78 static char hbuf[NI_MAXHOST]; 75 static char hbuf[NI_MAXHOST];
79 76
80 if (sdl->sdl_alen) { 77 if (sdl->sdl_alen) {
81 if (getnameinfo((struct sockaddr *)sdl, sdl->sdl_len, 78 if (getnameinfo((struct sockaddr *)sdl, sdl->sdl_len,
82 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 79 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
83 snprintf(hbuf, sizeof(hbuf), "<invalid>"); 80 snprintf(hbuf, sizeof(hbuf), "<invalid>");
84 } else 81 } else
85 snprintf(hbuf, sizeof(hbuf), "NONE"); 82 snprintf(hbuf, sizeof(hbuf), "NONE");
86 83
87 return(hbuf); 84 return(hbuf);
88} 85}
89 86
90static void 87static void
91if_dump() 88if_dump(void)
92{ 89{
93 struct rainfo *rai; 90 struct rainfo *rai;
94 struct prefix *pfx; 91 struct prefix *pfx;
95#ifdef ROUTEINFO 
96 struct rtinfo *rti; 92 struct rtinfo *rti;
97#endif 93 struct rdnss *rdns;
 94 struct rdnss_addr *rdnsa;
 95 struct dnssl *dnsl;
 96 struct dnssl_domain *dnsd;
 97 char *p, len;
98 char prefixbuf[INET6_ADDRSTRLEN]; 98 char prefixbuf[INET6_ADDRSTRLEN];
99 int first; 
100 struct timeval now; 99 struct timeval now;
101 100
102 gettimeofday(&now, NULL); /* XXX: unused in most cases */ 101 gettimeofday(&now, NULL); /* XXX: unused in most cases */
103 for (rai = ralist; rai; rai = rai->next) { 102 TAILQ_FOREACH(rai, &ralist, next) {
104 fprintf(fp, "%s:\n", rai->ifname); 103 fprintf(fp, "%s:\n", rai->ifname);
105 104
106 fprintf(fp, " Status: %s\n", 105 fprintf(fp, " Status: %s\n",
107 (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : 106 (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" :
108 "DOWN"); 107 "DOWN");
109 108
110 /* control information */ 109 /* control information */
111 if (rai->lastsent.tv_sec) { 110 if (rai->lastsent.tv_sec) {
112 /* note that ctime() appends CR by itself */ 111 /* note that ctime() appends CR by itself */
113 fprintf(fp, " Last RA sent: %s", 112 fprintf(fp, " Last RA sent: %s",
114 ctime((time_t *)&rai->lastsent.tv_sec)); 113 ctime((time_t *)&rai->lastsent.tv_sec));
115 } 114 }
116 if (rai->timer) { 115 if (rai->timer) {
@@ -141,34 +140,31 @@ if_dump() @@ -141,34 +140,31 @@ if_dump()
141 fprintf(fp, " DefaultLifetime: %d, MaxAdvInterval: %d, " 140 fprintf(fp, " DefaultLifetime: %d, MaxAdvInterval: %d, "
142 "MinAdvInterval: %d\n", rai->lifetime, rai->maxinterval, 141 "MinAdvInterval: %d\n", rai->lifetime, rai->maxinterval,
143 rai->mininterval); 142 rai->mininterval);
144 fprintf(fp, " Flags: %s%s%s, ", 143 fprintf(fp, " Flags: %s%s%s, ",
145 rai->managedflg ? "M" : "", rai->otherflg ? "O" : "", 144 rai->managedflg ? "M" : "", rai->otherflg ? "O" : "",
146 ""); 145 "");
147 fprintf(fp, "Preference: %s, ", 146 fprintf(fp, "Preference: %s, ",
148 rtpref_str[(rai->rtpref >> 3) & 0xff]); 147 rtpref_str[(rai->rtpref >> 3) & 0xff]);
149 fprintf(fp, "MTU: %d\n", rai->linkmtu); 148 fprintf(fp, "MTU: %d\n", rai->linkmtu);
150 fprintf(fp, " ReachableTime: %d, RetransTimer: %d, " 149 fprintf(fp, " ReachableTime: %d, RetransTimer: %d, "
151 "CurHopLimit: %d\n", rai->reachabletime, 150 "CurHopLimit: %d\n", rai->reachabletime,
152 rai->retranstimer, rai->hoplimit); 151 rai->retranstimer, rai->hoplimit);
153 if (rai->clockskew) 152 if (rai->clockskew)
154 fprintf(fp, " Clock skew: %ldsec\n", 153 fprintf(fp, " Clock skew: %dsec\n",
155 rai->clockskew); 154 rai->clockskew);
156 for (first = 1, pfx = rai->prefix.next; pfx != &rai->prefix; 155 TAILQ_FOREACH(pfx, &rai->prefix, next) {
157 pfx = pfx->next) { 156 if (pfx == TAILQ_FIRST(&rai->prefix))
158 if (first) { 
159 fprintf(fp, " Prefixes:\n"); 157 fprintf(fp, " Prefixes:\n");
160 first = 0; 
161 } 
162 fprintf(fp, " %s/%d(", 158 fprintf(fp, " %s/%d(",
163 inet_ntop(AF_INET6, &pfx->prefix, prefixbuf, 159 inet_ntop(AF_INET6, &pfx->prefix, prefixbuf,
164 sizeof(prefixbuf)), pfx->prefixlen); 160 sizeof(prefixbuf)), pfx->prefixlen);
165 switch (pfx->origin) { 161 switch (pfx->origin) {
166 case PREFIX_FROM_KERNEL: 162 case PREFIX_FROM_KERNEL:
167 fprintf(fp, "KERNEL, "); 163 fprintf(fp, "KERNEL, ");
168 break; 164 break;
169 case PREFIX_FROM_CONFIG: 165 case PREFIX_FROM_CONFIG:
170 fprintf(fp, "CONFIG, "); 166 fprintf(fp, "CONFIG, ");
171 break; 167 break;
172 case PREFIX_FROM_DYNAMIC: 168 case PREFIX_FROM_DYNAMIC:
173 fprintf(fp, "DYNAMIC, "); 169 fprintf(fp, "DYNAMIC, ");
174 break; 170 break;
@@ -200,52 +196,82 @@ if_dump() @@ -200,52 +196,82 @@ if_dump()
200 pfx->autoconfflg ? "A" : "", 196 pfx->autoconfflg ? "A" : "",
201 ""); 197 "");
202 if (pfx->timer) { 198 if (pfx->timer) {
203 struct timeval *rest; 199 struct timeval *rest;
204 200
205 rest = rtadvd_timer_rest(pfx->timer); 201 rest = rtadvd_timer_rest(pfx->timer);
206 if (rest) { /* XXX: what if not? */ 202 if (rest) { /* XXX: what if not? */
207 fprintf(fp, ", expire in: %ld", 203 fprintf(fp, ", expire in: %ld",
208 (long)rest->tv_sec); 204 (long)rest->tv_sec);
209 } 205 }
210 } 206 }
211 fprintf(fp, ")\n"); 207 fprintf(fp, ")\n");
212 } 208 }
213#ifdef ROUTEINFO 209
214 for (first = 1, rti = rai->route.next; rti != &rai->route; 210 TAILQ_FOREACH(rti, &rai->route, next) {
215 rti = rti->next) { 211 if (rti == TAILQ_FIRST(&rai->route))
216 if (first) { 
217 fprintf(fp, " Route Information:\n"); 212 fprintf(fp, " Route Information:\n");
218 first = 0; 
219 } 
220 fprintf(fp, " %s/%d (", 213 fprintf(fp, " %s/%d (",
221 inet_ntop(AF_INET6, &rti->prefix, 214 inet_ntop(AF_INET6, &rti->prefix,
222 prefixbuf, sizeof(prefixbuf)), 215 prefixbuf, sizeof(prefixbuf)),
223 rti->prefixlen); 216 rti->prefixlen);
224 fprintf(fp, "preference: %s, ", 217 fprintf(fp, "preference: %s, ",
225 rtpref_str[0xff & (rti->rtpref >> 3)]); 218 rtpref_str[0xff & (rti->rtpref >> 3)]);
226 if (rti->ltime == ND6_INFINITE_LIFETIME) 219 if (rti->ltime == ND6_INFINITE_LIFETIME)
227 fprintf(fp, "lifetime: infinity"); 220 fprintf(fp, "lifetime: infinity");
228 else 221 else
229 fprintf(fp, "lifetime: %ld", (long)rti->ltime); 222 fprintf(fp, "lifetime: %ld", (long)rti->ltime);
230 fprintf(fp, ")\n"); 223 fprintf(fp, ")\n");
231 } 224 }
232#endif 225
 226 TAILQ_FOREACH(rdns, &rai->rdnss, next) {
 227 fprintf(fp, " Recursive DNS Servers:\n");
 228 if (rdns->lifetime == ND6_INFINITE_LIFETIME)
 229 fprintf(fp, " lifetime: infinity\n");
 230 else
 231 fprintf(fp, " lifetime: %ld\n",
 232 (long)rdns->lifetime);
 233 TAILQ_FOREACH(rdnsa, &rdns->list, next)
 234 fprintf(fp, " %s\n",
 235 inet_ntop(AF_INET6, &rdnsa->addr,
 236 prefixbuf, sizeof(prefixbuf)));
 237 }
 238
 239 TAILQ_FOREACH(dnsl, &rai->dnssl, next) {
 240 fprintf(fp, " DNS Search List:\n");
 241 if (dnsl->lifetime == ND6_INFINITE_LIFETIME)
 242 fprintf(fp, " lifetime: infinity\n");
 243 else
 244 fprintf(fp, " lifetime: %ld\n",
 245 (long)dnsl->lifetime);
 246 TAILQ_FOREACH(dnsd, &dnsl->list, next) {
 247 fprintf(fp, " ");
 248 for (p = dnsd->domain, len = *p++;
 249 len != 0;
 250 len = *p++)
 251 {
 252 if (p != dnsd->domain)
 253 fputc('.', fp);
 254 while(len-- != 0)
 255 fputc(*p++, fp);
 256 }
 257 fputc('\n', fp);
 258 }
 259 }
233 } 260 }
234} 261}
235 262
236void 263void
237rtadvd_dump_file(dumpfile) 264rtadvd_dump_file(const char *dumpfile)
238 char *dumpfile; 
239{ 265{
240 syslog(LOG_DEBUG, "<%s> dump current status to %s", __func__, 266 syslog(LOG_DEBUG, "<%s> dump current status to %s", __func__,
241 dumpfile); 267 dumpfile);
242 268
243 if ((fp = fopen(dumpfile, "w")) == NULL) { 269 if ((fp = fopen(dumpfile, "w")) == NULL) {
244 syslog(LOG_WARNING, "<%s> open a dump file(%s)", 270 syslog(LOG_WARNING, "<%s> open a dump file(%s)",
245 __func__, dumpfile); 271 __func__, dumpfile);
246 return; 272 return;
247 } 273 }
248 274
249 if_dump(); 275 if_dump();
250 276
251 fclose(fp); 277 fclose(fp);

cvs diff -r1.1 -r1.2 src/usr.sbin/rtadvd/dump.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/dump.h 2000/05/23 11:37:58 1.1
+++ src/usr.sbin/rtadvd/dump.h 2011/12/10 19:14:29 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dump.h,v 1.1 2000/05/23 11:37:58 itojun Exp $ */ 1/* $NetBSD: dump.h,v 1.2 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: dump.h,v 1.1 2000/05/23 11:31:26 itojun Exp $ */ 2/* $KAME: dump.h,v 1.1 2000/05/23 11:31:26 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1998 WIDE Project. 5 * Copyright (C) 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
@@ -20,14 +20,14 @@ @@ -20,14 +20,14 @@
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
33extern void rtadvd_dump_file __P((char *)); 33extern void rtadvd_dump_file(const char *);

cvs diff -r1.18 -r1.19 src/usr.sbin/rtadvd/if.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/if.c 2006/03/05 23:47:08 1.18
+++ src/usr.sbin/rtadvd/if.c 2011/12/10 19:14:29 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if.c,v 1.18 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: if.c,v 1.19 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: if.c,v 1.36 2004/11/30 22:32:01 suz Exp $ */ 2/* $KAME: if.c,v 1.36 2004/11/30 22:32:01 suz 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
@@ -44,38 +44,38 @@ @@ -44,38 +44,38 @@
44#include <netinet/icmp6.h> 44#include <netinet/icmp6.h>
45#include <unistd.h> 45#include <unistd.h>
46#include <errno.h> 46#include <errno.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49#include <syslog.h> 49#include <syslog.h>
50#include "rtadvd.h" 50#include "rtadvd.h"
51#include "if.h" 51#include "if.h"
52 52
53#define ROUNDUP(a, size) \ 53#define ROUNDUP(a, size) \
54 (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) 54 (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
55 55
56#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ 56#define NEXT_SA(ap) (ap) = (struct sockaddr *) \
57 ((caddr_t)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\ 57 ((char *)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\
58 sizeof(u_long)) :\ 58 sizeof(u_long)) :\
59 sizeof(u_long))) 59 sizeof(u_long)))
60 60
61struct if_msghdr **iflist; 61struct if_msghdr **iflist;
62int iflist_init_ok; 62int iflist_init_ok;
63size_t ifblock_size; 63size_t ifblock_size;
64char *ifblock; 64char *ifblock;
65 65
66static void get_iflist __P((char **buf, size_t *size)); 66static void get_iflist(char **buf, size_t *size);
67static void parse_iflist __P((struct if_msghdr ***ifmlist_p, char *buf, 67static void parse_iflist(struct if_msghdr ***ifmlist_p, char *buf,
68 size_t bufsize)); 68 size_t bufsize);
69 69
70static void 70static void
71get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 71get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
72{ 72{
73 int i; 73 int i;
74  74
75 for (i = 0; i < RTAX_MAX; i++) { 75 for (i = 0; i < RTAX_MAX; i++) {
76 if (addrs & (1 << i)) { 76 if (addrs & (1 << i)) {
77 rti_info[i] = sa; 77 rti_info[i] = sa;
78 NEXT_SA(sa); 78 NEXT_SA(sa);
79 } 79 }
80 else 80 else
81 rti_info[i] = NULL; 81 rti_info[i] = NULL;
@@ -130,54 +130,54 @@ if_getmtu(char *name) @@ -130,54 +130,54 @@ if_getmtu(char *name)
130 freeifaddrs(ifap); 130 freeifaddrs(ifap);
131 131
132#ifdef SIOCGIFMTU /* XXX: this ifdef may not be necessary */ 132#ifdef SIOCGIFMTU /* XXX: this ifdef may not be necessary */
133 if (mtu == 0) { 133 if (mtu == 0) {
134 struct ifreq ifr; 134 struct ifreq ifr;
135 int s; 135 int s;
136 136
137 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 137 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
138 return(0); 138 return(0);
139 139
140 ifr.ifr_addr.sa_family = AF_INET6; 140 ifr.ifr_addr.sa_family = AF_INET6;
141 strncpy(ifr.ifr_name, name, 141 strncpy(ifr.ifr_name, name,
142 sizeof(ifr.ifr_name)); 142 sizeof(ifr.ifr_name));
143 if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0) { 143 if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
144 close(s); 144 close(s);
145 return(0); 145 return(0);
146 } 146 }
147 close(s); 147 close(s);
148 148
149 mtu = ifr.ifr_mtu; 149 mtu = ifr.ifr_mtu;
150 } 150 }
151#endif 151#endif
152 152
153 return(mtu); 153 return(mtu);
154} 154}
155 155
156/* give interface index and its old flags, then new flags returned */ 156/* give interface index and its old flags, then new flags returned */
157int 157int
158if_getflags(int ifindex, int oifflags) 158if_getflags(int ifindex, int oifflags)
159{ 159{
160 struct ifreq ifr; 160 struct ifreq ifr;
161 int s; 161 int s;
162 162
163 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 163 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
164 syslog(LOG_ERR, "<%s> socket: %s", __func__, 164 syslog(LOG_ERR, "<%s> socket: %s", __func__,
165 strerror(errno)); 165 strerror(errno));
166 return (oifflags & ~IFF_UP); 166 return (oifflags & ~IFF_UP);
167 } 167 }
168 168
169 if_indextoname(ifindex, ifr.ifr_name); 169 if_indextoname(ifindex, ifr.ifr_name);
170 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 170 if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
171 syslog(LOG_ERR, "<%s> ioctl:SIOCGIFFLAGS: failed for %s", 171 syslog(LOG_ERR, "<%s> ioctl:SIOCGIFFLAGS: failed for %s",
172 __func__, ifr.ifr_name); 172 __func__, ifr.ifr_name);
173 close(s); 173 close(s);
174 return (oifflags & ~IFF_UP); 174 return (oifflags & ~IFF_UP);
175 } 175 }
176 close(s); 176 close(s);
177 return (ifr.ifr_flags); 177 return (ifr.ifr_flags);
178} 178}
179 179
180#define ROUNDUP8(a) (1 + (((a) - 1) | 7)) 180#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
181int 181int
182lladdropt_length(struct sockaddr_dl *sdl) 182lladdropt_length(struct sockaddr_dl *sdl)
183{ 183{
@@ -345,39 +345,39 @@ get_ifam_ifindex(char *buf) @@ -345,39 +345,39 @@ get_ifam_ifindex(char *buf)
345int 345int
346get_ifm_flags(char *buf) 346get_ifm_flags(char *buf)
347{ 347{
348 struct if_msghdr *ifm = (struct if_msghdr *)buf; 348 struct if_msghdr *ifm = (struct if_msghdr *)buf;
349 349
350 return (ifm->ifm_flags); 350 return (ifm->ifm_flags);
351} 351}
352 352
353int 353int
354get_prefixlen(char *buf) 354get_prefixlen(char *buf)
355{ 355{
356 struct rt_msghdr *rtm = (struct rt_msghdr *)buf; 356 struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
357 struct sockaddr *sa, *rti_info[RTAX_MAX]; 357 struct sockaddr *sa, *rti_info[RTAX_MAX];
358 u_char *p, *lim; 358 unsigned char *p, *lim;
359  359
360 sa = (struct sockaddr *)(rtm + 1); 360 sa = (struct sockaddr *)(rtm + 1);
361 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); 361 get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
362 sa = rti_info[RTAX_NETMASK]; 362 sa = rti_info[RTAX_NETMASK];
363 363
364 p = (u_char *)(&SIN6(sa)->sin6_addr); 364 p = (unsigned char *)(&SIN6(sa)->sin6_addr);
365 lim = (u_char *)sa + sa->sa_len; 365 lim = (unsigned char *)sa + sa->sa_len;
366 return prefixlen(p, lim); 366 return prefixlen(p, lim);
367} 367}
368 368
369int 369int
370prefixlen(u_char *p, u_char *lim) 370prefixlen(const unsigned char *p, const unsigned char *lim)
371{ 371{
372 int masklen; 372 int masklen;
373 373
374 for (masklen = 0; p < lim; p++) { 374 for (masklen = 0; p < lim; p++) {
375 switch (*p) { 375 switch (*p) {
376 case 0xff: 376 case 0xff:
377 masklen += 8; 377 masklen += 8;
378 break; 378 break;
379 case 0xfe: 379 case 0xfe:
380 masklen += 7; 380 masklen += 7;
381 break; 381 break;
382 case 0xfc: 382 case 0xfc:
383 masklen += 6; 383 masklen += 6;

cvs diff -r1.7 -r1.8 src/usr.sbin/rtadvd/if.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/if.h 2006/03/05 23:47:08 1.7
+++ src/usr.sbin/rtadvd/if.h 2011/12/10 19:14:29 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if.h,v 1.7 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: if.h,v 1.8 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: if.h,v 1.12 2003/09/21 07:17:03 itojun Exp $ */ 2/* $KAME: if.h,v 1.12 2003/09/21 07:17:03 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 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
@@ -27,31 +27,31 @@ @@ -27,31 +27,31 @@
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#define RTADV_TYPE2BITMASK(type) (0x1 << type) 33#define RTADV_TYPE2BITMASK(type) (0x1 << type)
34 34
35extern struct if_msghdr **iflist; 35extern struct if_msghdr **iflist;
36extern size_t ifblock_size; 36extern size_t ifblock_size;
37extern char *ifblock; 37extern char *ifblock;
38 38
39struct nd_opt_hdr; 39struct nd_opt_hdr;
40struct sockaddr_dl *if_nametosdl __P((char *)); 40struct sockaddr_dl *if_nametosdl(char *);
41int if_getmtu __P((char *)); 41int if_getmtu(char *);
42int if_getflags __P((int, int)); 42int if_getflags(int, int);
43int lladdropt_length __P((struct sockaddr_dl *)); 43int lladdropt_length(struct sockaddr_dl *);
44void lladdropt_fill __P((struct sockaddr_dl *, struct nd_opt_hdr *)); 44void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *);
45char *get_next_msg __P((char *, char *, int, size_t *, int)); 45char *get_next_msg(char *, char *, int, size_t *, int);
46struct in6_addr *get_addr __P((char *)); 46struct in6_addr *get_addr(char *);
47int get_rtm_ifindex __P((char *)); 47int get_rtm_ifindex(char *);
48int get_ifm_ifindex __P((char *)); 48int get_ifm_ifindex(char *);
49int get_ifam_ifindex __P((char *)); 49int get_ifam_ifindex(char *);
50int get_ifm_flags __P((char *)); 50int get_ifm_flags(char *);
51int get_prefixlen __P((char *)); 51int get_prefixlen(char *);
52int prefixlen __P((u_char *, u_char *)); 52int prefixlen(const unsigned char *, const unsigned char *);
53int rtmsg_type __P((char *)); 53int rtmsg_type(char *);
54int ifmsg_type __P((char *)); 54int ifmsg_type(char *);
55int rtmsg_len __P((char *)); 55int rtmsg_len(char *);
56int ifmsg_len __P((char *)); 56int ifmsg_len(char *);
57void init_iflist __P((void)); 57void init_iflist(void);

cvs diff -r1.13 -r1.14 src/usr.sbin/rtadvd/Attic/rrenum.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/Attic/rrenum.c 2006/05/11 08:35:47 1.13
+++ src/usr.sbin/rtadvd/Attic/rrenum.c 2011/12/10 19:14:29 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rrenum.c,v 1.13 2006/05/11 08:35:47 mrg Exp $ */ 1/* $NetBSD: rrenum.c,v 1.14 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: rrenum.c,v 1.14 2004/06/14 05:36:00 itojun Exp $ */ 2/* $KAME: rrenum.c,v 1.14 2004/06/14 05:36:00 itojun 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
@@ -150,27 +150,27 @@ do_use_prefix(int len, struct rr_pco_mat @@ -150,27 +150,27 @@ do_use_prefix(int len, struct rr_pco_mat
150 if (rpm->rpm_code == RPM_PCO_ADD) 150 if (rpm->rpm_code == RPM_PCO_ADD)
151 return; 151 return;
152 152
153 irr->irr_u_uselen = 0; 153 irr->irr_u_uselen = 0;
154 irr->irr_u_keeplen = 0; 154 irr->irr_u_keeplen = 0;
155 irr->irr_raf_mask_onlink = 0; 155 irr->irr_raf_mask_onlink = 0;
156 irr->irr_raf_mask_auto = 0; 156 irr->irr_raf_mask_auto = 0;
157 irr->irr_vltime = 0; 157 irr->irr_vltime = 0;
158 irr->irr_pltime = 0; 158 irr->irr_pltime = 0;
159 memset(&irr->irr_flags, 0, sizeof(irr->irr_flags)); 159 memset(&irr->irr_flags, 0, sizeof(irr->irr_flags));
160 irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */ 160 irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */
161 irr->irr_useprefix.sin6_family = 0; 161 irr->irr_useprefix.sin6_family = 0;
162 irr->irr_useprefix.sin6_addr = in6addr_any; 162 irr->irr_useprefix.sin6_addr = in6addr_any;
163 if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 && 163 if (ioctl(s, rrcmd2pco[rpm->rpm_code], irr) < 0 &&
164 errno != EADDRNOTAVAIL) 164 errno != EADDRNOTAVAIL)
165 syslog(LOG_ERR, "<%s> ioctl: %s", __func__, 165 syslog(LOG_ERR, "<%s> ioctl: %s", __func__,
166 strerror(errno)); 166 strerror(errno));
167 return; 167 return;
168 } 168 }
169 169
170 for (rpu = (struct rr_pco_use *)(rpm + 1), 170 for (rpu = (struct rr_pco_use *)(rpm + 1),
171 rpulim = (struct rr_pco_use *)((char *)rpm + len); 171 rpulim = (struct rr_pco_use *)((char *)rpm + len);
172 rpu < rpulim; 172 rpu < rpulim;
173 rpu += 1) { 173 rpu += 1) {
174 /* init in6_rrenumreq fields */ 174 /* init in6_rrenumreq fields */
175 irr->irr_u_uselen = rpu->rpu_uselen; 175 irr->irr_u_uselen = rpu->rpu_uselen;
176 irr->irr_u_keeplen = rpu->rpu_keeplen; 176 irr->irr_u_keeplen = rpu->rpu_keeplen;
@@ -182,41 +182,40 @@ do_use_prefix(int len, struct rr_pco_mat @@ -182,41 +182,40 @@ do_use_prefix(int len, struct rr_pco_mat
182 irr->irr_pltime = ntohl(rpu->rpu_pltime); 182 irr->irr_pltime = ntohl(rpu->rpu_pltime);
183 irr->irr_raf_onlink = 183 irr->irr_raf_onlink =
184 (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK) == 0 ? 0 : 1; 184 (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK) == 0 ? 0 : 1;
185 irr->irr_raf_auto = 185 irr->irr_raf_auto =
186 (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO) == 0 ? 0 : 1; 186 (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO) == 0 ? 0 : 1;
187 irr->irr_rrf_decrvalid = 187 irr->irr_rrf_decrvalid =
188 (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME) == 0 ? 0 : 1; 188 (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME) == 0 ? 0 : 1;
189 irr->irr_rrf_decrprefd = 189 irr->irr_rrf_decrprefd =
190 (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) == 0 ? 0 : 1; 190 (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) == 0 ? 0 : 1;
191 irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix); 191 irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix);
192 irr->irr_useprefix.sin6_family = AF_INET6; 192 irr->irr_useprefix.sin6_family = AF_INET6;
193 irr->irr_useprefix.sin6_addr = rpu->rpu_prefix; 193 irr->irr_useprefix.sin6_addr = rpu->rpu_prefix;
194 194
195 if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 && 195 if (ioctl(s, rrcmd2pco[rpm->rpm_code], irr) < 0 &&
196 errno != EADDRNOTAVAIL) 196 errno != EADDRNOTAVAIL)
197 syslog(LOG_ERR, "<%s> ioctl: %s", __func__, 197 syslog(LOG_ERR, "<%s> ioctl: %s", __func__,
198 strerror(errno)); 198 strerror(errno));
199 199
200 /* very adhoc: should be rewritten */ 200 /* very adhoc: should be rewritten */
201 if (rpm->rpm_code == RPM_PCO_CHANGE && 201 if (rpm->rpm_code == RPM_PCO_CHANGE &&
202 IN6_ARE_ADDR_EQUAL(&rpm->rpm_prefix, &rpu->rpu_prefix) && 202 IN6_ARE_ADDR_EQUAL(&rpm->rpm_prefix, &rpu->rpu_prefix) &&
203 rpm->rpm_matchlen == rpu->rpu_uselen && 203 rpm->rpm_matchlen == rpu->rpu_uselen &&
204 rpu->rpu_uselen == rpu->rpu_keeplen) { 204 rpu->rpu_uselen == rpu->rpu_keeplen) {
205 if ((rai = if_indextorainfo(ifindex)) == NULL) 205 if ((rai = if_indextorainfo(ifindex)) == NULL)
206 continue; /* non-advertising IF */ 206 continue; /* non-advertising IF */
207 207
208 for (pp = rai->prefix.next; pp != &rai->prefix; 208 TAILQ_FOREACH(pp, &rai->prefix, next) {
209 pp = pp->next) { 
210 struct timeval now; 209 struct timeval now;
211 210
212 if (prefix_match(&pp->prefix, pp->prefixlen, 211 if (prefix_match(&pp->prefix, pp->prefixlen,
213 &rpm->rpm_prefix, 212 &rpm->rpm_prefix,
214 rpm->rpm_matchlen)) { 213 rpm->rpm_matchlen)) {
215 /* change parameters */ 214 /* change parameters */
216 pp->validlifetime = ntohl(rpu->rpu_vltime); 215 pp->validlifetime = ntohl(rpu->rpu_vltime);
217 pp->preflifetime = ntohl(rpu->rpu_pltime); 216 pp->preflifetime = ntohl(rpu->rpu_pltime);
218 if (irr->irr_rrf_decrvalid) { 217 if (irr->irr_rrf_decrvalid) {
219 gettimeofday(&now, 0); 218 gettimeofday(&now, 0);
220 pp->vltimeexpire = 219 pp->vltimeexpire =
221 now.tv_sec + pp->validlifetime; 220 now.tv_sec + pp->validlifetime;
222 } else 221 } else
@@ -278,98 +277,98 @@ do_pco(struct icmp6_router_renum *rr, in @@ -278,98 +277,98 @@ do_pco(struct icmp6_router_renum *rr, in
278 syslog(LOG_ERR, "<%s> if_indextoname: %s", __func__, 277 syslog(LOG_ERR, "<%s> if_indextoname: %s", __func__,
279 strerror(errno)); 278 strerror(errno));
280 return 1; 279 return 1;
281 } 280 }
282 return 0; 281 return 0;
283} 282}
284 283
285/* 284/*
286 * call do_pco() for each Prefix Control Operations(PCOs) in a received 285 * call do_pco() for each Prefix Control Operations(PCOs) in a received
287 * Router Renumbering Command packet. 286 * Router Renumbering Command packet.
288 * return 0 on success, 1 on failure 287 * return 0 on success, 1 on failure
289 */ 288 */
290static int 289static int
291do_rr(int len, struct icmp6_router_renum *rr) 290do_rr(size_t len, struct icmp6_router_renum *rr)
292{ 291{
293 struct rr_pco_match *rpm; 292 struct rr_pco_match *rpm;
294 char *cp, *lim; 293 char *cp, *lim;
295 294
296 lim = (char *)rr + len; 295 lim = (char *)rr + len;
297 cp = (char *)(rr + 1); 296 cp = (char *)(rr + 1);
298 len -= sizeof(struct icmp6_router_renum); 297 len -= sizeof(struct icmp6_router_renum);
299 298
300 /* get iflist block from kernel again, to get up-to-date information */ 299 /* get iflist block from kernel again, to get up-to-date information */
301 init_iflist(); 300 init_iflist();
302 301
303 while (cp < lim) { 302 while (cp < lim) {
304 int rpmlen; 303 size_t rpmlen;
305 304
306 rpm = (struct rr_pco_match *)cp; 305 rpm = (struct rr_pco_match *)cp;
307 if (len < sizeof(struct rr_pco_match)) { 306 if (len < sizeof(struct rr_pco_match)) {
308 tooshort: 307 tooshort:
309 syslog(LOG_ERR, "<%s> pkt too short. left len = %d. " 308 syslog(LOG_ERR, "<%s> pkt too short. left len = %zd. "
310 "gabage at end of pkt?", __func__, len); 309 "gabage at end of pkt?", __func__, len);
311 return 1; 310 return 1;
312 } 311 }
313 rpmlen = rpm->rpm_len << 3; 312 rpmlen = rpm->rpm_len << 3;
314 if (len < rpmlen) 313 if (len < rpmlen)
315 goto tooshort; 314 goto tooshort;
316 315
317 if (do_pco(rr, rpmlen, rpm)) { 316 if (do_pco(rr, rpmlen, rpm)) {
318 syslog(LOG_WARNING, "<%s> invalid PCO", __func__); 317 syslog(LOG_WARNING, "<%s> invalid PCO", __func__);
319 goto next; 318 goto next;
320 } 319 }
321 320
322 next: 321 next:
323 cp += rpmlen; 322 cp += rpmlen;
324 len -= rpmlen; 323 len -= rpmlen;
325 } 324 }
326 325
327 return 0; 326 return 0;
328} 327}
329 328
330/* 329/*
331 * check validity of a router renumbering command packet 330 * check validity of a router renumbering command packet
332 * return 0 on success, 1 on failure 331 * return 0 on success, 1 on failure
333 */ 332 */
334static int 333static int
335rr_command_check(int len, struct icmp6_router_renum *rr, struct in6_addr *from, 334rr_command_check(size_t len, struct icmp6_router_renum *rr,
336 struct in6_addr *dst) 335 struct in6_addr *from, struct in6_addr *dst)
337{ 336{
338 char ntopbuf[INET6_ADDRSTRLEN]; 337 char ntopbuf[INET6_ADDRSTRLEN];
339 338
340 /* omit rr minimal length check. hope kernel have done it. */ 339 /* omit rr minimal length check. hope kernel have done it. */
341 /* rr_command length check */ 340 /* rr_command length check */
342 if (len < (sizeof(struct icmp6_router_renum) + 341 if (len < (sizeof(struct icmp6_router_renum) +
343 sizeof(struct rr_pco_match))) { 342 sizeof(struct rr_pco_match))) {
344 syslog(LOG_ERR, "<%s> rr_command len %d is too short", 343 syslog(LOG_ERR, "<%s> rr_command len %zd is too short",
345 __func__, len); 344 __func__, len);
346 return 1; 345 return 1;
347 } 346 }
348 347
349 /* destination check. only for multicast. omit unicast check. */ 348 /* destination check. only for multicast. omit unicast check. */
350 if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) && 349 if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) &&
351 !IN6_IS_ADDR_MC_SITELOCAL(dst)) { 350 !IN6_IS_ADDR_MC_SITELOCAL(dst)) {
352 syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal", 351 syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal",
353 __func__, 352 __func__,
354 inet_ntop(AF_INET6, dst, ntopbuf, INET6_ADDRSTRLEN)); 353 inet_ntop(AF_INET6, dst, ntopbuf, INET6_ADDRSTRLEN));
355 return 1; 354 return 1;
356 } 355 }
357 356
358 /* seqnum and segnum check */ 357 /* seqnum and segnum check */
359 if (rro.rro_seqnum > rr->rr_seqnum) { 358 if (rro.rro_seqnum > rr->rr_seqnum) {
360 syslog(LOG_WARNING, 359 syslog(LOG_WARNING,
361 "<%s> rcvd old seqnum %d from %s", 360 "<%s> rcvd old seqnum %d from %s",
362 __func__, (u_int32_t)ntohl(rr->rr_seqnum), 361 __func__, (uint32_t)ntohl(rr->rr_seqnum),
363 inet_ntop(AF_INET6, from, ntopbuf, INET6_ADDRSTRLEN)); 362 inet_ntop(AF_INET6, from, ntopbuf, INET6_ADDRSTRLEN));
364 return 1; 363 return 1;
365 } 364 }
366 if (rro.rro_seqnum == rr->rr_seqnum && 365 if (rro.rro_seqnum == rr->rr_seqnum &&
367 (rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 && 366 (rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 &&
368 RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) { 367 RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) {
369 if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0) 368 if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0)
370 syslog(LOG_WARNING, 369 syslog(LOG_WARNING,
371 "<%s> rcvd duped segnum %d from %s", 370 "<%s> rcvd duped segnum %d from %s",
372 __func__, rr->rr_segnum, 371 __func__, rr->rr_segnum,
373 inet_ntop(AF_INET6, from, ntopbuf, 372 inet_ntop(AF_INET6, from, ntopbuf,
374 INET6_ADDRSTRLEN)); 373 INET6_ADDRSTRLEN));
375 return 0; 374 return 0;
@@ -405,61 +404,63 @@ rr_command_input(int len, struct icmp6_r @@ -405,61 +404,63 @@ rr_command_input(int len, struct icmp6_r
405 } 404 }
406 405
407 /* update segnum */ 406 /* update segnum */
408 RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum); 407 RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum);
409 408
410 return; 409 return;
411 410
412 failed: 411 failed:
413 syslog(LOG_ERR, "<%s> received RR was invalid", __func__); 412 syslog(LOG_ERR, "<%s> received RR was invalid", __func__);
414 return; 413 return;
415} 414}
416 415
417void 416void
418rr_input(int len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi, 417rr_input(size_t len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi,
419 struct sockaddr_in6 *from, struct in6_addr *dst) 418 struct sockaddr_in6 *from, struct in6_addr *dst)
420{ 419{
421 char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 420 char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
422 421
423 syslog(LOG_DEBUG, 422 syslog(LOG_DEBUG,
424 "<%s> RR received from %s to %s on %s", 423 "<%s> RR received from %s to %s on %s",
425 __func__, 424 __func__,
426 inet_ntop(AF_INET6, &from->sin6_addr, 425 inet_ntop(AF_INET6, &from->sin6_addr,
427 ntopbuf[0], INET6_ADDRSTRLEN), 426 ntopbuf[0], INET6_ADDRSTRLEN),
428 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN), 427 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN),
429 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 428 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
430 429
431 /* packet validation based on Section 4.1 of RFC2894 */ 430 /* packet validation based on Section 4.1 of RFC2894 */
432 if (len < sizeof(struct icmp6_router_renum)) { 431 if (len < sizeof(struct icmp6_router_renum)) {
433 syslog(LOG_NOTICE, 432 syslog(LOG_NOTICE,
434 "<%s>: RR short message (size %d) from %s to %s on %s", 433 "<%s>: RR short message (size %zd) from %s to %s on %s",
435 __func__, len, 434 __func__, len,
436 inet_ntop(AF_INET6, &from->sin6_addr, 435 inet_ntop(AF_INET6, &from->sin6_addr,
437 ntopbuf[0], INET6_ADDRSTRLEN), 436 ntopbuf[0], INET6_ADDRSTRLEN),
438 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN), 437 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN),
439 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 438 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
440 return; 439 return;
441 } 440 }
442 441
443 /* 442 /*
444 * If the IPv6 destination address is neither an All Routers multicast 443 * If the IPv6 destination address is neither an All Routers multicast
445 * address [AARCH] nor one of the receiving router's unicast addresses, 444 * address [AARCH] nor one of the receiving router's unicast addresses,
446 * the message MUST be discarded and SHOULD be logged to network 445 * the message MUST be discarded and SHOULD be logged to network
447 * management. 446 * management.
448 * We rely on the kernel input routine for unicast addresses, and thus 447 * We rely on the kernel input routine for unicast addresses, and thus
449 * check multicast destinations only. 448 * check multicast destinations only.
450 */ 449 */
451 if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) && 450 if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) &&
452 !IN6_ARE_ADDR_EQUAL(&in6a_site_allrouters, &pi->ipi6_addr)) { 451 !IN6_ARE_ADDR_EQUAL(&sin6_sitelocal_allrouters.sin6_addr,
 452 &pi->ipi6_addr))
 453 {
453 syslog(LOG_NOTICE, 454 syslog(LOG_NOTICE,
454 "<%s>: RR message with invalid destination (%s) " 455 "<%s>: RR message with invalid destination (%s) "
455 "from %s on %s", 456 "from %s on %s",
456 __func__, 457 __func__,
457 inet_ntop(AF_INET6, &dst, ntopbuf[0], INET6_ADDRSTRLEN), 458 inet_ntop(AF_INET6, &dst, ntopbuf[0], INET6_ADDRSTRLEN),
458 inet_ntop(AF_INET6, &from->sin6_addr, 459 inet_ntop(AF_INET6, &from->sin6_addr,
459 ntopbuf[1], INET6_ADDRSTRLEN), 460 ntopbuf[1], INET6_ADDRSTRLEN),
460 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 461 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
461 return; 462 return;
462 } 463 }
463 464
464 rr_rcvifindex = pi->ipi6_ifindex; 465 rr_rcvifindex = pi->ipi6_ifindex;
465 466

cvs diff -r1.4 -r1.5 src/usr.sbin/rtadvd/Attic/rrenum.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/Attic/rrenum.h 2001/01/21 15:39:33 1.4
+++ src/usr.sbin/rtadvd/Attic/rrenum.h 2011/12/10 19:14:29 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rrenum.h,v 1.4 2001/01/21 15:39:33 itojun Exp $ */ 1/* $NetBSD: rrenum.h,v 1.5 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: rrenum.h,v 1.3 2001/01/21 15:37:14 itojun Exp $ */ 2/* $KAME: rrenum.h,v 1.3 2001/01/21 15:37:14 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1998 WIDE Project. 5 * Copyright (C) 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
@@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
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
33void rr_input __P((int, struct icmp6_router_renum *, struct in6_pktinfo *, 33void rr_input(size_t, struct icmp6_router_renum *, struct in6_pktinfo *,
34 struct sockaddr_in6 *, struct in6_addr *)); 34 struct sockaddr_in6 *, struct in6_addr *);

cvs diff -r1.35 -r1.36 src/usr.sbin/rtadvd/rtadvd.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/rtadvd.c 2009/04/19 08:40:48 1.35
+++ src/usr.sbin/rtadvd/rtadvd.c 2011/12/10 19:14:29 1.36
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rtadvd.c,v 1.35 2009/04/19 08:40:48 lukem Exp $ */ 1/* $NetBSD: rtadvd.c,v 1.36 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $ */ 2/* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz 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
@@ -56,106 +56,125 @@ @@ -56,106 +56,125 @@
56#include <syslog.h> 56#include <syslog.h>
57#include <util.h> 57#include <util.h>
58#include <poll.h> 58#include <poll.h>
59 59
60#include "rtadvd.h" 60#include "rtadvd.h"
61#include "rrenum.h" 61#include "rrenum.h"
62#include "advcap.h" 62#include "advcap.h"
63#include "timer.h" 63#include "timer.h"
64#include "if.h" 64#include "if.h"
65#include "config.h" 65#include "config.h"
66#include "dump.h" 66#include "dump.h"
67 67
68struct msghdr rcvmhdr; 68struct msghdr rcvmhdr;
69static u_char *rcvcmsgbuf; 69static unsigned char *rcvcmsgbuf;
70static size_t rcvcmsgbuflen; 70static size_t rcvcmsgbuflen;
71static u_char *sndcmsgbuf = NULL; 71static unsigned char *sndcmsgbuf = NULL;
72static size_t sndcmsgbuflen; 72static size_t sndcmsgbuflen;
73volatile sig_atomic_t do_dump; 73volatile sig_atomic_t do_dump;
74volatile sig_atomic_t do_die; 74volatile sig_atomic_t do_die;
75struct msghdr sndmhdr; 75struct msghdr sndmhdr;
76struct iovec rcviov[2]; 76struct iovec rcviov[2];
77struct iovec sndiov[2]; 77struct iovec sndiov[2];
78struct sockaddr_in6 rcvfrom; 78struct sockaddr_in6 rcvfrom;
79struct sockaddr_in6 sin6_allnodes = {sizeof(sin6_allnodes), AF_INET6}; 79static const char *dumpfilename = "/var/run/rtadvd.dump"; /* XXX configurable */
80struct in6_addr in6a_site_allrouters; 
81static char *dumpfilename = "/var/run/rtadvd.dump"; /* XXX: should be configurable */ 
82static char *mcastif; 80static char *mcastif;
83int sock; 81int sock;
84int rtsock = -1; 82int rtsock = -1;
85int accept_rr = 0; 83int accept_rr = 0;
86int dflag = 0, sflag = 0; 84int dflag = 0, sflag = 0;
87 85
88char *conffile = NULL; 86char *conffile = NULL;
89 87
90struct rainfo *ralist = NULL; 88struct ralist_head_t ralist = TAILQ_HEAD_INITIALIZER(ralist);
 89
91struct nd_optlist { 90struct nd_optlist {
92 struct nd_optlist *next; 91 TAILQ_ENTRY(nd_optlist) next;
93 struct nd_opt_hdr *opt; 92 struct nd_opt_hdr *opt;
94}; 93};
95union nd_opts { 94union nd_opts {
96 struct nd_opt_hdr *nd_opt_array[9]; 95 struct nd_opt_hdr *nd_opt_array[9];
97 struct { 96 struct {
98 struct nd_opt_hdr *zero; 97 struct nd_opt_hdr *zero;
99 struct nd_opt_hdr *src_lladdr; 98 struct nd_opt_hdr *src_lladdr;
100 struct nd_opt_hdr *tgt_lladdr; 99 struct nd_opt_hdr *tgt_lladdr;
101 struct nd_opt_prefix_info *pi; 100 struct nd_opt_prefix_info *pi;
102 struct nd_opt_rd_hdr *rh; 101 struct nd_opt_rd_hdr *rh;
103 struct nd_opt_mtu *mtu; 102 struct nd_opt_mtu *mtu;
104 struct nd_optlist *list; 103 TAILQ_HEAD(, nd_optlist) list;
105 } nd_opt_each; 104 } nd_opt_each;
106}; 105};
107#define nd_opts_src_lladdr nd_opt_each.src_lladdr 106#define nd_opts_src_lladdr nd_opt_each.src_lladdr
108#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr 107#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
109#define nd_opts_pi nd_opt_each.pi 108#define nd_opts_pi nd_opt_each.pi
110#define nd_opts_rh nd_opt_each.rh 109#define nd_opts_rh nd_opt_each.rh
111#define nd_opts_mtu nd_opt_each.mtu 110#define nd_opts_mtu nd_opt_each.mtu
112#define nd_opts_list nd_opt_each.list 111#define nd_opts_list nd_opt_each.list
113 112
114#define NDOPT_FLAG_SRCLINKADDR 0x1 113#define NDOPT_FLAG_SRCLINKADDR (1 << 0)
115#define NDOPT_FLAG_TGTLINKADDR 0x2 114#define NDOPT_FLAG_TGTLINKADDR (1 << 1)
116#define NDOPT_FLAG_PREFIXINFO 0x4 115#define NDOPT_FLAG_PREFIXINFO (1 << 2)
117#define NDOPT_FLAG_RDHDR 0x8 116#define NDOPT_FLAG_RDHDR (1 << 3)
118#define NDOPT_FLAG_MTU 0x10 117#define NDOPT_FLAG_MTU (1 << 4)
119 118#define NDOPT_FLAG_RDNSS (1 << 5)
120u_int32_t ndopt_flags[] = { 119#define NDOPT_FLAG_DNSSL (1 << 6)
121 0, NDOPT_FLAG_SRCLINKADDR, NDOPT_FLAG_TGTLINKADDR, 120
122 NDOPT_FLAG_PREFIXINFO, NDOPT_FLAG_RDHDR, NDOPT_FLAG_MTU, 121uint32_t ndopt_flags[] = {
 122 [ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR,
 123 [ND_OPT_TARGET_LINKADDR] = NDOPT_FLAG_TGTLINKADDR,
 124 [ND_OPT_PREFIX_INFORMATION] = NDOPT_FLAG_PREFIXINFO,
 125 [ND_OPT_REDIRECTED_HEADER] = NDOPT_FLAG_RDHDR,
 126 [ND_OPT_MTU] = NDOPT_FLAG_MTU,
 127 [ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS,
 128 [ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL,
 129};
 130
 131struct sockaddr_in6 sin6_linklocal_allnodes = {
 132 .sin6_len = sizeof(sin6_linklocal_allnodes),
 133 .sin6_family = AF_INET6,
 134 .sin6_addr = IN6ADDR_LINKLOCAL_ALLNODES_INIT,
 135};
 136struct sockaddr_in6 sin6_linklocal_allrouters = {
 137 .sin6_len = sizeof(sin6_linklocal_allrouters),
 138 .sin6_family = AF_INET6,
 139 .sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT,
 140};
 141struct sockaddr_in6 sin6_sitelocal_allrouters = {
 142 .sin6_len = sizeof(sin6_sitelocal_allrouters),
 143 .sin6_family = AF_INET6,
 144 .sin6_addr = IN6ADDR_SITELOCAL_ALLROUTERS_INIT,
123}; 145};
124 146
125int main __P((int, char *[])); 147int main(int, char *[]);
126static void set_die __P((int)); 148static void set_die(int);
127static void die __P((void)); 149static void die(void);
128static void sock_open __P((void)); 150static void sock_open(void);
129static void rtsock_open __P((void)); 151static void rtsock_open(void);
130static void rtadvd_input __P((void)); 152static void rtadvd_input(void);
131static void rs_input __P((int, struct nd_router_solicit *, 153static void rs_input(int, struct nd_router_solicit *,
132 struct in6_pktinfo *, struct sockaddr_in6 *)); 154 struct in6_pktinfo *, struct sockaddr_in6 *);
133static void ra_input __P((int, struct nd_router_advert *, 155static void ra_input(int, struct nd_router_advert *,
134 struct in6_pktinfo *, struct sockaddr_in6 *)); 156 struct in6_pktinfo *, struct sockaddr_in6 *);
135static int prefix_check __P((struct nd_opt_prefix_info *, struct rainfo *, 157static int prefix_check(struct nd_opt_prefix_info *, struct rainfo *,
136 struct sockaddr_in6 *)); 158 struct sockaddr_in6 *);
137static int nd6_options __P((struct nd_opt_hdr *, int, 159static int nd6_options(struct nd_opt_hdr *, int, union nd_opts *, uint32_t);
138 union nd_opts *, u_int32_t)); 160static void free_ndopts(union nd_opts *);
139static void free_ndopts __P((union nd_opts *)); 161static void ra_output(struct rainfo *);
140static void ra_output __P((struct rainfo *)); 162static void rtmsg_input(void);
141static void rtmsg_input __P((void)); 163static void rtadvd_set_dump_file(int);
142static void rtadvd_set_dump_file __P((int)); 164static void set_short_delay(struct rainfo *);
143static void set_short_delay __P((struct rainfo *)); 
144 165
145int 166int
146main(argc, argv) 167main(int argc, char *argv[])
147 int argc; 
148 char *argv[]; 
149{ 168{
150 struct pollfd set[2]; 169 struct pollfd set[2];
151 struct timeval *timeout; 170 struct timeval *timeout;
152 int i, ch; 171 int i, ch;
153 int fflag = 0, logopt; 172 int fflag = 0, logopt;
154 173
155 /* get command line options and arguments */ 174 /* get command line options and arguments */
156#define OPTIONS "c:dDfM:Rs" 175#define OPTIONS "c:dDfM:Rs"
157 while ((ch = getopt(argc, argv, OPTIONS)) != -1) { 176 while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
158#undef OPTIONS 177#undef OPTIONS
159 switch (ch) { 178 switch (ch) {
160 case 'c': 179 case 'c':
161 conffile = optarg; 180 conffile = optarg;
@@ -202,31 +221,26 @@ main(argc, argv) @@ -202,31 +221,26 @@ main(argc, argv)
202 (void)setlogmask(LOG_UPTO(LOG_ERR)); 221 (void)setlogmask(LOG_UPTO(LOG_ERR));
203 if (dflag == 1) 222 if (dflag == 1)
204 (void)setlogmask(LOG_UPTO(LOG_INFO)); 223 (void)setlogmask(LOG_UPTO(LOG_INFO));
205 224
206 /* timer initialization */ 225 /* timer initialization */
207 rtadvd_timer_init(); 226 rtadvd_timer_init();
208 227
209 /* get iflist block from kernel */ 228 /* get iflist block from kernel */
210 init_iflist(); 229 init_iflist();
211 230
212 while (argc--) 231 while (argc--)
213 getconfig(*argv++); 232 getconfig(*argv++);
214 233
215 if (inet_pton(AF_INET6, ALLNODES, &sin6_allnodes.sin6_addr) != 1) { 
216 fprintf(stderr, "fatal: inet_pton failed\n"); 
217 exit(1); 
218 } 
219 
220 if (!fflag) 234 if (!fflag)
221 daemon(1, 0); 235 daemon(1, 0);
222 236
223 sock_open(); 237 sock_open();
224 238
225 /* record the current PID */ 239 /* record the current PID */
226 if (pidfile(NULL) < 0) { 240 if (pidfile(NULL) < 0) {
227 syslog(LOG_ERR, 241 syslog(LOG_ERR,
228 "<%s> failed to open the pid log file, run anyway.", 242 "<%s> failed to open the pid log file, run anyway.",
229 __func__); 243 __func__);
230 } 244 }
231 245
232 set[0].fd = sock; 246 set[0].fd = sock;
@@ -276,66 +290,64 @@ main(argc, argv) @@ -276,66 +290,64 @@ main(argc, argv)
276 continue; 290 continue;
277 } 291 }
278 if (i == 0) /* timeout */ 292 if (i == 0) /* timeout */
279 continue; 293 continue;
280 if (rtsock != -1 && set[1].revents & POLLIN) 294 if (rtsock != -1 && set[1].revents & POLLIN)
281 rtmsg_input(); 295 rtmsg_input();
282 if (set[0].revents & POLLIN) 296 if (set[0].revents & POLLIN)
283 rtadvd_input(); 297 rtadvd_input();
284 } 298 }
285 exit(0); /* NOTREACHED */ 299 exit(0); /* NOTREACHED */
286} 300}
287 301
288static void 302static void
289rtadvd_set_dump_file(sig) 303rtadvd_set_dump_file(int sig)
290 int sig; 
291{ 304{
292 do_dump = 1; 305 do_dump = 1;
293} 306}
294 307
295static void 308static void
296set_die(sig) 309set_die(int sig)
297 int sig; 
298{ 310{
299 do_die = 1; 311 do_die = 1;
300} 312}
301 313
302static void 314static void
303die() 315die(void)
304{ 316{
305 struct rainfo *ra; 317 struct rainfo *ra;
306 int i; 318 int i;
307 const int retrans = MAX_FINAL_RTR_ADVERTISEMENTS; 319 const int retrans = MAX_FINAL_RTR_ADVERTISEMENTS;
308 320
309 if (dflag > 1) { 321 if (dflag > 1) {
310 syslog(LOG_DEBUG, "<%s> cease to be an advertising router\n", 322 syslog(LOG_DEBUG, "<%s> cease to be an advertising router\n",
311 __func__); 323 __func__);
312 } 324 }
313 325
314 for (ra = ralist; ra; ra = ra->next) { 326 TAILQ_FOREACH(ra, &ralist, next) {
315 ra->lifetime = 0; 327 ra->lifetime = 0;
316 make_packet(ra); 328 make_packet(ra);
317 } 329 }
318 for (i = 0; i < retrans; i++) { 330 for (i = 0; i < retrans; i++) {
319 for (ra = ralist; ra; ra = ra->next) 331 TAILQ_FOREACH(ra, &ralist, next)
320 ra_output(ra); 332 ra_output(ra);
321 sleep(MIN_DELAY_BETWEEN_RAS); 333 sleep(MIN_DELAY_BETWEEN_RAS);
322 } 334 }
323 exit(0); 335 exit(0);
324 /*NOTREACHED*/ 336 /*NOTREACHED*/
325} 337}
326 338
327static void 339static void
328rtmsg_input() 340rtmsg_input(void)
329{ 341{
330 int n, type, ifindex = 0, plen; 342 int n, type, ifindex = 0, plen;
331 size_t len; 343 size_t len;
332 union rt_msghdr_buf { 344 union rt_msghdr_buf {
333 struct rt_msghdr rt_msghdr; 345 struct rt_msghdr rt_msghdr;
334 char data[2048]; 346 char data[2048];
335 } buffer; 347 } buffer;
336 char *msg, *next, *lim; 348 char *msg, *next, *lim;
337 char ifname[IF_NAMESIZE]; 349 char ifname[IF_NAMESIZE];
338 struct prefix *prefix; 350 struct prefix *prefix;
339 struct rainfo *rai; 351 struct rainfo *rai;
340 struct in6_addr *addr; 352 struct in6_addr *addr;
341 char addrbuf[INET6_ADDRSTRLEN]; 353 char addrbuf[INET6_ADDRSTRLEN];
@@ -535,29 +547,29 @@ rtmsg_input() @@ -535,29 +547,29 @@ rtmsg_input()
535 /* 547 /*
536 * An advertised prefix has been added or invalidated. 548 * An advertised prefix has been added or invalidated.
537 * Will notice the change in a short delay. 549 * Will notice the change in a short delay.
538 */ 550 */
539 rai->initcounter = 0; 551 rai->initcounter = 0;
540 set_short_delay(rai); 552 set_short_delay(rai);
541 } 553 }
542 } 554 }
543 555
544 return; 556 return;
545} 557}
546 558
547void 559void
548rtadvd_input() 560rtadvd_input(void)
549{ 561{
550 int i; 562 ssize_t i;
551 int *hlimp = NULL; 563 int *hlimp = NULL;
552#ifdef OLDRAWSOCKET 564#ifdef OLDRAWSOCKET
553 struct ip6_hdr *ip; 565 struct ip6_hdr *ip;
554#endif  566#endif
555 struct icmp6_hdr *icp; 567 struct icmp6_hdr *icp;
556 int ifindex = 0; 568 int ifindex = 0;
557 struct cmsghdr *cm; 569 struct cmsghdr *cm;
558 struct in6_pktinfo *pi = NULL; 570 struct in6_pktinfo *pi = NULL;
559 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 571 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
560 struct in6_addr dst = in6addr_any; 572 struct in6_addr dst = in6addr_any;
561 573
562 /* 574 /*
563 * Get message. We reset msg_controllen since the field could 575 * Get message. We reset msg_controllen since the field could
@@ -600,39 +612,39 @@ rtadvd_input() @@ -600,39 +612,39 @@ rtadvd_input()
600 /* 612 /*
601 * If we happen to receive data on an interface which is now down, 613 * If we happen to receive data on an interface which is now down,
602 * just discard the data. 614 * just discard the data.
603 */ 615 */
604 if ((iflist[pi->ipi6_ifindex]->ifm_flags & IFF_UP) == 0) { 616 if ((iflist[pi->ipi6_ifindex]->ifm_flags & IFF_UP) == 0) {
605 syslog(LOG_INFO, 617 syslog(LOG_INFO,
606 "<%s> received data on a disabled interface (%s)", 618 "<%s> received data on a disabled interface (%s)",
607 __func__, 619 __func__,
608 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 620 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
609 return; 621 return;
610 } 622 }
611 623
612#ifdef OLDRAWSOCKET 624#ifdef OLDRAWSOCKET
613 if (i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) { 625 if ((size_t)i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) {
614 syslog(LOG_ERR, 626 syslog(LOG_ERR,
615 "<%s> packet size(%d) is too short", 627 "<%s> packet size(%d) is too short",
616 __func__, i); 628 __func__, i);
617 return; 629 return;
618 } 630 }
619 631
620 ip = (struct ip6_hdr *)rcvmhdr.msg_iov[0].iov_base; 632 ip = (struct ip6_hdr *)rcvmhdr.msg_iov[0].iov_base;
621 icp = (struct icmp6_hdr *)(ip + 1); /* XXX: ext. hdr? */ 633 icp = (struct icmp6_hdr *)(ip + 1); /* XXX: ext. hdr? */
622#else 634#else
623 if (i < sizeof(struct icmp6_hdr)) { 635 if ((size_t)i < sizeof(struct icmp6_hdr)) {
624 syslog(LOG_ERR, 636 syslog(LOG_ERR,
625 "<%s> packet size(%d) is too short", 637 "<%s> packet size(%zd) is too short",
626 __func__, i); 638 __func__, i);
627 return; 639 return;
628 } 640 }
629 641
630 icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base; 642 icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base;
631#endif 643#endif
632 644
633 switch (icp->icmp6_type) { 645 switch (icp->icmp6_type) {
634 case ND_ROUTER_SOLICIT: 646 case ND_ROUTER_SOLICIT:
635 /* 647 /*
636 * Message verification - RFC-2461 6.1.1 648 * Message verification - RFC-2461 6.1.1
637 * XXX: these checks must be done in the kernel as well, 649 * XXX: these checks must be done in the kernel as well,
638 * but we can't completely rely on them. 650 * but we can't completely rely on them.
@@ -647,30 +659,30 @@ rtadvd_input() @@ -647,30 +659,30 @@ rtadvd_input()
647 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 659 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
648 return; 660 return;
649 } 661 }
650 if (icp->icmp6_code) { 662 if (icp->icmp6_code) {
651 syslog(LOG_NOTICE, 663 syslog(LOG_NOTICE,
652 "<%s> RS with invalid ICMP6 code(%d) " 664 "<%s> RS with invalid ICMP6 code(%d) "
653 "received from %s on %s", 665 "received from %s on %s",
654 __func__, icp->icmp6_code, 666 __func__, icp->icmp6_code,
655 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 667 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
656 INET6_ADDRSTRLEN), 668 INET6_ADDRSTRLEN),
657 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 669 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
658 return; 670 return;
659 } 671 }
660 if (i < sizeof(struct nd_router_solicit)) { 672 if ((size_t)i < sizeof(struct nd_router_solicit)) {
661 syslog(LOG_NOTICE, 673 syslog(LOG_NOTICE,
662 "<%s> RS from %s on %s does not have enough " 674 "<%s> RS from %s on %s does not have enough "
663 "length (len = %d)", 675 "length (len = %zd)",
664 __func__, 676 __func__,
665 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 677 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
666 INET6_ADDRSTRLEN), 678 INET6_ADDRSTRLEN),
667 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i); 679 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
668 return; 680 return;
669 } 681 }
670 rs_input(i, (struct nd_router_solicit *)icp, pi, &rcvfrom); 682 rs_input(i, (struct nd_router_solicit *)icp, pi, &rcvfrom);
671 break; 683 break;
672 case ND_ROUTER_ADVERT: 684 case ND_ROUTER_ADVERT:
673 /* 685 /*
674 * Message verification - RFC-2461 6.1.2 686 * Message verification - RFC-2461 6.1.2
675 * XXX: there's a same dilemma as above...  687 * XXX: there's a same dilemma as above...
676 */ 688 */
@@ -684,30 +696,30 @@ rtadvd_input() @@ -684,30 +696,30 @@ rtadvd_input()
684 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 696 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
685 return; 697 return;
686 } 698 }
687 if (icp->icmp6_code) { 699 if (icp->icmp6_code) {
688 syslog(LOG_NOTICE, 700 syslog(LOG_NOTICE,
689 "<%s> RA with invalid ICMP6 code(%d) " 701 "<%s> RA with invalid ICMP6 code(%d) "
690 "received from %s on %s", 702 "received from %s on %s",
691 __func__, icp->icmp6_code, 703 __func__, icp->icmp6_code,
692 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 704 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
693 INET6_ADDRSTRLEN), 705 INET6_ADDRSTRLEN),
694 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 706 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
695 return; 707 return;
696 } 708 }
697 if (i < sizeof(struct nd_router_advert)) { 709 if ((size_t)i < sizeof(struct nd_router_advert)) {
698 syslog(LOG_NOTICE, 710 syslog(LOG_NOTICE,
699 "<%s> RA from %s on %s does not have enough " 711 "<%s> RA from %s on %s does not have enough "
700 "length (len = %d)", 712 "length (len = %zd)",
701 __func__, 713 __func__,
702 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 714 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
703 INET6_ADDRSTRLEN), 715 INET6_ADDRSTRLEN),
704 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i); 716 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
705 return; 717 return;
706 } 718 }
707 ra_input(i, (struct nd_router_advert *)icp, pi, &rcvfrom); 719 ra_input(i, (struct nd_router_advert *)icp, pi, &rcvfrom);
708 break; 720 break;
709 case ICMP6_ROUTER_RENUMBERING: 721 case ICMP6_ROUTER_RENUMBERING:
710 if (accept_rr == 0) { 722 if (accept_rr == 0) {
711 syslog(LOG_ERR, "<%s> received a router renumbering " 723 syslog(LOG_ERR, "<%s> received a router renumbering "
712 "message, but not allowed to be accepted", 724 "message, but not allowed to be accepted",
713 __func__); 725 __func__);
@@ -739,26 +751,27 @@ rs_input(int len, struct nd_router_solic @@ -739,26 +751,27 @@ rs_input(int len, struct nd_router_solic
739 union nd_opts ndopts; 751 union nd_opts ndopts;
740 struct rainfo *ra; 752 struct rainfo *ra;
741 struct soliciter *sol; 753 struct soliciter *sol;
742 754
743 syslog(LOG_DEBUG, 755 syslog(LOG_DEBUG,
744 "<%s> RS received from %s on %s", 756 "<%s> RS received from %s on %s",
745 __func__, 757 __func__,
746 inet_ntop(AF_INET6, &from->sin6_addr, 758 inet_ntop(AF_INET6, &from->sin6_addr,
747 ntopbuf, INET6_ADDRSTRLEN), 759 ntopbuf, INET6_ADDRSTRLEN),
748 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 760 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
749 761
750 /* ND option check */ 762 /* ND option check */
751 memset(&ndopts, 0, sizeof(ndopts)); 763 memset(&ndopts, 0, sizeof(ndopts));
 764 TAILQ_INIT(&ndopts.nd_opts_list);
752 if (nd6_options((struct nd_opt_hdr *)(rs + 1), 765 if (nd6_options((struct nd_opt_hdr *)(rs + 1),
753 len - sizeof(struct nd_router_solicit), 766 len - sizeof(struct nd_router_solicit),
754 &ndopts, NDOPT_FLAG_SRCLINKADDR)) { 767 &ndopts, NDOPT_FLAG_SRCLINKADDR)) {
755 syslog(LOG_INFO, 768 syslog(LOG_INFO,
756 "<%s> ND option check failed for an RS from %s on %s", 769 "<%s> ND option check failed for an RS from %s on %s",
757 __func__, 770 __func__,
758 inet_ntop(AF_INET6, &from->sin6_addr, 771 inet_ntop(AF_INET6, &from->sin6_addr,
759 ntopbuf, INET6_ADDRSTRLEN), 772 ntopbuf, INET6_ADDRSTRLEN),
760 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 773 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
761 return; 774 return;
762 } 775 }
763 776
764 /* 777 /*
@@ -766,74 +779,70 @@ rs_input(int len, struct nd_router_solic @@ -766,74 +779,70 @@ rs_input(int len, struct nd_router_solic
766 * must be no source link-layer address option in the message. 779 * must be no source link-layer address option in the message.
767 * (RFC-2461 6.1.1) 780 * (RFC-2461 6.1.1)
768 */ 781 */
769 if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) && 782 if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) &&
770 ndopts.nd_opts_src_lladdr) { 783 ndopts.nd_opts_src_lladdr) {
771 syslog(LOG_INFO, 784 syslog(LOG_INFO,
772 "<%s> RS from unspecified src on %s has a link-layer" 785 "<%s> RS from unspecified src on %s has a link-layer"
773 " address option", 786 " address option",
774 __func__, 787 __func__,
775 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 788 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
776 goto done; 789 goto done;
777 } 790 }
778 791
779 ra = ralist; 792 TAILQ_FOREACH(ra, &ralist, next) {
780 while (ra != NULL) { 
781 if (pi->ipi6_ifindex == ra->ifindex) 793 if (pi->ipi6_ifindex == ra->ifindex)
782 break; 794 break;
783 ra = ra->next; 
784 } 795 }
785 if (ra == NULL) { 796 if (ra == NULL) {
786 syslog(LOG_INFO, 797 syslog(LOG_INFO,
787 "<%s> RS received on non advertising interface(%s)", 798 "<%s> RS received on non advertising interface(%s)",
788 __func__, 799 __func__,
789 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 800 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
790 goto done; 801 goto done;
791 } 802 }
792 803
793 ra->rsinput++; /* increment statistics */ 804 ra->rsinput++; /* increment statistics */
794 805
795 /* 806 /*
796 * Decide whether to send RA according to the rate-limit 807 * Decide whether to send RA according to the rate-limit
797 * consideration. 808 * consideration.
798 */ 809 */
799 810
800 /* record sockaddr waiting for RA, if possible */ 811 /* record sockaddr waiting for RA, if possible */
801 sol = (struct soliciter *)malloc(sizeof(*sol)); 812 sol = malloc(sizeof(*sol));
802 if (sol) { 813 if (sol) {
803 sol->addr = *from; 814 sol->addr = *from;
804 /* XXX RFC2553 need clarification on flowinfo */ 815 /* XXX RFC2553 need clarification on flowinfo */
805 sol->addr.sin6_flowinfo = 0; 816 sol->addr.sin6_flowinfo = 0;
806 sol->next = ra->soliciter; 817 TAILQ_INSERT_HEAD(&ra->soliciter, sol, next);
807 ra->soliciter = sol; 
808 } 818 }
809 819
810 /* 820 /*
811 * If there is already a waiting RS packet, don't 821 * If there is already a waiting RS packet, don't
812 * update the timer. 822 * update the timer.
813 */ 823 */
814 if (ra->waiting++) 824 if (ra->waiting++)
815 goto done; 825 goto done;
816 826
817 set_short_delay(ra); 827 set_short_delay(ra);
818 828
819done: 829done:
820 free_ndopts(&ndopts); 830 free_ndopts(&ndopts);
821 return; 831 return;
822} 832}
823 833
824static void 834static void
825set_short_delay(rai) 835set_short_delay(struct rainfo *rai)
826 struct rainfo *rai; 
827{ 836{
828 long delay; /* must not be greater than 1000000 */ 837 long delay; /* must not be greater than 1000000 */
829 struct timeval interval, now, min_delay, tm_tmp, *rest; 838 struct timeval interval, now, min_delay, tm_tmp, *rest;
830 839
831 /* 840 /*
832 * Compute a random delay. If the computed value 841 * Compute a random delay. If the computed value
833 * corresponds to a time later than the time the next 842 * corresponds to a time later than the time the next
834 * multicast RA is scheduled to be sent, ignore the random 843 * multicast RA is scheduled to be sent, ignore the random
835 * delay and send the advertisement at the 844 * delay and send the advertisement at the
836 * already-scheduled time. RFC2461 6.2.6 845 * already-scheduled time. RFC2461 6.2.6
837 */ 846 */
838 delay = arc4random() % MAX_RA_DELAY_TIME; 847 delay = arc4random() % MAX_RA_DELAY_TIME;
839 interval.tv_sec = 0; 848 interval.tv_sec = 0;
@@ -860,49 +869,53 @@ set_short_delay(rai) @@ -860,49 +869,53 @@ set_short_delay(rai)
860 TIMEVAL_SUB(&min_delay, &tm_tmp, &min_delay); 869 TIMEVAL_SUB(&min_delay, &tm_tmp, &min_delay);
861 TIMEVAL_ADD(&min_delay, &interval, &interval); 870 TIMEVAL_ADD(&min_delay, &interval, &interval);
862 } 871 }
863 rtadvd_set_timer(&interval, rai->timer); 872 rtadvd_set_timer(&interval, rai->timer);
864} 873}
865 874
866static void 875static void
867ra_input(int len, struct nd_router_advert *ra, 876ra_input(int len, struct nd_router_advert *ra,
868 struct in6_pktinfo *pi, struct sockaddr_in6 *from) 877 struct in6_pktinfo *pi, struct sockaddr_in6 *from)
869{ 878{
870 struct rainfo *rai; 879 struct rainfo *rai;
871 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 880 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
872 union nd_opts ndopts; 881 union nd_opts ndopts;
873 char *on_off[] = {"OFF", "ON"}; 882 const char *on_off[] = {"OFF", "ON"};
874 u_int32_t reachabletime, retranstimer, mtu; 883 uint32_t reachabletime, retranstimer, mtu;
 884 struct nd_optlist *optp;
875 int inconsistent = 0; 885 int inconsistent = 0;
876 886
877 syslog(LOG_DEBUG, 887 syslog(LOG_DEBUG,
878 "<%s> RA received from %s on %s", 888 "<%s> RA received from %s on %s",
879 __func__, 889 __func__,
880 inet_ntop(AF_INET6, &from->sin6_addr, 890 inet_ntop(AF_INET6, &from->sin6_addr,
881 ntopbuf, INET6_ADDRSTRLEN), 891 ntopbuf, INET6_ADDRSTRLEN),
882 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 892 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
883  893
884 /* ND option check */ 894 /* ND option check */
885 memset(&ndopts, 0, sizeof(ndopts)); 895 memset(&ndopts, 0, sizeof(ndopts));
 896 TAILQ_INIT(&ndopts.nd_opts_list);
886 if (nd6_options((struct nd_opt_hdr *)(ra + 1), 897 if (nd6_options((struct nd_opt_hdr *)(ra + 1),
887 len - sizeof(struct nd_router_advert), 898 len - sizeof(struct nd_router_advert),
888 &ndopts, NDOPT_FLAG_SRCLINKADDR | 899 &ndopts, NDOPT_FLAG_SRCLINKADDR |
889 NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU)) { 900 NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
 901 NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL))
 902 {
890 syslog(LOG_INFO, 903 syslog(LOG_INFO,
891 "<%s> ND option check failed for an RA from %s on %s", 904 "<%s> ND option check failed for an RA from %s on %s",
892 __func__, 905 __func__,
893 inet_ntop(AF_INET6, &from->sin6_addr, 906 inet_ntop(AF_INET6, &from->sin6_addr,
894 ntopbuf, INET6_ADDRSTRLEN), 907 ntopbuf, INET6_ADDRSTRLEN),
895 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 908 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
896 return; 909 return;
897 } 910 }
898 911
899 /* 912 /*
900 * RA consistency check according to RFC-2461 6.2.7 913 * RA consistency check according to RFC-2461 6.2.7
901 */ 914 */
902 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == 0) { 915 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == 0) {
903 syslog(LOG_INFO, 916 syslog(LOG_INFO,
904 "<%s> received RA from %s on non-advertising" 917 "<%s> received RA from %s on non-advertising"
905 " interface(%s)", 918 " interface(%s)",
906 __func__, 919 __func__,
907 inet_ntop(AF_INET6, &from->sin6_addr, 920 inet_ntop(AF_INET6, &from->sin6_addr,
908 ntopbuf, INET6_ADDRSTRLEN), 921 ntopbuf, INET6_ADDRSTRLEN),
@@ -989,55 +1002,48 @@ ra_input(int len, struct nd_router_adver @@ -989,55 +1002,48 @@ ra_input(int len, struct nd_router_adver
989 if (mtu && rai->linkmtu && mtu != rai->linkmtu) { 1002 if (mtu && rai->linkmtu && mtu != rai->linkmtu) {
990 syslog(LOG_INFO, 1003 syslog(LOG_INFO,
991 "<%s> MTU option value inconsistent on %s:" 1004 "<%s> MTU option value inconsistent on %s:"
992 " %d from %s, %d from us", 1005 " %d from %s, %d from us",
993 __func__, 1006 __func__,
994 rai->ifname, mtu, 1007 rai->ifname, mtu,
995 inet_ntop(AF_INET6, &from->sin6_addr, 1008 inet_ntop(AF_INET6, &from->sin6_addr,
996 ntopbuf, INET6_ADDRSTRLEN), 1009 ntopbuf, INET6_ADDRSTRLEN),
997 rai->linkmtu); 1010 rai->linkmtu);
998 inconsistent++; 1011 inconsistent++;
999 } 1012 }
1000 } 1013 }
1001 /* Preferred and Valid Lifetimes for prefixes */ 1014 /* Preferred and Valid Lifetimes for prefixes */
1002 { 1015 if (ndopts.nd_opts_pi)
1003 struct nd_optlist *optp = ndopts.nd_opts_list; 1016 if (prefix_check(ndopts.nd_opts_pi, rai, from))
1004 1017 inconsistent++;
1005 if (ndopts.nd_opts_pi) { 1018 TAILQ_FOREACH(optp, &ndopts.nd_opts_list, next)
1006 if (prefix_check(ndopts.nd_opts_pi, rai, from)) 1019 if (prefix_check((struct nd_opt_prefix_info *)optp->opt,
1007 inconsistent++; 1020 rai, from))
1008 } 1021 inconsistent++;
1009 while (optp) { 
1010 if (prefix_check((struct nd_opt_prefix_info *)optp->opt, 
1011 rai, from)) 
1012 inconsistent++; 
1013 optp = optp->next; 
1014 } 
1015 } 
1016 1022
1017 if (inconsistent) 1023 if (inconsistent)
1018 rai->rainconsistent++; 1024 rai->rainconsistent++;
1019  1025
1020done: 1026done:
1021 free_ndopts(&ndopts); 1027 free_ndopts(&ndopts);
1022 return; 1028 return;
1023} 1029}
1024 1030
1025/* return a non-zero value if the received prefix is inconsitent with ours */ 1031/* return a non-zero value if the received prefix is inconsitent with ours */
1026static int 1032static int
1027prefix_check(struct nd_opt_prefix_info *pinfo, 1033prefix_check(struct nd_opt_prefix_info *pinfo,
1028 struct rainfo *rai, struct sockaddr_in6 *from) 1034 struct rainfo *rai, struct sockaddr_in6 *from)
1029{ 1035{
1030 u_int32_t preferred_time, valid_time; 1036 uint32_t preferred_time, valid_time;
1031 struct prefix *pp; 1037 struct prefix *pp;
1032 int inconsistent = 0; 1038 int inconsistent = 0;
1033 char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN]; 1039 char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN];
1034 struct timeval now; 1040 struct timeval now;
1035 1041
1036#if 0 /* impossible */ 1042#if 0 /* impossible */
1037 if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION) 1043 if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION)
1038 return(0); 1044 return(0);
1039#endif 1045#endif
1040 1046
1041 /* 1047 /*
1042 * log if the adveritsed prefix has link-local scope(sanity check?) 1048 * log if the adveritsed prefix has link-local scope(sanity check?)
1043 */ 1049 */
@@ -1146,96 +1152,98 @@ prefix_check(struct nd_opt_prefix_info * @@ -1146,96 +1152,98 @@ prefix_check(struct nd_opt_prefix_info *
1146 ntopbuf, INET6_ADDRSTRLEN), 1152 ntopbuf, INET6_ADDRSTRLEN),
1147 pp->validlifetime); 1153 pp->validlifetime);
1148 inconsistent++; 1154 inconsistent++;
1149 } 1155 }
1150 1156
1151 return(inconsistent); 1157 return(inconsistent);
1152} 1158}
1153 1159
1154struct prefix * 1160struct prefix *
1155find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen) 1161find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen)
1156{ 1162{
1157 struct prefix *pp; 1163 struct prefix *pp;
1158 int bytelen, bitlen; 1164 int bytelen, bitlen;
1159 u_char bitmask; 1165 unsigned char bitmask;
1160 1166
1161 for (pp = rai->prefix.next; pp != &rai->prefix; pp = pp->next) { 1167 TAILQ_FOREACH(pp, &rai->prefix, next) {
1162 if (plen != pp->prefixlen) 1168 if (plen != pp->prefixlen)
1163 continue; 1169 continue;
1164 bytelen = plen / 8; 1170 bytelen = plen / 8;
1165 bitlen = plen % 8; 1171 bitlen = plen % 8;
1166 bitmask = 0xff << (8 - bitlen); 1172 bitmask = 0xff << (8 - bitlen);
1167 if (memcmp((void *)prefix, (void *)&pp->prefix, bytelen)) 1173 if (memcmp((void *)prefix, (void *)&pp->prefix, bytelen))
1168 continue; 1174 continue;
1169 if (bitlen == 0 || 1175 if (bitlen == 0 ||
1170 ((prefix->s6_addr[bytelen] & bitmask) ==  1176 ((prefix->s6_addr[bytelen] & bitmask) ==
1171 (pp->prefix.s6_addr[bytelen] & bitmask))) { 1177 (pp->prefix.s6_addr[bytelen] & bitmask))) {
1172 return(pp); 1178 return(pp);
1173 } 1179 }
1174 } 1180 }
1175 1181
1176 return(NULL); 1182 return(NULL);
1177} 1183}
1178 1184
1179/* check if p0/plen0 matches p1/plen1; return 1 if matches, otherwise 0. */ 1185/* check if p0/plen0 matches p1/plen1; return 1 if matches, otherwise 0. */
1180int 1186int
1181prefix_match(struct in6_addr *p0, int plen0, 1187prefix_match(struct in6_addr *p0, int plen0,
1182 struct in6_addr *p1, int plen1) 1188 struct in6_addr *p1, int plen1)
1183{ 1189{
1184 int bytelen, bitlen; 1190 int bytelen, bitlen;
1185 u_char bitmask; 1191 unsigned char bitmask;
1186 1192
1187 if (plen0 < plen1) 1193 if (plen0 < plen1)
1188 return(0); 1194 return(0);
1189 bytelen = plen1 / 8; 1195 bytelen = plen1 / 8;
1190 bitlen = plen1 % 8; 1196 bitlen = plen1 % 8;
1191 bitmask = 0xff << (8 - bitlen); 1197 bitmask = 0xff << (8 - bitlen);
1192 if (memcmp((void *)p0, (void *)p1, bytelen)) 1198 if (memcmp((void *)p0, (void *)p1, bytelen))
1193 return(0); 1199 return(0);
1194 if (bitlen == 0 || 1200 if (bitlen == 0 ||
1195 ((p0->s6_addr[bytelen] & bitmask) == 1201 ((p0->s6_addr[bytelen] & bitmask) ==
1196 (p1->s6_addr[bytelen] & bitmask))) {  1202 (p1->s6_addr[bytelen] & bitmask))) {
1197 return(1); 1203 return(1);
1198 } 1204 }
1199 1205
1200 return(0); 1206 return(0);
1201} 1207}
1202 1208
1203static int 1209static int
1204nd6_options(struct nd_opt_hdr *hdr, int limit, 1210nd6_options(struct nd_opt_hdr *hdr, int limit,
1205 union nd_opts *ndopts, u_int32_t optflags) 1211 union nd_opts *ndopts, uint32_t optflags)
1206{ 1212{
1207 int optlen = 0; 1213 int optlen = 0;
1208 1214
1209 for (; limit > 0; limit -= optlen) { 1215 for (; limit > 0; limit -= optlen) {
1210 if (limit < sizeof(struct nd_opt_hdr)) { 1216 if ((size_t)limit < sizeof(struct nd_opt_hdr)) {
1211 syslog(LOG_INFO, "<%s> short option header", __func__); 1217 syslog(LOG_INFO, "<%s> short option header", __func__);
1212 goto bad; 1218 goto bad;
1213 } 1219 }
1214 1220
1215 hdr = (struct nd_opt_hdr *)((caddr_t)hdr + optlen); 1221 hdr = (struct nd_opt_hdr *)((char *)hdr + optlen);
1216 if (hdr->nd_opt_len == 0) { 1222 if (hdr->nd_opt_len == 0) {
1217 syslog(LOG_INFO, 1223 syslog(LOG_INFO,
1218 "<%s> bad ND option length(0) (type = %d)", 1224 "<%s> bad ND option length(0) (type = %d)",
1219 __func__, hdr->nd_opt_type); 1225 __func__, hdr->nd_opt_type);
1220 goto bad; 1226 goto bad;
1221 } 1227 }
1222 optlen = hdr->nd_opt_len << 3; 1228 optlen = hdr->nd_opt_len << 3;
1223 if (optlen > limit) { 1229 if (optlen > limit) {
1224 syslog(LOG_INFO, "<%s> short option", __func__); 1230 syslog(LOG_INFO, "<%s> short option", __func__);
1225 goto bad; 1231 goto bad;
1226 } 1232 }
1227 1233
1228 if (hdr->nd_opt_type > ND_OPT_MTU) 1234 if (hdr->nd_opt_type > ND_OPT_MTU &&
 1235 hdr->nd_opt_type != ND_OPT_RDNSS &&
 1236 hdr->nd_opt_type != ND_OPT_DNSSL)
1229 { 1237 {
1230 syslog(LOG_INFO, "<%s> unknown ND option(type %d)", 1238 syslog(LOG_INFO, "<%s> unknown ND option(type %d)",
1231 __func__, hdr->nd_opt_type); 1239 __func__, hdr->nd_opt_type);
1232 continue; 1240 continue;
1233 } 1241 }
1234 1242
1235 if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) { 1243 if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) {
1236 syslog(LOG_INFO, "<%s> unexpected ND option(type %d)", 1244 syslog(LOG_INFO, "<%s> unexpected ND option(type %d)",
1237 __func__, hdr->nd_opt_type); 1245 __func__, hdr->nd_opt_type);
1238 continue; 1246 continue;
1239 } 1247 }
1240 1248
1241 /* 1249 /*
@@ -1268,78 +1276,76 @@ nd6_options(struct nd_opt_hdr *hdr, int  @@ -1268,78 +1276,76 @@ nd6_options(struct nd_opt_hdr *hdr, int
1268 { 1276 {
1269 struct nd_optlist *pfxlist; 1277 struct nd_optlist *pfxlist;
1270 1278
1271 if (ndopts->nd_opts_pi == 0) { 1279 if (ndopts->nd_opts_pi == 0) {
1272 ndopts->nd_opts_pi = 1280 ndopts->nd_opts_pi =
1273 (struct nd_opt_prefix_info *)hdr; 1281 (struct nd_opt_prefix_info *)hdr;
1274 continue; 1282 continue;
1275 } 1283 }
1276 if ((pfxlist = malloc(sizeof(*pfxlist))) == NULL) { 1284 if ((pfxlist = malloc(sizeof(*pfxlist))) == NULL) {
1277 syslog(LOG_ERR, "<%s> can't allocate memory", 1285 syslog(LOG_ERR, "<%s> can't allocate memory",
1278 __func__); 1286 __func__);
1279 goto bad; 1287 goto bad;
1280 } 1288 }
1281 pfxlist->next = ndopts->nd_opts_list; 
1282 pfxlist->opt = hdr; 1289 pfxlist->opt = hdr;
1283 ndopts->nd_opts_list = pfxlist; 1290 TAILQ_INSERT_TAIL(&ndopts->nd_opts_list, pfxlist, next);
1284 1291
1285 break; 1292 break;
1286 } 1293 }
1287 default: /* impossible */ 1294 default: /* impossible */
1288 break; 1295 break;
1289 } 1296 }
1290 } 1297 }
1291 1298
1292 return(0); 1299 return(0);
1293 1300
1294 bad: 1301 bad:
1295 free_ndopts(ndopts); 1302 free_ndopts(ndopts);
1296 1303
1297 return(-1); 1304 return(-1);
1298} 1305}
1299 1306
1300static void 1307static void
1301free_ndopts(union nd_opts *ndopts) 1308free_ndopts(union nd_opts *ndopts)
1302{ 1309{
1303 struct nd_optlist *opt = ndopts->nd_opts_list, *next; 1310 struct nd_optlist *opt;
1304 1311
1305 while (opt) { 1312 while ((opt = TAILQ_FIRST(&ndopts->nd_opts_list)) != NULL) {
1306 next = opt->next; 1313 TAILQ_REMOVE(&ndopts->nd_opts_list, opt, next);
1307 free(opt); 1314 free(opt);
1308 opt = next; 
1309 } 1315 }
1310} 1316}
1311 1317
1312void 1318void
1313sock_open() 1319sock_open(void)
1314{ 1320{
1315 struct icmp6_filter filt; 1321 struct icmp6_filter filt;
1316 struct ipv6_mreq mreq; 1322 struct ipv6_mreq mreq;
1317 struct rainfo *ra = ralist; 1323 struct rainfo *ra;
1318 int on; 1324 int on;
1319 /* XXX: should be max MTU attached to the node */ 1325 /* XXX: should be max MTU attached to the node */
1320 static u_char answer[1500]; 1326 static unsigned char answer[1500];
1321 1327
1322 rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 1328 rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1323 CMSG_SPACE(sizeof(int)); 1329 CMSG_SPACE(sizeof(int));
1324 rcvcmsgbuf = (u_char *)malloc(rcvcmsgbuflen); 1330 rcvcmsgbuf = malloc(rcvcmsgbuflen);
1325 if (rcvcmsgbuf == NULL) { 1331 if (rcvcmsgbuf == NULL) {
1326 syslog(LOG_ERR, "<%s> not enough core", __func__); 1332 syslog(LOG_ERR, "<%s> not enough core", __func__);
1327 exit(1); 1333 exit(1);
1328 } 1334 }
1329 1335
1330 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +  1336 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1331 CMSG_SPACE(sizeof(int)); 1337 CMSG_SPACE(sizeof(int));
1332 sndcmsgbuf = (u_char *)malloc(sndcmsgbuflen); 1338 sndcmsgbuf = malloc(sndcmsgbuflen);
1333 if (sndcmsgbuf == NULL) { 1339 if (sndcmsgbuf == NULL) {
1334 syslog(LOG_ERR, "<%s> not enough core", __func__); 1340 syslog(LOG_ERR, "<%s> not enough core", __func__);
1335 exit(1); 1341 exit(1);
1336 } 1342 }
1337 1343
1338 if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { 1344 if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
1339 syslog(LOG_ERR, "<%s> socket: %s", __func__, 1345 syslog(LOG_ERR, "<%s> socket: %s", __func__,
1340 strerror(errno)); 1346 strerror(errno));
1341 exit(1); 1347 exit(1);
1342 } 1348 }
1343 1349
1344 /* specify to tell receiving interface */ 1350 /* specify to tell receiving interface */
1345 on = 1; 1351 on = 1;
@@ -1383,139 +1389,138 @@ sock_open() @@ -1383,139 +1389,138 @@ sock_open()
1383 if (accept_rr) 1389 if (accept_rr)
1384 ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt); 1390 ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt);
1385 if (setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 1391 if (setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
1386 sizeof(filt)) < 0) { 1392 sizeof(filt)) < 0) {
1387 syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s", 1393 syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s",
1388 __func__, strerror(errno)); 1394 __func__, strerror(errno));
1389 exit(1); 1395 exit(1);
1390 } 1396 }
1391 1397
1392 /* 1398 /*
1393 * join all routers multicast address on each advertising interface. 1399 * join all routers multicast address on each advertising interface.
1394 */ 1400 */
1395 if (inet_pton(AF_INET6, ALLROUTERS_LINK, 1401 if (inet_pton(AF_INET6, ALLROUTERS_LINK,
1396 &mreq.ipv6mr_multiaddr.s6_addr) 1402 mreq.ipv6mr_multiaddr.s6_addr) != 1)
1397 != 1) { 1403 {
1398 syslog(LOG_ERR, "<%s> inet_pton failed(library bug?)", 1404 syslog(LOG_ERR, "<%s> inet_pton failed(library bug?)",
1399 __func__); 1405 __func__);
1400 exit(1); 1406 exit(1);
1401 } 1407 }
1402 while (ra) { 1408 TAILQ_FOREACH(ra, &ralist, next) {
1403 mreq.ipv6mr_interface = ra->ifindex; 1409 mreq.ipv6mr_interface = ra->ifindex;
1404 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, 1410 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq,
1405 sizeof(mreq)) < 0) { 1411 sizeof(mreq)) < 0) {
1406 syslog(LOG_ERR, "<%s> IPV6_JOIN_GROUP(link) on %s: %s", 1412 syslog(LOG_ERR, "<%s> IPV6_JOIN_GROUP(link) on %s: %s",
1407 __func__, ra->ifname, strerror(errno)); 1413 __func__, ra->ifname, strerror(errno));
1408 exit(1); 1414 exit(1);
1409 } 1415 }
1410 ra = ra->next; 
1411 } 1416 }
1412 1417
1413 /* 1418 /*
1414 * When attending router renumbering, join all-routers site-local 1419 * When attending router renumbering, join all-routers site-local
1415 * multicast group.  1420 * multicast group.
1416 */ 1421 */
1417 if (accept_rr) { 1422 if (accept_rr) {
1418 if (inet_pton(AF_INET6, ALLROUTERS_SITE, 1423 if (inet_pton(AF_INET6, ALLROUTERS_SITE,
1419 &in6a_site_allrouters) != 1) { 1424 mreq.ipv6mr_multiaddr.s6_addr) != 1)
 1425 {
1420 syslog(LOG_ERR, "<%s> inet_pton failed(library bug?)", 1426 syslog(LOG_ERR, "<%s> inet_pton failed(library bug?)",
1421 __func__); 1427 __func__);
1422 exit(1); 1428 exit(1);
1423 } 1429 }
1424 mreq.ipv6mr_multiaddr = in6a_site_allrouters; 1430 ra = TAILQ_FIRST(&ralist);
1425 if (mcastif) { 1431 if (mcastif) {
1426 if ((mreq.ipv6mr_interface = if_nametoindex(mcastif)) 1432 if ((mreq.ipv6mr_interface = if_nametoindex(mcastif))
1427 == 0) { 1433 == 0) {
1428 syslog(LOG_ERR, 1434 syslog(LOG_ERR,
1429 "<%s> invalid interface: %s", 1435 "<%s> invalid interface: %s",
1430 __func__, mcastif); 1436 __func__, mcastif);
1431 exit(1); 1437 exit(1);
1432 } 1438 }
1433 } else 1439 } else
1434 mreq.ipv6mr_interface = ralist->ifindex; 1440 mreq.ipv6mr_interface = ra->ifindex;
1435 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, 1441 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1436 &mreq, sizeof(mreq)) < 0) { 1442 &mreq, sizeof(mreq)) < 0) {
1437 syslog(LOG_ERR, 1443 syslog(LOG_ERR,
1438 "<%s> IPV6_JOIN_GROUP(site) on %s: %s", 1444 "<%s> IPV6_JOIN_GROUP(site) on %s: %s",
1439 __func__, 1445 __func__,
1440 mcastif ? mcastif : ralist->ifname, 1446 mcastif ? mcastif : ra->ifname,
1441 strerror(errno)); 1447 strerror(errno));
1442 exit(1); 1448 exit(1);
1443 } 1449 }
1444 } 1450 }
1445  1451
1446 /* initialize msghdr for receiving packets */ 1452 /* initialize msghdr for receiving packets */
1447 rcviov[0].iov_base = (caddr_t)answer; 1453 rcviov[0].iov_base = answer;
1448 rcviov[0].iov_len = sizeof(answer); 1454 rcviov[0].iov_len = sizeof(answer);
1449 rcvmhdr.msg_name = (caddr_t)&rcvfrom; 1455 rcvmhdr.msg_name = &rcvfrom;
1450 rcvmhdr.msg_namelen = sizeof(rcvfrom); 1456 rcvmhdr.msg_namelen = sizeof(rcvfrom);
1451 rcvmhdr.msg_iov = rcviov; 1457 rcvmhdr.msg_iov = rcviov;
1452 rcvmhdr.msg_iovlen = 1; 1458 rcvmhdr.msg_iovlen = 1;
1453 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; 1459 rcvmhdr.msg_control = rcvcmsgbuf;
1454 rcvmhdr.msg_controllen = rcvcmsgbuflen; 1460 rcvmhdr.msg_controllen = rcvcmsgbuflen;
1455 1461
1456 /* initialize msghdr for sending packets */ 1462 /* initialize msghdr for sending packets */
1457 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); 1463 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
1458 sndmhdr.msg_iov = sndiov; 1464 sndmhdr.msg_iov = sndiov;
1459 sndmhdr.msg_iovlen = 1; 1465 sndmhdr.msg_iovlen = 1;
1460 sndmhdr.msg_control = (caddr_t)sndcmsgbuf; 1466 sndmhdr.msg_control = (void *)sndcmsgbuf;
1461 sndmhdr.msg_controllen = sndcmsgbuflen; 1467 sndmhdr.msg_controllen = sndcmsgbuflen;
1462  1468
1463 return; 1469 return;
1464} 1470}
1465 1471
1466/* open a routing socket to watch the routing table */ 1472/* open a routing socket to watch the routing table */
1467static void 1473static void
1468rtsock_open() 1474rtsock_open(void)
1469{ 1475{
1470 if ((rtsock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) { 1476 if ((rtsock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
1471 syslog(LOG_ERR, 1477 syslog(LOG_ERR,
1472 "<%s> socket: %s", __func__, strerror(errno)); 1478 "<%s> socket: %s", __func__, strerror(errno));
1473 exit(1); 1479 exit(1);
1474 } 1480 }
1475} 1481}
1476 1482
1477struct rainfo * 1483struct rainfo *
1478if_indextorainfo(int idx) 1484if_indextorainfo(unsigned int idx)
1479{ 1485{
1480 struct rainfo *rai = ralist; 1486 struct rainfo *rai;
1481 1487
1482 for (rai = ralist; rai; rai = rai->next) { 1488 TAILQ_FOREACH(rai, &ralist, next) {
1483 if (rai->ifindex == idx) 1489 if (rai->ifindex == idx)
1484 return(rai); 1490 return(rai);
1485 } 1491 }
1486 1492
1487 return(NULL); /* search failed */ 1493 return(NULL); /* search failed */
1488} 1494}
1489 1495
1490static void 1496static void
1491ra_output(rainfo) 1497ra_output(struct rainfo *rainfo)
1492struct rainfo *rainfo; 
1493{ 1498{
1494 int i; 1499 int i;
1495 struct cmsghdr *cm; 1500 struct cmsghdr *cm;
1496 struct in6_pktinfo *pi; 1501 struct in6_pktinfo *pi;
1497 struct soliciter *sol, *nextsol; 1502 struct soliciter *sol;
1498 1503
1499 if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) { 1504 if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) {
1500 syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA", 1505 syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA",
1501 __func__, rainfo->ifname); 1506 __func__, rainfo->ifname);
1502 return; 1507 return;
1503 } 1508 }
1504 1509
1505 make_packet(rainfo); /* XXX: inefficient */ 1510 make_packet(rainfo); /* XXX: inefficient */
1506 1511
1507 sndmhdr.msg_name = (caddr_t)&sin6_allnodes; 1512 sndmhdr.msg_name = (void *)&sin6_linklocal_allnodes;
1508 sndmhdr.msg_iov[0].iov_base = (caddr_t)rainfo->ra_data; 1513 sndmhdr.msg_iov[0].iov_base = (void *)rainfo->ra_data;
1509 sndmhdr.msg_iov[0].iov_len = rainfo->ra_datalen; 1514 sndmhdr.msg_iov[0].iov_len = rainfo->ra_datalen;
1510 1515
1511 cm = CMSG_FIRSTHDR(&sndmhdr); 1516 cm = CMSG_FIRSTHDR(&sndmhdr);
1512 /* specify the outgoing interface */ 1517 /* specify the outgoing interface */
1513 cm->cmsg_level = IPPROTO_IPV6; 1518 cm->cmsg_level = IPPROTO_IPV6;
1514 cm->cmsg_type = IPV6_PKTINFO; 1519 cm->cmsg_type = IPV6_PKTINFO;
1515 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 1520 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
1516 pi = (struct in6_pktinfo *)CMSG_DATA(cm); 1521 pi = (struct in6_pktinfo *)CMSG_DATA(cm);
1517 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ 1522 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/
1518 pi->ipi6_ifindex = rainfo->ifindex; 1523 pi->ipi6_ifindex = rainfo->ifindex;
1519 1524
1520 /* specify the hop limit of the packet */ 1525 /* specify the hop limit of the packet */
1521 { 1526 {
@@ -1524,59 +1529,55 @@ struct rainfo *rainfo; @@ -1524,59 +1529,55 @@ struct rainfo *rainfo;
1524 cm = CMSG_NXTHDR(&sndmhdr, cm); 1529 cm = CMSG_NXTHDR(&sndmhdr, cm);
1525 cm->cmsg_level = IPPROTO_IPV6; 1530 cm->cmsg_level = IPPROTO_IPV6;
1526 cm->cmsg_type = IPV6_HOPLIMIT; 1531 cm->cmsg_type = IPV6_HOPLIMIT;
1527 cm->cmsg_len = CMSG_LEN(sizeof(int)); 1532 cm->cmsg_len = CMSG_LEN(sizeof(int));
1528 memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); 1533 memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
1529 } 1534 }
1530 1535
1531 syslog(LOG_DEBUG, 1536 syslog(LOG_DEBUG,
1532 "<%s> send RA on %s, # of waitings = %d", 1537 "<%s> send RA on %s, # of waitings = %d",
1533 __func__, rainfo->ifname, rainfo->waiting);  1538 __func__, rainfo->ifname, rainfo->waiting);
1534 1539
1535 i = sendmsg(sock, &sndmhdr, 0); 1540 i = sendmsg(sock, &sndmhdr, 0);
1536 1541
1537 if (i < 0 || i != rainfo->ra_datalen) { 1542 if (i < 0 || (size_t)i != rainfo->ra_datalen) {
1538 if (i < 0) { 1543 if (i < 0) {
1539 syslog(LOG_ERR, "<%s> sendmsg on %s: %s", 1544 syslog(LOG_ERR, "<%s> sendmsg on %s: %s",
1540 __func__, rainfo->ifname, 1545 __func__, rainfo->ifname,
1541 strerror(errno)); 1546 strerror(errno));
1542 } 1547 }
1543 } 1548 }
1544 1549
1545 /* 1550 /*
1546 * unicast advertisements 1551 * unicast advertisements
1547 * XXX commented out. reason: though spec does not forbit it, unicast 1552 * XXX commented out. reason: though spec does not forbit it, unicast
1548 * advert does not really help 1553 * advert does not really help
1549 */ 1554 */
1550 for (sol = rainfo->soliciter; sol; sol = nextsol) { 1555 while ((sol = TAILQ_FIRST(&rainfo->soliciter)) != NULL) {
1551 nextsol = sol->next; 
1552 
1553#if 0 1556#if 0
1554 sndmhdr.msg_name = (caddr_t)&sol->addr; 1557 sndmhdr.msg_name = (void *)&sol->addr;
1555 i = sendmsg(sock, &sndmhdr, 0); 1558 i = sendmsg(sock, &sndmhdr, 0);
1556 if (i < 0 || i != rainfo->ra_datalen) { 1559 if (i < 0 || i != rainfo->ra_datalen) {
1557 if (i < 0) { 1560 if (i < 0) {
1558 syslog(LOG_ERR, 1561 syslog(LOG_ERR,
1559 "<%s> unicast sendmsg on %s: %s", 1562 "<%s> unicast sendmsg on %s: %s",
1560 __func__, rainfo->ifname, 1563 __func__, rainfo->ifname,
1561 strerror(errno)); 1564 strerror(errno));
1562 } 1565 }
1563 } 1566 }
1564#endif 1567#endif
1565 1568 TAILQ_REMOVE(&rainfo->soliciter, sol, next);
1566 sol->next = NULL; 
1567 free(sol); 1569 free(sol);
1568 } 1570 }
1569 rainfo->soliciter = NULL; 
1570 1571
1571 /* update counter */ 1572 /* update counter */
1572 if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS) 1573 if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS)
1573 rainfo->initcounter++; 1574 rainfo->initcounter++;
1574 rainfo->raoutput++; 1575 rainfo->raoutput++;
1575 1576
1576 /* update timestamp */ 1577 /* update timestamp */
1577 gettimeofday(&rainfo->lastsent, NULL); 1578 gettimeofday(&rainfo->lastsent, NULL);
1578 1579
1579 /* reset waiting conter */ 1580 /* reset waiting conter */
1580 rainfo->waiting = 0; 1581 rainfo->waiting = 0;
1581} 1582}
1582 1583

cvs diff -r1.14 -r1.15 src/usr.sbin/rtadvd/rtadvd.conf.5 (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/rtadvd.conf.5 2009/11/01 15:19:19 1.14
+++ src/usr.sbin/rtadvd/rtadvd.conf.5 2011/12/10 19:14:29 1.15
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: rtadvd.conf.5,v 1.14 2009/11/01 15:19:19 jakllsch Exp $ 1.\" $NetBSD: rtadvd.conf.5,v 1.15 2011/12/10 19:14:29 roy Exp $
2.\" $KAME: rtadvd.conf.5,v 1.50 2005/01/14 05:30:59 jinmei Exp $ 2.\" $KAME: rtadvd.conf.5,v 1.50 2005/01/14 05:30:59 jinmei Exp $
3.\" 3.\"
4.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 4.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5.\" All rights reserved. 5.\" All rights reserved.
6.\" 6.\"
7.\" Redistribution and use in source and binary forms, with or without 7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions 8.\" modification, are permitted provided that the following conditions
9.\" are met: 9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright 10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer. 11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
@@ -18,27 +18,27 @@ @@ -18,27 +18,27 @@
18.\" 18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
30.\" 30.\"
31.Dd November 1, 2009 31.Dd December 7, 2012
32.Dt RTADVD.CONF 5 32.Dt RTADVD.CONF 5
33.Os 33.Os
34.Sh NAME 34.Sh NAME
35.Nm rtadvd.conf 35.Nm rtadvd.conf
36.Nd config file for router advertisement daemon 36.Nd config file for router advertisement daemon
37.Sh DESCRIPTION 37.Sh DESCRIPTION
38This file describes how the router advertisement packets must be constructed 38This file describes how the router advertisement packets must be constructed
39for each of the interfaces. 39for each of the interfaces.
40.Pp 40.Pp
41As described in 41As described in
42.Xr rtadvd 8 , 42.Xr rtadvd 8 ,
43you do not have to set this configuration file up at all, 43you do not have to set this configuration file up at all,
44unless you need some special configurations. 44unless you need some special configurations.
@@ -323,26 +323,86 @@ old version of the program. @@ -323,26 +323,86 @@ old version of the program.
323In the above list, each keyword beginning with 323In the above list, each keyword beginning with
324.Dq Li rt 324.Dq Li rt
325could be replaced with the one beginning with 325could be replaced with the one beginning with
326.Dq Li rtr 326.Dq Li rtr
327for backward compatibility reason. 327for backward compatibility reason.
328For example, 328For example,
329.Cm rtrplen 329.Cm rtrplen
330is accepted instead of 330is accepted instead of
331.Cm rtplen . 331.Cm rtplen .
332However, keywords that start with 332However, keywords that start with
333.Dq Li rtr 333.Dq Li rtr
334have basically been obsoleted, and should not be used any more. 334have basically been obsoleted, and should not be used any more.
335.Pp 335.Pp
 336The following items are for ICMPv6 Recursive DNS Server Option and
 337DNS Search List Option
 338.Pq RFC 6106 ,
 339which will be attached to router advertisement header.
 340These items are optional.
 341.Bl -tag -width indent
 342.It Cm \&rdnss
 343(str) The IPv6 address of one or more recursive DNS servers.
 344The argument must be inside double quotes.
 345Multiple DNS servers can be specified in a comma-separated string.
 346If different lifetimes are needed for different servers,
 347separate entries can be given by using
 348.Cm rdnss ,
 349.Cm rdnss0 ,
 350.Cm rdnss1 ,
 351.Cm rdnss2 ...
 352options with corresponding
 353.Cm rdnssltime ,
 354.Cm rdnssltime0 ,
 355.Cm rdnssltime1 ,
 356.Cm rdnssltime2 ...
 357entries.
 358Note that the maximum number of servers depends on the receiver side.
 359See also
 360.Xr resolver 5
 361manual page for resolver implementation in
 362.Fx .
 363.It Cm \&rdnssltime
 364The lifetime of the
 365.Cm rdnss
 366DNS server entries.
 367The default value is 3/2 of the interval time.
 368.It Cm \&dnssl
 369(str) One or more domain names in a comma-separated string.
 370These domain names will be used when making DNS queries on a
 371non-fully-qualified domain name.
 372If different lifetimes are needed for different domains, separate entries
 373can be given by using
 374.Cm dnssl ,
 375.Cm dnssl0 ,
 376.Cm dnssl1 ,
 377.Cm dnssl2 ...
 378options with corresponding
 379.Cm dnsslltime ,
 380.Cm dnsslltime0 ,
 381.Cm dnsslltime1 ,
 382.Cm dnsslltime2 ...
 383entries.
 384Note that the maximum number of names depends on the receiver side.
 385See also
 386.Xr resolver 5
 387manual page for resolver implementation in
 388.Fx .
 389.It Cm \&dnsslltime
 390The lifetime of the
 391.Cm dnssl
 392DNS search list entries.
 393The default value is 3/2 of the interval time.
 394.El
 395.Pp
336You can also refer one line from another by using 396You can also refer one line from another by using
337.Cm tc 397.Cm tc
338capability. 398capability.
339See 399See
340.Xr termcap 5 400.Xr termcap 5
341for details on the capability. 401for details on the capability.
342.Sh EXAMPLES 402.Sh EXAMPLES
343As presented above, all of the advertised parameters have default values 403As presented above, all of the advertised parameters have default values
344defined in specifications, and hence you usually do not have to set them 404defined in specifications, and hence you usually do not have to set them
345by hand, unless you need special non-default values. 405by hand, unless you need special non-default values.
346It can cause interoperability problem if you use an ill-configured 406It can cause interoperability problem if you use an ill-configured
347parameter. 407parameter.
348.Pp 408.Pp
@@ -359,47 +419,64 @@ ne0:\\ @@ -359,47 +419,64 @@ ne0:\\
359.Pp 419.Pp
360The following example manually configures prefixes advertised from the 420The following example manually configures prefixes advertised from the
361.Li ef0 421.Li ef0
362interface. 422interface.
363The configuration must be used with the 423The configuration must be used with the
364.Fl s 424.Fl s
365option to 425option to
366.Xr rtadvd 8 . 426.Xr rtadvd 8 .
367.Bd -literal 427.Bd -literal
368ef0:\\ 428ef0:\\
369 :addr="2001:db8:ffff:1000::":prefixlen#64: 429 :addr="2001:db8:ffff:1000::":prefixlen#64:
370.Ed 430.Ed
371.Pp 431.Pp
 432The following example configures the
 433.Li wlan0
 434interface and adds two DNS servers and a DNS domain search options
 435using the default option lifetime values.
 436.Bd -literal -offset
 437wlan0:\\
 438 :addr="2001:db8:ffff:1000::":prefixlen#64:\\
 439 :rdnss="2001:db8:ffff::10,2001:db8:ffff::2:43":\\
 440 :dnssl="example.com":
 441.Ed
 442.Pp
372The following example presents the default values in an explicit manner. 443The following example presents the default values in an explicit manner.
373The configuration is provided just for reference purposes; 444The configuration is provided just for reference purposes;
374YOU DO NOT NEED TO HAVE IT AT ALL. 445YOU DO NOT NEED TO HAVE IT AT ALL.
375.Bd -literal 446.Bd -literal
376default:\\ 447default:\\
377 :chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\\ 448 :chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\\
378 :pinfoflags="la":vltime#2592000:pltime#604800:mtu#0: 449 :pinfoflags="la":vltime#2592000:pltime#604800:mtu#0:
379ef0:\\ 450ef0:\\
380 :addr="2001:db8:ffff:1000::":prefixlen#64:tc=default: 451 :addr="2001:db8:ffff:1000::":prefixlen#64:tc=default:
381.Ed 452.Ed
382.Sh SEE ALSO 453.Sh SEE ALSO
383.Xr termcap 5 , 454.Xr termcap 5 ,
384.Xr rtadvd 8 , 455.Xr rtadvd 8 ,
385.Xr rtsol 8 456.Xr rtsol 8
386.Pp 457.Pp
387Thomas Narten, Erik Nordmark and W. A. Simpson, 458Thomas Narten, Erik Nordmark and W. A. Simpson,
388.Do 459.Do
389Neighbor Discovery for IP version 6 (IPv6) 460Neighbor Discovery for IP version 6 (IPv6)
390.Dc , 461.Dc ,
391RFC 2461 462RFC 2461
392.Pp 463.Pp
393Richard Draves, 464Richard Draves,
394.Do 465.Do
395Default Router Preferences and More-Specific Routes 466Default Router Preferences and More-Specific Routes
396.Dc , 467.Dc ,
397RFC 4191 468RFC 4191
 469.Pp
 470J. Jeong, S. Park, L. Beloeil, S. Madanapalli
 471.Do
 472IPv6 Router Advertisement Options for DNS Configuration
 473.Dc ,
 474RFC 6106
398.Sh HISTORY 475.Sh HISTORY
399The 476The
400.Xr rtadvd 8 477.Xr rtadvd 8
401and the configuration file 478and the configuration file
402.Nm 479.Nm
403first appeared in WIDE Hydrangea IPv6 protocol stack kit. 480first appeared in WIDE Hydrangea IPv6 protocol stack kit.
404.\" .Sh BUGS 481.\" .Sh BUGS
405.\" (to be written) 482.\" (to be written)

cvs diff -r1.10 -r1.11 src/usr.sbin/rtadvd/rtadvd.h (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/rtadvd.h 2006/03/05 23:47:08 1.10
+++ src/usr.sbin/rtadvd/rtadvd.h 2011/12/10 19:14:29 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rtadvd.h,v 1.10 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: rtadvd.h,v 1.11 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: rtadvd.h,v 1.30 2005/10/17 14:40:02 suz Exp $ */ 2/* $KAME: rtadvd.h,v 1.30 2005/10/17 14:40:02 suz Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1998 WIDE Project. 5 * Copyright (C) 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
@@ -23,28 +23,34 @@ @@ -23,28 +23,34 @@
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#define ALLNODES "ff02::1" 33#define ALLNODES "ff02::1"
34#define ALLROUTERS_LINK "ff02::2" 34#define ALLROUTERS_LINK "ff02::2"
35#define ALLROUTERS_SITE "ff05::2" 35#define ALLROUTERS_SITE "ff05::2"
36#define ANY "::" 36
37#define RTSOLLEN 8 37#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT \
 38 {{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
 39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
 40
 41//extern struct sockaddr_in6 sin6_linklocal_allnodes;
 42//extern struct sockaddr_in6 sin6_linklocal_allrouters;
 43extern struct sockaddr_in6 sin6_sitelocal_allrouters;
38 44
39/* protocol constants and default values */ 45/* protocol constants and default values */
40#define DEF_MAXRTRADVINTERVAL 600 46#define DEF_MAXRTRADVINTERVAL 600
41#define DEF_ADVLINKMTU 0 47#define DEF_ADVLINKMTU 0
42#define DEF_ADVREACHABLETIME 0 48#define DEF_ADVREACHABLETIME 0
43#define DEF_ADVRETRANSTIMER 0 49#define DEF_ADVRETRANSTIMER 0
44#define DEF_ADVCURHOPLIMIT 64 50#define DEF_ADVCURHOPLIMIT 64
45#define DEF_ADVVALIDLIFETIME 2592000 51#define DEF_ADVVALIDLIFETIME 2592000
46#define DEF_ADVPREFERREDLIFETIME 604800 52#define DEF_ADVPREFERREDLIFETIME 604800
47 53
48#define MAXROUTERLIFETIME 9000 54#define MAXROUTERLIFETIME 9000
49#define MIN_MAXINTERVAL 4 55#define MIN_MAXINTERVAL 4
50#define MAX_MAXINTERVAL 1800 56#define MAX_MAXINTERVAL 1800
@@ -52,110 +58,132 @@ @@ -52,110 +58,132 @@
52#define MAXREACHABLETIME 3600000 58#define MAXREACHABLETIME 3600000
53 59
54#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16 60#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16
55#define MAX_INITIAL_RTR_ADVERTISEMENTS 3 61#define MAX_INITIAL_RTR_ADVERTISEMENTS 3
56#define MAX_FINAL_RTR_ADVERTISEMENTS 3 62#define MAX_FINAL_RTR_ADVERTISEMENTS 3
57#define MIN_DELAY_BETWEEN_RAS 3 63#define MIN_DELAY_BETWEEN_RAS 3
58#define MAX_RA_DELAY_TIME 500000 /* usec */ 64#define MAX_RA_DELAY_TIME 500000 /* usec */
59 65
60#define PREFIX_FROM_KERNEL 1 66#define PREFIX_FROM_KERNEL 1
61#define PREFIX_FROM_CONFIG 2 67#define PREFIX_FROM_CONFIG 2
62#define PREFIX_FROM_DYNAMIC 3 68#define PREFIX_FROM_DYNAMIC 3
63 69
64struct prefix { 70struct prefix {
65 struct prefix *next; /* forward link */ 71 TAILQ_ENTRY(prefix) next;
66 struct prefix *prev; /* previous link */ 
67 72
68 struct rainfo *rainfo; /* back pointer to the interface */ 73 struct rainfo *rainfo; /* back pointer to the interface */
69 74
70 struct rtadvd_timer *timer; /* expiration timer. used when a prefix 75 struct rtadvd_timer *timer; /* expiration timer. used when a prefix
71 * derived from the kernel is deleted. 76 * derived from the kernel is deleted.
72 */ 77 */
73 78
74 u_int32_t validlifetime; /* AdvValidLifetime */ 79 uint32_t validlifetime; /* AdvValidLifetime */
75 long vltimeexpire; /* expiration of vltime; decrement case only */ 80 long vltimeexpire; /* expiration of vltime; decrement case only */
76 u_int32_t preflifetime; /* AdvPreferredLifetime */ 81 uint32_t preflifetime; /* AdvPreferredLifetime */
77 long pltimeexpire; /* expiration of pltime; decrement case only */ 82 long pltimeexpire; /* expiration of pltime; decrement case only */
78 u_int onlinkflg; /* bool: AdvOnLinkFlag */ 83 uint16_t onlinkflg; /* bool: AdvOnLinkFlag */
79 u_int autoconfflg; /* bool: AdvAutonomousFlag */ 84 uint16_t autoconfflg; /* bool: AdvAutonomousFlag */
80 int prefixlen; 85 int prefixlen;
81 int origin; /* from kernel or config */ 86 int origin; /* from kernel or config */
82 struct in6_addr prefix; 87 struct in6_addr prefix;
83}; 88};
84 89
85#ifdef ROUTEINFO 
86struct rtinfo { 90struct rtinfo {
87 struct rtinfo *prev; /* previous link */ 91 TAILQ_ENTRY(rtinfo) next;
88 struct rtinfo *next; /* forward link */ 
89 92
90 u_int32_t ltime; /* route lifetime */ 93 uint32_t ltime; /* route lifetime */
91 u_int rtpref; /* route preference */ 94 uint16_t rtpref; /* route preference */
92 int prefixlen; 95 int prefixlen;
93 struct in6_addr prefix; 96 struct in6_addr prefix;
94}; 97};
95#endif 98
 99struct rdnss_addr {
 100 TAILQ_ENTRY(rdnss_addr) next;
 101
 102 struct in6_addr addr;
 103};
 104
 105struct rdnss {
 106 TAILQ_ENTRY(rdnss) next;
 107
 108 TAILQ_HEAD(, rdnss_addr) list;
 109 uint32_t lifetime;
 110};
 111
 112struct dnssl_domain {
 113 TAILQ_ENTRY(dnssl_domain) next;
 114
 115 int len;
 116 char domain[256];
 117};
 118
 119struct dnssl {
 120 TAILQ_ENTRY(dnssl) next;
 121
 122 TAILQ_HEAD(, dnssl_domain) list;
 123 uint32_t lifetime;
 124};
96 125
97struct soliciter { 126struct soliciter {
98 struct soliciter *next; 127 TAILQ_ENTRY(soliciter) next;
 128
99 struct sockaddr_in6 addr; 129 struct sockaddr_in6 addr;
100}; 130};
101 131
102struct rainfo { 132struct rainfo {
103 /* pointer for list */ 133 TAILQ_ENTRY(rainfo) next;
104 struct rainfo *next; 
105 134
106 /* timer related parameters */ 135 /* timer related parameters */
107 struct rtadvd_timer *timer; 136 struct rtadvd_timer *timer;
108 int initcounter; /* counter for the first few advertisements */ 137 int initcounter; /* counter for the first few advertisements */
109 struct timeval lastsent; /* timestamp when the latest RA was sent */ 138 struct timeval lastsent; /* timestamp when the latest RA was sent */
110 int waiting; /* number of RS waiting for RA */ 139 int waiting; /* number of RS waiting for RA */
111 140
112 /* interface information */ 141 /* interface information */
113 int ifindex; 142 uint16_t ifindex;
114 int advlinkopt; /* bool: whether include link-layer addr opt */ 143 int advlinkopt; /* bool: whether include link-layer addr opt */
115 struct sockaddr_dl *sdl; 144 struct sockaddr_dl *sdl;
116 char ifname[16]; 145 char ifname[16];
117 int phymtu; /* mtu of the physical interface */ 146 uint32_t phymtu; /* mtu of the physical interface */
118 147
119 /* Router configuration variables */ 148 /* Router configuration variables */
120 u_short lifetime; /* AdvDefaultLifetime */ 149 uint16_t lifetime; /* AdvDefaultLifetime */
121 u_int maxinterval; /* MaxRtrAdvInterval */ 150 uint16_t maxinterval; /* MaxRtrAdvInterval */
122 u_int mininterval; /* MinRtrAdvInterval */ 151 uint16_t mininterval; /* MinRtrAdvInterval */
123 int managedflg; /* AdvManagedFlag */ 152 int managedflg; /* AdvManagedFlag */
124 int otherflg; /* AdvOtherConfigFlag */ 153 int otherflg; /* AdvOtherConfigFlag */
125 154
126 int rtpref; /* router preference */ 155 int rtpref; /* router preference */
127 u_int32_t linkmtu; /* AdvLinkMTU */ 156 uint32_t linkmtu; /* AdvLinkMTU */
128 u_int32_t reachabletime; /* AdvReachableTime */ 157 uint32_t reachabletime; /* AdvReachableTime */
129 u_int32_t retranstimer; /* AdvRetransTimer */ 158 uint32_t retranstimer; /* AdvRetransTimer */
130 u_int hoplimit; /* AdvCurHopLimit */ 159 uint16_t hoplimit; /* AdvCurHopLimit */
131 struct prefix prefix; /* AdvPrefixList(link head) */ 160 TAILQ_HEAD(, prefix) prefix; /* AdvPrefixList(link head) */
132 int pfxs; /* number of prefixes */ 161 int pfxs;
133 long clockskew; /* used for consisitency check of lifetimes */ 162 uint16_t clockskew;/* used for consisitency check of lifetimes */
134 163
135#ifdef ROUTEINFO 164 TAILQ_HEAD(, rtinfo) route;
136 struct rtinfo route; /* route information option (link head) */ 165 TAILQ_HEAD(, rdnss) rdnss; /* RDNSS list */
137 int routes; /* number of route information options */ 166 TAILQ_HEAD(, dnssl) dnssl; /* DNS Search List */
138#endif 
139 167
140 /* actual RA packet data and its length */ 168 /* actual RA packet data and its length */
141 size_t ra_datalen; 169 size_t ra_datalen;
142 u_char *ra_data; 170 char *ra_data;
143 171
144 /* statistics */ 172 /* statistics */
145 u_quad_t raoutput; /* number of RAs sent */ 173 uint64_t raoutput; /* number of RAs sent */
146 u_quad_t rainput; /* number of RAs received */ 174 uint64_t rainput; /* number of RAs received */
147 u_quad_t rainconsistent; /* number of RAs inconsistent with ours */ 175 uint64_t rainconsistent; /* number of RAs inconsistent with ours */
148 u_quad_t rsinput; /* number of RSs received */ 176 uint64_t rsinput; /* number of RSs received */
149 177
150 /* info about soliciter */ 178 /* info about soliciter */
151 struct soliciter *soliciter; /* recent solication source */ 179 TAILQ_HEAD(, soliciter) soliciter; /* recent solication source */
152}; 180};
153 181
154struct rtadvd_timer *ra_timeout __P((void *)); 182extern TAILQ_HEAD(ralist_head_t, rainfo) ralist;
155void ra_timer_update __P((void *, struct timeval *)); 
156 183
157int prefix_match __P((struct in6_addr *, int, struct in6_addr *, int)); 184struct rtadvd_timer *ra_timeout(void *);
158struct rainfo *if_indextorainfo __P((int)); 185void ra_timer_update(void *, struct timeval *);
159struct prefix *find_prefix __P((struct rainfo *, struct in6_addr *, int)); 
160 186
161extern struct in6_addr in6a_site_allrouters; 187int prefix_match(struct in6_addr *, int, struct in6_addr *, int);
 188struct rainfo *if_indextorainfo(unsigned int);
 189struct prefix *find_prefix(struct rainfo *, struct in6_addr *, int);

cvs diff -r1.9 -r1.10 src/usr.sbin/rtadvd/timer.c (expand / switch to unified diff)

--- src/usr.sbin/rtadvd/timer.c 2006/03/05 23:47:08 1.9
+++ src/usr.sbin/rtadvd/timer.c 2011/12/10 19:14:29 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: timer.c,v 1.9 2006/03/05 23:47:08 rpaulo Exp $ */ 1/* $NetBSD: timer.c,v 1.10 2011/12/10 19:14:29 roy Exp $ */
2/* $KAME: timer.c,v 1.11 2005/04/14 06:22:35 suz Exp $ */ 2/* $KAME: timer.c,v 1.11 2005/04/14 06:22:35 suz Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1998 WIDE Project. 5 * Copyright (C) 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
@@ -20,148 +20,147 @@ @@ -20,148 +20,147 @@
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#include <sys/queue.h>
33#include <sys/time.h> 34#include <sys/time.h>
34 35
35#include <unistd.h> 36#include <unistd.h>
36#include <syslog.h> 37#include <syslog.h>
37#include <stdlib.h> 38#include <stdlib.h>
38#include <string.h> 39#include <string.h>
39#include <search.h> 40#include <search.h>
40#include "timer.h" 41#include "timer.h"
41 42
42static struct rtadvd_timer timer_head; 43struct rtadvd_timer_head_t ra_timer = TAILQ_HEAD_INITIALIZER(ra_timer);
43 44
44#define MILLION 1000000 45#define MILLION 1000000
45#define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\ 46#define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\
46 (t1)->tv_usec == (t2)->tv_usec) 47 (t1)->tv_usec == (t2)->tv_usec)
47 48
48static struct timeval tm_max = {0x7fffffff, 0x7fffffff}; 49static struct timeval tm_limit = {0x7fffffff, 0x7fffffff};
 50static struct timeval tm_max;
49 51
50void 52void
51rtadvd_timer_init() 53rtadvd_timer_init(void)
52{ 54{
53 memset(&timer_head, 0, sizeof(timer_head)); 
54 55
55 timer_head.next = timer_head.prev = &timer_head; 56 TAILQ_INIT(&ra_timer);
56 timer_head.tm = tm_max; 57 tm_max = tm_limit;
57} 58}
58 59
59struct rtadvd_timer * 60struct rtadvd_timer *
60rtadvd_add_timer(struct rtadvd_timer *(*timeout) __P((void *)), 61rtadvd_add_timer(struct rtadvd_timer *(*timeout) (void *),
61 void (*update) __P((void *, struct timeval *)), 62 void (*update) (void *, struct timeval *),
62 void *timeodata, void *updatedata) 63 void *timeodata, void *updatedata)
63{ 64{
64 struct rtadvd_timer *newtimer; 65 struct rtadvd_timer *newtimer;
65 66
66 if ((newtimer = malloc(sizeof(*newtimer))) == NULL) { 67 if ((newtimer = malloc(sizeof(*newtimer))) == NULL) {
67 syslog(LOG_ERR, 68 syslog(LOG_ERR,
68 "<%s> can't allocate memory", __func__); 69 "<%s> can't allocate memory", __func__);
69 exit(1); 70 exit(1);
70 } 71 }
71 72
72 memset(newtimer, 0, sizeof(*newtimer)); 73 memset(newtimer, 0, sizeof(*newtimer));
73 74
74 if (timeout == NULL) { 75 if (timeout == NULL) {
75 syslog(LOG_ERR, 76 syslog(LOG_ERR,
76 "<%s> timeout function unspecified", __func__); 77 "<%s> timeout function unspecified", __func__);
77 exit(1); 78 exit(1);
78 } 79 }
79 newtimer->expire = timeout; 80 newtimer->expire = timeout;
80 newtimer->update = update; 81 newtimer->update = update;
81 newtimer->expire_data = timeodata; 82 newtimer->expire_data = timeodata;
82 newtimer->update_data = updatedata; 83 newtimer->update_data = updatedata;
83 newtimer->tm = tm_max; 84 newtimer->tm = tm_max;
84 85
85 /* link into chain */ 86 /* link into chain */
86 insque(newtimer, &timer_head); 87 TAILQ_INSERT_TAIL(&ra_timer, newtimer, next);
87 88
88 return(newtimer); 89 return(newtimer);
89} 90}
90 91
91void 92void
92rtadvd_remove_timer(struct rtadvd_timer **timer) 93rtadvd_remove_timer(struct rtadvd_timer **timer)
93{ 94{
94 remque(*timer); 95
 96 TAILQ_REMOVE(&ra_timer, *timer, next);
95 free(*timer); 97 free(*timer);
96 *timer = NULL; 98 *timer = NULL;
97} 99}
98 100
99void 101void
100rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer) 102rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer)
101{ 103{
102 struct timeval now; 104 struct timeval now;
103 105
104 /* reset the timer */ 106 /* reset the timer */
105 gettimeofday(&now, NULL); 107 gettimeofday(&now, NULL);
106 108
107 TIMEVAL_ADD(&now, tm, &timer->tm); 109 TIMEVAL_ADD(&now, tm, &timer->tm);
108 110
109 /* update the next expiration time */ 111 /* update the next expiration time */
110 if (TIMEVAL_LT(timer->tm, timer_head.tm)) 112 if (TIMEVAL_LT(timer->tm, tm_max))
111 timer_head.tm = timer->tm; 113 tm_max = timer->tm;
112 114
113 return; 115 return;
114} 116}
115 117
116/* 118/*
117 * Check expiration for each timer. If a timer expires, 119 * Check expiration for each timer. If a timer expires,
118 * call the expire function for the timer and update the timer. 120 * call the expire function for the timer and update the timer.
119 * Return the next interval for select() call. 121 * Return the next interval for select() call.
120 */ 122 */
121struct timeval * 123struct timeval *
122rtadvd_check_timer() 124rtadvd_check_timer(void)
123{ 125{
124 static struct timeval returnval; 126 static struct timeval returnval;
125 struct timeval now; 127 struct timeval now;
126 struct rtadvd_timer *tm = timer_head.next, *tm_next; 128 struct rtadvd_timer *tm;
127 129
128 gettimeofday(&now, NULL); 130 gettimeofday(&now, NULL);
 131 tm_max = tm_limit;
129 132
130 timer_head.tm = tm_max; 133 TAILQ_FOREACH(tm, &ra_timer, next) {
131 
132 for (tm = timer_head.next; tm != &timer_head; tm = tm_next) { 
133 tm_next = tm->next; 
134 
135 if (TIMEVAL_LEQ(tm->tm, now)) { 134 if (TIMEVAL_LEQ(tm->tm, now)) {
136 if ((*tm->expire)(tm->expire_data) == NULL) 135 if ((*tm->expire)(tm->expire_data) == NULL)
137 continue; /* the timer was removed */ 136 continue; /* the timer was removed */
138 if (tm->update) 137 if (tm->update)
139 (*tm->update)(tm->update_data, &tm->tm); 138 (*tm->update)(tm->update_data, &tm->tm);
140 TIMEVAL_ADD(&tm->tm, &now, &tm->tm); 139 TIMEVAL_ADD(&tm->tm, &now, &tm->tm);
141 } 140 }
142 141
143 if (TIMEVAL_LT(tm->tm, timer_head.tm)) 142 if (TIMEVAL_LT(tm->tm, tm_max))
144 timer_head.tm = tm->tm; 143 tm_max = tm->tm;
145 } 144 }
146 145
147 if (TIMEVAL_EQUAL(&tm_max, &timer_head.tm)) { 146 if (TIMEVAL_EQUAL(&tm_max, &tm_limit)) {
148 /* no need to timeout */ 147 /* no need to timeout */
149 return(NULL); 148 return(NULL);
150 } else if (TIMEVAL_LT(timer_head.tm, now)) { 149 } else if (TIMEVAL_LT(tm_max, now)) {
151 /* this may occur when the interval is too small */ 150 /* this may occur when the interval is too small */
152 returnval.tv_sec = returnval.tv_usec = 0; 151 returnval.tv_sec = returnval.tv_usec = 0;
153 } else 152 } else
154 TIMEVAL_SUB(&timer_head.tm, &now, &returnval); 153 TIMEVAL_SUB(&tm_max, &now, &returnval);
155 return(&returnval); 154 return(&returnval);
156} 155}
157 156
158struct timeval * 157struct timeval *
159rtadvd_timer_rest(struct rtadvd_timer *timer) 158rtadvd_timer_rest(struct rtadvd_timer *timer)
160{ 159{
161 static struct timeval returnval, now; 160 static struct timeval returnval, now;
162 161
163 gettimeofday(&now, NULL); 162 gettimeofday(&now, NULL);
164 if (TIMEVAL_LEQ(timer->tm, now)) { 163 if (TIMEVAL_LEQ(timer->tm, now)) {
165 syslog(LOG_DEBUG, 164 syslog(LOG_DEBUG,
166 "<%s> a timer must be expired, but not yet", 165 "<%s> a timer must be expired, but not yet",
167 __func__); 166 __func__);