/* * BIRD Internet Routing Daemon -- Unix Entry Point * * (c) 1998--1999 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ #include #include #include #include #include #include #include "nest/bird.h" #include "lib/lists.h" #include "lib/resource.h" #include "lib/socket.h" #include "lib/event.h" #include "nest/route.h" #include "nest/protocol.h" #include "nest/iface.h" #include "conf/conf.h" #include "filter/filter.h" #include "unix.h" #include "krt.h" int shutting_down; /* * Debugging */ void async_dump(void) { debug("INTERNAL STATE DUMP\n\n"); sk_dump_all(); tm_dump_all(); if_dump_all(); neigh_dump_all(); rta_dump_all(); rt_dump_all(); protos_dump_all(); debug("\n"); } /* * Reading the Configuration */ static int conf_fd; static char *config_name = PATH_CONFIG; static int cf_read(byte *dest, unsigned int len) { int l = read(conf_fd, dest, len); if (l < 0) cf_error("Read error"); return l; } static void read_config(void) { struct config *conf = config_alloc(config_name); conf_fd = open(config_name, O_RDONLY); if (conf_fd < 0) die("Unable to open configuration file %s: %m", config_name); cf_read_hook = cf_read; if (!config_parse(conf)) die("%s, line %d: %s", config_name, conf->err_lino, conf->err_msg); config_commit(conf); } void async_config(void) { debug("Asynchronous reconfigurations are not supported in demo version\n"); } /* * Shutdown */ void async_shutdown(void) { debug("Shutting down...\n"); shutting_down = 1; protos_shutdown(); } void protos_shutdown_notify(void) { die("System shutdown completed"); } /* * Signals */ static void handle_sighup(int sig) { debug("Caught SIGHUP...\n"); async_config_flag = 1; } static void handle_sigusr(int sig) { debug("Caught SIGUSR...\n"); async_dump_flag = 1; } static void handle_sigterm(int sig) { debug("Caught SIGTERM...\n"); async_shutdown_flag = 1; } static void signal_init(void) { struct sigaction sa; bzero(&sa, sizeof(sa)); sa.sa_handler = handle_sigusr; sa.sa_flags = SA_RESTART; sigaction(SIGUSR1, &sa, NULL); sa.sa_handler = handle_sighup; sa.sa_flags = SA_RESTART; sigaction(SIGHUP, &sa, NULL); sa.sa_handler = handle_sigterm; sa.sa_flags = SA_RESTART; sigaction(SIGTERM, &sa, NULL); signal(SIGPIPE, SIG_IGN); } /* * Parsing of command-line arguments */ static char *opt_list = "c:d:"; static void usage(void) { fprintf(stderr, "Usage: bird [-c ] [-d ]\n"); exit(1); } static void parse_args(int argc, char **argv) { int c; while ((c = getopt(argc, argv, opt_list)) >= 0) switch (c) { case 'c': config_name = optarg; break; case 'd': log_init_debug(optarg); break; default: usage(); } if (optind < argc) usage(); } /* * Hic Est main() */ int main(int argc, char **argv) { #ifdef HAVE_LIBDMALLOC if (!getenv("DMALLOC_OPTIONS")) dmalloc_debug(0x2f03d00); #endif log_init_debug(NULL); parse_args(argc, argv); log(L_INFO "Launching BIRD 0.0.0..."); debug("Initializing.\n"); resource_init(); io_init(); rt_init(); if_init(); protos_build(); add_tail(&protocol_list, &proto_unix_kernel.n); add_tail(&protocol_list, &proto_unix_iface.n); read_config(); signal_init(); protos_start(); ev_run_list(&global_event_list); async_dump(); debug("Entering I/O loop.\n"); io_loop(); bug("I/O loop died"); }