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} |
|