1/* 2 * Copyright (C) 1999 Yasuhiro Ohara 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 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 02111-1307, USA. 20 */ 21 22#include <zebra.h> 23#include "getopt.h" 24#include "thread.h" 25#include "log.h" 26#include "version.h" 27#include "command.h" 28#include "vty.h" 29#include "memory.h" 30 31#include "ospf6d.h" 32#include "ospf6_network.h" 33 34void ospf6_init (); 35void ospf6_terminate (); 36void nexthop_init (); 37int ospf6_receive (struct thread *); 38 39extern int ospf6_sock; 40 41/* Default configuration file name for ospf6d. */ 42#define OSPF6_DEFAULT_CONFIG "ospf6d.conf" 43/* Default port values. */ 44#define OSPF6_VTY_PORT 2606 45 46/* ospf6d options, we use GNU getopt library. */ 47struct option longopts[] = 48{ 49 { "daemon", no_argument, NULL, 'd'}, 50 { "config_file", required_argument, NULL, 'f'}, 51 { "pid_file", required_argument, NULL, 'i'}, 52 { "vty_addr", required_argument, NULL, 'A'}, 53 { "vty_port", required_argument, NULL, 'P'}, 54 { "version", no_argument, NULL, 'v'}, 55 { "help", no_argument, NULL, 'h'}, 56 { 0 } 57}; 58 59/* Configuration file and directory. */ 60char config_current[] = OSPF6_DEFAULT_CONFIG; 61char config_default[] = SYSCONFDIR OSPF6_DEFAULT_CONFIG; 62 63/* ospf6d program name. */ 64 65/* is daemon? */ 66int daemon_mode = 0; 67 68/* Master of threads. */ 69struct thread_master *master; 70 71/* Process ID saved for use by init system */ 72char *pid_file = PATH_OSPF6D_PID; 73 74/* for reload */ 75char _cwd[64]; 76char _progpath[64]; 77int _argc; 78char **_argv; 79char **_envp; 80 81/* Help information display. */ 82static void 83usage (char *progname, int status) 84{ 85 if (status != 0) 86 fprintf (stderr, "Try `%s --help' for more information.\n", progname); 87 else 88 { 89 printf ("Usage : %s [OPTION...]\n\n\ 90Daemon which manages OSPF version 3.\n\n\ 91-d, --daemon Runs in daemon mode\n\ 92-f, --config_file Set configuration file name\n\ 93-i, --pid_file Set process identifier file name\n\ 94-A, --vty_addr Set vty's bind address\n\ 95-P, --vty_port Set vty's port number\n\ 96-v, --version Print program version\n\ 97-h, --help Display this help and exit\n\ 98\n\ 99Report bugs to yasu@sfc.wide.ad.jp\n", progname); 100 } 101 102 exit (status); 103} 104 105 106void 107_reload () 108{ 109 zlog_notice ("OSPF6d (Zebra-%s ospf6d-%s) reloaded", 110 ZEBRA_VERSION, OSPF6_DAEMON_VERSION); 111 ospf6_zebra_finish (); 112 vty_finish (); 113 execve (_progpath, _argv, _envp); 114} 115 116void 117terminate (int i) 118{ 119 ospf6_delete (ospf6); 120 unlink (PATH_OSPF6D_PID); 121 zlog_notice ("OSPF6d (Zebra-%s ospf6d-%s) terminated", 122 ZEBRA_VERSION, OSPF6_DAEMON_VERSION); 123 exit (i); 124} 125 126/* SIGHUP handler. */ 127void 128sighup (int sig) 129{ 130 zlog_info ("SIGHUP received"); 131 _reload (); 132} 133 134/* SIGINT handler. */ 135void 136sigint (int sig) 137{ 138 zlog_info ("SIGINT received"); 139 terminate (0); 140} 141 142/* SIGTERM handler. */ 143void 144sigterm (int sig) 145{ 146 zlog_info ("SIGTERM received"); 147 terminate (0); 148} 149 150/* SIGUSR1 handler. */ 151void 152sigusr1 (int sig) 153{ 154 zlog_info ("SIGUSR1 received"); 155 zlog_rotate (NULL); 156} 157 158/* Signale wrapper. */ 159RETSIGTYPE * 160signal_set (int signo, void (*func)(int)) 161{ 162 int ret; 163 struct sigaction sig; 164 struct sigaction osig; 165 166 sig.sa_handler = func; 167 sigemptyset (&sig.sa_mask); 168 sig.sa_flags = 0; 169#ifdef SA_RESTART 170 sig.sa_flags |= SA_RESTART; 171#endif /* SA_RESTART */ 172 173 ret = sigaction (signo, &sig, &osig); 174 175 if (ret < 0) 176 return (SIG_ERR); 177 else 178 return (osig.sa_handler); 179} 180 181/* Initialization of signal handles. */ 182void 183signal_init () 184{ 185 signal_set (SIGHUP, sighup); 186 signal_set (SIGINT, sigint); 187 signal_set (SIGTERM, sigterm); 188 signal_set (SIGPIPE, SIG_IGN); 189#ifdef SIGTSTP 190 signal_set (SIGTSTP, SIG_IGN); 191#endif 192#ifdef SIGTTIN 193 signal_set (SIGTTIN, SIG_IGN); 194#endif 195#ifdef SIGTTOU 196 signal_set (SIGTTOU, SIG_IGN); 197#endif 198 signal_set (SIGUSR1, sigusr1); 199} 200 201/* Main routine of ospf6d. Treatment of argument and start ospf finite 202 state machine is handled here. */ 203int 204main (int argc, char *argv[], char *envp[]) 205{ 206 char *p; 207 int opt; 208 char *vty_addr = NULL; 209 int vty_port = 0; 210 char *config_file = NULL; 211 char *progname; 212 struct thread thread; 213 int flag; 214 215 /* Set umask before anything for security */ 216 umask (0027); 217 218 /* Preserve name of myself. */ 219 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); 220 221 /* for reload */ 222 _argc = argc; 223 _argv = argv; 224 _envp = envp; 225 getcwd (_cwd, sizeof (_cwd)); 226 if (*argv[0] == '.') 227 snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]); 228 else 229 snprintf (_progpath, sizeof (_progpath), "%s", argv[0]); 230 231 /* Command line argument treatment. */ 232 while (1) 233 { 234 opt = getopt_long (argc, argv, "df:hp:A:P:v", longopts, 0); 235 236 if (opt == EOF) 237 break; 238 239 switch (opt) 240 { 241 case 0: 242 break; 243 case 'd': 244 daemon_mode = 1; 245 break; 246 case 'f': 247 config_file = optarg; 248 break; 249 case 'A': 250 vty_addr = optarg; 251 break; 252 case 'i': 253 pid_file = optarg; 254 break; 255 case 'P': 256 vty_port = atoi (optarg); 257 break; 258 case 'v': 259 print_version (progname); 260 exit (0); 261 break; 262 case 'h': 263 usage (progname, 0); 264 break; 265 default: 266 usage (progname, 1); 267 break; 268 } 269 } 270 271 /* thread master */ 272 master = thread_master_create (); 273 274 /* Initializations. */ 275 if (! daemon_mode) 276 flag = ZLOG_STDOUT; 277 else 278 flag = 0; 279 280 zlog_default = openzlog (progname, flag, ZLOG_OSPF6, 281 LOG_CONS|LOG_NDELAY|LOG_PERROR|LOG_PID, 282 LOG_DAEMON); 283 signal_init (); 284 cmd_init (1); 285 vty_init (); 286 ospf6_init (); 287 memory_init (); 288 sort_node (); 289 290 /* parse config file */ 291 vty_read_config (config_file, config_current, config_default); 292 293 if (daemon_mode) 294 daemon (0, 0); 295 296 /* pid file create */ 297#if 0 298 pid_output_lock (pid_file); 299#else 300 pid_output (pid_file); 301#endif 302 303 /* Make ospf protocol socket. */ 304 ospf6_serv_sock (); 305 thread_add_read (master, ospf6_receive, NULL, ospf6_sock); 306 307 /* Make ospf vty socket. */ 308 vty_serv_sock (vty_addr, 309 vty_port ? vty_port : OSPF6_VTY_PORT, OSPF6_VTYSH_PATH); 310 311 /* Print start message */ 312 zlog_notice ("OSPF6d (Zebra-%s ospf6d-%s) starts", 313 ZEBRA_VERSION, OSPF6_DAEMON_VERSION); 314 315 /* Start finite state machine, here we go! */ 316 while (thread_fetch (master, &thread)) 317 thread_call (&thread); 318 319 /* Log in case thread failed */ 320 zlog_warn ("Thread failed"); 321 terminate (0); 322 323 /* Not reached. */ 324 exit (0); 325} 326 327