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
= NULL
;
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");
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
== NULL
) {
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
== NULL
) {
1094 parse_error("no DCS configured for server");
1099 * Mark the end of the server
1101 current_server
= NULL
;
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");