/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static char *myname; /* copied from argv[0] */ #define RA_CONF_FILE "/etc/inet/routing.conf" #define RA_MAX_CONF_LINE 256 #define ND_IP_FORWARDING "ip_forwarding" #define ND_IP6_FORWARDING "ip6_forwarding" #define ND_IP6_SENDREDIR "ip6_send_redirects" #define ND_IP6_IGNREDIR "ip6_ignore_redirect" #define ND_ON_STR "\0" "1" "\0" #define ND_OFF_STR "\0" "0" "\0" #define OPT_STRBUFSIZE 1024 #define RAD_ARGNUM 10 #define IPV4_ROUTING_DAEMON_DEF "/usr/sbin/in.routed" #define IPV4_ROUTING_DAEMON_ARGS_DEF "" #define IPV4_ROUTING_STOP_CMD_DEF "kill -TERM `cat /var/tmp/in.routed.pid`" #define IPV6_ROUTING_DAEMON_DEF "/usr/lib/inet/in.ripngd" #define IPV6_ROUTING_DAEMON_ARGS_DEF "-s" #define IPV6_ROUTING_STOP_CMD_DEF "kill -TERM `cat /var/tmp/in.ripngd.pid`" #define NDPD_DAEMON_DEF "/usr/lib/inet/in.ndpd" #define NDPD_STOP_CMD_DEF "kill -TERM `cat /var/run/in.ndpd.pid`" #define IN_ROUTED_PID "/var/run/in.routed.pid" #define IN_RIPNGD_PID "/var/run/in.ripngd.pid" #define IN_NDPD_PID "/var/run/in.ndpd.pid" /* * The rad_stop_cmd is exec-ed only if rad_pidfile is NULL, i.e., * default routing daemon has changed. */ typedef struct ra_daemon { size_t rad_argvsize; char **rad_argv; char *rad_pidfile; char *rad_stop_cmd; } ra_daemon_t; static ra_daemon_t v4d, v6d; static char *ndpd_args[] = { NDPD_DAEMON_DEF, NULL }; static ra_daemon_t in_ndpd = { 2, ndpd_args, IN_NDPD_PID, NDPD_STOP_CMD_DEF }; static char nd_ip_forw_on[] = ND_IP_FORWARDING ND_ON_STR; static char nd_ip_forw_off[] = ND_IP_FORWARDING ND_OFF_STR; static char nd_ip6_forw_on[] = ND_IP6_FORWARDING ND_ON_STR; static char nd_ip6_forw_off[] = ND_IP6_FORWARDING ND_OFF_STR; static char nd_ip6_sendredir_on[] = ND_IP6_SENDREDIR ND_ON_STR; static char nd_ip6_sendredir_off[] = ND_IP6_SENDREDIR ND_OFF_STR; static char nd_ip6_ignredir_on[] = ND_IP6_IGNREDIR ND_ON_STR; static char nd_ip6_ignredir_off[] = ND_IP6_IGNREDIR ND_OFF_STR; static int ipsock = -1; static boolean_t booting = B_FALSE; /* boot script defaults? */ static boolean_t forwarding_only = B_FALSE; typedef enum option_values { OPT_INVALID, OPT_ENABLED, OPT_DISABLED, OPT_DEFAULT, OPT_UNKNOWN } oval_t; #define OPT2STR(oval) \ (oval == OPT_ENABLED ? "enabled" : \ (oval == OPT_UNKNOWN ? "unknown" : \ (oval == OPT_DISABLED ? "disabled" : "default"))) #define OPT2INTLSTR(oval) \ (oval == OPT_ENABLED ? gettext("enabled") : \ (oval == OPT_UNKNOWN ? gettext("unknown") : \ (oval == OPT_DISABLED ? gettext("disabled") : \ gettext("default")))) typedef oval_t (*ra_stat_func_t)(void); typedef void (*ra_update_func_t)(void); /* * A routeadm option. These options are those that are enabled or disabled * with the -e and -d command-line options. */ typedef struct ra_opt { const char *opt_name; oval_t opt_new; /* specified on command-line */ oval_t opt_newrev; /* new revert value on command-line */ oval_t opt_conf; /* value currently configured */ oval_t opt_rev; /* revert value configured */ oval_t opt_def; /* default value */ ra_update_func_t opt_enable; ra_update_func_t opt_disable; ra_stat_func_t opt_getcur; } raopt_t; #define OPT_IS_FORWARDING(opt) \ (strcmp((opt).opt_name, "ipv4-forwarding") == 0 || \ strcmp((opt).opt_name, "ipv6-forwarding") == 0) /* * A routeadm variable. These are assigned using the -s command-line * option. */ typedef struct ra_var { const char *var_name; char *var_new; /* specified on command-line */ char *var_conf; /* Currently configured value */ char *var_def; /* The variable's default value */ } ravar_t; static boolean_t init_daemon(ra_daemon_t *, ravar_t *, ravar_t *, ravar_t *, char *); static oval_t v4forw_cur(void); static oval_t v4rout_cur(void); static oval_t v6forw_cur(void); static oval_t v6rout_cur(void); static void enable_v4forw(void); static void disable_v4forw(void); static void enable_v4rout(void); static void disable_v4rout(void); static void enable_v6forw(void); static void disable_v6forw(void); static void enable_v6rout(void); static void disable_v6rout(void); static void usage(void); static void ra_update(void); static void ra_report(boolean_t); static int ra_parseconf(void); static int ra_parseopt(char *, int, raopt_t *); static int ra_parsevar(char *, int, ravar_t *); static int ra_writeconf(void); static raopt_t *ra_str2opt(const char *); static oval_t ra_str2oval(const char *); static ravar_t *ra_str2var(const char *); static char *ra_intloptname(const char *); static int open_ipsock(void); static int ra_ndioctl(int, char *, int); static pid_t ra_isrunning(ra_daemon_t *); static void ra_rundaemon(ra_daemon_t *); static void ra_killdaemon(ra_daemon_t *); static int ra_numv6intfs(void); static void start_ndpd(void); /* * The list describing the supported options. If an option is added here, * remember to also add support for the human readable description of the * option to the ra_intloptname() function. */ static raopt_t ra_opts[] = { { "ipv4-forwarding", OPT_INVALID, OPT_INVALID, OPT_INVALID, OPT_DISABLED, OPT_DISABLED, enable_v4forw, disable_v4forw, v4forw_cur }, { "ipv4-routing", OPT_INVALID, OPT_INVALID, OPT_INVALID, OPT_ENABLED, OPT_DEFAULT, enable_v4rout, disable_v4rout, v4rout_cur }, { "ipv6-forwarding", OPT_INVALID, OPT_INVALID, OPT_INVALID, OPT_DISABLED, OPT_DISABLED, enable_v6forw, disable_v6forw, v6forw_cur }, { "ipv6-routing", OPT_INVALID, OPT_INVALID, OPT_INVALID, OPT_DISABLED, OPT_DISABLED, enable_v6rout, disable_v6rout, v6rout_cur }, { NULL, OPT_INVALID, OPT_INVALID, OPT_INVALID, OPT_INVALID, OPT_INVALID, NULL, NULL, NULL } }; char *v_opt[] = { #define IPV4_ROUTING_DAEMON 0 "ipv4-routing-daemon", #define IPV4_ROUTING_DAEMON_ARGS 1 "ipv4-routing-daemon-args", #define IPV4_ROUTING_STOP_CMD 2 "ipv4-routing-stop-cmd", #define IPV6_ROUTING_DAEMON 3 "ipv6-routing-daemon", #define IPV6_ROUTING_DAEMON_ARGS 4 "ipv6-routing-daemon-args", #define IPV6_ROUTING_STOP_CMD 5 "ipv6-routing-stop-cmd", NULL }; /* * the list describing the supported routeadm variables. */ static ravar_t ra_vars[] = { { "ipv4-routing-daemon", NULL, NULL, IPV4_ROUTING_DAEMON_DEF }, { "ipv4-routing-daemon-args", NULL, NULL, IPV4_ROUTING_DAEMON_ARGS_DEF }, { "ipv4-routing-stop-cmd", NULL, NULL, IPV4_ROUTING_STOP_CMD_DEF }, { "ipv6-routing-daemon", NULL, NULL, IPV6_ROUTING_DAEMON_DEF }, { "ipv6-routing-daemon-args", NULL, NULL, IPV6_ROUTING_DAEMON_ARGS_DEF }, { "ipv6-routing-stop-cmd", NULL, NULL, IPV6_ROUTING_STOP_CMD_DEF }, { NULL, NULL, NULL, NULL } }; static void usage(void) { (void) fprintf(stderr, gettext( "usage: %1$s [-p] [-R ]\n" " %1$s [-e