Annotation of embedaddon/pimdd/main.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 1998 by the University of Oregon.
! 3: * All rights reserved.
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software and
! 6: * its documentation in source and binary forms for lawful
! 7: * purposes and without fee is hereby granted, provided
! 8: * that the above copyright notice appear in all copies and that both
! 9: * the copyright notice and this permission notice appear in supporting
! 10: * documentation, and that any documentation, advertising materials,
! 11: * and other materials related to such distribution and use acknowledge
! 12: * that the software was developed by the University of Oregon.
! 13: * The name of the University of Oregon may not be used to endorse or
! 14: * promote products derived from this software without specific prior
! 15: * written permission.
! 16: *
! 17: * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
! 18: * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
! 19: * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
! 20: * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
! 21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
! 22: * NON-INFRINGEMENT.
! 23: *
! 24: * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
! 25: * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
! 26: * TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
! 27: * THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 28: *
! 29: * Other copyrights might apply to parts of this software and are so
! 30: * noted when applicable.
! 31: */
! 32: /*
! 33: * Questions concerning this software should be directed to
! 34: * Kurt Windisch (kurtw@antc.uoregon.edu)
! 35: *
! 36: * $Id: main.c,v 1.13 1998/06/01 15:25:46 kurtw Exp $
! 37: */
! 38: /*
! 39: * Part of this program has been derived from PIM sparse-mode pimd.
! 40: * The pimd program is covered by the license in the accompanying file
! 41: * named "LICENSE.pimd".
! 42: *
! 43: * The pimd program is COPYRIGHT 1998 by University of Southern California.
! 44: *
! 45: * Part of this program has been derived from mrouted.
! 46: * The mrouted program is covered by the license in the accompanying file
! 47: * named "LICENSE.mrouted".
! 48: *
! 49: * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
! 50: * Leland Stanford Junior University.
! 51: *
! 52: */
! 53:
! 54: #include "defs.h"
! 55:
! 56: #ifdef SNMP
! 57: #include "snmp.h"
! 58: #endif
! 59:
! 60: char configfilename[256] = _PATH_PIMD_CONF;
! 61: char versionstring[100];
! 62:
! 63: static char pidfilename[] = _PATH_PIMD_PID;
! 64: /* TODO: not used
! 65: static char genidfilename[] = _PATH_PIMD_GENID;
! 66: */
! 67:
! 68: int haveterminal = 1;
! 69: char *progname;
! 70:
! 71: static int sighandled = 0;
! 72: #define GOT_SIGINT 0x01
! 73: #define GOT_SIGHUP 0x02
! 74: #define GOT_SIGUSR1 0x04
! 75: #define GOT_SIGUSR2 0x08
! 76: #define GOT_SIGALRM 0x10
! 77:
! 78:
! 79: #ifdef SNMP
! 80: #define NHANDLERS 34
! 81: #else
! 82: #define NHANDLERS 3
! 83: #endif
! 84:
! 85: static struct ihandler {
! 86: int fd; /* File descriptor */
! 87: ihfunc_t func; /* Function to call with &fd_set */
! 88: } ihandlers[NHANDLERS];
! 89: static int nhandlers = 0;
! 90:
! 91: static struct debugname {
! 92: char *name;
! 93: int level;
! 94: int nchars;
! 95: } debugnames[] = {
! 96: { "dvmrp_detail", DEBUG_DVMRP_DETAIL, 5 },
! 97: { "dvmrp_prunes", DEBUG_DVMRP_PRUNE, 8 },
! 98: { "dvmrp_pruning", DEBUG_DVMRP_PRUNE, 8 },
! 99: { "dvmrp_mrt", DEBUG_DVMRP_ROUTE, 7 },
! 100: { "dvmrp_routes", DEBUG_DVMRP_ROUTE, 7 },
! 101: { "dvmrp_routing", DEBUG_DVMRP_ROUTE, 7 },
! 102: { "dvmrp_neighbors", DEBUG_DVMRP_PEER, 7 },
! 103: { "dvmrp_peers", DEBUG_DVMRP_PEER, 8 },
! 104: { "dvmrp_hello", DEBUG_DVMRP_PEER, 7 },
! 105: { "dvmrp_timers", DEBUG_DVMRP_TIMER, 7 },
! 106: { "dvmrp", DEBUG_DVMRP, 1 },
! 107: { "igmp_proto", DEBUG_IGMP_PROTO, 6 },
! 108: { "igmp_timers", DEBUG_IGMP_TIMER, 6 },
! 109: { "igmp_members", DEBUG_IGMP_MEMBER, 6 },
! 110: { "groups", DEBUG_MEMBER, 1 },
! 111: { "membership", DEBUG_MEMBER, 2 },
! 112: { "igmp", DEBUG_IGMP, 1 },
! 113: { "trace", DEBUG_TRACE, 2 },
! 114: { "mtrace", DEBUG_TRACE, 2 },
! 115: { "traceroute", DEBUG_TRACE, 2 },
! 116: { "timeout", DEBUG_TIMEOUT, 2 },
! 117: { "callout", DEBUG_TIMEOUT, 3 },
! 118: { "pkt", DEBUG_PKT, 2 },
! 119: { "packets", DEBUG_PKT, 2 },
! 120: { "interfaces", DEBUG_IF, 2 },
! 121: { "vif", DEBUG_IF, 1 },
! 122: { "kernel", DEBUG_KERN, 2 },
! 123: { "cache", DEBUG_MFC, 1 },
! 124: { "mfc", DEBUG_MFC, 2 },
! 125: { "k_cache", DEBUG_MFC, 2 },
! 126: { "k_mfc", DEBUG_MFC, 2 },
! 127: { "rsrr", DEBUG_RSRR, 2 },
! 128: { "pim_detail", DEBUG_PIM_DETAIL, 5 },
! 129: { "pim_hello", DEBUG_PIM_HELLO, 5 },
! 130: { "pim_neighbors", DEBUG_PIM_HELLO, 5 },
! 131: { "pim_register", DEBUG_PIM_REGISTER, 5 },
! 132: { "registers", DEBUG_PIM_REGISTER, 2 },
! 133: { "pim_join_prune", DEBUG_PIM_JOIN_PRUNE, 5 },
! 134: { "pim_j_p", DEBUG_PIM_JOIN_PRUNE, 5 },
! 135: { "pim_jp", DEBUG_PIM_JOIN_PRUNE, 5 },
! 136: { "pim_graft", DEBUG_PIM_GRAFT, 5 },
! 137: { "pim_bootstrap", DEBUG_PIM_BOOTSTRAP, 5 },
! 138: { "pim_bsr", DEBUG_PIM_BOOTSTRAP, 5 },
! 139: { "bsr", DEBUG_PIM_BOOTSTRAP, 1 },
! 140: { "bootstrap", DEBUG_PIM_BOOTSTRAP, 1 },
! 141: { "pim_asserts", DEBUG_PIM_ASSERT, 5 },
! 142: { "pim_cand_rp", DEBUG_PIM_CAND_RP, 5 },
! 143: { "pim_c_rp", DEBUG_PIM_CAND_RP, 5 },
! 144: { "pim_rp", DEBUG_PIM_CAND_RP, 6 },
! 145: { "rp", DEBUG_PIM_CAND_RP, 2 },
! 146: { "pim_routes", DEBUG_PIM_MRT, 6 },
! 147: { "pim_routing", DEBUG_PIM_MRT, 6 },
! 148: { "pim_mrt", DEBUG_PIM_MRT, 5 },
! 149: { "pim_timers", DEBUG_PIM_TIMER, 5 },
! 150: { "pim_rpf", DEBUG_PIM_RPF, 6 },
! 151: { "rpf", DEBUG_RPF, 3 },
! 152: { "pim", DEBUG_PIM, 1 },
! 153: { "routes", DEBUG_MRT, 1 },
! 154: { "routing", DEBUG_MRT, 1 },
! 155: { "mrt", DEBUG_MRT, 1 },
! 156: { "routers", DEBUG_NEIGHBORS, 6 },
! 157: { "mrouters", DEBUG_NEIGHBORS, 7 },
! 158: { "neighbors", DEBUG_NEIGHBORS, 1 },
! 159: { "timers", DEBUG_TIMER, 1 },
! 160: { "asserts", DEBUG_ASSERT, 1 },
! 161: { "all", DEBUG_ALL, 2 },
! 162: { "3", 0xffffffff, 1 } /* compat. */
! 163: };
! 164:
! 165: /*
! 166: * Forward declarations.
! 167: */
! 168: static void handler __P((int));
! 169: static void timer __P((void *));
! 170: static void cleanup __P((void));
! 171: static void restart __P((int));
! 172: static void cleanup __P((void));
! 173: static void resetlogging __P((void *));
! 174:
! 175:
! 176: /* To shut up gcc -Wstrict-prototypes */
! 177: int main __P((int argc, char **argv));
! 178:
! 179: int
! 180: register_input_handler(fd, func)
! 181: int fd;
! 182: ihfunc_t func;
! 183: {
! 184: if (nhandlers >= NHANDLERS)
! 185: return -1;
! 186:
! 187: ihandlers[nhandlers].fd = fd;
! 188: ihandlers[nhandlers++].func = func;
! 189:
! 190: return 0;
! 191: }
! 192:
! 193: int
! 194: main(argc, argv)
! 195: int argc;
! 196: char *argv[];
! 197: {
! 198: int dummy, dummysigalrm;
! 199: FILE *fp;
! 200: struct timeval tv, difftime, curtime, lasttime, *timeout;
! 201: fd_set rfds, readers;
! 202: int nfds, n, i, secs;
! 203: extern char todaysversion[];
! 204: struct sigaction sa;
! 205: struct debugname *d;
! 206: char c;
! 207: int tmpd;
! 208:
! 209:
! 210: setlinebuf(stderr);
! 211:
! 212: if (geteuid() != 0) {
! 213: fprintf(stderr, "pimdd: must be root\n");
! 214: exit(1);
! 215: }
! 216:
! 217: progname = strrchr(argv[0], '/');
! 218: if (progname)
! 219: progname++;
! 220: else
! 221: progname = argv[0];
! 222:
! 223: argv++;
! 224: argc--;
! 225: while (argc > 0 && *argv[0] == '-') {
! 226: if (strcmp(*argv, "-d") == 0) {
! 227: if (argc > 1 && *(argv + 1)[0] != '-') {
! 228: char *p,*q;
! 229: int i, len;
! 230: struct debugname *d;
! 231:
! 232: argv++;
! 233: argc--;
! 234: debug = 0;
! 235: p = *argv; q = NULL;
! 236: while (p) {
! 237: q = strchr(p, ',');
! 238: if (q)
! 239: *q++ = '\0';
! 240: len = strlen(p);
! 241: for (i = 0, d = debugnames;
! 242: i < sizeof(debugnames) / sizeof(debugnames[0]);
! 243: i++, d++)
! 244: if (len >= d->nchars && strncmp(d->name, p, len) == 0)
! 245: break;
! 246: if (i == sizeof(debugnames) / sizeof(debugnames[0])) {
! 247: int j = 0xffffffff;
! 248: int k = 0;
! 249: fprintf(stderr, "Valid debug levels: ");
! 250: for (i = 0, d = debugnames;
! 251: i < sizeof(debugnames) / sizeof(debugnames[0]);
! 252: i++, d++) {
! 253: if ((j & d->level) == d->level) {
! 254: if (k++)
! 255: putc(',', stderr);
! 256: fputs(d->name, stderr);
! 257: j &= ~d->level;
! 258: }
! 259: }
! 260: putc('\n', stderr);
! 261: goto usage;
! 262: }
! 263: debug |= d->level;
! 264: p = q;
! 265: }
! 266: }
! 267: else
! 268: debug = DEBUG_DEFAULT;
! 269: }
! 270: else if (strcmp(*argv, "-c") == 0) {
! 271: if (argc > 1) {
! 272: argv++; argc--;
! 273: strcpy(configfilename, *argv);
! 274: }
! 275: else
! 276: goto usage;
! 277: /* TODO: not implemented */
! 278: #ifdef SNMP
! 279: }
! 280: else if (strcmp(*argv, "-P") == 0) {
! 281: if (argc > 1 && isdigit(*(argv + 1)[0])) {
! 282: argv++, argc--;
! 283: dest_port = atoi(*argv);
! 284: }
! 285: else
! 286: dest_port = DEFAULT_PORT;
! 287: #endif
! 288: }
! 289: else
! 290: goto usage;
! 291: argv++; argc--;
! 292: }
! 293:
! 294: if (argc > 0) {
! 295: usage:
! 296: tmpd = 0xffffffff;
! 297: fprintf(stderr, "usage: pimdd [-c configfile] [-d [debug_level][,debug_level]]\n");
! 298:
! 299: fprintf(stderr, "debug levels: ");
! 300: c = '(';
! 301: for (d = debugnames; d < debugnames +
! 302: sizeof(debugnames) / sizeof(debugnames[0]); d++) {
! 303: if ((tmpd & d->level) == d->level) {
! 304: tmpd &= ~d->level;
! 305: fprintf(stderr, "%c%s", c, d->name);
! 306: c = ',';
! 307: }
! 308: }
! 309: fprintf(stderr, ")\n");
! 310: exit(1);
! 311: }
! 312:
! 313: if (debug != 0) {
! 314: tmpd = debug;
! 315: fprintf(stderr, "debug level 0x%lx ", debug);
! 316: c = '(';
! 317: for (d = debugnames; d < debugnames +
! 318: sizeof(debugnames) / sizeof(debugnames[0]); d++) {
! 319: if ((tmpd & d->level) == d->level) {
! 320: tmpd &= ~d->level;
! 321: fprintf(stderr, "%c%s", c, d->name);
! 322: c = ',';
! 323: }
! 324: }
! 325: fprintf(stderr, ")\n");
! 326: }
! 327:
! 328: #ifdef LOG_DAEMON
! 329: (void)openlog("pimdd", LOG_PID, LOG_DAEMON);
! 330: (void)setlogmask(LOG_UPTO(LOG_NOTICE));
! 331: #else
! 332: (void)openlog("pimdd", LOG_PID);
! 333: #endif /* LOG_DAEMON */
! 334: sprintf(versionstring, "pimdd version %s", todaysversion);
! 335:
! 336: log(LOG_DEBUG, 0, "%s starting", versionstring);
! 337:
! 338: /* TODO: XXX: use a combination of time and hostid to initialize the random
! 339: * generator.
! 340: */
! 341: #ifdef SYSV
! 342: srand48(time(NULL));
! 343: #else
! 344: srandom(gethostid());
! 345: #endif
! 346:
! 347: /* Start up the log rate-limiter */
! 348: resetlogging(NULL);
! 349:
! 350: callout_init();
! 351: init_igmp();
! 352: init_pim();
! 353: #ifdef HAVE_ROUTING_SOCKETS
! 354: init_routesock();
! 355: #endif /* HAVE_ROUTING_SOCKETS */
! 356: init_pim_mrt();
! 357: init_timers();
! 358:
! 359: /* TODO: check the kernel DVMRP/MROUTED/PIM support version */
! 360:
! 361: #ifdef SNMP
! 362: if (i = snmp_init())
! 363: return i;
! 364: #endif /* SNMP */
! 365: init_vifs();
! 366:
! 367: #ifdef RSRR
! 368: rsrr_init();
! 369: #endif /* RSRR */
! 370:
! 371: sa.sa_handler = handler;
! 372: sa.sa_flags = 0; /* Interrupt system calls */
! 373: sigemptyset(&sa.sa_mask);
! 374: sigaction(SIGALRM, &sa, NULL);
! 375: sigaction(SIGHUP, &sa, NULL);
! 376: sigaction(SIGTERM, &sa, NULL);
! 377: sigaction(SIGINT, &sa, NULL);
! 378: sigaction(SIGUSR1, &sa, NULL);
! 379: sigaction(SIGUSR2, &sa, NULL);
! 380:
! 381: FD_ZERO(&readers);
! 382: FD_SET(igmp_socket, &readers);
! 383: nfds = igmp_socket + 1;
! 384: for (i = 0; i < nhandlers; i++) {
! 385: FD_SET(ihandlers[i].fd, &readers);
! 386: if (ihandlers[i].fd >= nfds)
! 387: nfds = ihandlers[i].fd + 1;
! 388: }
! 389:
! 390: IF_DEBUG(DEBUG_IF)
! 391: dump_vifs(stderr);
! 392: IF_DEBUG(DEBUG_PIM_MRT)
! 393: dump_pim_mrt(stderr);
! 394:
! 395: /* schedule first timer interrupt */
! 396: timer_setTimer(TIMER_INTERVAL, timer, NULL);
! 397:
! 398: if (debug == 0) {
! 399: /* Detach from the terminal */
! 400: #ifdef TIOCNOTTY
! 401: int t;
! 402: #endif /* TIOCNOTTY */
! 403:
! 404: haveterminal = 0;
! 405: if (fork())
! 406: exit(0);
! 407: (void)close(0);
! 408: (void)close(1);
! 409: (void)close(2);
! 410: (void)open("/", 0);
! 411: (void)dup2(0, 1);
! 412: (void)dup2(0, 2);
! 413: #if defined(SYSV) || defined(linux)
! 414: (void)setpgrp();
! 415: #else
! 416: #ifdef TIOCNOTTY
! 417: t = open("/dev/tty", 2);
! 418: if (t >= 0) {
! 419: (void)ioctl(t, TIOCNOTTY, (char *)0);
! 420: (void)close(t);
! 421: }
! 422: #else
! 423: if (setsid() < 0)
! 424: perror("setsid");
! 425: #endif /* TIOCNOTTY */
! 426: #endif /* SYSV */
! 427: } /* End of child process code */
! 428:
! 429: fp = fopen(pidfilename, "w");
! 430: if (fp != NULL) {
! 431: fprintf(fp, "%d\n", (int)getpid());
! 432: (void) fclose(fp);
! 433: }
! 434:
! 435: /*
! 436: * Main receive loop.
! 437: */
! 438: dummy = 0;
! 439: dummysigalrm = SIGALRM;
! 440: difftime.tv_usec = 0;
! 441: gettimeofday(&curtime, NULL);
! 442: lasttime = curtime;
! 443: for(;;) {
! 444: bcopy((char *)&readers, (char *)&rfds, sizeof(rfds));
! 445: secs = timer_nextTimer();
! 446: if (secs == -1)
! 447: timeout = NULL;
! 448: else {
! 449: timeout = &tv;
! 450: timeout->tv_sec = secs;
! 451: timeout->tv_usec = 0;
! 452: }
! 453:
! 454: if (sighandled) {
! 455: if (sighandled & GOT_SIGINT) {
! 456: sighandled &= ~GOT_SIGINT;
! 457: break;
! 458: }
! 459: if (sighandled & GOT_SIGHUP) {
! 460: sighandled &= ~GOT_SIGHUP;
! 461: restart(SIGHUP);
! 462: }
! 463: if (sighandled & GOT_SIGUSR1) {
! 464: sighandled &= ~GOT_SIGUSR1;
! 465: fdump(SIGUSR1);
! 466: }
! 467: if (sighandled & GOT_SIGUSR2) {
! 468: sighandled &= ~GOT_SIGUSR2;
! 469: cdump(SIGUSR2);
! 470: }
! 471: if (sighandled & GOT_SIGALRM) {
! 472: sighandled &= ~GOT_SIGALRM;
! 473: timer(&dummysigalrm);
! 474: }
! 475: }
! 476: if ((n = select(nfds, &rfds, NULL, NULL, timeout)) < 0) {
! 477: if (errno != EINTR) /* SIGALRM is expected */
! 478: log(LOG_WARNING, errno, "select failed");
! 479: continue;
! 480: }
! 481:
! 482: /*
! 483: * Handle timeout queue.
! 484: *
! 485: * If select + packet processing took more than 1 second,
! 486: * or if there is a timeout pending, age the timeout queue.
! 487: *
! 488: * If not, collect usec in difftime to make sure that the
! 489: * time doesn't drift too badly.
! 490: *
! 491: * If the timeout handlers took more than 1 second,
! 492: * age the timeout queue again. XXX This introduces the
! 493: * potential for infinite loops!
! 494: */
! 495: do {
! 496: /*
! 497: * If the select timed out, then there's no other
! 498: * activity to account for and we don't need to
! 499: * call gettimeofday.
! 500: */
! 501: if (n == 0) {
! 502: curtime.tv_sec = lasttime.tv_sec + secs;
! 503: curtime.tv_usec = lasttime.tv_usec;
! 504: n = -1; /* don't do this next time through the loop */
! 505: } else
! 506: gettimeofday(&curtime, NULL);
! 507: difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec;
! 508: difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec;
! 509: #ifdef TIMERDEBUG
! 510: IF_DEBUG(DEBUG_TIMEOUT)
! 511: log(LOG_DEBUG, 0, "TIMEOUT: secs %d, diff secs %d, diff usecs %d", secs, difftime.tv_sec, difftime.tv_usec );
! 512: #endif
! 513: while (difftime.tv_usec > 1000000) {
! 514: difftime.tv_sec++;
! 515: difftime.tv_usec -= 1000000;
! 516: }
! 517: if (difftime.tv_usec < 0) {
! 518: difftime.tv_sec--;
! 519: difftime.tv_usec += 1000000;
! 520: }
! 521: lasttime = curtime;
! 522: if (secs == 0 || difftime.tv_sec > 0) {
! 523: #ifdef TIMERDEBUG
! 524: IF_DEBUG(DEBUG_TIMEOUT)
! 525: log(LOG_DEBUG, 0, "\taging callouts: secs %d, diff secs %d, diff usecs %d", secs, difftime.tv_sec, difftime.tv_usec );
! 526: #endif
! 527: age_callout_queue(difftime.tv_sec);
! 528: }
! 529: secs = -1;
! 530: } while (difftime.tv_sec > 0);
! 531:
! 532: /* Handle sockets */
! 533: if (n > 0) {
! 534: /* TODO: shall check first igmp_socket for better performance? */
! 535: for (i = 0; i < nhandlers; i++) {
! 536: if (FD_ISSET(ihandlers[i].fd, &rfds)) {
! 537: (*ihandlers[i].func)(ihandlers[i].fd, &rfds);
! 538: }
! 539: }
! 540: }
! 541:
! 542: } /* Main loop */
! 543:
! 544: log(LOG_NOTICE, 0, "%s exiting", versionstring);
! 545: cleanup();
! 546: exit(0);
! 547: }
! 548:
! 549: /*
! 550: * The 'virtual_time' variable is initialized to a value that will cause the
! 551: * first invocation of timer() to send a probe or route report to all vifs
! 552: * and send group membership queries to all subnets for which this router is
! 553: * querier. This first invocation occurs approximately TIMER_INTERVAL seconds
! 554: * after the router starts up. Note that probes for neighbors and queries
! 555: * for group memberships are also sent at start-up time, as part of initial-
! 556: * ization. This repetition after a short interval is desirable for quickly
! 557: * building up topology and membership information in the presence of possible
! 558: * packet loss.
! 559: *
! 560: * 'virtual_time' advances at a rate that is only a crude approximation of
! 561: * real time, because it does not take into account any time spent processing,
! 562: * and because the timer intervals are sometimes shrunk by a random amount to
! 563: * avoid unwanted synchronization with other routers.
! 564: */
! 565:
! 566: u_long virtual_time = 0;
! 567:
! 568: /*
! 569: * Timer routine. Performs all perodic functions:
! 570: * aging interfaces, quering neighbors and members, etc... The granularity
! 571: * is equal to TIMER_INTERVAL.
! 572: */
! 573: static void
! 574: timer(i)
! 575: void *i;
! 576: {
! 577: age_vifs(); /* Timeout neighbors and groups */
! 578: age_routes(); /* Timeout routing entries */
! 579:
! 580: virtual_time += TIMER_INTERVAL;
! 581: timer_setTimer(TIMER_INTERVAL, timer, NULL);
! 582: }
! 583:
! 584: /*
! 585: * Performs all necessary functions to quit gracefully
! 586: */
! 587: /* TODO: implement all necessary stuff */
! 588: static void
! 589: cleanup()
! 590: {
! 591:
! 592: #ifdef RSRR
! 593: rsrr_clean();
! 594: #endif /* RSRR */
! 595:
! 596: /* TODO: XXX (not in the spec)
! 597: */
! 598: }
! 599:
! 600:
! 601: /*
! 602: * Signal handler. Take note of the fact that the signal arrived
! 603: * so that the main loop can take care of it.
! 604: */
! 605: static void
! 606: handler(sig)
! 607: int sig;
! 608: {
! 609: switch (sig) {
! 610: case SIGALRM:
! 611: sighandled |= GOT_SIGALRM;
! 612: case SIGINT:
! 613: case SIGTERM:
! 614: sighandled |= GOT_SIGINT;
! 615: break;
! 616:
! 617: case SIGHUP:
! 618: sighandled |= GOT_SIGHUP;
! 619: break;
! 620:
! 621: case SIGUSR1:
! 622: sighandled |= GOT_SIGUSR1;
! 623: break;
! 624:
! 625: case SIGUSR2:
! 626: sighandled |= GOT_SIGUSR2;
! 627: break;
! 628: }
! 629: }
! 630:
! 631:
! 632: /* TODO: not verified */
! 633: /* PIMDM TODO */
! 634: /*
! 635: * Restart the daemon
! 636: */
! 637: static void
! 638: restart(i)
! 639: int i;
! 640: {
! 641: #ifdef SNMP
! 642: int s;
! 643: #endif /* SNMP */
! 644:
! 645: log(LOG_NOTICE, 0, "% restart", versionstring);
! 646:
! 647: /*
! 648: * reset all the entries
! 649: */
! 650: /* TODO: delete?
! 651: free_all_routes();
! 652: */
! 653: free_all_callouts();
! 654: stop_all_vifs();
! 655: k_stop_pim(igmp_socket);
! 656: close(igmp_socket);
! 657: close(pim_socket);
! 658: close(udp_socket);
! 659:
! 660: /*
! 661: * start processing again
! 662: */
! 663:
! 664: init_igmp();
! 665: init_pim();
! 666: #ifdef HAVE_ROUTING_SOCKETS
! 667: init_routesock();
! 668: #endif /* HAVE_ROUTING_SOCKETS */
! 669: init_pim_mrt();
! 670: #ifdef SNMP
! 671: if ( s = snmp_init())
! 672: exit(s);
! 673: #endif /* SNMP */
! 674: init_vifs();
! 675:
! 676: #ifdef RSRR
! 677: rsrr_init();
! 678: #endif /* RSRR */
! 679:
! 680: /* schedule timer interrupts */
! 681: timer_setTimer(TIMER_INTERVAL, timer, NULL);
! 682: }
! 683:
! 684:
! 685: static void
! 686: resetlogging(arg)
! 687: void *arg;
! 688: {
! 689: int nxttime = 60;
! 690: void *narg = NULL;
! 691:
! 692: if (arg == NULL && log_nmsgs > LOG_MAX_MSGS) {
! 693: nxttime = LOG_SHUT_UP;
! 694: narg = (void *)&log_nmsgs; /* just need some valid void * */
! 695: syslog(LOG_WARNING, "logging too fast, shutting up for %d minutes",
! 696: LOG_SHUT_UP / 60);
! 697: } else {
! 698: log_nmsgs = 0;
! 699: }
! 700:
! 701: timer_setTimer(nxttime, resetlogging, narg);
! 702: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>