blob: 5fb04448da81b4041b03d87237c7b32e81e04d52 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * RIPngd main routine.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "version.h"
26#include "getopt.h"
27#include "vector.h"
28#include "vty.h"
29#include "command.h"
hassoa94434b2003-05-25 17:10:12 +000030#include "memory.h"
paul718e3742002-12-13 20:15:29 +000031#include "thread.h"
32#include "log.h"
33#include "prefix.h"
34#include "if.h"
pauledd7c242003-06-04 13:59:38 +000035#include "privs.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ripngd/ripngd.h"
38
39/* Configuration filename and directory. */
40char config_current[] = RIPNG_DEFAULT_CONFIG;
41char config_default[] = SYSCONFDIR RIPNG_DEFAULT_CONFIG;
hassoa94434b2003-05-25 17:10:12 +000042char *config_file = NULL;
paul718e3742002-12-13 20:15:29 +000043
44/* RIPngd options. */
45struct option longopts[] =
46{
47 { "daemon", no_argument, NULL, 'd'},
48 { "config_file", required_argument, NULL, 'f'},
49 { "pid_file", required_argument, NULL, 'i'},
50 { "log_mode", no_argument, NULL, 'l'},
51 { "help", no_argument, NULL, 'h'},
52 { "vty_addr", required_argument, NULL, 'A'},
53 { "vty_port", required_argument, NULL, 'P'},
54 { "retain", no_argument, NULL, 'r'},
pauledd7c242003-06-04 13:59:38 +000055 { "user", required_argument, NULL, 'u'},
paul718e3742002-12-13 20:15:29 +000056 { "version", no_argument, NULL, 'v'},
57 { 0 }
58};
59
pauledd7c242003-06-04 13:59:38 +000060/* ripngd privileges */
61zebra_capabilities_t _caps_p [] =
62{
63 ZCAP_RAW,
64 ZCAP_BIND
65};
66
67struct zebra_privs_t ripngd_privs =
68{
69#if defined(ZEBRA_USER)
70 .user = ZEBRA_USER,
71#endif
72#if defined ZEBRA_GROUP
73 .group = ZEBRA_GROUP,
74#endif
75 .caps_p = _caps_p,
76 .cap_num_p = 2,
77 .cap_num_i = 0
78};
79
80
paul718e3742002-12-13 20:15:29 +000081/* RIPngd program name */
82
83/* Route retain mode flag. */
84int retain_mode = 0;
85
hassoa94434b2003-05-25 17:10:12 +000086/* RIPng VTY bind address. */
87char *vty_addr = NULL;
88
89/* RIPng VTY connection port. */
90int vty_port = RIPNG_VTY_PORT;
91
paul718e3742002-12-13 20:15:29 +000092/* Master of threads. */
93struct thread_master *master;
94
95/* Process ID saved for use by init system */
96char *pid_file = PATH_RIPNGD_PID;
97
98/* Help information display. */
99static void
100usage (char *progname, int status)
101{
102 if (status != 0)
103 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
104 else
105 {
106 printf ("Usage : %s [OPTION...]\n\
107Daemon which manages RIPng.\n\n\
108-d, --daemon Runs in daemon mode\n\
109-f, --config_file Set configuration file name\n\
110-i, --pid_file Set process identifier file name\n\
111-l. --log_mode Set verbose log mode flag\n\
112-A, --vty_addr Set vty's bind address\n\
113-P, --vty_port Set vty's port number\n\
114-r, --retain When program terminates, retain added route by ripngd.\n\
pauledd7c242003-06-04 13:59:38 +0000115-u, --user User and group to run as\n\
paul718e3742002-12-13 20:15:29 +0000116-v, --version Print program version\n\
117-h, --help Display this help and exit\n\
118\n\
119Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
120 }
121 exit (status);
122}
123
124/* SIGHUP handler. */
125void
126sighup (int sig)
127{
hassoa94434b2003-05-25 17:10:12 +0000128 zlog_info ("SIGHUP received");
129 ripng_clean ();
130 ripng_reset ();
131 zlog_info ("Terminating on signal");
132
133 /* Reload config file. */
134 vty_read_config (config_file, config_current, config_default);
135 /* Create VTY's socket */
136 vty_serv_sock (vty_addr, vty_port, RIPNG_VTYSH_PATH);
137
138 /* Try to return to normal operation. */
paul718e3742002-12-13 20:15:29 +0000139}
140
141/* SIGINT handler. */
142void
143sigint (int sig)
144{
hassoa94434b2003-05-25 17:10:12 +0000145 zlog_info ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000146
147 if (! retain_mode)
hassoa94434b2003-05-25 17:10:12 +0000148 ripng_clean ();
paul718e3742002-12-13 20:15:29 +0000149
150 exit (0);
151}
152
153/* SIGUSR1 handler. */
154void
155sigusr1 (int sig)
156{
157 zlog_rotate (NULL);
158}
159
160/* Signale wrapper. */
161RETSIGTYPE *
162signal_set (int signo, void (*func)(int))
163{
164 int ret;
165 struct sigaction sig;
166 struct sigaction osig;
167
168 sig.sa_handler = func;
169 sigemptyset (&sig.sa_mask);
170 sig.sa_flags = 0;
171#ifdef SA_RESTART
172 sig.sa_flags |= SA_RESTART;
173#endif /* SA_RESTART */
174
175 ret = sigaction (signo, &sig, &osig);
176
177 if (ret < 0)
178 return (SIG_ERR);
179 else
180 return (osig.sa_handler);
181}
182
183/* Initialization of signal handles. */
184void
185signal_init ()
186{
187 signal_set (SIGHUP, sighup);
188 signal_set (SIGINT, sigint);
189 signal_set (SIGTERM, sigint);
190 signal_set (SIGPIPE, SIG_IGN);
191 signal_set (SIGUSR1, sigusr1);
192}
193
194/* RIPngd main routine. */
195int
196main (int argc, char **argv)
197{
198 char *p;
paul4fc4e7a2003-01-22 19:47:09 +0000199 int vty_port = RIPNG_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000200 int daemon_mode = 0;
paul718e3742002-12-13 20:15:29 +0000201 char *progname;
202 struct thread thread;
203
204 /* Set umask before anything for security */
205 umask (0027);
206
207 /* get program name */
208 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
209
210 zlog_default = openzlog(progname, ZLOG_NOLOG, ZLOG_RIPNG,
211 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
212
213 while (1)
214 {
215 int opt;
216
pauledd7c242003-06-04 13:59:38 +0000217 opt = getopt_long (argc, argv, "dlf:hA:P:u:v", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000218
219 if (opt == EOF)
220 break;
221
222 switch (opt)
223 {
224 case 0:
225 break;
226 case 'd':
227 daemon_mode = 1;
228 break;
229 case 'l':
230 /* log_mode = 1; */
231 break;
232 case 'f':
233 config_file = optarg;
234 break;
235 case 'A':
236 vty_addr = optarg;
237 break;
238 case 'i':
239 pid_file = optarg;
paul4fc4e7a2003-01-22 19:47:09 +0000240 break;
paul718e3742002-12-13 20:15:29 +0000241 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000242 /* Deal with atoi() returning 0 on failure, and ripngd not
243 listening on ripngd port... */
244 if (strcmp(optarg, "0") == 0)
245 {
246 vty_port = 0;
247 break;
248 }
249 vty_port = atoi (optarg);
250 vty_port = (vty_port ? vty_port : RIPNG_VTY_PORT);
251 break;
paul718e3742002-12-13 20:15:29 +0000252 case 'r':
253 retain_mode = 1;
254 break;
pauledd7c242003-06-04 13:59:38 +0000255 case 'u':
256 ripngd_privs.group = ripngd_privs.user = optarg;
257 break;
paul718e3742002-12-13 20:15:29 +0000258 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 master = thread_master_create ();
272
273 /* Library inits. */
pauledd7c242003-06-04 13:59:38 +0000274 zprivs_init (&ripngd_privs);
paul718e3742002-12-13 20:15:29 +0000275 signal_init ();
276 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000277 vty_init (master);
hassoa94434b2003-05-25 17:10:12 +0000278 memory_init ();
paul718e3742002-12-13 20:15:29 +0000279
280 /* RIPngd inits. */
281 ripng_init ();
282 zebra_init ();
hassoa94434b2003-05-25 17:10:12 +0000283 ripng_peer_init ();
284
285 /* Sort all installed commands. */
paul718e3742002-12-13 20:15:29 +0000286 sort_node ();
287
288 /* Get configuration file. */
289 vty_read_config (config_file, config_current, config_default);
290
291 /* Change to the daemon program. */
292 if (daemon_mode)
293 daemon (0, 0);
294
295 /* Create VTY socket */
paul4fc4e7a2003-01-22 19:47:09 +0000296 vty_serv_sock (vty_addr, vty_port, RIPNG_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000297
298 /* Process id file create. */
299 pid_output (pid_file);
300
301 /* Fetch next active thread. */
302 while (thread_fetch (master, &thread))
303 thread_call (&thread);
304
305 /* Not reached. */
306 exit (0);
307}