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 $
30 * Server Cache Synchronization Protocol (SCSP) Support
31 * ----------------------------------------------------
33 * Configuration file processing
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <netatm/port.h>
43 #include <netatm/queue.h>
44 #include <netatm/atm.h>
45 #include <netatm/atm_if.h>
46 #include <netatm/atm_sap.h>
47 #include <netatm/atm_sys.h>
48 #include <netatm/atm_ioctl.h>
61 extern int yyparse(void);
67 Scsp_server *current_server;
68 Scsp_dcs *current_dcs;
72 * Process the configuration file
74 * This routine is called when the daemon starts, and it can also be
75 * called while it is running, as the result of a SIGHUP signal. It
76 * therefore has to be capable of both configuring the daemon from
77 * scratch and modifying the configuration of a running daemon.
80 * cfn configuration file name
83 * 0 configuration read with no errors
84 * else error found in configuration file
88 scsp_config(char *cfn)
91 Scsp_server *ssp, *snext;
94 * Open the configuration file
96 cfg_file = fopen(cfn, "r");
98 scsp_log(LOG_ERR, "can't open config file %s", cfn);
103 * Initialize current interface pointer
105 current_server = NULL;
108 * Clear marks on any existing servers
110 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
115 * Scan the configuration file, processing each line as
121 * Close the configuration file
126 * Delete any server entries that weren't updated
128 for (ssp = scsp_server_head; ssp; ssp = snext) {
129 snext = ssp->ss_next;
131 scsp_server_delete(ssp);
139 * Prepare for SCSP DCS setup
141 * This routine is called from yyparse() when a DCS command is found.
148 * 1 error encountered
157 * Make sure we have a current server block
159 if (!current_server) {
160 parse_error("server not found");
165 * Allocate a DCS block
167 dcsp = (Scsp_dcs *)UM_ALLOC(sizeof(Scsp_dcs));
169 scsp_mem_err("start_dcs: sizeof(Scsp_dcs)");
171 UM_ZERO(dcsp, sizeof(Scsp_dcs));
174 * Fill out DCS links and default values
176 dcsp->sd_server = current_server;
177 dcsp->sd_addr.address_format = T_ATM_ABSENT;
178 dcsp->sd_subaddr.address_format = T_ATM_ABSENT;
180 dcsp->sd_ca_rexmt_int = SCSP_CAReXmitInterval;
181 dcsp->sd_csus_rexmt_int = SCSP_CSUSReXmitInterval;
182 dcsp->sd_hops = SCSP_CSA_HOP_CNT;
183 dcsp->sd_csu_rexmt_int = SCSP_CSUReXmitInterval;
184 dcsp->sd_csu_rexmt_max = SCSP_CSUReXmitMax;
185 LINK2TAIL(dcsp, Scsp_dcs, current_server->ss_dcs, sd_next);
193 * Finish up server configuration
195 * This routine is called from yyparse() to at the end of a DCS
196 * command. It checks that required fields are set and finishes
204 * 1 error encountered
214 * Make sure we have a current server block and DCS block
216 if (!current_server) {
217 parse_error("server not found");
222 parse_error("server not found");
228 * Make sure the DCS ID is set
230 if (dcsp->sd_dcsid.id_len == 0) {
231 parse_error("DCS ID not set");
236 * Make sure the ATM address is set
238 if (dcsp->sd_addr.address_format == T_ATM_ABSENT) {
239 parse_error("DCS ATM address not set");
249 * Configure DCS ATM address
251 * This routine is called from yyparse() to process an ATMaddr command.
254 * ap pointer to DCS's ATM address (in ASCII)
255 * sap pointer to DCS's ATM subaddress (in ASCII)
259 * 1 error encountered
263 set_dcs_addr(char *ap, char *sap)
266 Atm_addr addr, subaddr;
269 * Make sure we have a current server block and DCS block
271 if (!current_server) {
272 parse_error("server not found");
277 parse_error("server not found");
285 UM_ZERO(&addr, sizeof(addr));
286 addr.address_format = T_ATM_ABSENT;
287 UM_ZERO(&subaddr, sizeof(subaddr));
288 subaddr.address_format = T_ATM_ABSENT;
291 * Convert the ATM address from character to internal format
294 addr.address_length = get_hex_atm_addr(ap,
295 (u_char *)addr.address, strlen(ap));
296 if (addr.address_length == 0) {
297 parse_error("invalid ATM address");
300 if (addr.address_length == sizeof(Atm_addr_nsap)) {
301 addr.address_format = T_ATM_ENDSYS_ADDR;
302 } else if (addr.address_length <=
303 sizeof(Atm_addr_e164)) {
304 addr.address_format = T_ATM_E164_ADDR;
306 parse_error("invalid ATM address");
312 * Convert the ATM subaddress from character to internal format
315 subaddr.address_length = get_hex_atm_addr(sap,
316 (u_char *)subaddr.address, strlen(sap));
317 if (subaddr.address_length == 0) {
318 parse_error("invalid ATM address");
321 if (subaddr.address_length == sizeof(Atm_addr_nsap)) {
322 subaddr.address_format = T_ATM_ENDSYS_ADDR;
323 } else if (subaddr.address_length <=
324 sizeof(Atm_addr_e164)) {
325 subaddr.address_format = T_ATM_E164_ADDR;
327 parse_error("invalid ATM subaddress");
333 * Make sure we have a legal ATM address type combination
335 if (((addr.address_format != T_ATM_ENDSYS_ADDR) ||
336 (subaddr.address_format != T_ATM_ABSENT)) &&
337 ((addr.address_format != T_ATM_E164_ADDR) ||
338 (subaddr.address_format != T_ATM_ENDSYS_ADDR))) {
339 parse_error("invalid address/subaddress combination");
344 * Save the address and subaddress
346 ATM_ADDR_COPY(&addr, &dcsp->sd_addr);
347 ATM_ADDR_COPY(&subaddr, &dcsp->sd_subaddr);
354 * Configure CA retransmit interval for DCS
356 * This routine is called from yyparse() to process a CAReXmitInt
364 * 1 error encountered
368 set_dcs_ca_rexmit(int val)
373 * Make sure we have a current server block and DCS block
375 if (!current_server) {
376 parse_error("server not found");
381 parse_error("server not found");
388 * Validate the interval
390 if (val <= 0 || val > 1024) {
391 parse_error("invalid CA retransmit interval");
396 * Set CA retransmit interval
398 dcsp->sd_ca_rexmt_int = val;
405 * Configure CSUS retransmit interval for DCS
407 * This routine is called from yyparse() to process a CSUSReXmitInt
415 * 1 error encountered
419 set_dcs_csus_rexmit(int val)
424 * Make sure we have a current server block and DCS block
426 if (!current_server) {
427 parse_error("server not found");
432 parse_error("server not found");
439 * Validate the interval
441 if (val <= 0 || val > 1024) {
442 parse_error("invalid CSUS retransmit interval");
447 * Set CSUS retransmit interval
449 dcsp->sd_csus_rexmt_int = val;
456 * Configure CSU retransmit interval for DCS
458 * This routine is called from yyparse() to process a CSUReXmitInt
466 * 1 error encountered
470 set_dcs_csu_rexmit(int val)
475 * Make sure we have a current server block and DCS block
477 if (!current_server) {
478 parse_error("server not found");
483 parse_error("server not found");
490 * Validate the interval
492 if (val <= 0 || val > 1024) {
493 parse_error("invalid CSU retransmit interval");
498 * Set CSU retransmit interval
500 dcsp->sd_csu_rexmt_int = val;
507 * Configure CSU retransmit limit for DCS
509 * This routine is called from yyparse() to process a CSUReXmitMax
517 * 1 error encountered
521 set_dcs_csu_rexmit_max(int val)
526 * Make sure we have a current server block and DCS block
528 if (!current_server) {
529 parse_error("server not found");
534 parse_error("server not found");
541 * Validate the interval
543 if (val <= 0 || val > 1024) {
544 parse_error("invalid CSU retransmit maximum");
549 * Set CSU retransmit limit
551 dcsp->sd_csu_rexmt_max = val;
558 * Configure Hello dead factor for DCS
560 * This routine is called from yyparse() to process a HelloDead
564 * val number of times Hello interval has to expire before
565 * a DCS is considered dead
569 * 1 error encountered
573 set_dcs_hello_df(int val)
578 * Make sure we have a current server block and DCS block
580 if (!current_server) {
581 parse_error("server not found");
586 parse_error("server not found");
595 if (val <= 0 || val > 1024) {
596 parse_error("invalid Hello dead factor");
601 * Set Hello dead factor
603 dcsp->sd_hello_df = val;
610 * Configure Hello interval for DCS
612 * This routine is called from yyparse() to process a HelloInt
620 * 1 error encountered
624 set_dcs_hello_int(int val)
629 * Make sure we have a current server block and DCS block
631 if (!current_server) {
632 parse_error("server not found");
637 parse_error("server not found");
644 * Validate the interval
646 if (val <= 0 || val > 1024) {
647 parse_error("invalid Hello interval");
654 dcsp->sd_hello_int = val;
661 * Configure hop count for SCSP server
663 * This routine is called from yyparse() to process a Hops command.
666 * hops number of hops
670 * 1 error encountered
674 set_dcs_hops(int hops)
679 * Make sure we have a current server block and DCS block
681 if (!current_server) {
682 parse_error("server not found");
687 parse_error("server not found");
696 if (hops <= 0 || hops > 1024) {
697 parse_error("invalid hop count");
704 dcsp->sd_hops = hops;
713 * This routine is called from yyparse() to process an ID command.
716 * name pointer to DCS's DNS name or IP address (in ASCII)
720 * 1 error encountered
724 set_dcs_id(char *name)
728 struct sockaddr_in *ip_addr;
731 * Make sure we have a current server block and DCS block
733 if (!current_server) {
734 parse_error("server not found");
739 parse_error("server not found");
742 ssp = current_server;
746 * Convert the DNS name or IP address
748 ip_addr = get_ip_addr(name);
750 parse_error("invalid DCS IP address");
755 * Verify the address length
757 if (ssp->ss_id_len != sizeof(ip_addr->sin_addr)) {
758 parse_error("invalid DCS ID length");
763 * Set the ID in the DCS block
765 dcsp->sd_dcsid.id_len = ssp->ss_id_len;
766 UM_COPY(&ip_addr->sin_addr, dcsp->sd_dcsid.id, ssp->ss_id_len);
773 * Configure network interface for SCSP server
775 * This routine is called from yyparse() to process a Netif command.
776 * It verifies the network interface name, gets interface information
777 * from the kernel, and sets the appropriate fields in the server
781 * netif pointer to network interface name
785 * 1 error encountered
789 set_intf(char *netif)
795 * Get the current network interface address
797 ssp = current_server;
799 parse_error("Server not found");
805 * Make sure we're configuring a valid
808 rc = verify_nif_name(netif);
810 parse_error("%s is not a valid network interface", netif);
814 scsp_log(LOG_ERR, "Netif name verify error");
819 * Save the server's network interface name
821 strcpy(ssp->ss_intf, netif);
830 * Configure protocol for SCSP server
832 * This routine is called from yyparse() to process a Protocol command.
835 * proto SCSP protocol being configured
839 * 1 error encountered
843 set_protocol(int proto)
848 * Get address of current server block
850 ssp = current_server;
852 parse_error("server not found");
857 * Process based on protocol ID
860 case SCSP_PROTO_ATMARP:
862 ssp->ss_id_len = SCSP_ATMARP_ID_LEN;
863 ssp->ss_ckey_len = SCSP_ATMARP_KEY_LEN;
865 case SCSP_PROTO_NHRP:
867 ssp->ss_id_len = SCSP_NHRP_ID_LEN;
868 ssp->ss_ckey_len = SCSP_NHRP_KEY_LEN;
870 case SCSP_PROTO_MARS:
871 case SCSP_PROTO_DHCP:
872 case SCSP_PROTO_LNNI:
874 parse_error("invalid protocol");
883 * Configure server group for SCSP server
885 * This routine is called from yyparse() to process a ServerGroupID
889 * sgid server group id
893 * 1 error encountered
897 set_server_group(int sgid)
902 * Get address of current server block
904 ssp = current_server;
906 parse_error("server not found");
911 * Validate server group ID
914 parse_error("invalid server group ID");
928 * Prepare for SCSP server setup
930 * This routine is called from yyparse() when a Server statment is
934 * name pointer to LIS name
938 * else error encountered
942 start_server(char *name)
946 Scsp_dcs *dcsp, *next_dcs;
947 Scsp_cse *csep, *next_cse;
950 * See if we already have an entry for this name
952 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
953 if (strcasecmp(ssp->ss_name, name) == 0)
959 * Log the fact that we're updating the entry
961 scsp_log(LOG_INFO, "updating server entry for %s", name);
964 * Free the existing cache
966 for (i = 0; i < SCSP_HASHSZ; i++) {
967 for (csep = ssp->ss_cache[i]; csep;
969 next_cse = csep->sc_next;
970 UNLINK(csep, Scsp_cse, ssp->ss_cache[i],
977 * Delete existing DCS blocks
979 for (dcsp = ssp->ss_dcs; dcsp; dcsp = next_dcs) {
980 next_dcs = dcsp->sd_next;
981 scsp_dcs_delete(dcsp);
985 * Get a new server entry
987 ssp = (Scsp_server *)UM_ALLOC(sizeof(Scsp_server));
989 scsp_log(LOG_ERR, "unable to allocate server entry");
992 UM_ZERO(ssp, sizeof(Scsp_server));
994 ssp->ss_dcs_lsock = -1;
999 ssp->ss_name = strdup(name);
1002 * Link in the new interface entry
1004 LINK2TAIL(ssp, Scsp_server, scsp_server_head,
1009 * If the mark is already set, this is a duplicate command
1012 parse_error("duplicate server \"%s\"", name);
1017 * Make this the current interface
1019 current_server = ssp;
1026 * Finish up server configuration
1028 * This routine is called from yyparse() when the end of a server
1029 * statement is reached. It checks that required fields are set
1030 * and marks the entry as processed.
1047 * Get the current network interface address
1049 ssp = current_server;
1051 parse_error("Server not found");
1056 * Mark the interface as processed
1061 * Make sure the interface has been configured
1063 if (ssp->ss_intf == NULL) {
1064 parse_error("netif missing from server specification");
1069 * Make sure the protocol is set
1071 if (ssp->ss_pid == 0) {
1072 parse_error("protocol missing from server specification");
1077 * Make sure the server group is set
1079 if (ssp->ss_sgid == 0) {
1080 parse_error("server group ID missing from server specification");
1085 * Make sure at least one DCS is configured
1087 if (ssp->ss_dcs == NULL) {
1088 parse_error("no DCS configured for server");
1093 * Mark the end of the server
1095 current_server = NULL;
1102 * Configure log file for SCSP server
1104 * This routine is called from yyparse() to process a log File command.
1107 * file name of logging file
1111 * 1 error encountered
1115 set_log_file(char *file)
1118 * Make sure we haven't already got a log file
1120 if (scsp_log_file) {
1121 parse_error("multiple log files specified");
1128 scsp_log_file = fopen(file, "a");
1129 if (!scsp_log_file) {
1130 parse_error("can't open log file");