1: /*
2: * IS-IS Rout(e)ing protocol - isis_main.c
3: *
4: * Copyright (C) 2001,2002 Sampo Saaristo
5: * Tampere University of Technology
6: * Institute of Communications Engineering
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public Licenseas published by the Free
10: * Software Foundation; either version 2 of the License, or (at your option)
11: * any later version.
12: *
13: * This program is distributed in the hope that it will be useful,but WITHOUT
14: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16: * more details.
17:
18: * You should have received a copy of the GNU General Public License along
19: * with this program; if not, write to the Free Software Foundation, Inc.,
20: * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "getopt.h"
26: #include "thread.h"
27: #include "log.h"
28: #include <lib/version.h>
29: #include "command.h"
30: #include "vty.h"
31: #include "memory.h"
32: #include "stream.h"
33: #include "if.h"
34: #include "privs.h"
35: #include "sigevent.h"
36: #include "filter.h"
37:
38: #include "isisd/dict.h"
39: #include "include-netbsd/iso.h"
40: #include "isisd/isis_constants.h"
41: #include "isisd/isis_common.h"
42: #include "isisd/isis_flags.h"
43: #include "isisd/isis_circuit.h"
44: #include "isisd/isisd.h"
45: #include "isisd/isis_dynhn.h"
46:
47: /* Default configuration file name */
48: #define ISISD_DEFAULT_CONFIG "isisd.conf"
49: /* Default vty port */
50: #define ISISD_VTY_PORT 2608
51:
52: /* isisd privileges */
53: zebra_capabilities_t _caps_p[] = {
54: ZCAP_NET_RAW,
55: ZCAP_BIND
56: };
57:
58: struct zebra_privs_t isisd_privs = {
59: #if defined(QUAGGA_USER)
60: .user = QUAGGA_USER,
61: #endif
62: #if defined QUAGGA_GROUP
63: .group = QUAGGA_GROUP,
64: #endif
65: #ifdef VTY_GROUP
66: .vty_group = VTY_GROUP,
67: #endif
68: .caps_p = _caps_p,
69: .cap_num_p = 2,
70: .cap_num_i = 0
71: };
72:
73: /* isisd options */
74: struct option longopts[] = {
75: {"daemon", no_argument, NULL, 'd'},
76: {"config_file", required_argument, NULL, 'f'},
77: {"pid_file", required_argument, NULL, 'i'},
78: {"vty_addr", required_argument, NULL, 'A'},
79: {"vty_port", required_argument, NULL, 'P'},
80: {"user", required_argument, NULL, 'u'},
81: {"group", required_argument, NULL, 'g'},
82: {"version", no_argument, NULL, 'v'},
83: {"dryrun", no_argument, NULL, 'C'},
84: {"help", no_argument, NULL, 'h'},
85: {0}
86: };
87:
88: /* Configuration file and directory. */
89: char config_default[] = SYSCONFDIR ISISD_DEFAULT_CONFIG;
90: char *config_file = NULL;
91:
92: /* isisd program name. */
93: char *progname;
94:
95: int daemon_mode = 0;
96:
97: /* Master of threads. */
98: struct thread_master *master;
99:
100: /* Process ID saved for use by init system */
101: const char *pid_file = PATH_ISISD_PID;
102:
103: /* for reload */
104: char _cwd[MAXPATHLEN];
105: char _progpath[MAXPATHLEN];
106: int _argc;
107: char **_argv;
108: char **_envp;
109:
110: /*
111: * Prototypes.
112: */
113: void reload(void);
114: void sighup(void);
115: void sigint(void);
116: void sigterm(void);
117: void sigusr1(void);
118:
119:
120: /* Help information display. */
121: static void
122: usage (int status)
123: {
124: if (status != 0)
125: fprintf (stderr, "Try `%s --help' for more information.\n", progname);
126: else
127: {
128: printf ("Usage : %s [OPTION...]\n\n\
129: Daemon which manages IS-IS routing\n\n\
130: -d, --daemon Runs in daemon mode\n\
131: -f, --config_file Set configuration file name\n\
132: -i, --pid_file Set process identifier file name\n\
133: -A, --vty_addr Set vty's bind address\n\
134: -P, --vty_port Set vty's port number\n\
135: -u, --user User to run as\n\
136: -g, --group Group to run as\n\
137: -v, --version Print program version\n\
138: -C, --dryrun Check configuration for validity and exit\n\
139: -h, --help Display this help and exit\n\
140: \n\
141: Report bugs to http://bugzilla.quagga.net\n", progname);
142: }
143:
144: exit (status);
145: }
146:
147:
148: void
149: reload ()
150: {
151: zlog_debug ("Reload");
152: /* FIXME: Clean up func call here */
153: vty_reset ();
154: execve (_progpath, _argv, _envp);
155: }
156:
157: static void
158: terminate (int i)
159: {
160: exit (i);
161: }
162:
163: /*
164: * Signal handlers
165: */
166:
167: void
168: sighup (void)
169: {
170: zlog_debug ("SIGHUP received");
171: reload ();
172:
173: return;
174: }
175:
176: void
177: sigint (void)
178: {
179: zlog_notice ("Terminating on signal SIGINT");
180: terminate (0);
181: }
182:
183: void
184: sigterm (void)
185: {
186: zlog_notice ("Terminating on signal SIGTERM");
187: terminate (0);
188: }
189:
190: void
191: sigusr1 (void)
192: {
193: zlog_debug ("SIGUSR1 received");
194: zlog_rotate (NULL);
195: }
196:
197: struct quagga_signal_t isisd_signals[] =
198: {
199: {
200: .signal = SIGHUP,
201: .handler = &sighup,
202: },
203: {
204: .signal = SIGUSR1,
205: .handler = &sigusr1,
206: },
207: {
208: .signal = SIGINT,
209: .handler = &sigint,
210: },
211: {
212: .signal = SIGTERM,
213: .handler = &sigterm,
214: },
215: };
216:
217: /*
218: * Main routine of isisd. Parse arguments and handle IS-IS state machine.
219: */
220: int
221: main (int argc, char **argv, char **envp)
222: {
223: char *p;
224: int opt, vty_port = ISISD_VTY_PORT;
225: struct thread thread;
226: char *config_file = NULL;
227: char *vty_addr = NULL;
228: int dryrun = 0;
229:
230: /* Get the programname without the preceding path. */
231: progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
232:
233: zlog_default = openzlog (progname, ZLOG_ISIS,
234: LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
235:
236: /* for reload */
237: _argc = argc;
238: _argv = argv;
239: _envp = envp;
240: getcwd (_cwd, sizeof (_cwd));
241: if (*argv[0] == '.')
242: snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
243: else
244: snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
245:
246: /* Command line argument treatment. */
247: while (1)
248: {
249: opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:vC", longopts, 0);
250:
251: if (opt == EOF)
252: break;
253:
254: switch (opt)
255: {
256: case 0:
257: break;
258: case 'd':
259: daemon_mode = 1;
260: break;
261: case 'f':
262: config_file = optarg;
263: break;
264: case 'i':
265: pid_file = optarg;
266: break;
267: case 'A':
268: vty_addr = optarg;
269: break;
270: case 'P':
271: /* Deal with atoi() returning 0 on failure, and isisd not
272: listening on isisd port... */
273: if (strcmp (optarg, "0") == 0)
274: {
275: vty_port = 0;
276: break;
277: }
278: vty_port = atoi (optarg);
279: vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
280: break;
281: case 'u':
282: isisd_privs.user = optarg;
283: break;
284: case 'g':
285: isisd_privs.group = optarg;
286: break;
287: case 'v':
288: printf ("ISISd version %s\n", ISISD_VERSION);
289: printf ("Copyright (c) 2001-2002 Sampo Saaristo,"
290: " Ofer Wald and Hannes Gredler\n");
291: print_version ("Zebra");
292: exit (0);
293: break;
294: case 'C':
295: dryrun = 1;
296: break;
297: case 'h':
298: usage (0);
299: break;
300: default:
301: usage (1);
302: break;
303: }
304: }
305:
306: /* thread master */
307: master = thread_master_create ();
308:
309: /* random seed from time */
310: srand (time (NULL));
311:
312: /*
313: * initializations
314: */
315: zprivs_init (&isisd_privs);
316: signal_init (master, Q_SIGC (isisd_signals), isisd_signals);
317: cmd_init (1);
318: vty_init (master);
319: memory_init ();
320: access_list_init();
321: isis_init ();
322: dyn_cache_init ();
323: sort_node ();
324:
325: /* parse config file */
326: /* this is needed three times! because we have interfaces before the areas */
327: vty_read_config (config_file, config_default);
328: vty_read_config (config_file, config_default);
329: vty_read_config (config_file, config_default);
330:
331: /* Start execution only if not in dry-run mode */
332: if (dryrun)
333: return(0);
334:
335: /* demonize */
336: if (daemon_mode && daemon (0, 0) < 0)
337: {
338: zlog_err("ISISd daemon failed: %s", strerror(errno));
339: exit (1);
340: }
341:
342: /* Process ID file creation. */
343: pid_output (pid_file);
344:
345: /* Make isis vty socket. */
346: vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
347:
348: /* Print banner. */
349: zlog_notice ("Quagga-ISISd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
350:
351: /* Start finite state machine. */
352: while (thread_fetch (master, &thread))
353: thread_call (&thread);
354:
355: /* Not reached. */
356: exit (0);
357: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>