games/quiz: add another president answer section and update data
[dragonfly.git] / usr.sbin / atm / atmarpd / atmarpd.c
blob9d030f791a255344d502381106282ae20f4200f8
1 /*
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/usr.sbin/atm/atmarpd/atmarpd.c,v 1.3.2.1 2000/12/11 01:03:29 obrien Exp $
27 * @(#) $DragonFly: src/usr.sbin/atm/atmarpd/atmarpd.c,v 1.5 2007/11/25 01:28:23 swildner Exp $
31 * Server Cache Synchronization Protocol (SCSP) Support
32 * ----------------------------------------------------
34 * SCSP-ATMARP server interface: main line code
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
41 #include <sys/stat.h>
42 #include <sys/ttycom.h>
43 #include <net/if.h>
44 #include <netinet/in.h>
45 #include <netatm/queue.h>
46 #include <netatm/atm.h>
47 #include <netatm/atm_if.h>
48 #include <netatm/atm_sap.h>
49 #include <netatm/atm_sys.h>
50 #include <netatm/atm_ioctl.h>
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <libatm.h>
55 #include <paths.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <syslog.h>
60 #include <unistd.h>
62 #include "../scspd/scsp_msg.h"
63 #include "../scspd/scsp_if.h"
64 #include "../scspd/scsp_var.h"
65 #include "atmarp_var.h"
68 * Global variables
70 char *prog;
71 int atmarp_debug_mode = 0;
72 int atmarp_max_socket = 0;
73 Atmarp_intf *atmarp_intf_head = NULL;
74 Atmarp_slis *atmarp_slis_head = NULL;
75 FILE *atmarp_log_file = NULL;
76 char *atmarp_log_file_name = NULL;
77 Harp_timer cache_timer, perm_timer;
81 * Print a usage message
83 * Arguments:
84 * none
86 * Returns:
87 * exits, does not return
90 void
91 usage(void)
93 fprintf(stderr, "usage: %s [-d] [-l <log_file>] <net_intf> ...\n", prog);
94 exit(1);
99 * Process command line parameters
101 * Arguments:
102 * argc number of command-line arguments
103 * argv list of pointers to command-line arguments
105 * Returns:
106 * none
109 static void
110 initialize(int argc, char **argv)
113 int i, rc;
116 * Save program name, ignoring any path components
118 if ((prog = (char *)strrchr(argv[0], '/')) != NULL)
119 prog++;
120 else
121 prog = argv[0];
124 * Make sure we're being invoked by the super user
126 i = getuid();
127 if (i != 0) {
128 fprintf(stderr, "%s: You must be root to run this program\n",
129 prog);
130 exit(1);
134 * Scan arguments, checking for options
136 for (i = 1; i < argc; i++) {
137 if (argv[i][0] == '-') {
138 if (strcmp(argv[i], "-d") == 0) {
139 atmarp_debug_mode = TRUE;
140 } else if (strcmp(argv[i], "-l") == 0) {
141 i++;
142 if (i >= argc) {
143 fprintf(stderr, "%s: Log file name missing\n",
144 prog);
145 exit(1);
147 atmarp_log_file_name = argv[i];
148 } else {
149 fprintf(stderr, "%s: Unrecognized option \"%s\"\n",
150 prog, argv[i]);
151 exit(1);
153 } else {
155 * Parameter is a network interface name
157 rc = atmarp_cfg_netif(argv[i]);
158 if (rc) {
159 fprintf(stderr, "%s: Error configuring network interface %s\n",
160 prog, argv[i]);
161 exit(1);
167 * Make sure we had at least one interface configured
169 if (!atmarp_intf_head) {
170 usage();
176 * Daemon housekeeping
178 * Arguments:
179 * None
181 * Returns:
182 * None
185 static void
186 start_daemon(void)
188 int dpid, fd, file_count, rc;
191 * Ignore selected signals
193 #ifdef SIGTTOU
194 signal(SIGTTOU, SIG_IGN);
195 #endif
196 #ifdef SIGTTIN
197 signal(SIGTTIN, SIG_IGN);
198 #endif
199 #ifdef SIGTSTP
200 signal(SIGTSTP, SIG_IGN);
201 #endif
202 #ifdef SIGPIPE
203 signal(SIGPIPE, SIG_IGN);
204 #endif
207 * Skip putting things into the background if we're
208 * in debugging mode
210 if (atmarp_debug_mode)
211 goto daemon_bypass;
214 * Set up syslog for error logging
216 if (!atmarp_log_file) {
217 openlog(prog, LOG_PID | LOG_CONS, LOG_DAEMON);
221 * Put the daemon into the background
223 dpid = fork();
224 if (dpid < 0) {
225 atmarp_log(LOG_ERR, "fork failed");
226 exit(1);
228 if (dpid > 0) {
230 * This is the parent process--just exit and let
231 * the daughter do all the work
233 exit(0);
237 * Disassociate from any controlling terminal
239 rc = setpgrp(0, getpid());
240 if (rc < 0) {
241 atmarp_log(LOG_ERR, "can't change process group");
242 exit(1);
244 fd = open(_PATH_TTY, O_RDWR);
245 if (fd >= 0) {
246 ioctl(fd, TIOCNOTTY, NULL);
247 close(fd);
251 * Close all open file descriptors
253 file_count = getdtablesize();
254 for (fd=0; fd<file_count; fd++) {
255 close(fd);
259 * Open log file, if specified
261 if (atmarp_log_file_name) {
262 atmarp_log_file = fopen(atmarp_log_file_name, "a");
263 if (!atmarp_log_file) {
264 atmarp_log(LOG_ERR, "%s: Can't open log file \'%s\'\n",
265 prog, atmarp_log_file_name);
266 exit(1);
271 * Set up and start interval timer
273 daemon_bypass:
274 init_timer();
277 * Move to a safe directory
279 chdir(ATMARP_DIR);
282 * Clear the file mode creation mask
284 umask(0);
288 * Set up signal handlers
290 if (signal(SIGINT, atmarp_sigint) == SIG_ERR) {
291 atmarp_log(LOG_ERR, "SIGINT signal setup failed");
292 exit(1);
298 * Main line code
300 * The ATMARP server resides in the kernel, while SCSP runs as a daemon
301 * in user space. This program exists to provide an interface between
302 * the two. It periodically polls the kernel to get the ATMARP cache
303 * and passes information about new entries to SCSP. It also accepts
304 * new information from SCSP and passes it to the kernel.
306 * Arguments:
307 * argc number of command-line arguments
308 * argv list of pointers to command-line arguments
310 * Returns:
311 * none
315 main(int argc, char **argv)
317 int i, rc;
318 fd_set read_set, write_set, except_set;
319 Atmarp_intf *aip;
322 * Process command line arguments
324 initialize(argc, argv);
327 * Put the daemon into the background
329 start_daemon();
332 * Start the cache update timer
334 HARP_TIMER(&cache_timer, ATMARP_CACHE_INTERVAL,
335 atmarp_cache_timeout);
338 * Start the permanent cache entry timer
340 HARP_TIMER(&perm_timer, ATMARP_PERM_INTERVAL,
341 atmarp_perm_timeout);
344 * Establish a connection to SCSP for each interface. If a
345 * connect fails, it will be retried when the cache update
346 * timer fires.
348 for (aip = atmarp_intf_head; aip; aip = aip->ai_next) {
349 if (atmarp_if_ready(aip)) {
350 atmarp_scsp_connect(aip);
355 * Read the cache from the kernel
357 atmarp_get_updated_cache();
360 * Main program loop -- wait for data to come in from SCSP.
361 * When the timer fires, it will be handled elsewhere.
363 while (1) {
365 * Wait for input from SCSP
367 FD_ZERO(&read_set);
368 FD_ZERO(&write_set);
369 FD_ZERO(&except_set);
370 for (aip = atmarp_intf_head; aip; aip = aip->ai_next) {
371 if (aip->ai_scsp_sock != -1) {
372 FD_SET(aip->ai_scsp_sock, &read_set);
375 rc = select(atmarp_max_socket + 1,
376 &read_set, &write_set,
377 &except_set, NULL);
378 if (rc < 0) {
379 if (harp_timer_exec) {
380 timer_proc();
381 continue;
382 } else if (errno == EINTR) {
383 continue;
384 } else {
385 atmarp_log(LOG_ERR, "Select failed");
386 abort();
391 * Read and process the input from SCSP
393 for (i = 0; i <= atmarp_max_socket; i++) {
394 if (FD_ISSET(i, &read_set)) {
395 aip = atmarp_find_intf_sock(i);
396 if (aip)
397 rc = atmarp_scsp_read(aip);