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.4 2004/12/18 22:48:02 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>
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>
61 #include "../scspd/scsp_msg.h"
62 #include "../scspd/scsp_if.h"
63 #include "../scspd/scsp_var.h"
64 #include "atmarp_var.h"
70 int atmarp_debug_mode
= 0;
71 int atmarp_max_socket
= 0;
72 Atmarp_intf
*atmarp_intf_head
= (Atmarp_intf
*)0;
73 Atmarp_slis
*atmarp_slis_head
= (Atmarp_slis
*)0;
74 FILE *atmarp_log_file
= (FILE *)0;
75 char *atmarp_log_file_name
= (char *)0;
76 Harp_timer cache_timer
, perm_timer
;
80 * Print a usage message
86 * exits, does not return
92 fprintf(stderr
, "usage: %s [-d] [-l <log_file>] <net_intf> ...\n", prog
);
98 * Process command line parameters
101 * argc number of command-line arguments
102 * argv list of pointers to command-line arguments
109 initialize(int argc
, char **argv
)
115 * Save program name, ignoring any path components
117 if ((prog
= (char *)strrchr(argv
[0], '/')) != NULL
)
123 * Make sure we're being invoked by the super user
127 fprintf(stderr
, "%s: You must be root to run this program\n",
133 * Scan arguments, checking for options
135 for (i
= 1; i
< argc
; i
++) {
136 if (argv
[i
][0] == '-') {
137 if (strcmp(argv
[i
], "-d") == 0) {
138 atmarp_debug_mode
= TRUE
;
139 } else if (strcmp(argv
[i
], "-l") == 0) {
142 fprintf(stderr
, "%s: Log file name missing\n",
146 atmarp_log_file_name
= argv
[i
];
148 fprintf(stderr
, "%s: Unrecognized option \"%s\"\n",
154 * Parameter is a network interface name
156 rc
= atmarp_cfg_netif(argv
[i
]);
158 fprintf(stderr
, "%s: Error configuring network interface %s\n",
166 * Make sure we had at least one interface configured
168 if (!atmarp_intf_head
) {
175 * Daemon housekeeping
187 int dpid
, fd
, file_count
, rc
;
190 * Ignore selected signals
193 signal(SIGTTOU
, SIG_IGN
);
196 signal(SIGTTIN
, SIG_IGN
);
199 signal(SIGTSTP
, SIG_IGN
);
202 signal(SIGPIPE
, SIG_IGN
);
206 * Skip putting things into the background if we're
209 if (atmarp_debug_mode
)
213 * Set up syslog for error logging
215 if (!atmarp_log_file
) {
216 openlog(prog
, LOG_PID
| LOG_CONS
, LOG_DAEMON
);
220 * Put the daemon into the background
224 atmarp_log(LOG_ERR
, "fork failed");
229 * This is the parent process--just exit and let
230 * the daughter do all the work
236 * Disassociate from any controlling terminal
238 rc
= setpgrp(0, getpid());
240 atmarp_log(LOG_ERR
, "can't change process group");
243 fd
= open(_PATH_TTY
, O_RDWR
);
245 ioctl(fd
, TIOCNOTTY
, (char *)0);
250 * Close all open file descriptors
252 file_count
= getdtablesize();
253 for (fd
=0; fd
<file_count
; fd
++) {
258 * Open log file, if specified
260 if (atmarp_log_file_name
) {
261 atmarp_log_file
= fopen(atmarp_log_file_name
, "a");
262 if (!atmarp_log_file
) {
263 atmarp_log(LOG_ERR
, "%s: Can't open log file \'%s\'\n",
264 prog
, atmarp_log_file_name
);
270 * Set up and start interval timer
276 * Move to a safe directory
281 * Clear the file mode creation mask
287 * Set up signal handlers
289 rc
= (int)signal(SIGINT
, atmarp_sigint
);
291 atmarp_log(LOG_ERR
, "SIGINT signal setup failed");
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.
307 * argc number of command-line arguments
308 * argv list of pointers to command-line arguments
315 main(int argc
, char **argv
)
318 fd_set read_set
, write_set
, except_set
;
322 * Process command line arguments
324 initialize(argc
, argv
);
327 * Put the daemon into the background
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
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.
365 * Wait for input from SCSP
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
, (struct timeval
*)0);
379 if (harp_timer_exec
) {
382 } else if (errno
== EINTR
) {
385 atmarp_log(LOG_ERR
, "Select failed");
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
);
397 rc
= atmarp_scsp_read(aip
);