Sync zoneinfo database with tzdata2009n from elsie.
[dragonfly.git] / usr.sbin / atm / scspd / scsp_config.c
blob8e3708c763bf48469185fb1f14db0730463e2fa0
1 /*
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>
41 #include <net/if.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>
51 #include <errno.h>
52 #include <libatm.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <syslog.h>
58 #include "scsp_msg.h"
59 #include "scsp_if.h"
60 #include "scsp_var.h"
62 extern int yyparse(void);
65 * Global variables
67 FILE *cfg_file;
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.
80 * Arguments:
81 * cfn configuration file name
83 * Returns:
84 * 0 configuration read with no errors
85 * else error found in configuration file
88 int
89 scsp_config(char *cfn)
91 int rc;
92 Scsp_server *ssp, *snext;
95 * Open the configuration file
97 cfg_file = fopen(cfn, "r");
98 if (!cfg_file) {
99 scsp_log(LOG_ERR, "can't open config file %s",
100 (void *)cfn);
101 exit(1);
105 * Initialize current interface pointer
107 current_server = NULL;
110 * Clear marks on any existing servers
112 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
113 ssp->ss_mark = 0;
117 * Scan the configuration file, processing each line as
118 * it is read
120 rc = yyparse();
123 * Close the configuration file
125 fclose(cfg_file);
128 * Delete any server entries that weren't updated
130 for (ssp = scsp_server_head; ssp; ssp = snext) {
131 snext = ssp->ss_next;
132 if (!ssp->ss_mark)
133 scsp_server_delete(ssp);
136 return(rc);
141 * Prepare for SCSP DCS setup
143 * This routine is called from yyparse() when a DCS command is found.
145 * Arguments:
146 * none
148 * Returns:
149 * 0 success
150 * 1 error encountered
154 start_dcs(void)
156 Scsp_dcs *dcsp;
159 * Make sure we have a current server block
161 if (!current_server) {
162 parse_error("server not found");
163 return(1);
167 * Allocate a DCS block
169 dcsp = (Scsp_dcs *)UM_ALLOC(sizeof(Scsp_dcs));
170 if (!dcsp) {
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;
181 dcsp->sd_sock = -1;
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);
189 current_dcs = dcsp;
190 return(0);
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
199 * up the DCS block.
201 * Arguments:
202 * none
204 * Returns:
205 * 0 success
206 * 1 error encountered
210 finish_dcs(void)
212 int rc = 0;
213 Scsp_dcs *dcsp;
214 Scsp_server *ssp;
217 * Make sure we have a current server block and DCS block
219 if (!current_server) {
220 parse_error("server not found");
221 return(1);
224 if (!current_dcs) {
225 parse_error("server not found");
226 return(1);
228 ssp = current_server;
229 dcsp = current_dcs;
232 * Make sure the DCS ID is set
234 if (dcsp->sd_dcsid.id_len == 0) {
235 parse_error("DCS ID not set");
236 rc++;
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");
244 rc++;
247 current_dcs = NULL;
248 return(rc);
253 * Configure DCS ATM address
255 * This routine is called from yyparse() to process an ATMaddr command.
257 * Arguments:
258 * ap pointer to DCS's ATM address (in ASCII)
259 * sap pointer to DCS's ATM subaddress (in ASCII)
261 * Returns:
262 * 0 success
263 * 1 error encountered
267 set_dcs_addr(char *ap, char *sap)
269 Scsp_dcs *dcsp;
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");
277 return(1);
280 if (!current_dcs) {
281 parse_error("server not found");
282 return(1);
284 dcsp = current_dcs;
287 * Initialize
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
297 if (ap) {
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");
302 return(1);
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;
309 } else {
310 parse_error("invalid ATM address");
311 return(1);
316 * Convert the ATM subaddress from character to internal format
318 if (sap) {
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");
323 return(1);
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;
330 } else {
331 parse_error("invalid ATM subaddress");
332 return(1);
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");
344 return(1);
348 * Save the address and subaddress
350 ATM_ADDR_COPY(&addr, &dcsp->sd_addr);
351 ATM_ADDR_COPY(&subaddr, &dcsp->sd_subaddr);
353 return(0);
358 * Configure CA retransmit interval for DCS
360 * This routine is called from yyparse() to process a CAReXmitInt
361 * command.
363 * Arguments:
364 * val time interval
366 * Returns:
367 * 0 success
368 * 1 error encountered
372 set_dcs_ca_rexmit(int val)
374 Scsp_dcs *dcsp;
377 * Make sure we have a current server block and DCS block
379 if (!current_server) {
380 parse_error("server not found");
381 return(1);
384 if (!current_dcs) {
385 parse_error("server not found");
386 return(1);
388 dcsp = current_dcs;
392 * Validate the interval
394 if (val <= 0 || val > 1024) {
395 parse_error("invalid CA retransmit interval");
396 return(1);
400 * Set CA retransmit interval
402 dcsp->sd_ca_rexmt_int = val;
404 return(0);
409 * Configure CSUS retransmit interval for DCS
411 * This routine is called from yyparse() to process a CSUSReXmitInt
412 * command.
414 * Arguments:
415 * val time interval
417 * Returns:
418 * 0 success
419 * 1 error encountered
423 set_dcs_csus_rexmit(int val)
425 Scsp_dcs *dcsp;
428 * Make sure we have a current server block and DCS block
430 if (!current_server) {
431 parse_error("server not found");
432 return(1);
435 if (!current_dcs) {
436 parse_error("server not found");
437 return(1);
439 dcsp = current_dcs;
443 * Validate the interval
445 if (val <= 0 || val > 1024) {
446 parse_error("invalid CSUS retransmit interval");
447 return(1);
451 * Set CSUS retransmit interval
453 dcsp->sd_csus_rexmt_int = val;
455 return(0);
460 * Configure CSU retransmit interval for DCS
462 * This routine is called from yyparse() to process a CSUReXmitInt
463 * command.
465 * Arguments:
466 * val time interval
468 * Returns:
469 * 0 success
470 * 1 error encountered
474 set_dcs_csu_rexmit(int val)
476 Scsp_dcs *dcsp;
479 * Make sure we have a current server block and DCS block
481 if (!current_server) {
482 parse_error("server not found");
483 return(1);
486 if (!current_dcs) {
487 parse_error("server not found");
488 return(1);
490 dcsp = current_dcs;
494 * Validate the interval
496 if (val <= 0 || val > 1024) {
497 parse_error("invalid CSU retransmit interval");
498 return(1);
502 * Set CSU retransmit interval
504 dcsp->sd_csu_rexmt_int = val;
506 return(0);
511 * Configure CSU retransmit limit for DCS
513 * This routine is called from yyparse() to process a CSUReXmitMax
514 * command.
516 * Arguments:
517 * val time interval
519 * Returns:
520 * 0 success
521 * 1 error encountered
525 set_dcs_csu_rexmit_max(int val)
527 Scsp_dcs *dcsp;
530 * Make sure we have a current server block and DCS block
532 if (!current_server) {
533 parse_error("server not found");
534 return(1);
537 if (!current_dcs) {
538 parse_error("server not found");
539 return(1);
541 dcsp = current_dcs;
545 * Validate the interval
547 if (val <= 0 || val > 1024) {
548 parse_error("invalid CSU retransmit maximum");
549 return(1);
553 * Set CSU retransmit limit
555 dcsp->sd_csu_rexmt_max = val;
557 return(0);
562 * Configure Hello dead factor for DCS
564 * This routine is called from yyparse() to process a HelloDead
565 * command.
567 * Arguments:
568 * val number of times Hello interval has to expire before
569 * a DCS is considered dead
571 * Returns:
572 * 0 success
573 * 1 error encountered
577 set_dcs_hello_df(int val)
579 Scsp_dcs *dcsp;
582 * Make sure we have a current server block and DCS block
584 if (!current_server) {
585 parse_error("server not found");
586 return(1);
589 if (!current_dcs) {
590 parse_error("server not found");
591 return(1);
593 dcsp = current_dcs;
597 * Validate the limit
599 if (val <= 0 || val > 1024) {
600 parse_error("invalid Hello dead factor");
601 return(1);
605 * Set Hello dead factor
607 dcsp->sd_hello_df = val;
609 return(0);
614 * Configure Hello interval for DCS
616 * This routine is called from yyparse() to process a HelloInt
617 * command.
619 * Arguments:
620 * val time interval
622 * Returns:
623 * 0 success
624 * 1 error encountered
628 set_dcs_hello_int(int val)
630 Scsp_dcs *dcsp;
633 * Make sure we have a current server block and DCS block
635 if (!current_server) {
636 parse_error("server not found");
637 return(1);
640 if (!current_dcs) {
641 parse_error("server not found");
642 return(1);
644 dcsp = current_dcs;
648 * Validate the interval
650 if (val <= 0 || val > 1024) {
651 parse_error("invalid Hello interval");
652 return(1);
656 * Set Hello interval
658 dcsp->sd_hello_int = val;
660 return(0);
665 * Configure hop count for SCSP server
667 * This routine is called from yyparse() to process a Hops command.
669 * Arguments:
670 * hops number of hops
672 * Returns:
673 * 0 success
674 * 1 error encountered
678 set_dcs_hops(int hops)
680 Scsp_dcs *dcsp;
683 * Make sure we have a current server block and DCS block
685 if (!current_server) {
686 parse_error("server not found");
687 return(1);
690 if (!current_dcs) {
691 parse_error("server not found");
692 return(1);
694 dcsp = current_dcs;
698 * Validate the count
700 if (hops <= 0 || hops > 1024) {
701 parse_error("invalid hop count");
702 return(1);
706 * Set hop count
708 dcsp->sd_hops = hops;
710 return(0);
715 * Configure DCS ID
717 * This routine is called from yyparse() to process an ID command.
719 * Arguments:
720 * name pointer to DCS's DNS name or IP address (in ASCII)
722 * Returns:
723 * 0 success
724 * 1 error encountered
728 set_dcs_id(char *name)
730 Scsp_dcs *dcsp;
731 Scsp_server *ssp;
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");
739 return(1);
742 if (!current_dcs) {
743 parse_error("server not found");
744 return(1);
746 ssp = current_server;
747 dcsp = current_dcs;
750 * Convert the DNS name or IP address
752 ip_addr = get_ip_addr(name);
753 if (!ip_addr) {
754 parse_error("invalid DCS IP address");
755 return(1);
759 * Verify the address length
761 if (ssp->ss_id_len != sizeof(ip_addr->sin_addr)) {
762 parse_error("invalid DCS ID length");
763 return(1);
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);
772 return(0);
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
782 * control block.
784 * Arguments:
785 * netif pointer to network interface name
787 * Returns:
788 * 0 success
789 * 1 error encountered
793 set_intf(char *netif)
795 int rc;
796 Scsp_server *ssp;
799 * Get the current network interface address
801 ssp = current_server;
802 if (!ssp) {
803 parse_error("Server not found");
804 rc = 1;
805 goto set_intf_done;
809 * Make sure we're configuring a valid
810 * network interface
812 rc = verify_nif_name(netif);
813 if (rc == 0) {
814 parse_error("%s is not a valid network interface",
815 (void *)netif);
816 rc = 1;
817 goto set_intf_done;
818 } else if (rc < 0) {
819 scsp_log(LOG_ERR, "Netif name verify error");
820 exit(1);
824 * Save the server's network interface name
826 strcpy(ssp->ss_intf, netif);
827 rc = 0;
829 set_intf_done:
830 return(rc);
835 * Configure protocol for SCSP server
837 * This routine is called from yyparse() to process a Protocol command.
839 * Arguments:
840 * proto SCSP protocol being configured
842 * Returns:
843 * 0 success
844 * 1 error encountered
848 set_protocol(int proto)
850 Scsp_server *ssp;
853 * Get address of current server block
855 ssp = current_server;
856 if (!ssp) {
857 parse_error("server not found");
858 return(1);
862 * Process based on protocol ID
864 switch(proto) {
865 case SCSP_PROTO_ATMARP:
866 ssp->ss_pid = proto;
867 ssp->ss_id_len = SCSP_ATMARP_ID_LEN;
868 ssp->ss_ckey_len = SCSP_ATMARP_KEY_LEN;
869 break;
870 case SCSP_PROTO_NHRP:
871 ssp->ss_pid = proto;
872 ssp->ss_id_len = SCSP_NHRP_ID_LEN;
873 ssp->ss_ckey_len = SCSP_NHRP_KEY_LEN;
874 break;
875 case SCSP_PROTO_MARS:
876 case SCSP_PROTO_DHCP:
877 case SCSP_PROTO_LNNI:
878 default:
879 parse_error("invalid protocol");
880 return(1);
883 return(0);
888 * Configure server group for SCSP server
890 * This routine is called from yyparse() to process a ServerGroupID
891 * command.
893 * Arguments:
894 * sgid server group id
896 * Returns:
897 * 0 success
898 * 1 error encountered
902 set_server_group(int sgid)
904 Scsp_server *ssp;
907 * Get address of current server block
909 ssp = current_server;
910 if (!ssp) {
911 parse_error("server not found");
912 return(1);
916 * Validate server group ID
918 if (sgid <= 0) {
919 parse_error("invalid server group ID");
920 return(1);
924 * Save the ID
926 ssp->ss_sgid = sgid;
928 return(0);
933 * Prepare for SCSP server setup
935 * This routine is called from yyparse() when a Server statment is
936 * found.
938 * Arguments:
939 * name pointer to LIS name
941 * Returns:
942 * 0 success
943 * else error encountered
947 start_server(char *name)
949 int i;
950 Scsp_server *ssp;
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)
959 break;
962 if (ssp) {
964 * Log the fact that we're updating the entry
966 scsp_log(LOG_INFO, "updating server entry for %s",
967 (void *)name);
970 * Free the existing cache
972 for (i = 0; i < SCSP_HASHSZ; i++) {
973 for (csep = ssp->ss_cache[i]; csep;
974 csep = next_cse) {
975 next_cse = csep->sc_next;
976 UNLINK(csep, Scsp_cse, ssp->ss_cache[i],
977 sc_next);
978 UM_FREE(csep);
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);
989 } else {
991 * Get a new server entry
993 ssp = (Scsp_server *)UM_ALLOC(sizeof(Scsp_server));
994 if (!ssp) {
995 scsp_log(LOG_ERR, "unable to allocate server entry");
996 exit(1);
998 UM_ZERO(ssp, sizeof(Scsp_server));
999 ssp->ss_sock = -1;
1000 ssp->ss_dcs_lsock = -1;
1003 * Set the name
1005 ssp->ss_name = strdup(name);
1008 * Link in the new interface entry
1010 LINK2TAIL(ssp, Scsp_server, scsp_server_head,
1011 ss_next);
1015 * If the mark is already set, this is a duplicate command
1017 if (ssp->ss_mark) {
1018 parse_error("duplicate server \"%s\"", name);
1019 return(1);
1023 * Make this the current interface
1025 current_server = ssp;
1027 return(0);
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.
1038 * Arguments:
1039 * None
1041 * Returns:
1042 * 0 OK
1043 * 1 Error
1047 finish_server(void)
1049 int rc = 0;
1050 Scsp_server *ssp;
1053 * Get the current network interface address
1055 ssp = current_server;
1056 if (!ssp) {
1057 parse_error("Server not found");
1058 rc++;
1062 * Mark the interface as processed
1064 ssp->ss_mark = 1;
1067 * Make sure the interface has been configured
1069 if (ssp->ss_intf == NULL) {
1070 parse_error("netif missing from server specification");
1071 rc++;
1075 * Make sure the protocol is set
1077 if (ssp->ss_pid == 0) {
1078 parse_error("protocol missing from server specification");
1079 rc++;
1083 * Make sure the server group is set
1085 if (ssp->ss_sgid == 0) {
1086 parse_error("server group ID missing from server specification");
1087 rc++;
1091 * Make sure at least one DCS is configured
1093 if (ssp->ss_dcs == NULL) {
1094 parse_error("no DCS configured for server");
1095 rc++;
1099 * Mark the end of the server
1101 current_server = NULL;
1103 return(rc);
1108 * Configure log file for SCSP server
1110 * This routine is called from yyparse() to process a log File command.
1112 * Arguments:
1113 * file name of logging file
1115 * Returns:
1116 * 0 success
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");
1128 return(1);
1132 * Open the file
1134 scsp_log_file = fopen(file, "a");
1135 if (!scsp_log_file) {
1136 parse_error("can't open log file");
1137 return(1);
1140 return(0);