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",
105 * Initialize current interface pointer
107 current_server = (Scsp_server *)0;
110 * Clear marks on any existing servers
112 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
117 * Scan the configuration file, processing each line as
123 * Close the configuration file
128 * Delete any server entries that weren't updated
130 for (ssp = scsp_server_head; ssp; ssp = snext) {
131 snext = ssp->ss_next;
133 scsp_server_delete(ssp);
141 * Prepare for SCSP DCS setup
143 * This routine is called from yyparse() when a DCS command is found.
150 * 1 error encountered
159 * Make sure we have a current server block
161 if (!current_server) {
162 parse_error("server not found");
167 * Allocate a DCS block
169 dcsp = (Scsp_dcs *)UM_ALLOC(sizeof(Scsp_dcs));
171 scsp_mem_err("start_dcs: sizeof(Scsp_dcs)");
173 UM_ZERO(dcsp, sizeof(Scsp_dcs));
176 * Fill out DCS links and default values
178 dcsp->sd_server = current_server;
179 dcsp->sd_addr.address_format = T_ATM_ABSENT;
180 dcsp->sd_subaddr.address_format = T_ATM_ABSENT;
182 dcsp->sd_ca_rexmt_int = SCSP_CAReXmitInterval;
183 dcsp->sd_csus_rexmt_int = SCSP_CSUSReXmitInterval;
184 dcsp->sd_hops = SCSP_CSA_HOP_CNT;
185 dcsp->sd_csu_rexmt_int = SCSP_CSUReXmitInterval;
186 dcsp->sd_csu_rexmt_max = SCSP_CSUReXmitMax;
187 LINK2TAIL(dcsp, Scsp_dcs, current_server->ss_dcs, sd_next);
195 * Finish up server configuration
197 * This routine is called from yyparse() to at the end of a DCS
198 * command. It checks that required fields are set and finishes
206 * 1 error encountered
217 * Make sure we have a current server block and DCS block
219 if (!current_server) {
220 parse_error("server not found");
225 parse_error("server not found");
228 ssp = current_server;
232 * Make sure the DCS ID is set
234 if (dcsp->sd_dcsid.id_len == 0) {
235 parse_error("DCS ID not set");
240 * Make sure the ATM address is set
242 if (dcsp->sd_addr.address_format == T_ATM_ABSENT) {
243 parse_error("DCS ATM address not set");
247 current_dcs = (Scsp_dcs *)0;
253 * Configure DCS ATM address
255 * This routine is called from yyparse() to process an ATMaddr command.
258 * ap pointer to DCS's ATM address (in ASCII)
259 * sap pointer to DCS's ATM subaddress (in ASCII)
263 * 1 error encountered
267 set_dcs_addr(char *ap, char *sap)
270 Atm_addr addr, subaddr;
273 * Make sure we have a current server block and DCS block
275 if (!current_server) {
276 parse_error("server not found");
281 parse_error("server not found");
289 UM_ZERO(&addr, sizeof(addr));
290 addr.address_format = T_ATM_ABSENT;
291 UM_ZERO(&subaddr, sizeof(subaddr));
292 subaddr.address_format = T_ATM_ABSENT;
295 * Convert the ATM address from character to internal format
298 addr.address_length = get_hex_atm_addr(ap,
299 (u_char *)addr.address, strlen(ap));
300 if (addr.address_length == 0) {
301 parse_error("invalid ATM address");
304 if (addr.address_length == sizeof(Atm_addr_nsap)) {
305 addr.address_format = T_ATM_ENDSYS_ADDR;
306 } else if (addr.address_length <=
307 sizeof(Atm_addr_e164)) {
308 addr.address_format = T_ATM_E164_ADDR;
310 parse_error("invalid ATM address");
316 * Convert the ATM subaddress from character to internal format
319 subaddr.address_length = get_hex_atm_addr(sap,
320 (u_char *)subaddr.address, strlen(sap));
321 if (subaddr.address_length == 0) {
322 parse_error("invalid ATM address");
325 if (subaddr.address_length == sizeof(Atm_addr_nsap)) {
326 subaddr.address_format = T_ATM_ENDSYS_ADDR;
327 } else if (subaddr.address_length <=
328 sizeof(Atm_addr_e164)) {
329 subaddr.address_format = T_ATM_E164_ADDR;
331 parse_error("invalid ATM subaddress");
337 * Make sure we have a legal ATM address type combination
339 if (((addr.address_format != T_ATM_ENDSYS_ADDR) ||
340 (subaddr.address_format != T_ATM_ABSENT)) &&
341 ((addr.address_format != T_ATM_E164_ADDR) ||
342 (subaddr.address_format != T_ATM_ENDSYS_ADDR))) {
343 parse_error("invalid address/subaddress combination");
348 * Save the address and subaddress
350 ATM_ADDR_COPY(&addr, &dcsp->sd_addr);
351 ATM_ADDR_COPY(&subaddr, &dcsp->sd_subaddr);
358 * Configure CA retransmit interval for DCS
360 * This routine is called from yyparse() to process a CAReXmitInt
368 * 1 error encountered
372 set_dcs_ca_rexmit(int val)
377 * Make sure we have a current server block and DCS block
379 if (!current_server) {
380 parse_error("server not found");
385 parse_error("server not found");
392 * Validate the interval
394 if (val <= 0 || val > 1024) {
395 parse_error("invalid CA retransmit interval");
400 * Set CA retransmit interval
402 dcsp->sd_ca_rexmt_int = val;
409 * Configure CSUS retransmit interval for DCS
411 * This routine is called from yyparse() to process a CSUSReXmitInt
419 * 1 error encountered
423 set_dcs_csus_rexmit(int val)
428 * Make sure we have a current server block and DCS block
430 if (!current_server) {
431 parse_error("server not found");
436 parse_error("server not found");
443 * Validate the interval
445 if (val <= 0 || val > 1024) {
446 parse_error("invalid CSUS retransmit interval");
451 * Set CSUS retransmit interval
453 dcsp->sd_csus_rexmt_int = val;
460 * Configure CSU retransmit interval for DCS
462 * This routine is called from yyparse() to process a CSUReXmitInt
470 * 1 error encountered
474 set_dcs_csu_rexmit(int val)
479 * Make sure we have a current server block and DCS block
481 if (!current_server) {
482 parse_error("server not found");
487 parse_error("server not found");
494 * Validate the interval
496 if (val <= 0 || val > 1024) {
497 parse_error("invalid CSU retransmit interval");
502 * Set CSU retransmit interval
504 dcsp->sd_csu_rexmt_int = val;
511 * Configure CSU retransmit limit for DCS
513 * This routine is called from yyparse() to process a CSUReXmitMax
521 * 1 error encountered
525 set_dcs_csu_rexmit_max(int val)
530 * Make sure we have a current server block and DCS block
532 if (!current_server) {
533 parse_error("server not found");
538 parse_error("server not found");
545 * Validate the interval
547 if (val <= 0 || val > 1024) {
548 parse_error("invalid CSU retransmit maximum");
553 * Set CSU retransmit limit
555 dcsp->sd_csu_rexmt_max = val;
562 * Configure Hello dead factor for DCS
564 * This routine is called from yyparse() to process a HelloDead
568 * val number of times Hello interval has to expire before
569 * a DCS is considered dead
573 * 1 error encountered
577 set_dcs_hello_df(int val)
582 * Make sure we have a current server block and DCS block
584 if (!current_server) {
585 parse_error("server not found");
590 parse_error("server not found");
599 if (val <= 0 || val > 1024) {
600 parse_error("invalid Hello dead factor");
605 * Set Hello dead factor
607 dcsp->sd_hello_df = val;
614 * Configure Hello interval for DCS
616 * This routine is called from yyparse() to process a HelloInt
624 * 1 error encountered
628 set_dcs_hello_int(int val)
633 * Make sure we have a current server block and DCS block
635 if (!current_server) {
636 parse_error("server not found");
641 parse_error("server not found");
648 * Validate the interval
650 if (val <= 0 || val > 1024) {
651 parse_error("invalid Hello interval");
658 dcsp->sd_hello_int = val;
665 * Configure hop count for SCSP server
667 * This routine is called from yyparse() to process a Hops command.
670 * hops number of hops
674 * 1 error encountered
678 set_dcs_hops(int hops)
683 * Make sure we have a current server block and DCS block
685 if (!current_server) {
686 parse_error("server not found");
691 parse_error("server not found");
700 if (hops <= 0 || hops > 1024) {
701 parse_error("invalid hop count");
708 dcsp->sd_hops = hops;
717 * This routine is called from yyparse() to process an ID command.
720 * name pointer to DCS's DNS name or IP address (in ASCII)
724 * 1 error encountered
728 set_dcs_id(char *name)
732 struct sockaddr_in *ip_addr;
735 * Make sure we have a current server block and DCS block
737 if (!current_server) {
738 parse_error("server not found");
743 parse_error("server not found");
746 ssp = current_server;
750 * Convert the DNS name or IP address
752 ip_addr = get_ip_addr(name);
754 parse_error("invalid DCS IP address");
759 * Verify the address length
761 if (ssp->ss_id_len != sizeof(ip_addr->sin_addr)) {
762 parse_error("invalid DCS ID length");
767 * Set the ID in the DCS block
769 dcsp->sd_dcsid.id_len = ssp->ss_id_len;
770 UM_COPY(&ip_addr->sin_addr, dcsp->sd_dcsid.id, ssp->ss_id_len);
777 * Configure network interface for SCSP server
779 * This routine is called from yyparse() to process a Netif command.
780 * It verifies the network interface name, gets interface information
781 * from the kernel, and sets the appropriate fields in the server
785 * netif pointer to network interface name
789 * 1 error encountered
793 set_intf(char *netif)
799 * Get the current network interface address
801 ssp = current_server;
803 parse_error("Server not found");
809 * Make sure we're configuring a valid
812 rc = verify_nif_name(netif);
814 parse_error("%s is not a valid network interface",
819 scsp_log(LOG_ERR, "Netif name verify error");
824 * Save the server's network interface name
826 strcpy(ssp->ss_intf, netif);
835 * Configure protocol for SCSP server
837 * This routine is called from yyparse() to process a Protocol command.
840 * proto SCSP protocol being configured
844 * 1 error encountered
848 set_protocol(int proto)
853 * Get address of current server block
855 ssp = current_server;
857 parse_error("server not found");
862 * Process based on protocol ID
865 case SCSP_PROTO_ATMARP:
867 ssp->ss_id_len = SCSP_ATMARP_ID_LEN;
868 ssp->ss_ckey_len = SCSP_ATMARP_KEY_LEN;
870 case SCSP_PROTO_NHRP:
872 ssp->ss_id_len = SCSP_NHRP_ID_LEN;
873 ssp->ss_ckey_len = SCSP_NHRP_KEY_LEN;
875 case SCSP_PROTO_MARS:
876 case SCSP_PROTO_DHCP:
877 case SCSP_PROTO_LNNI:
879 parse_error("invalid protocol");
888 * Configure server group for SCSP server
890 * This routine is called from yyparse() to process a ServerGroupID
894 * sgid server group id
898 * 1 error encountered
902 set_server_group(int sgid)
907 * Get address of current server block
909 ssp = current_server;
911 parse_error("server not found");
916 * Validate server group ID
919 parse_error("invalid server group ID");
933 * Prepare for SCSP server setup
935 * This routine is called from yyparse() when a Server statment is
939 * name pointer to LIS name
943 * else error encountered
947 start_server(char *name)
951 Scsp_dcs *dcsp, *next_dcs;
952 Scsp_cse *csep, *next_cse;
955 * See if we already have an entry for this name
957 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
958 if (strcasecmp(ssp->ss_name, name) == 0)
964 * Log the fact that we're updating the entry
966 scsp_log(LOG_INFO, "updating server entry for %s",
970 * Free the existing cache
972 for (i = 0; i < SCSP_HASHSZ; i++) {
973 for (csep = ssp->ss_cache[i]; csep;
975 next_cse = csep->sc_next;
976 UNLINK(csep, Scsp_cse, ssp->ss_cache[i],
983 * Delete existing DCS blocks
985 for (dcsp = ssp->ss_dcs; dcsp; dcsp = next_dcs) {
986 next_dcs = dcsp->sd_next;
987 scsp_dcs_delete(dcsp);
991 * Get a new server entry
993 ssp = (Scsp_server *)UM_ALLOC(sizeof(Scsp_server));
995 scsp_log(LOG_ERR, "unable to allocate server entry");
998 UM_ZERO(ssp, sizeof(Scsp_server));
1000 ssp->ss_dcs_lsock = -1;
1005 ssp->ss_name = strdup(name);
1008 * Link in the new interface entry
1010 LINK2TAIL(ssp, Scsp_server, scsp_server_head,
1015 * If the mark is already set, this is a duplicate command
1018 parse_error("duplicate server \"%s\"", name);
1023 * Make this the current interface
1025 current_server = ssp;
1032 * Finish up server configuration
1034 * This routine is called from yyparse() when the end of a server
1035 * statement is reached. It checks that required fields are set
1036 * and marks the entry as processed.
1053 * Get the current network interface address
1055 ssp = current_server;
1057 parse_error("Server not found");
1062 * Mark the interface as processed
1067 * Make sure the interface has been configured
1069 if (ssp->ss_intf == (char *)0) {
1070 parse_error("netif missing from server specification");
1075 * Make sure the protocol is set
1077 if (ssp->ss_pid == 0) {
1078 parse_error("protocol missing from server specification");
1083 * Make sure the server group is set
1085 if (ssp->ss_sgid == 0) {
1086 parse_error("server group ID missing from server specification");
1091 * Make sure at least one DCS is configured
1093 if (ssp->ss_dcs == (Scsp_dcs *)0) {
1094 parse_error("no DCS configured for server");
1099 * Mark the end of the server
1101 current_server = (Scsp_server *)0;
1108 * Configure log file for SCSP server
1110 * This routine is called from yyparse() to process a log File command.
1113 * file name of logging file
1117 * 1 error encountered
1121 set_log_file(char *file)
1124 * Make sure we haven't already got a log file
1126 if (scsp_log_file) {
1127 parse_error("multiple log files specified");
1134 scsp_log_file = fopen(file, "a");
1135 if (!scsp_log_file) {
1136 parse_error("can't open log file");