Deleted Added
full compact
config.c (71437) config.c (78064)
1/* $FreeBSD: head/usr.sbin/rtadvd/config.c 71437 2001-01-23 17:29:12Z ume $ */
2/* $KAME: config.c,v 1.11 2000/05/16 13:34:13 itojun Exp $ */
1/* $FreeBSD: head/usr.sbin/rtadvd/config.c 78064 2001-06-11 12:39:29Z ume $ */
2/* $KAME: config.c,v 1.37 2001/05/25 07:34:00 itojun Exp $ */
3
4/*
5 * Copyright (C) 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 18 unchanged lines hidden (view full) ---

29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/ioctl.h>
35#include <sys/socket.h>
36#include <sys/time.h>
3
4/*
5 * Copyright (C) 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 18 unchanged lines hidden (view full) ---

29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/ioctl.h>
35#include <sys/socket.h>
36#include <sys/time.h>
37#include <sys/sysctl.h>
37
38#include <net/if.h>
39#if defined(__FreeBSD__) && __FreeBSD__ >= 3
40#include <net/if_var.h>
41#endif /* __FreeBSD__ >= 3 */
42#include <net/route.h>
43#include <net/if_dl.h>
44

--- 12 unchanged lines hidden (view full) ---

57#include <syslog.h>
58#include <errno.h>
59#include <string.h>
60#include <stdlib.h>
61#if defined(__NetBSD__) || defined(__OpenBSD__)
62#include <search.h>
63#endif
64#include <unistd.h>
38
39#include <net/if.h>
40#if defined(__FreeBSD__) && __FreeBSD__ >= 3
41#include <net/if_var.h>
42#endif /* __FreeBSD__ >= 3 */
43#include <net/route.h>
44#include <net/if_dl.h>
45

--- 12 unchanged lines hidden (view full) ---

58#include <syslog.h>
59#include <errno.h>
60#include <string.h>
61#include <stdlib.h>
62#if defined(__NetBSD__) || defined(__OpenBSD__)
63#include <search.h>
64#endif
65#include <unistd.h>
66#include <ifaddrs.h>
65
66#include "rtadvd.h"
67#include "advcap.h"
68#include "timer.h"
69#include "if.h"
70#include "config.h"
71
72static void makeentry __P((char *, int, char *, int));
73static void get_prefix __P((struct rainfo *));
67
68#include "rtadvd.h"
69#include "advcap.h"
70#include "timer.h"
71#include "if.h"
72#include "config.h"
73
74static void makeentry __P((char *, int, char *, int));
75static void get_prefix __P((struct rainfo *));
76static int getinet6sysctl __P((int));
74
75extern struct rainfo *ralist;
76
77void
78getconfig(intface)
79 char *intface;
80{
81 int stat, pfxs, i;
82 char tbuf[BUFSIZ];
83 struct rainfo *tmp;
84 long val;
77
78extern struct rainfo *ralist;
79
80void
81getconfig(intface)
82 char *intface;
83{
84 int stat, pfxs, i;
85 char tbuf[BUFSIZ];
86 struct rainfo *tmp;
87 long val;
88 long long val64;
85 char buf[BUFSIZ];
86 char *bp = buf;
87 char *addr;
89 char buf[BUFSIZ];
90 char *bp = buf;
91 char *addr;
92 static int forwarding = -1;
88
89#define MUSTHAVE(var, cap) \
90 do { \
91 int t; \
92 if ((t = agetnum(cap)) < 0) { \
93 fprintf(stderr, "rtadvd: need %s for interface %s\n", \
94 cap, intface); \
95 exit(1); \

--- 13 unchanged lines hidden (view full) ---

109 " or the configuration file doesn't exist."
110 " Treat it as default",
111 __FUNCTION__, intface);
112 }
113
114 tmp = (struct rainfo *)malloc(sizeof(*ralist));
115 memset(tmp, 0, sizeof(*tmp));
116 tmp->prefix.next = tmp->prefix.prev = &tmp->prefix;
93
94#define MUSTHAVE(var, cap) \
95 do { \
96 int t; \
97 if ((t = agetnum(cap)) < 0) { \
98 fprintf(stderr, "rtadvd: need %s for interface %s\n", \
99 cap, intface); \
100 exit(1); \

--- 13 unchanged lines hidden (view full) ---

114 " or the configuration file doesn't exist."
115 " Treat it as default",
116 __FUNCTION__, intface);
117 }
118
119 tmp = (struct rainfo *)malloc(sizeof(*ralist));
120 memset(tmp, 0, sizeof(*tmp));
121 tmp->prefix.next = tmp->prefix.prev = &tmp->prefix;
122 tmp->route.next = tmp->route.prev = &tmp->route;
117
123
124 /* check if we are allowed to forward packets (if not determined) */
125 if (forwarding < 0) {
126 if ((forwarding = getinet6sysctl(IPV6CTL_FORWARDING)) < 0)
127 exit(1);
128 }
129
118 /* get interface information */
119 if (agetflag("nolladdr"))
120 tmp->advlinkopt = 0;
121 else
122 tmp->advlinkopt = 1;
123 if (tmp->advlinkopt) {
124 if ((tmp->sdl = if_nametosdl(intface)) == NULL) {
125 syslog(LOG_ERR,

--- 33 unchanged lines hidden (view full) ---

159 exit(1);
160 }
161 tmp->mininterval = (u_int)val;
162
163 MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
164 tmp->hoplimit = val & 0xff;
165
166 MAYHAVE(val, "raflags", 0);
130 /* get interface information */
131 if (agetflag("nolladdr"))
132 tmp->advlinkopt = 0;
133 else
134 tmp->advlinkopt = 1;
135 if (tmp->advlinkopt) {
136 if ((tmp->sdl = if_nametosdl(intface)) == NULL) {
137 syslog(LOG_ERR,

--- 33 unchanged lines hidden (view full) ---

171 exit(1);
172 }
173 tmp->mininterval = (u_int)val;
174
175 MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
176 tmp->hoplimit = val & 0xff;
177
178 MAYHAVE(val, "raflags", 0);
167 tmp->managedflg= val & ND_RA_FLAG_MANAGED;
179 tmp->managedflg = val & ND_RA_FLAG_MANAGED;
168 tmp->otherflg = val & ND_RA_FLAG_OTHER;
169#ifdef MIP6
170 if (mobileip6)
171 tmp->haflg = val & ND_RA_FLAG_HA;
172#endif
180 tmp->otherflg = val & ND_RA_FLAG_OTHER;
181#ifdef MIP6
182 if (mobileip6)
183 tmp->haflg = val & ND_RA_FLAG_HA;
184#endif
185#ifndef ND_RA_FLAG_RTPREF_MASK
186#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
187#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
188#endif
189 tmp->rtpref = val & ND_RA_FLAG_RTPREF_MASK;
190 if (tmp->rtpref == ND_RA_FLAG_RTPREF_RSV) {
191 syslog(LOG_ERR, "<%s> invalid router preference on %s",
192 __FUNCTION__, intface);
193 exit(1);
194 }
173
174 MAYHAVE(val, "rltime", tmp->maxinterval * 3);
175 if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) {
176 syslog(LOG_ERR,
177 "<%s> router lifetime on %s must be 0 or"
178 " between %d and %d",
179 __FUNCTION__, intface,
180 tmp->maxinterval, MAXROUTERLIFETIME);
181 exit(1);
182 }
195
196 MAYHAVE(val, "rltime", tmp->maxinterval * 3);
197 if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) {
198 syslog(LOG_ERR,
199 "<%s> router lifetime on %s must be 0 or"
200 " between %d and %d",
201 __FUNCTION__, intface,
202 tmp->maxinterval, MAXROUTERLIFETIME);
203 exit(1);
204 }
205 /*
206 * Basically, hosts MUST NOT send Router Advertisement messages at any
207 * time (RFC 2461, Section 6.2.3). However, it would sometimes be
208 * useful to allow hosts to advertise some parameters such as prefix
209 * information and link MTU. Thus, we allow hosts to invoke rtadvd
210 * only when router lifetime (on every advertising interface) is
211 * explicitly set zero. (see also the above section)
212 */
213 if (val && forwarding == 0) {
214 syslog(LOG_WARNING,
215 "<%s> non zero router lifetime is specified for %s, "
216 "which must not be allowed for hosts.",
217 __FUNCTION__, intface);
218 exit(1);
219 }
183 tmp->lifetime = val & 0xffff;
184
185 MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME);
186 if (val > MAXREACHABLETIME) {
187 syslog(LOG_ERR,
188 "<%s> reachable time must be no greater than %d",
189 __FUNCTION__, MAXREACHABLETIME);
190 exit(1);
191 }
192 tmp->reachabletime = (u_int32_t)val;
193
220 tmp->lifetime = val & 0xffff;
221
222 MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME);
223 if (val > MAXREACHABLETIME) {
224 syslog(LOG_ERR,
225 "<%s> reachable time must be no greater than %d",
226 __FUNCTION__, MAXREACHABLETIME);
227 exit(1);
228 }
229 tmp->reachabletime = (u_int32_t)val;
230
194 MAYHAVE(val, "retrans", DEF_ADVRETRANSTIMER);
195 if (val < 0 || val > 0xffffffff) {
231 MAYHAVE(val64, "retrans", DEF_ADVRETRANSTIMER);
232 if (val64 < 0 || val64 > 0xffffffff) {
196 syslog(LOG_ERR,
197 "<%s> retrans time out of range", __FUNCTION__);
198 exit(1);
199 }
233 syslog(LOG_ERR,
234 "<%s> retrans time out of range", __FUNCTION__);
235 exit(1);
236 }
200 tmp->retranstimer = (u_int32_t)val;
237 tmp->retranstimer = (u_int32_t)val64;
201
238
202#ifdef MIP6
203 if (!mobileip6)
239#ifndef MIP6
240 if (agetstr("hapref", &bp) || agetstr("hatime", &bp)) {
241 syslog(LOG_ERR,
242 "<%s> mobile-ip6 configuration not supported",
243 __FUNCTION__);
244 exit(1);
245 }
204#else
246#else
205 if (1)
206#endif
207 {
247 if (!mobileip6) {
208 if (agetstr("hapref", &bp) || agetstr("hatime", &bp)) {
209 syslog(LOG_ERR,
210 "<%s> mobile-ip6 configuration without "
211 "proper command line option",
212 __FUNCTION__);
213 exit(1);
214 }
248 if (agetstr("hapref", &bp) || agetstr("hatime", &bp)) {
249 syslog(LOG_ERR,
250 "<%s> mobile-ip6 configuration without "
251 "proper command line option",
252 __FUNCTION__);
253 exit(1);
254 }
215 }
216#ifdef MIP6
217 else {
255 } else {
218 tmp->hapref = 0;
219 if ((val = agetnum("hapref")) >= 0)
220 tmp->hapref = (int16_t)val;
221 if (tmp->hapref != 0) {
222 tmp->hatime = 0;
223 MUSTHAVE(val, "hatime");
224 tmp->hatime = (u_int16_t)val;
225 if (tmp->hatime <= 0) {
226 syslog(LOG_ERR,
227 "<%s> home agent lifetime must be greater than 0",
228 __FUNCTION__);
229 exit(1);
230 }
231 }
232 }
233#endif
234
235 /* prefix information */
256 tmp->hapref = 0;
257 if ((val = agetnum("hapref")) >= 0)
258 tmp->hapref = (int16_t)val;
259 if (tmp->hapref != 0) {
260 tmp->hatime = 0;
261 MUSTHAVE(val, "hatime");
262 tmp->hatime = (u_int16_t)val;
263 if (tmp->hatime <= 0) {
264 syslog(LOG_ERR,
265 "<%s> home agent lifetime must be greater than 0",
266 __FUNCTION__);
267 exit(1);
268 }
269 }
270 }
271#endif
272
273 /* prefix information */
274
275 /*
276 * This is an implementation specific parameter to consinder
277 * link propagation delays and poorly synchronized clocks when
278 * checking consistency of advertised lifetimes.
279 */
280 MAYHAVE(val, "clockskew", 0);
281 tmp->clockskew = val;
282
236 if ((pfxs = agetnum("addrs")) < 0) {
237 /* auto configure prefix information */
238 if (agetstr("addr", &bp) || agetstr("addr1", &bp)) {
239 syslog(LOG_ERR,
240 "<%s> conflicting prefix configuration for %s: "
241 "automatic and manual config at the same time",
242 __FUNCTION__, intface);
243 exit(1);

--- 32 unchanged lines hidden (view full) ---

276 pfx->prefixlen = (int)val;
277
278 makeentry(entbuf, i, "pinfoflags", added);
279#ifdef MIP6
280 if (mobileip6)
281 {
282 MAYHAVE(val, entbuf,
283 (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO|
283 if ((pfxs = agetnum("addrs")) < 0) {
284 /* auto configure prefix information */
285 if (agetstr("addr", &bp) || agetstr("addr1", &bp)) {
286 syslog(LOG_ERR,
287 "<%s> conflicting prefix configuration for %s: "
288 "automatic and manual config at the same time",
289 __FUNCTION__, intface);
290 exit(1);

--- 32 unchanged lines hidden (view full) ---

323 pfx->prefixlen = (int)val;
324
325 makeentry(entbuf, i, "pinfoflags", added);
326#ifdef MIP6
327 if (mobileip6)
328 {
329 MAYHAVE(val, entbuf,
330 (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO|
284 ND_OPT_PI_FLAG_RTADDR));
331 ND_OPT_PI_FLAG_ROUTER));
285 } else
286#endif
287 {
288 MAYHAVE(val, entbuf,
289 (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO));
290 }
291 pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
292 pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
293#ifdef MIP6
332 } else
333#endif
334 {
335 MAYHAVE(val, entbuf,
336 (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO));
337 }
338 pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
339 pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
340#ifdef MIP6
294 if (mobileip6)
295 pfx->routeraddr = val & ND_OPT_PI_FLAG_RTADDR;
341 pfx->routeraddr = val & ND_OPT_PI_FLAG_ROUTER;
296#endif
297
298 makeentry(entbuf, i, "vltime", added);
342#endif
343
344 makeentry(entbuf, i, "vltime", added);
299 MAYHAVE(val, entbuf, DEF_ADVVALIDLIFETIME);
300 if (val < 0 || val > 0xffffffff) {
345 MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
346 if (val64 < 0 || val64 > 0xffffffff) {
301 syslog(LOG_ERR,
302 "<%s> vltime out of range",
303 __FUNCTION__);
304 exit(1);
305 }
347 syslog(LOG_ERR,
348 "<%s> vltime out of range",
349 __FUNCTION__);
350 exit(1);
351 }
306 pfx->validlifetime = (u_int32_t)val;
352 pfx->validlifetime = (u_int32_t)val64;
307
353
354 makeentry(entbuf, i, "vltimedecr", added);
355 if (agetflag(entbuf)) {
356 struct timeval now;
357 gettimeofday(&now, 0);
358 pfx->vltimeexpire =
359 now.tv_sec + pfx->validlifetime;
360 }
361
308 makeentry(entbuf, i, "pltime", added);
362 makeentry(entbuf, i, "pltime", added);
309 MAYHAVE(val, entbuf, DEF_ADVPREFERREDLIFETIME);
310 if (val < 0 || val > 0xffffffff) {
363 MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME);
364 if (val64 < 0 || val64 > 0xffffffff) {
311 syslog(LOG_ERR,
312 "<%s> pltime out of range",
313 __FUNCTION__);
314 exit(1);
315 }
365 syslog(LOG_ERR,
366 "<%s> pltime out of range",
367 __FUNCTION__);
368 exit(1);
369 }
316 pfx->preflifetime = (u_int32_t)val;
370 pfx->preflifetime = (u_int32_t)val64;
317
371
372 makeentry(entbuf, i, "pltimedecr", added);
373 if (agetflag(entbuf)) {
374 struct timeval now;
375 gettimeofday(&now, 0);
376 pfx->pltimeexpire =
377 now.tv_sec + pfx->preflifetime;
378 }
379
318 makeentry(entbuf, i, "addr", added);
319 addr = (char *)agetstr(entbuf, &bp);
320 if (addr == NULL) {
321 syslog(LOG_ERR,
322 "<%s> need %s as an prefix for "
323 "interface %s",
324 __FUNCTION__, entbuf, intface);
325 exit(1);

--- 37 unchanged lines hidden (view full) ---

363 else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) {
364 syslog(LOG_ERR,
365 "<%s> advertised link mtu must be between"
366 " least MTU and physical link MTU",
367 __FUNCTION__);
368 exit(1);
369 }
370
380 makeentry(entbuf, i, "addr", added);
381 addr = (char *)agetstr(entbuf, &bp);
382 if (addr == NULL) {
383 syslog(LOG_ERR,
384 "<%s> need %s as an prefix for "
385 "interface %s",
386 __FUNCTION__, entbuf, intface);
387 exit(1);

--- 37 unchanged lines hidden (view full) ---

425 else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) {
426 syslog(LOG_ERR,
427 "<%s> advertised link mtu must be between"
428 " least MTU and physical link MTU",
429 __FUNCTION__);
430 exit(1);
431 }
432
433 /* route information */
434
435 MAYHAVE(val, "routes", 0);
436 if (val < 0 || val > 0xffffffff) {
437 syslog(LOG_ERR,
438 "<%s> number of route information improper", __FUNCTION__);
439 exit(1);
440 }
441 tmp->routes = val;
442 for (i = 0; i < tmp->routes; i++) {
443 struct rtinfo *rti;
444 char entbuf[256];
445 int added = (tmp->routes > 1) ? 1 : 0;
446
447 /* allocate memory to store prefix information */
448 if ((rti = malloc(sizeof(struct rtinfo))) == NULL) {
449 syslog(LOG_ERR,
450 "<%s> can't allocate enough memory",
451 __FUNCTION__);
452 exit(1);
453 }
454 memset(rti, 0, sizeof(*rti));
455
456 /* link into chain */
457 insque(rti, &tmp->route);
458
459 makeentry(entbuf, i, "rtrplen", added);
460 MAYHAVE(val, entbuf, 64);
461 if (val < 0 || val > 128) {
462 syslog(LOG_ERR,
463 "<%s> prefixlen out of range",
464 __FUNCTION__);
465 exit(1);
466 }
467 rti->prefixlen = (int)val;
468
469 makeentry(entbuf, i, "rtrflags", added);
470 MAYHAVE(val, entbuf, 0);
471 rti->rtpref = val & ND_RA_FLAG_RTPREF_MASK;
472 if (rti->rtpref == ND_RA_FLAG_RTPREF_RSV) {
473 syslog(LOG_ERR, "<%s> invalid router preference",
474 __FUNCTION__);
475 exit(1);
476 }
477
478 makeentry(entbuf, i, "rtrltime", added);
479 /*
480 * XXX: since default value of route lifetime is not defined in
481 * draft-draves-route-selection-01.txt, I took the default
482 * value of valid lifetime of prefix as its default.
483 * It need be much considered.
484 */
485 MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
486 if (val64 < 0 || val64 > 0xffffffff) {
487 syslog(LOG_ERR,
488 "<%s> rtrltime out of range",
489 __FUNCTION__);
490 exit(1);
491 }
492 rti->ltime = (u_int32_t)val64;
493
494 makeentry(entbuf, i, "rtrprefix", added);
495 addr = (char *)agetstr(entbuf, &bp);
496 if (addr == NULL) {
497 syslog(LOG_ERR,
498 "<%s> need %s as an route for "
499 "interface %s",
500 __FUNCTION__, entbuf, intface);
501 exit(1);
502 }
503 if (inet_pton(AF_INET6, addr, &rti->prefix) != 1) {
504 syslog(LOG_ERR,
505 "<%s> inet_pton failed for %s",
506 __FUNCTION__, addr);
507 exit(1);
508 }
509#if 0
510 /*
511 * XXX: currently there's no restriction in route information
512 * prefix according to draft-draves-route-selection-01.txt,
513 * however I think the similar restriction be necessary.
514 */
515 MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
516 if (IN6_IS_ADDR_MULTICAST(&rti->prefix)) {
517 syslog(LOG_ERR,
518 "<%s> multicast route (%s) must "
519 "not be advertised (IF=%s)",
520 __FUNCTION__, addr, intface);
521 exit(1);
522 }
523 if (IN6_IS_ADDR_LINKLOCAL(&rti->prefix)) {
524 syslog(LOG_NOTICE,
525 "<%s> link-local route (%s) must "
526 "not be advertised on %s",
527 __FUNCTION__, addr, intface);
528 exit(1);
529 }
530#endif
531 }
532
371 /* okey */
372 tmp->next = ralist;
373 ralist = tmp;
374
375 /* construct the sending packet */
376 make_packet(tmp);
377
378 /* set timer */
379 tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
380 tmp, tmp);
381 ra_timer_update((void *)tmp, &tmp->timer->tm);
382 rtadvd_set_timer(&tmp->timer->tm, tmp->timer);
383}
384
385static void
386get_prefix(struct rainfo *rai)
387{
533 /* okey */
534 tmp->next = ralist;
535 ralist = tmp;
536
537 /* construct the sending packet */
538 make_packet(tmp);
539
540 /* set timer */
541 tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
542 tmp, tmp);
543 ra_timer_update((void *)tmp, &tmp->timer->tm);
544 rtadvd_set_timer(&tmp->timer->tm, tmp->timer);
545}
546
547static void
548get_prefix(struct rainfo *rai)
549{
388 size_t len;
389 u_char *buf, *lim, *next;
550 struct ifaddrs *ifap, *ifa;
551 struct prefix *pp;
552 struct in6_addr *a;
553 u_char *p, *ep, *m, *lim;
390 u_char ntopbuf[INET6_ADDRSTRLEN];
391
554 u_char ntopbuf[INET6_ADDRSTRLEN];
555
392 if ((len = rtbuf_len()) < 0) {
556 if (getifaddrs(&ifap) < 0) {
393 syslog(LOG_ERR,
557 syslog(LOG_ERR,
394 "<%s> can't get buffer length for routing info",
558 "<%s> can't get interface addresses",
395 __FUNCTION__);
396 exit(1);
397 }
559 __FUNCTION__);
560 exit(1);
561 }
398 if ((buf = malloc(len)) == NULL) {
399 syslog(LOG_ERR,
400 "<%s> can't allocate buffer", __FUNCTION__);
401 exit(1);
402 }
403 if (get_rtinfo(buf, &len) < 0) {
404 syslog(LOG_ERR,
405 "<%s> can't get routing inforamtion", __FUNCTION__);
406 exit(1);
407 }
562 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
563 if (strcmp(ifa->ifa_name, rai->ifname) != 0)
564 continue;
565 if (ifa->ifa_addr->sa_family != AF_INET6)
566 continue;
567 a = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
568 if (IN6_IS_ADDR_LINKLOCAL(a))
569 continue;
408
570
409 lim = buf + len;
410 next = get_next_msg(buf, lim, rai->ifindex, &len,
411 RTADV_TYPE2BITMASK(RTM_GET));
412 while (next < lim) {
413 struct prefix *pp;
414 struct in6_addr *a;
415
416 /* allocate memory to store prefix info. */
417 if ((pp = malloc(sizeof(*pp))) == NULL) {
418 syslog(LOG_ERR,
419 "<%s> can't get allocate buffer for prefix",
420 __FUNCTION__);
421 exit(1);
422 }
423 memset(pp, 0, sizeof(*pp));
424
571 /* allocate memory to store prefix info. */
572 if ((pp = malloc(sizeof(*pp))) == NULL) {
573 syslog(LOG_ERR,
574 "<%s> can't get allocate buffer for prefix",
575 __FUNCTION__);
576 exit(1);
577 }
578 memset(pp, 0, sizeof(*pp));
579
425 /* set prefix and its length */
426 a = get_addr(next);
427 memcpy(&pp->prefix, a, sizeof(*a));
428 if ((pp->prefixlen = get_prefixlen(next)) < 0) {
580 /* set prefix length */
581 m = (u_char *)&((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
582 lim = (u_char *)(ifa->ifa_netmask) + ifa->ifa_netmask->sa_len;
583 pp->prefixlen = prefixlen(m, lim);
584 if (pp->prefixlen < 0 || pp->prefixlen > 128) {
429 syslog(LOG_ERR,
430 "<%s> failed to get prefixlen "
585 syslog(LOG_ERR,
586 "<%s> failed to get prefixlen "
431 "or prefixl is invalid",
587 "or prefix is invalid",
432 __FUNCTION__);
433 exit(1);
434 }
588 __FUNCTION__);
589 exit(1);
590 }
591
592 /* set prefix, sweep bits outside of prefixlen */
593 memcpy(&pp->prefix, a, sizeof(*a));
594 p = (u_char *)&pp->prefix;
595 ep = (u_char *)(&pp->prefix + 1);
596 while (m < lim)
597 *p++ &= *m++;
598 while (p < ep)
599 *p++ = 0x00;
600
601 if (!inet_ntop(AF_INET6, &pp->prefix, ntopbuf,
602 sizeof(ntopbuf))) {
603 syslog(LOG_ERR, "<%s> inet_ntop failed", __FUNCTION__);
604 exit(1);
605 }
435 syslog(LOG_DEBUG,
436 "<%s> add %s/%d to prefix list on %s",
606 syslog(LOG_DEBUG,
607 "<%s> add %s/%d to prefix list on %s",
437 __FUNCTION__,
438 inet_ntop(AF_INET6, a, ntopbuf, INET6_ADDRSTRLEN),
439 pp->prefixlen, rai->ifname);
608 __FUNCTION__, ntopbuf, pp->prefixlen, rai->ifname);
440
441 /* set other fields with protocol defaults */
442 pp->validlifetime = DEF_ADVVALIDLIFETIME;
443 pp->preflifetime = DEF_ADVPREFERREDLIFETIME;
444 pp->onlinkflg = 1;
445 pp->autoconfflg = 1;
446 pp->origin = PREFIX_FROM_KERNEL;
447
448 /* link into chain */
449 insque(pp, &rai->prefix);
450
451 /* counter increment */
452 rai->pfxs++;
609
610 /* set other fields with protocol defaults */
611 pp->validlifetime = DEF_ADVVALIDLIFETIME;
612 pp->preflifetime = DEF_ADVPREFERREDLIFETIME;
613 pp->onlinkflg = 1;
614 pp->autoconfflg = 1;
615 pp->origin = PREFIX_FROM_KERNEL;
616
617 /* link into chain */
618 insque(pp, &rai->prefix);
619
620 /* counter increment */
621 rai->pfxs++;
453
454 /* forward pointer and get next prefix(if any) */
455 next += len;
456 next = get_next_msg(next, lim, rai->ifindex,
457 &len, RTADV_TYPE2BITMASK(RTM_GET));
458 }
459
622 }
623
460 free(buf);
624 freeifaddrs(ifap);
461}
462
463static void
464makeentry(buf, id, string, add)
465 char *buf, *string;
466 int id, add;
467{
468 strcpy(buf, string);

--- 19 unchanged lines hidden (view full) ---

488 struct prefix *prefix;
489 u_char ntopbuf[INET6_ADDRSTRLEN];
490
491 if ((prefix = malloc(sizeof(*prefix))) == NULL) {
492 syslog(LOG_ERR, "<%s> memory allocation failed",
493 __FUNCTION__);
494 return; /* XXX: error or exit? */
495 }
625}
626
627static void
628makeentry(buf, id, string, add)
629 char *buf, *string;
630 int id, add;
631{
632 strcpy(buf, string);

--- 19 unchanged lines hidden (view full) ---

652 struct prefix *prefix;
653 u_char ntopbuf[INET6_ADDRSTRLEN];
654
655 if ((prefix = malloc(sizeof(*prefix))) == NULL) {
656 syslog(LOG_ERR, "<%s> memory allocation failed",
657 __FUNCTION__);
658 return; /* XXX: error or exit? */
659 }
660 memset(prefix, 0, sizeof(*prefix));
496 prefix->prefix = ipr->ipr_prefix.sin6_addr;
497 prefix->prefixlen = ipr->ipr_plen;
498 prefix->validlifetime = ipr->ipr_vltime;
499 prefix->preflifetime = ipr->ipr_pltime;
500 prefix->onlinkflg = ipr->ipr_raf_onlink;
501 prefix->autoconfflg = ipr->ipr_raf_auto;
502 prefix->origin = PREFIX_FROM_DYNAMIC;
503
504 insque(prefix, &rai->prefix);
505
506 syslog(LOG_DEBUG, "<%s> new prefix %s/%d was added on %s",
507 __FUNCTION__, inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr,
508 ntopbuf, INET6_ADDRSTRLEN),
509 ipr->ipr_plen, rai->ifname);
510
511 /* free the previous packet */
512 free(rai->ra_data);
661 prefix->prefix = ipr->ipr_prefix.sin6_addr;
662 prefix->prefixlen = ipr->ipr_plen;
663 prefix->validlifetime = ipr->ipr_vltime;
664 prefix->preflifetime = ipr->ipr_pltime;
665 prefix->onlinkflg = ipr->ipr_raf_onlink;
666 prefix->autoconfflg = ipr->ipr_raf_auto;
667 prefix->origin = PREFIX_FROM_DYNAMIC;
668
669 insque(prefix, &rai->prefix);
670
671 syslog(LOG_DEBUG, "<%s> new prefix %s/%d was added on %s",
672 __FUNCTION__, inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr,
673 ntopbuf, INET6_ADDRSTRLEN),
674 ipr->ipr_plen, rai->ifname);
675
676 /* free the previous packet */
677 free(rai->ra_data);
513 rai->ra_data = 0;
678 rai->ra_data = NULL;
514
515 /* reconstruct the packet */
516 rai->pfxs++;
517 make_packet(rai);
518
519 /*
520 * reset the timer so that the new prefix will be advertised quickly.
521 */

--- 90 unchanged lines hidden (view full) ---

612make_packet(struct rainfo *rainfo)
613{
614 size_t packlen, lladdroptlen = 0;
615 char *buf;
616 struct nd_router_advert *ra;
617 struct nd_opt_prefix_info *ndopt_pi;
618 struct nd_opt_mtu *ndopt_mtu;
619#ifdef MIP6
679
680 /* reconstruct the packet */
681 rai->pfxs++;
682 make_packet(rai);
683
684 /*
685 * reset the timer so that the new prefix will be advertised quickly.
686 */

--- 90 unchanged lines hidden (view full) ---

777make_packet(struct rainfo *rainfo)
778{
779 size_t packlen, lladdroptlen = 0;
780 char *buf;
781 struct nd_router_advert *ra;
782 struct nd_opt_prefix_info *ndopt_pi;
783 struct nd_opt_mtu *ndopt_mtu;
784#ifdef MIP6
620 struct nd_opt_advint *ndopt_advint;
621 struct nd_opt_hai *ndopt_hai;
785 struct nd_opt_advinterval *ndopt_advint;
786 struct nd_opt_homeagent_info *ndopt_hai;
622#endif
787#endif
788 struct nd_opt_route_info *ndopt_rti;
623 struct prefix *pfx;
789 struct prefix *pfx;
790 struct rtinfo *rti;
624
625 /* calculate total length */
626 packlen = sizeof(struct nd_router_advert);
627 if (rainfo->advlinkopt) {
628 if ((lladdroptlen = lladdropt_length(rainfo->sdl)) == 0) {
629 syslog(LOG_INFO,
630 "<%s> link-layer address option has"
631 " null length on %s."

--- 4 unchanged lines hidden (view full) ---

636 packlen += lladdroptlen;
637 }
638 if (rainfo->pfxs)
639 packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs;
640 if (rainfo->linkmtu)
641 packlen += sizeof(struct nd_opt_mtu);
642#ifdef MIP6
643 if (mobileip6 && rainfo->maxinterval)
791
792 /* calculate total length */
793 packlen = sizeof(struct nd_router_advert);
794 if (rainfo->advlinkopt) {
795 if ((lladdroptlen = lladdropt_length(rainfo->sdl)) == 0) {
796 syslog(LOG_INFO,
797 "<%s> link-layer address option has"
798 " null length on %s."

--- 4 unchanged lines hidden (view full) ---

803 packlen += lladdroptlen;
804 }
805 if (rainfo->pfxs)
806 packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs;
807 if (rainfo->linkmtu)
808 packlen += sizeof(struct nd_opt_mtu);
809#ifdef MIP6
810 if (mobileip6 && rainfo->maxinterval)
644 packlen += sizeof(struct nd_opt_advint);
811 packlen += sizeof(struct nd_opt_advinterval);
645 if (mobileip6 && rainfo->hatime)
812 if (mobileip6 && rainfo->hatime)
646 packlen += sizeof(struct nd_opt_hai);
813 packlen += sizeof(struct nd_opt_homeagent_info);
647#endif
814#endif
815#ifdef ND_OPT_ROUTE_INFO
816 for (rti = rainfo->route.next; rti != &rainfo->route; rti = rti->next)
817 packlen += sizeof(struct nd_opt_route_info) +
818 ((rti->prefixlen + 0x3f) >> 6) * 8;
819#endif
648
649 /* allocate memory for the packet */
650 if ((buf = malloc(packlen)) == NULL) {
651 syslog(LOG_ERR,
652 "<%s> can't get enough memory for an RA packet",
653 __FUNCTION__);
654 exit(1);
655 }
820
821 /* allocate memory for the packet */
822 if ((buf = malloc(packlen)) == NULL) {
823 syslog(LOG_ERR,
824 "<%s> can't get enough memory for an RA packet",
825 __FUNCTION__);
826 exit(1);
827 }
828 if (rainfo->ra_data) {
829 /* free the previous packet */
830 free(rainfo->ra_data);
831 rainfo->ra_data = NULL;
832 }
656 rainfo->ra_data = buf;
657 /* XXX: what if packlen > 576? */
658 rainfo->ra_datalen = packlen;
659
660 /*
661 * construct the packet
662 */
663 ra = (struct nd_router_advert *)buf;
664 ra->nd_ra_type = ND_ROUTER_ADVERT;
665 ra->nd_ra_code = 0;
666 ra->nd_ra_cksum = 0;
667 ra->nd_ra_curhoplimit = (u_int8_t)(0xff & rainfo->hoplimit);
833 rainfo->ra_data = buf;
834 /* XXX: what if packlen > 576? */
835 rainfo->ra_datalen = packlen;
836
837 /*
838 * construct the packet
839 */
840 ra = (struct nd_router_advert *)buf;
841 ra->nd_ra_type = ND_ROUTER_ADVERT;
842 ra->nd_ra_code = 0;
843 ra->nd_ra_cksum = 0;
844 ra->nd_ra_curhoplimit = (u_int8_t)(0xff & rainfo->hoplimit);
668 ra->nd_ra_flags_reserved = 0;
845 ra->nd_ra_flags_reserved = 0; /* just in case */
846 /*
847 * XXX: the router preference field, which is a 2-bit field, should be
848 * initialized before other fields.
849 */
850 ra->nd_ra_flags_reserved = 0xff & rainfo->rtpref;
669 ra->nd_ra_flags_reserved |=
670 rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0;
671 ra->nd_ra_flags_reserved |=
672 rainfo->otherflg ? ND_RA_FLAG_OTHER : 0;
673#ifdef MIP6
674 ra->nd_ra_flags_reserved |=
675 rainfo->haflg ? ND_RA_FLAG_HA : 0;
676#endif

--- 7 unchanged lines hidden (view full) ---

684 buf += lladdroptlen;
685 }
686
687 if (rainfo->linkmtu) {
688 ndopt_mtu = (struct nd_opt_mtu *)buf;
689 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU;
690 ndopt_mtu->nd_opt_mtu_len = 1;
691 ndopt_mtu->nd_opt_mtu_reserved = 0;
851 ra->nd_ra_flags_reserved |=
852 rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0;
853 ra->nd_ra_flags_reserved |=
854 rainfo->otherflg ? ND_RA_FLAG_OTHER : 0;
855#ifdef MIP6
856 ra->nd_ra_flags_reserved |=
857 rainfo->haflg ? ND_RA_FLAG_HA : 0;
858#endif

--- 7 unchanged lines hidden (view full) ---

866 buf += lladdroptlen;
867 }
868
869 if (rainfo->linkmtu) {
870 ndopt_mtu = (struct nd_opt_mtu *)buf;
871 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU;
872 ndopt_mtu->nd_opt_mtu_len = 1;
873 ndopt_mtu->nd_opt_mtu_reserved = 0;
692 ndopt_mtu->nd_opt_mtu_mtu = ntohl(rainfo->linkmtu);
874 ndopt_mtu->nd_opt_mtu_mtu = htonl(rainfo->linkmtu);
693 buf += sizeof(struct nd_opt_mtu);
694 }
695
696#ifdef MIP6
697 if (mobileip6 && rainfo->maxinterval) {
875 buf += sizeof(struct nd_opt_mtu);
876 }
877
878#ifdef MIP6
879 if (mobileip6 && rainfo->maxinterval) {
698 ndopt_advint = (struct nd_opt_advint *)buf;
699 ndopt_advint->nd_opt_int_type = ND_OPT_ADV_INTERVAL;
700 ndopt_advint->nd_opt_int_len = 1;
701 ndopt_advint->nd_opt_int_reserved = 0;
702 ndopt_advint->nd_opt_int_interval = ntohl(rainfo->maxinterval *
880 ndopt_advint = (struct nd_opt_advinterval *)buf;
881 ndopt_advint->nd_opt_adv_type = ND_OPT_ADVINTERVAL;
882 ndopt_advint->nd_opt_adv_len = 1;
883 ndopt_advint->nd_opt_adv_reserved = 0;
884 ndopt_advint->nd_opt_adv_interval = htonl(rainfo->maxinterval *
703 1000);
885 1000);
704 buf += sizeof(struct nd_opt_advint);
886 buf += sizeof(struct nd_opt_advinterval);
705 }
706#endif
707
708#ifdef MIP6
709 if (rainfo->hatime) {
887 }
888#endif
889
890#ifdef MIP6
891 if (rainfo->hatime) {
710 ndopt_hai = (struct nd_opt_hai *)buf;
711 ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
892 ndopt_hai = (struct nd_opt_homeagent_info *)buf;
893 ndopt_hai->nd_opt_hai_type = ND_OPT_HOMEAGENT_INFO;
712 ndopt_hai->nd_opt_hai_len = 1;
713 ndopt_hai->nd_opt_hai_reserved = 0;
894 ndopt_hai->nd_opt_hai_len = 1;
895 ndopt_hai->nd_opt_hai_reserved = 0;
714 ndopt_hai->nd_opt_hai_pref = ntohs(rainfo->hapref);
715 ndopt_hai->nd_opt_hai_lifetime = ntohs(rainfo->hatime);
716 buf += sizeof(struct nd_opt_hai);
896 ndopt_hai->nd_opt_hai_preference = htons(rainfo->hapref);
897 ndopt_hai->nd_opt_hai_lifetime = htons(rainfo->hatime);
898 buf += sizeof(struct nd_opt_homeagent_info);
717 }
718#endif
719
720 for (pfx = rainfo->prefix.next;
721 pfx != &rainfo->prefix; pfx = pfx->next) {
899 }
900#endif
901
902 for (pfx = rainfo->prefix.next;
903 pfx != &rainfo->prefix; pfx = pfx->next) {
904 u_int32_t vltime, pltime;
905 struct timeval now;
906
722 ndopt_pi = (struct nd_opt_prefix_info *)buf;
723 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
724 ndopt_pi->nd_opt_pi_len = 4;
725 ndopt_pi->nd_opt_pi_prefix_len = pfx->prefixlen;
726 ndopt_pi->nd_opt_pi_flags_reserved = 0;
727 if (pfx->onlinkflg)
728 ndopt_pi->nd_opt_pi_flags_reserved |=
729 ND_OPT_PI_FLAG_ONLINK;
730 if (pfx->autoconfflg)
731 ndopt_pi->nd_opt_pi_flags_reserved |=
732 ND_OPT_PI_FLAG_AUTO;
733#ifdef MIP6
734 if (pfx->routeraddr)
735 ndopt_pi->nd_opt_pi_flags_reserved |=
907 ndopt_pi = (struct nd_opt_prefix_info *)buf;
908 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
909 ndopt_pi->nd_opt_pi_len = 4;
910 ndopt_pi->nd_opt_pi_prefix_len = pfx->prefixlen;
911 ndopt_pi->nd_opt_pi_flags_reserved = 0;
912 if (pfx->onlinkflg)
913 ndopt_pi->nd_opt_pi_flags_reserved |=
914 ND_OPT_PI_FLAG_ONLINK;
915 if (pfx->autoconfflg)
916 ndopt_pi->nd_opt_pi_flags_reserved |=
917 ND_OPT_PI_FLAG_AUTO;
918#ifdef MIP6
919 if (pfx->routeraddr)
920 ndopt_pi->nd_opt_pi_flags_reserved |=
736 ND_OPT_PI_FLAG_RTADDR;
921 ND_OPT_PI_FLAG_ROUTER;
737#endif
922#endif
738 ndopt_pi->nd_opt_pi_valid_time = ntohl(pfx->validlifetime);
739 ndopt_pi->nd_opt_pi_preferred_time =
740 ntohl(pfx->preflifetime);
923 if (pfx->vltimeexpire || pfx->pltimeexpire)
924 gettimeofday(&now, NULL);
925 if (pfx->vltimeexpire == 0)
926 vltime = pfx->validlifetime;
927 else
928 vltime = (pfx->vltimeexpire > now.tv_sec) ?
929 pfx->vltimeexpire - now.tv_sec : 0;
930 if (pfx->pltimeexpire == 0)
931 pltime = pfx->preflifetime;
932 else
933 pltime = (pfx->pltimeexpire > now.tv_sec) ?
934 pfx->pltimeexpire - now.tv_sec : 0;
935 if (vltime < pltime) {
936 /*
937 * this can happen if vltime is decrement but pltime
938 * is not.
939 */
940 pltime = vltime;
941 }
942 ndopt_pi->nd_opt_pi_valid_time = htonl(vltime);
943 ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime);
741 ndopt_pi->nd_opt_pi_reserved2 = 0;
742 ndopt_pi->nd_opt_pi_prefix = pfx->prefix;
743
744 buf += sizeof(struct nd_opt_prefix_info);
745 }
746
944 ndopt_pi->nd_opt_pi_reserved2 = 0;
945 ndopt_pi->nd_opt_pi_prefix = pfx->prefix;
946
947 buf += sizeof(struct nd_opt_prefix_info);
948 }
949
950#ifdef ND_OPT_ROUTE_INFO
951 for (rti = rainfo->route.next; rti != &rainfo->route; rti = rti->next) {
952 u_int8_t psize = (rti->prefixlen + 0x3f) >> 6;
953
954 ndopt_rti = (struct nd_opt_route_info *)buf;
955 ndopt_rti->nd_opt_rti_type = ND_OPT_ROUTE_INFO;
956 ndopt_rti->nd_opt_rti_len = 1 + psize;
957 ndopt_rti->nd_opt_rti_prefixlen = rti->prefixlen;
958 ndopt_rti->nd_opt_rti_flags = 0xff & rti->rtpref;
959 ndopt_rti->nd_opt_rti_lifetime = rti->ltime;
960 memcpy(ndopt_rti + 1, &rti->prefix, psize * 8);
961 buf += sizeof(struct nd_opt_route_info) + psize * 8;
962 }
963#endif
964
747 return;
748}
965 return;
966}
967
968static int
969getinet6sysctl(int code)
970{
971 int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 };
972 int value;
973 size_t size;
974
975 mib[3] = code;
976 size = sizeof(value);
977 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0)
978 < 0) {
979 syslog(LOG_ERR, "<%s>: failed to get ip6 sysctl(%d): %s",
980 __FUNCTION__, code,
981 strerror(errno));
982 return(-1);
983 }
984 else
985 return(value);
986}