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.3 2003/11/03 19:31:35 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
93 Scsp_server *ssp, *snext;
96 * Open the configuration file
98 cfg_file = fopen(cfn, "r");
100 scsp_log(LOG_ERR, "can't open config file %s",
106 * Initialize current interface pointer
108 current_server = (Scsp_server *)0;
111 * Clear marks on any existing servers
113 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
118 * Scan the configuration file, processing each line as
124 * Close the configuration file
129 * Delete any server entries that weren't updated
131 for (ssp = scsp_server_head; ssp; ssp = snext) {
132 snext = ssp->ss_next;
134 scsp_server_delete(ssp);
142 * Prepare for SCSP DCS setup
144 * This routine is called from yyparse() when a DCS command is found.
151 * 1 error encountered
160 * Make sure we have a current server block
162 if (!current_server) {
163 parse_error("server not found");
168 * Allocate a DCS block
170 dcsp = (Scsp_dcs *)UM_ALLOC(sizeof(Scsp_dcs));
172 scsp_mem_err("start_dcs: sizeof(Scsp_dcs)");
174 UM_ZERO(dcsp, sizeof(Scsp_dcs));
177 * Fill out DCS links and default values
179 dcsp->sd_server = current_server;
180 dcsp->sd_addr.address_format = T_ATM_ABSENT;
181 dcsp->sd_subaddr.address_format = T_ATM_ABSENT;
183 dcsp->sd_ca_rexmt_int = SCSP_CAReXmitInterval;
184 dcsp->sd_csus_rexmt_int = SCSP_CSUSReXmitInterval;
185 dcsp->sd_hops = SCSP_CSA_HOP_CNT;
186 dcsp->sd_csu_rexmt_int = SCSP_CSUReXmitInterval;
187 dcsp->sd_csu_rexmt_max = SCSP_CSUReXmitMax;
188 LINK2TAIL(dcsp, Scsp_dcs, current_server->ss_dcs, sd_next);
196 * Finish up server configuration
198 * This routine is called from yyparse() to at the end of a DCS
199 * command. It checks that required fields are set and finishes
207 * 1 error encountered
218 * Make sure we have a current server block and DCS block
220 if (!current_server) {
221 parse_error("server not found");
226 parse_error("server not found");
229 ssp = current_server;
233 * Make sure the DCS ID is set
235 if (dcsp->sd_dcsid.id_len == 0) {
236 parse_error("DCS ID not set");
241 * Make sure the ATM address is set
243 if (dcsp->sd_addr.address_format == T_ATM_ABSENT) {
244 parse_error("DCS ATM address not set");
248 current_dcs = (Scsp_dcs *)0;
254 * Configure DCS ATM address
256 * This routine is called from yyparse() to process an ATMaddr command.
259 * ap pointer to DCS's ATM address (in ASCII)
260 * sap pointer to DCS's ATM subaddress (in ASCII)
264 * 1 error encountered
268 set_dcs_addr(ap, sap)
272 Atm_addr addr, subaddr;
275 * Make sure we have a current server block and DCS block
277 if (!current_server) {
278 parse_error("server not found");
283 parse_error("server not found");
291 UM_ZERO(&addr, sizeof(addr));
292 addr.address_format = T_ATM_ABSENT;
293 UM_ZERO(&subaddr, sizeof(subaddr));
294 subaddr.address_format = T_ATM_ABSENT;
297 * Convert the ATM address from character to internal format
300 addr.address_length = get_hex_atm_addr(ap,
301 (u_char *)addr.address, strlen(ap));
302 if (addr.address_length == 0) {
303 parse_error("invalid ATM address");
306 if (addr.address_length == sizeof(Atm_addr_nsap)) {
307 addr.address_format = T_ATM_ENDSYS_ADDR;
308 } else if (addr.address_length <=
309 sizeof(Atm_addr_e164)) {
310 addr.address_format = T_ATM_E164_ADDR;
312 parse_error("invalid ATM address");
318 * Convert the ATM subaddress from character to internal format
321 subaddr.address_length = get_hex_atm_addr(sap,
322 (u_char *)subaddr.address, strlen(sap));
323 if (subaddr.address_length == 0) {
324 parse_error("invalid ATM address");
327 if (subaddr.address_length == sizeof(Atm_addr_nsap)) {
328 subaddr.address_format = T_ATM_ENDSYS_ADDR;
329 } else if (subaddr.address_length <=
330 sizeof(Atm_addr_e164)) {
331 subaddr.address_format = T_ATM_E164_ADDR;
333 parse_error("invalid ATM subaddress");
339 * Make sure we have a legal ATM address type combination
341 if (((addr.address_format != T_ATM_ENDSYS_ADDR) ||
342 (subaddr.address_format != T_ATM_ABSENT)) &&
343 ((addr.address_format != T_ATM_E164_ADDR) ||
344 (subaddr.address_format != T_ATM_ENDSYS_ADDR))) {
345 parse_error("invalid address/subaddress combination");
350 * Save the address and subaddress
352 ATM_ADDR_COPY(&addr, &dcsp->sd_addr);
353 ATM_ADDR_COPY(&subaddr, &dcsp->sd_subaddr);
360 * Configure CA retransmit interval for DCS
362 * This routine is called from yyparse() to process a CAReXmitInt
370 * 1 error encountered
374 set_dcs_ca_rexmit(val)
380 * Make sure we have a current server block and DCS block
382 if (!current_server) {
383 parse_error("server not found");
388 parse_error("server not found");
395 * Validate the interval
397 if (val <= 0 || val > 1024) {
398 parse_error("invalid CA retransmit interval");
403 * Set CA retransmit interval
405 dcsp->sd_ca_rexmt_int = val;
412 * Configure CSUS retransmit interval for DCS
414 * This routine is called from yyparse() to process a CSUSReXmitInt
422 * 1 error encountered
426 set_dcs_csus_rexmit(val)
432 * Make sure we have a current server block and DCS block
434 if (!current_server) {
435 parse_error("server not found");
440 parse_error("server not found");
447 * Validate the interval
449 if (val <= 0 || val > 1024) {
450 parse_error("invalid CSUS retransmit interval");
455 * Set CSUS retransmit interval
457 dcsp->sd_csus_rexmt_int = val;
464 * Configure CSU retransmit interval for DCS
466 * This routine is called from yyparse() to process a CSUReXmitInt
474 * 1 error encountered
478 set_dcs_csu_rexmit(val)
484 * Make sure we have a current server block and DCS block
486 if (!current_server) {
487 parse_error("server not found");
492 parse_error("server not found");
499 * Validate the interval
501 if (val <= 0 || val > 1024) {
502 parse_error("invalid CSU retransmit interval");
507 * Set CSU retransmit interval
509 dcsp->sd_csu_rexmt_int = val;
516 * Configure CSU retransmit limit for DCS
518 * This routine is called from yyparse() to process a CSUReXmitMax
526 * 1 error encountered
530 set_dcs_csu_rexmit_max(val)
536 * Make sure we have a current server block and DCS block
538 if (!current_server) {
539 parse_error("server not found");
544 parse_error("server not found");
551 * Validate the interval
553 if (val <= 0 || val > 1024) {
554 parse_error("invalid CSU retransmit maximum");
559 * Set CSU retransmit limit
561 dcsp->sd_csu_rexmt_max = val;
568 * Configure Hello dead factor for DCS
570 * This routine is called from yyparse() to process a HelloDead
574 * val number of times Hello interval has to expire before
575 * a DCS is considered dead
579 * 1 error encountered
583 set_dcs_hello_df(val)
589 * Make sure we have a current server block and DCS block
591 if (!current_server) {
592 parse_error("server not found");
597 parse_error("server not found");
606 if (val <= 0 || val > 1024) {
607 parse_error("invalid Hello dead factor");
612 * Set Hello dead factor
614 dcsp->sd_hello_df = val;
621 * Configure Hello interval for DCS
623 * This routine is called from yyparse() to process a HelloInt
631 * 1 error encountered
635 set_dcs_hello_int(val)
641 * Make sure we have a current server block and DCS block
643 if (!current_server) {
644 parse_error("server not found");
649 parse_error("server not found");
656 * Validate the interval
658 if (val <= 0 || val > 1024) {
659 parse_error("invalid Hello interval");
666 dcsp->sd_hello_int = val;
673 * Configure hop count for SCSP server
675 * This routine is called from yyparse() to process a Hops command.
678 * hops number of hops
682 * 1 error encountered
692 * Make sure we have a current server block and DCS block
694 if (!current_server) {
695 parse_error("server not found");
700 parse_error("server not found");
709 if (hops <= 0 || hops > 1024) {
710 parse_error("invalid hop count");
717 dcsp->sd_hops = hops;
726 * This routine is called from yyparse() to process an ID command.
729 * name pointer to DCS's DNS name or IP address (in ASCII)
733 * 1 error encountered
742 struct sockaddr_in *ip_addr;
745 * Make sure we have a current server block and DCS block
747 if (!current_server) {
748 parse_error("server not found");
753 parse_error("server not found");
756 ssp = current_server;
760 * Convert the DNS name or IP address
762 ip_addr = get_ip_addr(name);
764 parse_error("invalid DCS IP address");
769 * Verify the address length
771 if (ssp->ss_id_len != sizeof(ip_addr->sin_addr)) {
772 parse_error("invalid DCS ID length");
777 * Set the ID in the DCS block
779 dcsp->sd_dcsid.id_len = ssp->ss_id_len;
780 UM_COPY(&ip_addr->sin_addr, dcsp->sd_dcsid.id, ssp->ss_id_len);
787 * Configure network interface for SCSP server
789 * This routine is called from yyparse() to process a Netif command.
790 * It verifies the network interface name, gets interface information
791 * from the kernel, and sets the appropriate fields in the server
795 * netif pointer to network interface name
799 * 1 error encountered
810 * Get the current network interface address
812 ssp = current_server;
814 parse_error("Server not found");
820 * Make sure we're configuring a valid
823 rc = verify_nif_name(netif);
825 parse_error("%s is not a valid network interface",
830 scsp_log(LOG_ERR, "Netif name verify error");
835 * Save the server's network interface name
837 strcpy(ssp->ss_intf, netif);
846 * Configure protocol for SCSP server
848 * This routine is called from yyparse() to process a Protocol command.
851 * proto SCSP protocol being configured
855 * 1 error encountered
865 * Get address of current server block
867 ssp = current_server;
869 parse_error("server not found");
874 * Process based on protocol ID
877 case SCSP_PROTO_ATMARP:
879 ssp->ss_id_len = SCSP_ATMARP_ID_LEN;
880 ssp->ss_ckey_len = SCSP_ATMARP_KEY_LEN;
882 case SCSP_PROTO_NHRP:
884 ssp->ss_id_len = SCSP_NHRP_ID_LEN;
885 ssp->ss_ckey_len = SCSP_NHRP_KEY_LEN;
887 case SCSP_PROTO_MARS:
888 case SCSP_PROTO_DHCP:
889 case SCSP_PROTO_LNNI:
891 parse_error("invalid protocol");
900 * Configure server group for SCSP server
902 * This routine is called from yyparse() to process a ServerGroupID
906 * sgid server group id
910 * 1 error encountered
914 set_server_group(sgid)
920 * Get address of current server block
922 ssp = current_server;
924 parse_error("server not found");
929 * Validate server group ID
932 parse_error("invalid server group ID");
946 * Prepare for SCSP server setup
948 * This routine is called from yyparse() when a Server statment is
952 * name pointer to LIS name
956 * else error encountered
965 Scsp_dcs *dcsp, *next_dcs;
966 Scsp_cse *csep, *next_cse;
969 * See if we already have an entry for this name
971 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
972 if (strcasecmp(ssp->ss_name, name) == 0)
978 * Log the fact that we're updating the entry
980 scsp_log(LOG_INFO, "updating server entry for %s",
984 * Free the existing cache
986 for (i = 0; i < SCSP_HASHSZ; i++) {
987 for (csep = ssp->ss_cache[i]; csep;
989 next_cse = csep->sc_next;
990 UNLINK(csep, Scsp_cse, ssp->ss_cache[i],
997 * Delete existing DCS blocks
999 for (dcsp = ssp->ss_dcs; dcsp; dcsp = next_dcs) {
1000 next_dcs = dcsp->sd_next;
1001 scsp_dcs_delete(dcsp);
1005 * Get a new server entry
1007 ssp = (Scsp_server *)UM_ALLOC(sizeof(Scsp_server));
1009 scsp_log(LOG_ERR, "unable to allocate server entry");
1012 UM_ZERO(ssp, sizeof(Scsp_server));
1014 ssp->ss_dcs_lsock = -1;
1019 ssp->ss_name = strdup(name);
1022 * Link in the new interface entry
1024 LINK2TAIL(ssp, Scsp_server, scsp_server_head,
1029 * If the mark is already set, this is a duplicate command
1032 parse_error("duplicate server \"%s\"", name);
1037 * Make this the current interface
1039 current_server = ssp;
1046 * Finish up server configuration
1048 * This routine is called from yyparse() when the end of a server
1049 * statement is reached. It checks that required fields are set
1050 * and marks the entry as processed.
1067 * Get the current network interface address
1069 ssp = current_server;
1071 parse_error("Server not found");
1076 * Mark the interface as processed
1081 * Make sure the interface has been configured
1083 if (ssp->ss_intf == (char *)0) {
1084 parse_error("netif missing from server specification");
1089 * Make sure the protocol is set
1091 if (ssp->ss_pid == 0) {
1092 parse_error("protocol missing from server specification");
1097 * Make sure the server group is set
1099 if (ssp->ss_sgid == 0) {
1100 parse_error("server group ID missing from server specification");
1105 * Make sure at least one DCS is configured
1107 if (ssp->ss_dcs == (Scsp_dcs *)0) {
1108 parse_error("no DCS configured for server");
1113 * Mark the end of the server
1115 current_server = (Scsp_server *)0;
1122 * Configure log file for SCSP server
1124 * This routine is called from yyparse() to process a log File command.
1127 * file name of logging file
1131 * 1 error encountered
1139 * Make sure we haven't already got a log file
1141 if (scsp_log_file) {
1142 parse_error("multiple log files specified");
1149 scsp_log_file = fopen(file, "a");
1150 if (!scsp_log_file) {
1151 parse_error("can't open log file");