1/* RIPd main routine. 2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org> 3 * 4 * This file is part of GNU Zebra. 5 * 6 * GNU Zebra is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2, or (at your option) any 9 * later version. 10 * 11 * GNU Zebra is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with GNU Zebra; see the file COPYING. If not, write to the Free 18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 * 02111-1307, USA. 20 */ 21 22#include <zebra.h> 23 24#include "version.h" 25#include "getopt.h" 26#include "thread.h" 27#include "command.h" 28#include "memory.h" 29#include "prefix.h" 30#include "filter.h" 31#include "keychain.h" 32#include "log.h" 33 34#include "ripd/ripd.h" 35 36/* ripd options. */ 37static struct option longopts[] = 38{ 39 { "daemon", no_argument, NULL, 'd'}, 40 { "config_file", required_argument, NULL, 'f'}, 41 { "pid_file", required_argument, NULL, 'i'}, 42 { "help", no_argument, NULL, 'h'}, 43 { "vty_addr", required_argument, NULL, 'A'}, 44 { "vty_port", required_argument, NULL, 'P'}, 45 { "retain", no_argument, NULL, 'r'}, 46 { "version", no_argument, NULL, 'v'}, 47 { 0 } 48}; 49 50/* Configuration file and directory. */ 51char config_current[] = RIPD_DEFAULT_CONFIG; 52char config_default[] = SYSCONFDIR RIPD_DEFAULT_CONFIG; 53char *config_file = NULL; 54 55/* ripd program name */ 56 57/* Route retain mode flag. */ 58int retain_mode = 0; 59 60/* RIP VTY bind address. */ 61char *vty_addr = NULL; 62 63/* RIP VTY connection port. */ 64int vty_port = RIP_VTY_PORT; 65 66/* Master of threads. */ 67struct thread_master *master; 68 69/* Process ID saved for use by init system */ 70char *pid_file = PATH_RIPD_PID; 71 72/* Help information display. */ 73static void 74usage (char *progname, int status) 75{ 76 if (status != 0) 77 fprintf (stderr, "Try `%s --help' for more information.\n", progname); 78 else 79 { 80 printf ("Usage : %s [OPTION...]\n\ 81Daemon which manages RIP version 1 and 2.\n\n\ 82-d, --daemon Runs in daemon mode\n\ 83-f, --config_file Set configuration file name\n\ 84-i, --pid_file Set process identifier file name\n\ 85-A, --vty_addr Set vty's bind address\n\ 86-P, --vty_port Set vty's port number\n\ 87-r, --retain When program terminates, retain added route by ripd.\n\ 88-v, --version Print program version\n\ 89-h, --help Display this help and exit\n\ 90\n\ 91Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); 92 } 93 94 exit (status); 95} 96 97/* Signale wrapper. */ 98RETSIGTYPE * 99signal_set (int signo, void (*func)(int)) 100{ 101 int ret; 102 struct sigaction sig; 103 struct sigaction osig; 104 105 sig.sa_handler = func; 106 sigemptyset (&sig.sa_mask); 107 sig.sa_flags = 0; 108#ifdef SA_RESTART 109 sig.sa_flags |= SA_RESTART; 110#endif /* SA_RESTART */ 111 112 ret = sigaction (signo, &sig, &osig); 113 114 if (ret < 0) 115 return (SIG_ERR); 116 else 117 return (osig.sa_handler); 118} 119 120/* SIGHUP handler. */ 121void 122sighup (int sig) 123{ 124#ifdef FOX_RIP_DEBUG 125 zlog_info ("SIGHUP received"); 126#endif /* FOX_RIP_DEBUG */ 127 rip_clean (); 128 rip_reset (); 129#ifdef FOX_RIP_DEBUG 130 zlog_info ("ripd restarting!"); 131#endif /* FOX_RIP_DEBUG */ 132 /* Reload config file. */ 133 vty_read_config (config_file, config_current, config_default); 134 135#ifdef FOX_CMD_SUPPORT 136 /* Create VTY's socket */ 137 vty_serv_sock (vty_addr, vty_port, RIP_VTYSH_PATH); 138#endif /* FOX_CMD_SUPPORT */ 139 140 /* Try to return to normal operation. */ 141} 142 143/* SIGINT handler. */ 144void 145sigint (int sig) 146{ 147#ifdef FOX_RIP_DEBUG 148 zlog (NULL, LOG_INFO, "Terminating on signal"); 149#endif /* FOX_RIP_DEBUG */ 150 if (! retain_mode) 151 rip_clean (); 152 153 exit (0); 154} 155 156/* SIGUSR1 handler. */ 157void 158sigusr1 (int sig) 159{ 160#ifdef FOX_RIP_DEBUG 161 zlog_rotate (NULL); 162#endif /* FOX_RIP_DEBUG */ 163} 164 165/* Initialization of signal handles. */ 166void 167signal_init () 168{ 169 signal_set (SIGHUP, sighup); 170 signal_set (SIGINT, sigint); 171 signal_set (SIGTERM, sigint); 172 signal_set (SIGPIPE, SIG_IGN); 173 signal_set (SIGUSR1, sigusr1); 174} 175 176/* Main routine of ripd. */ 177int 178main (int argc, char **argv) 179{ 180 char *p; 181 int daemon_mode = 0; 182 char *progname; 183 struct thread thread; 184 185 /* Set umask before anything for security */ 186 umask (0027); 187 188 /* Get program name. */ 189 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); 190 191#ifdef FOX_RIP_DEBUG 192 /* First of all we need logging init. */ 193 zlog_default = openzlog (progname, ZLOG_NOLOG, ZLOG_RIP, 194 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); 195#endif /* FOX_RIP_DEBUG */ 196 197 /* Command line option parse. */ 198 while (1) 199 { 200 int opt; 201 202 opt = getopt_long (argc, argv, "df:hA:P:rv", longopts, 0); 203 204 if (opt == EOF) 205 break; 206 207 switch (opt) 208 { 209 case 0: 210 break; 211 case 'd': 212 daemon_mode = 1; 213 break; 214 case 'f': 215 config_file = optarg; 216 break; 217 case 'A': 218 vty_addr = optarg; 219 break; 220 case 'i': 221 pid_file = optarg; 222 break; 223 case 'P': 224 vty_port = atoi (optarg); 225 break; 226 case 'r': 227 retain_mode = 1; 228 break; 229 case 'v': 230#ifdef FOX_CMD_SUPPORT 231 print_version (progname); 232#endif /* FOX_CMD_SUPPORT */ 233 exit (0); 234 break; 235 case 'h': 236 usage (progname, 0); 237 break; 238 default: 239 usage (progname, 1); 240 break; 241 } 242 } 243 244 /* Prepare master thread. */ 245 master = thread_master_create (); 246 247 /* Library initialization. */ 248 signal_init (); 249 cmd_init (1); 250 vty_init (); 251#ifdef FOX_CMD_SUPPORT 252 memory_init (); 253#endif /* FOX_CMD_SUPPORT */ 254#ifdef FOX_AUTH_SUPPORT 255 keychain_init (); 256#endif /* FOX_AUTH_SUPPORT */ 257 258 /* RIP related initialization. */ 259 rip_init (); 260 rip_if_init (); 261 rip_zclient_init (); 262#ifdef FOX_RIP_DEBUG 263 rip_peer_init (); 264#endif /* FOX_RIP_DEBUG */ 265 266 /* Sort all installed commands. */ 267 sort_node (); 268 269 /* Get configuration file. */ 270 vty_read_config (config_file, config_current, config_default); 271 272 /* Change to the daemon program. */ 273 if (daemon_mode) 274 daemon (0, 0); 275 276 /* Pid file create. */ 277 pid_output (pid_file); 278#ifdef FOX_CMD_SUPPORT 279 /* Create VTY's socket */ 280 vty_serv_sock (vty_addr, vty_port, RIP_VTYSH_PATH); 281#endif /* BRCM_CMD_SUPPORT */ 282 283 /* Execute each thread. */ 284 while (thread_fetch (master, &thread)) 285 thread_call (&thread); 286 287 /* Not reached. */ 288 exit (0); 289} 290