/* * setaliases - configure red aliased interfaces * * This program is distributed under the terms of the GNU General Public * Licence. See the file COPYING for details. * * (c) Steve Bootes, 2002/04/15 * * 21/04/03 Robert Kerr Changed to link directly to libsmooth rather than * using a copy & paste * * $Id: setaliases.c,v 1.2.2.5 2006/07/25 23:15:20 franck78 Exp $ * */ #include #include #include #include #include #include #include #include "libsmooth.h" #include "setuid.h" #include "netutil.h" struct keyvalue *kv = NULL; FILE *file = NULL; void exithandler(void) { if (kv) freekeyvalues(kv); if (file) fclose(file); } int main(void) { char s[STRING_SIZE]; char command[STRING_SIZE]; char red_netmask[STRING_SIZE]; char red_dev[STRING_SIZE]; char default_gateway[STRING_SIZE]; char *aliasip; char *enabled; char *sptr; char *comment; char* intf = NULL; int alias; int count; if (!(initsetuid())) { fprintf(stderr, "Cannot run setuid\n"); exit(1); } atexit(exithandler); /* Init the keyvalue structure */ kv=initkeyvalues(); /* Read in the current values */ if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) { fprintf(stderr, "Cannot read ethernet settings\n"); exit(1); } /* Find the CONFIG_TYPE value */ if (!findkey(kv, "CONFIG_TYPE", s)) { fprintf(stderr, "Cannot read CONFIG_TYPE\n"); exit(1); } /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not, * exit gracefully. This is not an error... */ if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0))) exit(0); /* Now check the RED_TYPE - aliases only work with STATIC. * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */ /* Find the RED_TYPE value */ if (!findkey(kv, "RED_TYPE", s)) { fprintf(stderr, "Cannot read RED_TYPE\n"); exit(1); } /* Make sure it's the right type */ if (!(strcmp(s, "STATIC")==0)) exit(0); /* Get the RED interface details */ if((!findkey(kv, "RED_NETMASK", red_netmask)) || (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway))) { fprintf(stderr, "Cannot read RED settings\n"); exit(1); } if (!VALID_DEVICE(red_dev)) { fprintf(stderr, "Bad red_dev: %s\n", red_dev); exit(1); } if (!VALID_IP(red_netmask)) { fprintf(stderr, "Bad red_netmask : %s\n", red_netmask); exit(1); } if (!VALID_IP(default_gateway)) { fprintf(stderr, "Bad default_gateway : %s\n", default_gateway); exit(1); } // Flush all previous aliases alias = 0; do { snprintf(command, STRING_SIZE - 1, "ip addr flush secondary dev red%d 2>/dev/null", alias++); } while (safe_system(command) == 0); /* Now set up the new aliases from the config file */ if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r"))) { fprintf(stderr, "Unable to open aliases configuration file\n"); exit(1); } alias=0; int linecounter = 0; while (fgets(s, STRING_SIZE, file) != NULL) { linecounter++; if (s[strlen(s) - 1] == '\n') s[strlen(s) - 1] = '\0'; count = 0; aliasip = NULL; enabled = NULL; comment = NULL; intf = NULL; sptr = strtok(s, ","); while (sptr) { if (count == 0) aliasip = sptr; else if (count == 1) enabled = sptr; else if (count == 2) comment = sptr; else if (count == 3) intf = sptr; count++; sptr = strtok(NULL, ","); } if (!(aliasip && enabled)) { fprintf(stderr, "Incomplete data line: in %s(%d)\n", CONFIG_ROOT "/ethernet/aliases", linecounter); exit(1); } if (!strcmp(enabled, "on") == 0) /* disabled rule? */ continue; if (!VALID_IP(aliasip)) { fprintf(stderr, "Bad alias : %s in %s(%d)\n", aliasip, CONFIG_ROOT "/ethernet/aliases", linecounter); exit(1); } // Default to RED_DEV if intf isn't set if (!intf) intf = red_dev; snprintf(command, STRING_SIZE - 1, "ip addr add %s/%s secondary dev %s 2>/dev/null", aliasip, red_netmask, intf); safe_system(command); alias++; } return 0; }