summaryrefslogtreecommitdiffstats
path: root/usr.sbin/atm/atmarpd/atmarpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/atm/atmarpd/atmarpd.c')
-rw-r--r--usr.sbin/atm/atmarpd/atmarpd.c409
1 files changed, 409 insertions, 0 deletions
diff --git a/usr.sbin/atm/atmarpd/atmarpd.c b/usr.sbin/atm/atmarpd/atmarpd.c
new file mode 100644
index 0000000..72ebb52
--- /dev/null
+++ b/usr.sbin/atm/atmarpd/atmarpd.c
@@ -0,0 +1,409 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: atmarpd.c,v 1.5 1998/08/13 20:11:13 johnc Exp $
+ *
+ */
+
+/*
+ * Server Cache Synchronization Protocol (SCSP) Support
+ * ----------------------------------------------------
+ *
+ * SCSP-ATMARP server interface: main line code
+ *
+ */
+
+#ifndef lint
+static char *RCSid = "@(#) $Id: atmarpd.c,v 1.5 1998/08/13 20:11:13 johnc Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/ttycom.h>
+#include <netatm/queue.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include <libatm.h>
+#include "../scspd/scsp_msg.h"
+#include "../scspd/scsp_if.h"
+#include "../scspd/scsp_var.h"
+#include "atmarp_var.h"
+
+
+/*
+ * Global variables
+ */
+char *prog;
+int atmarp_debug_mode = 0;
+int atmarp_max_socket = 0;
+Atmarp_intf *atmarp_intf_head = (Atmarp_intf *)0;
+Atmarp_slis *atmarp_slis_head = (Atmarp_slis *)0;
+FILE *atmarp_log_file = (FILE *)0;
+char *atmarp_log_file_name = (char *)0;
+Harp_timer cache_timer, perm_timer;
+
+
+
+/*
+ * Print a usage message
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * exits, does not return
+ *
+ */
+void
+usage()
+{
+ fprintf(stderr, "usage: %s [-d] [-l <log_file>] <net_intf> ...\n", prog);
+ exit(1);
+}
+
+
+/*
+ * Process command line parameters
+ *
+ * Arguments:
+ * argc number of command-line arguments
+ * argv list of pointers to command-line arguments
+ *
+ * Returns:
+ * none
+ *
+ */
+static void
+initialize(argc, argv)
+ int argc;
+ char *argv[];
+
+{
+ int i, rc;
+
+ /*
+ * Save program name, ignoring any path components
+ */
+ if (prog = (char *)strrchr(argv[0], '/'))
+ prog++;
+ else
+ prog = argv[0];
+
+ /*
+ * Make sure we're being invoked by the super user
+ */
+ i = getuid();
+ if (i != 0) {
+ fprintf(stderr, "%s: You must be root to run this program\n",
+ prog);
+ exit(1);
+ }
+
+ /*
+ * Scan arguments, checking for options
+ */
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (strcmp(argv[i], "-d") == 0) {
+ atmarp_debug_mode = TRUE;
+ } else if (strcmp(argv[i], "-l") == 0) {
+ i++;
+ if (i >= argc) {
+ fprintf(stderr, "%s: Log file name missing\n",
+ prog);
+ exit(1);
+ }
+ atmarp_log_file_name = argv[i];
+ } else {
+ fprintf(stderr, "%s: Unrecognized option \"%s\"\n",
+ prog, argv[i]);
+ exit(1);
+ }
+ } else {
+ /*
+ * Parameter is a network interface name
+ */
+ rc = atmarp_cfg_netif(argv[i]);
+ if (rc) {
+ fprintf(stderr, "%s: Error configuring network interface %s\n",
+ prog, argv[i]);
+ exit(1);
+ }
+ }
+ }
+
+ /*
+ * Make sure we had at least one interface configured
+ */
+ if (!atmarp_intf_head) {
+ usage();
+ }
+}
+
+
+/*
+ * Daemon housekeeping
+ *
+ * Arguments:
+ * None
+ *
+ * Returns:
+ * None
+ *
+ */
+static void
+start_daemon()
+
+{
+ int dpid, fd, file_count, rc;
+
+ /*
+ * Ignore selected signals
+ */
+#ifdef SIGTTOU
+ signal(SIGTTOU, SIG_IGN);
+#endif
+#ifdef SIGTTIN
+ signal(SIGTTIN, SIG_IGN);
+#endif
+#ifdef SIGTSTP
+ signal(SIGTSTP, SIG_IGN);
+#endif
+#ifdef SIGPIPE
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ /*
+ * Skip putting things into the background if we're
+ * in debugging mode
+ */
+ if (atmarp_debug_mode)
+ goto daemon_bypass;
+
+ /*
+ * Set up syslog for error logging
+ */
+ if (!atmarp_log_file) {
+ openlog(prog, LOG_PID | LOG_CONS, LOG_DAEMON);
+ }
+
+ /*
+ * Put the daemon into the background
+ */
+ dpid = fork();
+ if (dpid < 0) {
+ atmarp_log(LOG_ERR, "fork failed");
+ exit(1);
+ }
+ if (dpid > 0) {
+ /*
+ * This is the parent process--just exit and let
+ * the daughter do all the work
+ */
+ exit(0);
+ }
+
+ /*
+ * Disassociate from any controlling terminal
+ */
+ rc = setpgrp(0, getpid());
+ if (rc < 0) {
+ atmarp_log(LOG_ERR, "can't change process group");
+ exit(1);
+ }
+ fd = open("/dev/tty", O_RDWR);
+ if (fd >= 0) {
+ ioctl(fd, TIOCNOTTY, (char *)0);
+ close(fd);
+ }
+
+ /*
+ * Close all open file descriptors
+ */
+ file_count = getdtablesize();
+ for (fd=0; fd<file_count; fd++) {
+ close(fd);
+ }
+
+ /*
+ * Open log file, if specified
+ */
+ if (atmarp_log_file_name) {
+ atmarp_log_file = fopen(atmarp_log_file_name, "a");
+ if (!atmarp_log_file) {
+ atmarp_log(LOG_ERR, "%s: Can't open log file \'%s\'\n",
+ prog, atmarp_log_file_name);
+ exit(1);
+ }
+ }
+
+ /*
+ * Set up and start interval timer
+ */
+daemon_bypass:
+ init_timer();
+
+ /*
+ * Move to a safe directory
+ */
+ chdir(ATMARP_DIR);
+
+ /*
+ * Clear the file mode creation mask
+ */
+ umask(0);
+
+
+ /*
+ * Set up signal handlers
+ */
+ rc = (int)signal(SIGINT, atmarp_sigint);
+ if (rc == -1) {
+ atmarp_log(LOG_ERR, "SIGINT signal setup failed");
+ exit(1);
+ }
+}
+
+
+/*
+ * Main line code
+ *
+ * The ATMARP server resides in the kernel, while SCSP runs as a daemon
+ * in user space. This program exists to provide an interface between
+ * the two. It periodically polls the kernel to get the ATMARP cache
+ * and passes information about new entries to SCSP. It also accepts
+ * new information from SCSP and passes it to the kernel.
+ *
+ * Arguments:
+ * argc number of command-line arguments
+ * argv list of pointers to command-line arguments
+ *
+ * Returns:
+ * none
+ *
+ */
+main(argc, argv)
+ int argc;
+ char *argv[];
+
+{
+ int i, rc;
+ fd_set read_set, write_set, except_set;
+ Atmarp_intf *aip;
+
+ /*
+ * Process command line arguments
+ */
+ initialize(argc, argv);
+
+ /*
+ * Put the daemon into the background
+ */
+ start_daemon();
+
+ /*
+ * Start the cache update timer
+ */
+ HARP_TIMER(&cache_timer, ATMARP_CACHE_INTERVAL,
+ atmarp_cache_timeout);
+
+ /*
+ * Start the permanent cache entry timer
+ */
+ HARP_TIMER(&perm_timer, ATMARP_PERM_INTERVAL,
+ atmarp_perm_timeout);
+
+ /*
+ * Establish a connection to SCSP for each interface. If a
+ * connect fails, it will be retried when the cache update
+ * timer fires.
+ */
+ for (aip = atmarp_intf_head; aip; aip = aip->ai_next) {
+ if (atmarp_if_ready(aip)) {
+ (void)atmarp_scsp_connect(aip);
+ }
+ }
+
+ /*
+ * Read the cache from the kernel
+ */
+ atmarp_get_updated_cache();
+
+ /*
+ * Main program loop -- wait for data to come in from SCSP.
+ * When the timer fires, it will be handled elsewhere.
+ */
+ while (1) {
+ /*
+ * Wait for input from SCSP
+ */
+ FD_ZERO(&read_set);
+ FD_ZERO(&write_set);
+ FD_ZERO(&except_set);
+ for (aip = atmarp_intf_head; aip; aip = aip->ai_next) {
+ if (aip->ai_scsp_sock != -1) {
+ FD_SET(aip->ai_scsp_sock, &read_set);
+ }
+ }
+ rc = select(atmarp_max_socket + 1,
+ &read_set, &write_set,
+ &except_set, (struct timeval *)0);
+ if (rc < 0) {
+ if (harp_timer_exec) {
+ timer_proc();
+ continue;
+ } else if (errno = EINTR) {
+ continue;
+ } else {
+ atmarp_log(LOG_ERR, "Select failed");
+ abort();
+ }
+ }
+
+ /*
+ * Read and process the input from SCSP
+ */
+ for (i = 0; i <= atmarp_max_socket; i++) {
+ if (FD_ISSET(i, &read_set)) {
+ aip = atmarp_find_intf_sock(i);
+ if (aip)
+ rc = atmarp_scsp_read(aip);
+ }
+ }
+ }
+}
OpenPOWER on IntegriCloud