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/scspd/scsp_config.c,v 1.3 1999/08/28 01:15:32 peter Exp $
27 * @(#) $DragonFly: src/usr.sbin/atm/scspd/scsp_config.c,v 1.4 2003/11/15 20:33:43 eirikn Exp $
31 * Server Cache Synchronization Protocol (SCSP) Support
32 * ----------------------------------------------------
34 * Configuration file processing
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_if.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_sys.h>
49 #include <netatm/atm_ioctl.h>
62 extern int yyparse(void);
68 Scsp_server *current_server;
69 Scsp_dcs *current_dcs;
73 * Process the configuration file
75 * This routine is called when the daemon starts, and it can also be
76 * called while it is running, as the result of a SIGHUP signal. It
77 * therefore has to be capable of both configuring the daemon from
78 * scratch and modifying the configuration of a running daemon.
81 * cfn configuration file name
84 * 0 configuration read with no errors
85 * else error found in configuration file
89 scsp_config(char *cfn)
92 Scsp_server *ssp, *snext;
95 * Open the configuration file
97 cfg_file = fopen(cfn, "r");
99 scsp_log(LOG_ERR, "can't open config file %s", cfn);
104 * Initialize current interface pointer
106 current_server = NULL;
109 * Clear marks on any existing servers
111 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
116 * Scan the configuration file, processing each line as
122 * Close the configuration file
127 * Delete any server entries that weren't updated
129 for (ssp = scsp_server_head; ssp; ssp = snext) {
130 snext = ssp->ss_next;
132 scsp_server_delete(ssp);
140 * Prepare for SCSP DCS setup
142 * This routine is called from yyparse() when a DCS command is found.
149 * 1 error encountered
158 * Make sure we have a current server block
160 if (!current_server) {
161 parse_error("server not found");
166 * Allocate a DCS block
168 dcsp = (Scsp_dcs *)UM_ALLOC(sizeof(Scsp_dcs));
170 scsp_mem_err("start_dcs: sizeof(Scsp_dcs)");
172 UM_ZERO(dcsp, sizeof(Scsp_dcs));
175 * Fill out DCS links and default values
177 dcsp->sd_server = current_server;
178 dcsp->sd_addr.address_format = T_ATM_ABSENT;
179 dcsp->sd_subaddr.address_format = T_ATM_ABSENT;
181 dcsp->sd_ca_rexmt_int = SCSP_CAReXmitInterval;
182 dcsp->sd_csus_rexmt_int = SCSP_CSUSReXmitInterval;
183 dcsp->sd_hops = SCSP_CSA_HOP_CNT;
184 dcsp->sd_csu_rexmt_int = SCSP_CSUReXmitInterval;
185 dcsp->sd_csu_rexmt_max = SCSP_CSUReXmitMax;
186 LINK2TAIL(dcsp, Scsp_dcs, current_server->ss_dcs, sd_next);
194 * Finish up server configuration
196 * This routine is called from yyparse() to at the end of a DCS
197 * command. It checks that required fields are set and finishes
205 * 1 error encountered
216 * Make sure we have a current server block and DCS block
218 if (!current_server) {
219 parse_error("server not found");
224 parse_error("server not found");
227 ssp = current_server;
231 * Make sure the DCS ID is set
233 if (dcsp->sd_dcsid.id_len == 0) {
234 parse_error("DCS ID not set");
239 * Make sure the ATM address is set
241 if (dcsp->sd_addr.address_format == T_ATM_ABSENT) {
242 parse_error("DCS ATM address not set");
252 * Configure DCS ATM address
254 * This routine is called from yyparse() to process an ATMaddr command.
257 * ap pointer to DCS's ATM address (in ASCII)
258 * sap pointer to DCS's ATM subaddress (in ASCII)
262 * 1 error encountered
266 set_dcs_addr(char *ap, char *sap)
269 Atm_addr addr, subaddr;
272 * Make sure we have a current server block and DCS block
274 if (!current_server) {
275 parse_error("server not found");
280 parse_error("server not found");
288 UM_ZERO(&addr, sizeof(addr));
289 addr.address_format = T_ATM_ABSENT;
290 UM_ZERO(&subaddr, sizeof(subaddr));
291 subaddr.address_format = T_ATM_ABSENT;
294 * Convert the ATM address from character to internal format
297 addr.address_length = get_hex_atm_addr(ap,
298 (u_char *)addr.address, strlen(ap));
299 if (addr.address_length == 0) {
300 parse_error("invalid ATM address");
303 if (addr.address_length == sizeof(Atm_addr_nsap)) {
304 addr.address_format = T_ATM_ENDSYS_ADDR;
305 } else if (addr.address_length <=
306 sizeof(Atm_addr_e164)) {
307 addr.address_format = T_ATM_E164_ADDR;
309 parse_error("invalid ATM address");
315 * Convert the ATM subaddress from character to internal format
318 subaddr.address_length = get_hex_atm_addr(sap,
319 (u_char *)subaddr.address, strlen(sap));
320 if (subaddr.address_length == 0) {
321 parse_error("invalid ATM address");
324 if (subaddr.address_length == sizeof(Atm_addr_nsap)) {
325 subaddr.address_format = T_ATM_ENDSYS_ADDR;
326 } else if (subaddr.address_length <=
327 sizeof(Atm_addr_e164)) {
328 subaddr.address_format = T_ATM_E164_ADDR;
330 parse_error("invalid ATM subaddress");
336 * Make sure we have a legal ATM address type combination
338 if (((addr.address_format != T_ATM_ENDSYS_ADDR) ||
339 (subaddr.address_format != T_ATM_ABSENT)) &&
340 ((addr.address_format != T_ATM_E164_ADDR) ||
341 (subaddr.address_format != T_ATM_ENDSYS_ADDR))) {
342 parse_error("invalid address/subaddress combination");
347 * Save the address and subaddress
349 ATM_ADDR_COPY(&addr, &dcsp->sd_addr);
350 ATM_ADDR_COPY(&subaddr, &dcsp->sd_subaddr);
357 * Configure CA retransmit interval for DCS
359 * This routine is called from yyparse() to process a CAReXmitInt
367 * 1 error encountered
371 set_dcs_ca_rexmit(int val)
376 * Make sure we have a current server block and DCS block
378 if (!current_server) {
379 parse_error("server not found");
384 parse_error("server not found");
391 * Validate the interval
393 if (val <= 0 || val > 1024) {
394 parse_error("invalid CA retransmit interval");
399 * Set CA retransmit interval
401 dcsp->sd_ca_rexmt_int = val;
408 * Configure CSUS retransmit interval for DCS
410 * This routine is called from yyparse() to process a CSUSReXmitInt
418 * 1 error encountered
422 set_dcs_csus_rexmit(int val)
427 * Make sure we have a current server block and DCS block
429 if (!current_server) {
430 parse_error("server not found");
435 parse_error("server not found");
442 * Validate the interval
444 if (val <= 0 || val > 1024) {
445 parse_error("invalid CSUS retransmit interval");
450 * Set CSUS retransmit interval
452 dcsp->sd_csus_rexmt_int = val;
459 * Configure CSU retransmit interval for DCS
461 * This routine is called from yyparse() to process a CSUReXmitInt
469 * 1 error encountered
473 set_dcs_csu_rexmit(int val)
478 * Make sure we have a current server block and DCS block
480 if (!current_server) {
481 parse_error("server not found");
486 parse_error("server not found");
493 * Validate the interval
495 if (val <= 0 || val > 1024) {
496 parse_error("invalid CSU retransmit interval");
501 * Set CSU retransmit interval
503 dcsp->sd_csu_rexmt_int = val;
510 * Configure CSU retransmit limit for DCS
512 * This routine is called from yyparse() to process a CSUReXmitMax
520 * 1 error encountered
524 set_dcs_csu_rexmit_max(int val)
529 * Make sure we have a current server block and DCS block
531 if (!current_server) {
532 parse_error("server not found");
537 parse_error("server not found");
544 * Validate the interval
546 if (val <= 0 || val > 1024) {
547 parse_error("invalid CSU retransmit maximum");
552 * Set CSU retransmit limit
554 dcsp->sd_csu_rexmt_max = val;
561 * Configure Hello dead factor for DCS
563 * This routine is called from yyparse() to process a HelloDead
567 * val number of times Hello interval has to expire before
568 * a DCS is considered dead
572 * 1 error encountered
576 set_dcs_hello_df(int val)
581 * Make sure we have a current server block and DCS block
583 if (!current_server) {
584 parse_error("server not found");
589 parse_error("server not found");
598 if (val <= 0 || val > 1024) {
599 parse_error("invalid Hello dead factor");
604 * Set Hello dead factor
606 dcsp->sd_hello_df = val;
613 * Configure Hello interval for DCS
615 * This routine is called from yyparse() to process a HelloInt
623 * 1 error encountered
627 set_dcs_hello_int(int val)
632 * Make sure we have a current server block and DCS block
634 if (!current_server) {
635 parse_error("server not found");
640 parse_error("server not found");
647 * Validate the interval
649 if (val <= 0 || val > 1024) {
650 parse_error("invalid Hello interval");
657 dcsp->sd_hello_int = val;
664 * Configure hop count for SCSP server
666 * This routine is called from yyparse() to process a Hops command.
669 * hops number of hops
673 * 1 error encountered
677 set_dcs_hops(int hops)
682 * Make sure we have a current server block and DCS block
684 if (!current_server) {
685 parse_error("server not found");
690 parse_error("server not found");
699 if (hops <= 0 || hops > 1024) {
700 parse_error("invalid hop count");
707 dcsp->sd_hops = hops;
716 * This routine is called from yyparse() to process an ID command.
719 * name pointer to DCS's DNS name or IP address (in ASCII)
723 * 1 error encountered
727 set_dcs_id(char *name)
731 struct sockaddr_in *ip_addr;
734 * Make sure we have a current server block and DCS block
736 if (!current_server) {
737 parse_error("server not found");
742 parse_error("server not found");
745 ssp = current_server;
749 * Convert the DNS name or IP address
751 ip_addr = get_ip_addr(name);
753 parse_error("invalid DCS IP address");
758 * Verify the address length
760 if (ssp->ss_id_len != sizeof(ip_addr->sin_addr)) {
761 parse_error("invalid DCS ID length");
766 * Set the ID in the DCS block
768 dcsp->sd_dcsid.id_len = ssp->ss_id_len;
769 UM_COPY(&ip_addr->sin_addr, dcsp->sd_dcsid.id, ssp->ss_id_len);
776 * Configure network interface for SCSP server
778 * This routine is called from yyparse() to process a Netif command.
779 * It verifies the network interface name, gets interface information
780 * from the kernel, and sets the appropriate fields in the server
784 * netif pointer to network interface name
788 * 1 error encountered
792 set_intf(char *netif)
798 * Get the current network interface address
800 ssp = current_server;
802 parse_error("Server not found");
808 * Make sure we're configuring a valid
811 rc = verify_nif_name(netif);
813 parse_error("%s is not a valid network interface", netif);
817 scsp_log(LOG_ERR, "Netif name verify error");
822 * Save the server's network interface name
824 strcpy(ssp->ss_intf, netif);
833 * Configure protocol for SCSP server
835 * This routine is called from yyparse() to process a Protocol command.
838 * proto SCSP protocol being configured
842 * 1 error encountered
846 set_protocol(int proto)
851 * Get address of current server block
853 ssp = current_server;
855 parse_error("server not found");
860 * Process based on protocol ID
863 case SCSP_PROTO_ATMARP:
865 ssp->ss_id_len = SCSP_ATMARP_ID_LEN;
866 ssp->ss_ckey_len = SCSP_ATMARP_KEY_LEN;
868 case SCSP_PROTO_NHRP:
870 ssp->ss_id_len = SCSP_NHRP_ID_LEN;
871 ssp->ss_ckey_len = SCSP_NHRP_KEY_LEN;
873 case SCSP_PROTO_MARS:
874 case SCSP_PROTO_DHCP:
875 case SCSP_PROTO_LNNI:
877 parse_error("invalid protocol");
886 * Configure server group for SCSP server
888 * This routine is called from yyparse() to process a ServerGroupID
892 * sgid server group id
896 * 1 error encountered
900 set_server_group(int sgid)
905 * Get address of current server block
907 ssp = current_server;
909 parse_error("server not found");
914 * Validate server group ID
917 parse_error("invalid server group ID");
931 * Prepare for SCSP server setup
933 * This routine is called from yyparse() when a Server statment is
937 * name pointer to LIS name
941 * else error encountered
945 start_server(char *name)
949 Scsp_dcs *dcsp, *next_dcs;
950 Scsp_cse *csep, *next_cse;
953 * See if we already have an entry for this name
955 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
956 if (strcasecmp(ssp->ss_name, name) == 0)
962 * Log the fact that we're updating the entry
964 scsp_log(LOG_INFO, "updating server entry for %s", name);
967 * Free the existing cache
969 for (i = 0; i < SCSP_HASHSZ; i++) {
970 for (csep = ssp->ss_cache[i]; csep;
972 next_cse = csep->sc_next;
973 UNLINK(csep, Scsp_cse, ssp->ss_cache[i],
980 * Delete existing DCS blocks
982 for (dcsp = ssp->ss_dcs; dcsp; dcsp = next_dcs) {
983 next_dcs = dcsp->sd_next;
984 scsp_dcs_delete(dcsp);
988 * Get a new server entry
990 ssp = (Scsp_server *)UM_ALLOC(sizeof(Scsp_server));
992 scsp_log(LOG_ERR, "unable to allocate server entry");
995 UM_ZERO(ssp, sizeof(Scsp_server));
997 ssp->ss_dcs_lsock = -1;
1002 ssp->ss_name = strdup(name);
1005 * Link in the new interface entry
1007 LINK2TAIL(ssp, Scsp_server, scsp_server_head,
1012 * If the mark is already set, this is a duplicate command
1015 parse_error("duplicate server \"%s\"", name);
1020 * Make this the current interface
1022 current_server = ssp;
1029 * Finish up server configuration
1031 * This routine is called from yyparse() when the end of a server
1032 * statement is reached. It checks that required fields are set
1033 * and marks the entry as processed.
1050 * Get the current network interface address
1052 ssp = current_server;
1054 parse_error("Server not found");
1059 * Mark the interface as processed
1064 * Make sure the interface has been configured
1066 if (ssp->ss_intf == NULL) {
1067 parse_error("netif missing from server specification");
1072 * Make sure the protocol is set
1074 if (ssp->ss_pid == 0) {
1075 parse_error("protocol missing from server specification");
1080 * Make sure the server group is set
1082 if (ssp->ss_sgid == 0) {
1083 parse_error("server group ID missing from server specification");
1088 * Make sure at least one DCS is configured
1090 if (ssp->ss_dcs == NULL) {
1091 parse_error("no DCS configured for server");
1096 * Mark the end of the server
1098 current_server = NULL;
1105 * Configure log file for SCSP server
1107 * This routine is called from yyparse() to process a log File command.
1110 * file name of logging file
1114 * 1 error encountered
1118 set_log_file(char *file)
1121 * Make sure we haven't already got a log file
1123 if (scsp_log_file) {
1124 parse_error("multiple log files specified");
1131 scsp_log_file = fopen(file, "a");
1132 if (!scsp_log_file) {
1133 parse_error("can't open log file");