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.
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>
42 #include <sys/ttycom.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>
60 #include "../scspd/scsp_msg.h"
61 #include "../scspd/scsp_if.h"
62 #include "../scspd/scsp_var.h"
63 #include "atmarp_var.h"
66 __RCSID("@(#) $FreeBSD$");
74 int atmarp_debug_mode = 0;
75 int atmarp_max_socket = 0;
76 Atmarp_intf *atmarp_intf_head = (Atmarp_intf *)0;
77 Atmarp_slis *atmarp_slis_head = (Atmarp_slis *)0;
78 FILE *atmarp_log_file = (FILE *)0;
79 char *atmarp_log_file_name = (char *)0;
80 Harp_timer cache_timer, perm_timer;
84 * Print a usage message
90 * exits, does not return
96 fprintf(stderr, "usage: %s [-d] [-l <log_file>] <net_intf> ...\n", prog);
102 * Process command line parameters
105 * argc number of command-line arguments
106 * argv list of pointers to command-line arguments
113 initialize(argc, argv)
121 * Save program name, ignoring any path components
123 if ((prog = (char *)strrchr(argv[0], '/')) != NULL)
129 * Make sure we're being invoked by the super user
133 fprintf(stderr, "%s: You must be root to run this program\n",
139 * Scan arguments, checking for options
141 for (i = 1; i < argc; i++) {
142 if (argv[i][0] == '-') {
143 if (strcmp(argv[i], "-d") == 0) {
144 atmarp_debug_mode = TRUE;
145 } else if (strcmp(argv[i], "-l") == 0) {
148 fprintf(stderr, "%s: Log file name missing\n",
152 atmarp_log_file_name = argv[i];
154 fprintf(stderr, "%s: Unrecognized option \"%s\"\n",
160 * Parameter is a network interface name
162 rc = atmarp_cfg_netif(argv[i]);
164 fprintf(stderr, "%s: Error configuring network interface %s\n",
172 * Make sure we had at least one interface configured
174 if (!atmarp_intf_head) {
181 * Daemon housekeeping
194 int dpid, fd, file_count, rc;
197 * Ignore selected signals
200 signal(SIGTTOU, SIG_IGN);
203 signal(SIGTTIN, SIG_IGN);
206 signal(SIGTSTP, SIG_IGN);
209 signal(SIGPIPE, SIG_IGN);
213 * Skip putting things into the background if we're
216 if (atmarp_debug_mode)
220 * Set up syslog for error logging
222 if (!atmarp_log_file) {
223 openlog(prog, LOG_PID | LOG_CONS, LOG_DAEMON);
227 * Put the daemon into the background
231 atmarp_log(LOG_ERR, "fork failed");
236 * This is the parent process--just exit and let
237 * the daughter do all the work
243 * Disassociate from any controlling terminal
245 rc = setpgrp(0, getpid());
247 atmarp_log(LOG_ERR, "can't change process group");
250 fd = open("/dev/tty", O_RDWR);
252 ioctl(fd, TIOCNOTTY, (char *)0);
257 * Close all open file descriptors
259 file_count = getdtablesize();
260 for (fd=0; fd<file_count; fd++) {
265 * Open log file, if specified
267 if (atmarp_log_file_name) {
268 atmarp_log_file = fopen(atmarp_log_file_name, "a");
269 if (!atmarp_log_file) {
270 atmarp_log(LOG_ERR, "%s: Can't open log file \'%s\'\n",
271 prog, atmarp_log_file_name);
277 * Set up and start interval timer
283 * Move to a safe directory
288 * Clear the file mode creation mask
294 * Set up signal handlers
296 rc = (int)signal(SIGINT, atmarp_sigint);
298 atmarp_log(LOG_ERR, "SIGINT signal setup failed");
307 * The ATMARP server resides in the kernel, while SCSP runs as a daemon
308 * in user space. This program exists to provide an interface between
309 * the two. It periodically polls the kernel to get the ATMARP cache
310 * and passes information about new entries to SCSP. It also accepts
311 * new information from SCSP and passes it to the kernel.
314 * argc number of command-line arguments
315 * argv list of pointers to command-line arguments
328 fd_set read_set, write_set, except_set;
332 * Process command line arguments
334 initialize(argc, argv);
337 * Put the daemon into the background
342 * Start the cache update timer
344 HARP_TIMER(&cache_timer, ATMARP_CACHE_INTERVAL,
345 atmarp_cache_timeout);
348 * Start the permanent cache entry timer
350 HARP_TIMER(&perm_timer, ATMARP_PERM_INTERVAL,
351 atmarp_perm_timeout);
354 * Establish a connection to SCSP for each interface. If a
355 * connect fails, it will be retried when the cache update
358 for (aip = atmarp_intf_head; aip; aip = aip->ai_next) {
359 if (atmarp_if_ready(aip)) {
360 (void)atmarp_scsp_connect(aip);
365 * Read the cache from the kernel
367 atmarp_get_updated_cache();
370 * Main program loop -- wait for data to come in from SCSP.
371 * When the timer fires, it will be handled elsewhere.
375 * Wait for input from SCSP
379 FD_ZERO(&except_set);
380 for (aip = atmarp_intf_head; aip; aip = aip->ai_next) {
381 if (aip->ai_scsp_sock != -1) {
382 FD_SET(aip->ai_scsp_sock, &read_set);
385 rc = select(atmarp_max_socket + 1,
386 &read_set, &write_set,
387 &except_set, (struct timeval *)0);
389 if (harp_timer_exec) {
392 } else if (errno == EINTR) {
395 atmarp_log(LOG_ERR, "Select failed");
401 * Read and process the input from SCSP
403 for (i = 0; i <= atmarp_max_socket; i++) {
404 if (FD_ISSET(i, &read_set)) {
405 aip = atmarp_find_intf_sock(i);
407 rc = atmarp_scsp_read(aip);