home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************/
- /* config.c config.c */
- /**************************************************************************/
-
- /* config.c is an simple configuration program that creates
- (or edits) a file called 'pcroute.cfg' that containing configuration
- information for the pcroute program. the pcroute file is a Binary
- file whose structure is simply a PCROUTE_CONFIG structure followed
- by a list of ROUTE structures */
-
- /* AUTHOR: Vance Morrison
- DATE : 1/10/89
- ADDRESS: morrison@accuvax.nwu.edu */
-
- /**************************************************************************/
-
- #include <stdio.h>
-
- #define MAX_DATA 4096
-
- typedef struct {
- unsigned char type; /* type of configuration data */
- unsigned char version; /* version of this piece of data */
- unsigned short len; /* length of the DATA (that comes next) */
- char buff[MAX_DATA]; /* the config data */
- } CONF;
-
- /* types for the 'type' field */
- #define CONF_GENERIC 1 /* interface that requires no special config data */
- #define CONF_LOCALTALK 2 /* Special localtalk extentions (zone name etc) */
- #define CONF_SLIP 3 /* Special SLIP extentions (speed) */
-
- #define CONF_ROUTE 10 /* static route configuration data */
- #define CONF_BOOTP 20 /* Bootp configration data (forwarding host) */
- #define CONF_ADMIN 21 /* administrative data (admin host) */
- #define CONF_SYSLOG 22 /* host to send loging messages to */
-
- typedef struct {
- unsigned char addr[4];
- } INET_ADDR;
-
- typedef struct {
- INET_ADDR address;
- INET_ADDR mask;
- unsigned short flags;
- unsigned short metric;
- } CONFIG_GENERIC;
-
- typedef struct {
- INET_ADDR address;
- INET_ADDR mask;
- unsigned short flags;
- unsigned short metric;
- unsigned char zones[64]; /* actually variable length */
- } CONFIG_LOCALTALK;
-
- typedef struct {
- INET_ADDR address;
- INET_ADDR mask;
- unsigned short flags;
- unsigned short metric;
- unsigned short speed; /* actual 8250 divisor */
- } CONFIG_SLIP;
-
- typedef struct {
- INET_ADDR net;
- INET_ADDR gateway;
- unsigned char metric;
- unsigned char flags;
- } CONFIG_ROUTE_ENTRY;
-
- typedef struct {
- unsigned short len;
- CONFIG_ROUTE_ENTRY routes[1]; /* actually variable length */
- } CONFIG_ROUTE;
-
- typedef struct {
- INET_ADDR forward_addr;
- } CONFIG_BOOTP;
-
- typedef struct {
- INET_ADDR log_host;
- short log_priority;
- short log_mask;
- } CONFIG_SYSLOG;
-
- typedef struct {
- INET_ADDR admin;
- } CONFIG_ADMIN;
-
-
- /**************************************************************************/
- main()
- {
- FILE *cfg_rfile, *cfg_wfile;
- char config[64];
-
- printf("This program creates/edits the pcroute.cfg file\n");
-
- if (get_config(config, 64) != 0) {
- fprintf(stderr, "Could not get configuration from 'pcroute.exe'\n");
- return;
- }
-
- cfg_wfile = fopen("pcroute.new", "wb");
- if (cfg_wfile == NULL) {
- fprintf(stderr, "Could not open 'pcroute.new'\n");
- return;
- }
-
- cfg_rfile = fopen("pcroute.cfg", "rb");
-
- if (update_config(cfg_wfile, cfg_rfile, config) == 0) {
- fclose(cfg_wfile);
- unlink("pcroute.cfg");
- rename("pcroute.new", "pcroute.cfg");
- }
- else {
- fclose(cfg_wfile);
- unlink("pcroute.new");
- fprintf(stderr, "Error generating configuration file\n");
- }
- }
-
-
- /**************************************************************************/
- /* update_config writes out a configuration file 'cfg_wfile' conforming
- to the configuration in 'config' using 'cfg_rfile' as defaults. It
- returns 0 on success */
-
- int update_config(cfg_wfile, cfg_rfile, config)
- FILE *cfg_wfile, *cfg_rfile;
- char *config;
- {
- CONF data, datain;
- int len;
-
- datain.type = 0;
- while(*config != 0) {
- /* get the old data structure if possible */
- while (datain.type < *config) {
- read_config(&datain, cfg_rfile);
- if (datain.type == 0)
- break;
- }
- if (datain.type == *config) {
- memcpy(&data, &datain, sizeof(CONF));
- datain.type = 0;
- }
- else
- memset(&data, 0, sizeof(CONF));
-
- len = -1;
- switch(config[0]) {
- case CONF_GENERIC:
- len = config_generic(data.version, config[1], data.buff, MAX_DATA);
- break;
-
- case CONF_ROUTE:
- len = config_routes(data.version, config[1], data.buff, MAX_DATA);
- break;
-
- case CONF_LOCALTALK:
- len = config_localtalk(data.version, config[1], data.buff, MAX_DATA);
- break;
-
- case CONF_SLIP:
- len = config_slip(data.version, config[1], data.buff, MAX_DATA);
- break;
-
- case CONF_BOOTP:
- len = config_bootp(data.version, config[1], data.buff, MAX_DATA);
- break;
-
- case CONF_SYSLOG:
- len = config_syslog(data.version, config[1], data.buff, MAX_DATA);
- break;
-
- case CONF_ADMIN:
- break;
- }
- if (len < 0 || len > MAX_DATA) {
- fprintf(stderr, "I do not understand the pcroute.exe config\n");
- return(-1);
- }
- data.len = len;
- data.type = *config++;
- data.version = *config++;
- fwrite(&data, data.len+4, 1, cfg_wfile);
- }
-
- return(0);
- }
-
-
- /***************************************************************************/
- /* read_config reads in the next configuration object from the file 'cfg_rfile'
- and puts in in the conf structure 'data'. If any errors return, the conf
- structure is nulled */
-
- read_config(data, cfg_rfile)
- CONF *data;
- FILE *cfg_rfile;
- {
- memset(data, 0, sizeof(CONF));
- if (cfg_rfile != NULL)
- if (fread(data, 4, 1, cfg_rfile) == 1)
- if (data->len <= MAX_DATA)
- if (fread(data->buff, data->len, 1, cfg_rfile) == 1)
- return;
-
- memset(data, 0, sizeof(CONF));
- }
-
-
- /**************************************************************************/
- /* config_generic prompts for the generic interface configuration data
- it puts it in the buffer 'generic' of length 'len'. The buffer is
- loaded with version 'oldver' and should be inititialized for version
- 'newver' */
-
- int config_generic(oldver, newver, generic, len)
- unsigned int oldver, newver;
- CONFIG_GENERIC *generic;
- int len;
- {
- int flags;
-
- if (len < sizeof(CONFIG_GENERIC) || newver != 2) {
- fprintf(stderr,"Can't configure this version of PCroute's interface\n");
- return(-1);
- }
- if (oldver == 1)
- generic->metric = 0;
- else if (oldver > 2)
- memset(generic, 0, sizeof(CONFIG_GENERIC));
-
- printf("\nConfiguring an interface\n");
- get_INET_addr(&generic->address, "Address for the interface");
- get_INET_addr(&generic->mask, "Subnet mask for the interface");
- printf("Flag Meanings (if set)\n");
- printf(" Bit 0 (1h) - Don't send routing updates out this interface\n");
- printf(" Bit 1 (2h) - Don't listen to routing updates from this interface\n");
- printf(" Bit 2 (4h) - Proxy Arp for all subnets\n");
- printf(" Bit 3 (8h) - Turn off directed broadcasts\n");
- printf(" Bit 4 (10h) - Turn off the issuing of ICMP redirects\n");
- printf(" Bit 5 (20h) - Broadcast using old (0's) format\n");
- get_hex(&generic->flags, "Flags (HEX) for the interface");
- if (generic->metric == 0)
- generic->metric = 1;
- for(;;) {
- get_hex(&generic->metric, "Routing Metric (HEX) for the interface");
- if (generic->metric >= 0 && generic->metric < 16)
- break;
- generic->metric = 1;
- }
-
- return(sizeof(CONFIG_GENERIC));
- }
-
-
- /**************************************************************************/
- /* config_localtalk prompts for the localtalk configuration data
- It puts it in the buffer 'localt' of length 'len'. The buffer is
- loaded with version 'oldver' and should be inititialized for version
- 'newver' */
-
- int config_localtalk(oldver, newver, localt, len)
- int oldver, newver;
- CONFIG_LOCALTALK *localt;
- int len;
- {
- int flags;
- unsigned char *ptr;
- char buff[256];
- char changed;
-
- if (len < sizeof(CONFIG_LOCALTALK) || newver != 2) {
- fprintf(stderr,"Can't configure this version of PCroute's localtalk\n");
- return(-1);
- }
- if (oldver == 1)
- memset(&localt->metric, 0, 66);
- if (oldver > 2)
- memset(localt, 0, len);
-
- printf("\nConfiguring an interface\n");
- get_INET_addr(&localt->address, "Address for LOCALTALK interface");
- get_INET_addr(&localt->mask, "Subnet mask for LOCALTALK interface");
- printf("Flag Meanings (if set)\n");
- printf(" Bit 0 (1h) - Don't send routing updates out this interface\n");
- printf(" Bit 1 (2h) - Don't listen to routing updates from this interface\n");
- printf(" Bit 2 (4h) - Proxy Arp for all subnets\n");
- printf(" Bit 3 (8h) - Turn off directed broadcasts\n");
- printf(" Bit 4 (10h) - Turn off the issuing of ICMP redirects\n");
- get_hex(&localt->flags, "Flags (HEX) for the interface");
- if (localt->metric == 0)
- localt->metric = 1;
- for(;;) {
- get_hex(&localt->metric, "Routing Metric (HEX) for the interface");
- if (localt->metric > 0 && localt->metric < 16)
- break;
- localt->metric = 1;
- }
-
- printf("\nPlease list all LOCALTALK zones that have gatways that this\n");
- printf("router talks to. (don't forget '*' (the current zone)\n");
- printf("End with a '.'\n");
-
- ptr = localt->zones;
- changed = 0;
- for(;;) {
- if (changed)
- *ptr = 0;
- strncpy(buff, &ptr[1], ptr[0]); /* copy the default */
- buff[ptr[0]] = '\0'; /* make sure the string is ended */
-
- printf("Zone [%s]: ", buff);
- gets(buff);
- if (*buff == '.')
- break;
- if (*buff != '\0') { /* not the default */
- changed = 1;
- ptr[0] = strlen(buff);
- if (ptr + ptr[0] < &localt->zones[64 - 2]) { /* will it fit? */
- strcpy(&ptr[1], buff);
- }
- else {
- printf("Sorry, zone buffer full\n");
- break;
- }
- }
- ptr += ptr[0]+1;
- }
- *ptr = 0;
-
- return(sizeof(CONFIG_LOCALTALK));
- }
-
-
- /**************************************************************************/
- /* config_slip prompts for the slip configuration data
- It puts it in the buffer 'slip' of length 'len'. The buffer is
- loaded with version 'oldver' and should be inititialized for version
- 'newver' */
-
- int config_slip(oldver, newver, slip, len)
- int oldver;
- CONFIG_SLIP *slip;
- int len;
- {
- unsigned int speed;
- unsigned char *ptr;
- char buff[256];
- char changed;
-
- if (len < sizeof(CONFIG_SLIP) || newver != 1) {
- fprintf(stderr,"Can't configure this version of PCroute's slip\n");
- return(-1);
- }
- if (oldver != 1)
- memset(slip, 0, len);
-
- printf("\nConfiguring a SLIP interface\n");
- get_INET_addr(&slip->address, "Address for SLIP interface");
- get_INET_addr(&slip->mask, "Subnet mask for SLIP interface");
- printf("Flag Meanings (if set)\n");
- printf(" Bit 0 (1h) - Don't send routing updates out this interface\n");
- printf(" Bit 1 (2h) - Don't listen to routing updates from this interface\n");
- printf(" Bit 2 (4h) - Proxy Arp for all subnets\n");
- printf(" Bit 3 (8h) - Turn off directed broadcasts\n");
- printf(" Bit 4 (10h) - Turn off the issuing of ICMP redirects\n");
- get_hex(&slip->flags, "Flags (HEX) for the interface");
-
- if( slip->speed == 0 )
- slip->speed = 12; /* default of 9600 baud */
-
- for(;;) {
- printf( "\nEnter speed for this interface (ex. 9600, 19200, ...) [%ld] ", 115200L / slip->speed );
- gets(buff);
- if( *buff == 0 ) {
- speed = slip->speed;
- break;
- }
- speed = 115200L / (unsigned) atol( buff );
- if( (long)speed * (unsigned) atol( buff ) == 115200L )
- break;
- printf( "Bad speed\n" );
- }
- slip->speed = speed;
-
- if (slip->metric == 0)
- slip->metric = 1;
- for(;;) {
- get_hex(&slip->metric, "Routing Metric (HEX) for the interface");
- if (slip->metric > 0 && slip->metric < 16)
- break;
- slip->metric = 1;
- }
-
- return(sizeof(CONFIG_SLIP));
- }
-
-
- /**************************************************************************/
- /* config_bootp prompts for the bootp configuration data.
- It puts it in the buffer 'bootp' of length 'len'. The buffer is
- loaded with version 'oldver' and should be inititialized for version
- 'newver' */
-
- int config_bootp(oldver, newver, bootp, len)
- int oldver, newver;
- CONFIG_BOOTP *bootp;
- int len;
- {
- if (len < sizeof(CONFIG_BOOTP) || newver != 1) {
- fprintf(stderr, "Can't configure this version of PCroute's bootp\n");
- return(-1);
- }
- if (oldver != 1)
- memset(bootp, 0, sizeof(CONFIG_BOOTP));
-
- printf("\nIf you wish to forward bootp packets please enter the address\n");
- printf(" of the address to forward it to. This address can be a\n");
- printf(" directed broadcast. 0.0.0.0 means don't forward\n\n");
- get_INET_addr(&bootp->forward_addr, "Address to forward bootp packets");
-
- return(sizeof(CONFIG_BOOTP));
- }
-
-
- /**************************************************************************/
- /* config_syslog prompts for the logging configuration data.
- It puts it in the buffer 'localt' of length 'len'. The buffer is
- loaded with version 'oldver' and should be inititialized for version
- 'newver' */
-
- int config_syslog(oldver, newver, log, len)
- int oldver, newver;
- CONFIG_SYSLOG *log;
- int len;
- {
- if (len < sizeof(CONFIG_SYSLOG) || newver != 1) {
- fprintf(stderr, "Can't configure this version of PCroute's syslog\n");
- return(-1);
- }
- if (oldver != 1)
- memset(log, 0, sizeof(CONFIG_SYSLOG));
-
- printf("\nOnce PCroute boots up, it sends all log messages to a network\n");
- printf(" host running a BSD UNIX syslogd daemon. To disable\n");
- printf(" logging enter 0.0.0.0\n\n");
- get_INET_addr(&log->log_host, "Host to send loging info to");
-
- printf("Mask Meanings (0 = Log, 1 = Don't log)\n");
- printf(" Bit 0 (1h) - System\n");
- printf(" Bit 1 (2h) - Routing\n");
- printf(" Bit 2 (4h) - Monitor\n");
- printf(" Bit 3 (8h) - Localtalk\n");
- get_hex(&log->log_mask, "Logging mask for this router");
-
- printf("There are 8 routing 'levels' supported\n");
- printf(" 0 - Emergency 1 - Alert 2 - Critical 3 - Error\n");
- printf(" 4 - Warning 5 - Notice 6 - info 7 - Debug\n");
- printf("Only messages with a level less than the logging level are sent\n");
- get_hex(&log->log_priority, "Logging level");
-
- return(sizeof(CONFIG_SYSLOG));
- }
-
-
- /**************************************************************************/
- /* config_routes prompts for the static routes data.
- It puts it in the buffer 'localt' of length 'len'. The buffer is
- loaded with version 'oldver' and should be inititialized for version
- 'newver' */
-
- int config_routes(oldver, newver, route, len)
- int oldver, newver;
- CONFIG_ROUTE *route;
- int len;
- {
- CONFIG_ROUTE_ENTRY *ptr;
- int count;
- short holder;
-
- if (len < sizeof(CONFIG_ROUTE_ENTRY)+2 || newver != 1) {
- fprintf(stderr, "Can't configure this version of PCroute's RIP\n");
- return(-1);
- }
- if (oldver != 1)
- memset(route, 0, len);
-
- printf("\nIf you wish to configure static routes do so here. ");
- printf("To stop type a '.'\n\n");
- printf(" Flag Meanings (if set)\n");
- printf(" Bit 0 (1h) - Local route, do not propagate it\n");
- printf(" Bit 1 (2h) - Transient route, subject to RIP protocol\n");
- count = 0;
- ptr = route->routes;
- while (count < (len-2)/sizeof(CONFIG_ROUTE_ENTRY)) {
- printf("\n");
- if (get_INET_addr(&ptr->net, "Network") < 0)
- break;
- if (get_INET_addr(&ptr->gateway, "Gateway") < 0)
- break;
- holder = ptr->metric;
- if (holder == 0)
- holder = 9;
- if (get_hex(&holder, "Metric (HEX) ") < 0)
- break;
- ptr->metric = holder;
- holder = ptr->flags;
- if (get_hex(&holder, "Flags (HEX)") < 0)
- break;
- ptr->flags = holder;
- count++;
- ptr++;
- }
-
- route->len = count;
- return(count*sizeof(CONFIG_ROUTE_ENTRY)+2);
- }
-
-
- /**************************************************************************/
- /* get_config reads in the binary file 'pcroute.exe' and extracts the
- configuration information from it and put it in the string 'str' of
- length 'len' It returns 0 on SUCCESS */
-
- int get_config(str, len)
- char *str;
- int len;
- {
- FILE *pcroute;
- static char look_for[] = "CONFIG ->";
- char *ptr;
- int c;
-
- pcroute = fopen("pcroute.exe", "rb");
- if (pcroute == NULL) {
- return(-1);
- }
-
- ptr = look_for;
- while(*ptr != '\0') {
- c = getc(pcroute);
- if (c < 0) {
- fclose(pcroute);
- return(-1);
- }
- else if (c == *ptr)
- ptr++;
- else
- ptr = look_for;
- }
-
- --len;
- --len;
- for(;;) {
- if (len <= 0)
- break;
- *str = getc(pcroute);
- if (*str <= 0) /* either EOF or null character */
- break;
-
- str++;
- --len;
- }
-
- *str++ = '\0';
- *str = '\0'; /* need a word of null, just in case */
- fclose(pcroute);
- return(0);
- }
-
-
- /**************************************************************************/
- /* get_hex prompts the user with 'prompt' and retrieves a two byte
- hex number and returns it in in addr. It returns
- 0 if successful. If the user inputs an invalid address, get_hex
- will loop. If the user inputs a '.' it returns -1 if the user inputs
- a '^', get_INET_addr returns -2 */
-
- get_hex(addr, prompt)
- short *addr;
- char *prompt;
- {
- char buffer[256];
- int flags;
-
- for(;;) {
- printf("%s [%xH] ? ", prompt, *addr);
- gets(buffer);
- if (*buffer == 0) /* carrage return = default */
- return(0);
- if (*buffer == '.') /* wish to return */
- return(-1);
- if (*buffer == '^') /* wish to return */
- return(-2);
- if (sscanf(buffer, "%x", &flags) == 1) {
- *addr = flags;
- return(0);
- }
- }
- }
-
-
- /**************************************************************************/
- /* get_INET_addr prompts the user with 'prompt' and retrieves an internet
- address (in dot notation) from the user and places it in addr. It returns
- 0 if successful. If the user inputs an invalid address, get_INET_addr
- will loop. If the user inputs a '.' it returns -1 if the user inputs
- a '^', get_INET_addr returns -2 */
-
- get_INET_addr(addr, prompt)
- INET_ADDR *addr;
- char *prompt;
- {
- char buffer[256];
-
- for(;;) {
- INET_to_dot(*addr, buffer);
- printf("%s [%s] ? ", prompt, buffer);
- gets(buffer);
- if (*buffer == 0) /* carrage return = default */
- return(0);
- if (*buffer == '.') /* wish to return */
- return(-1);
- if (*buffer == '^') /* wish to return */
- return(-2);
- if (dot_to_INET(buffer, addr))
- return(0);
- }
- }
-
-
-
- /*****************************************************************************/
- /* routines for converting to and from dot notation and INET_ADDR structures */
-
- INET_to_dot(inet, dot)
- INET_ADDR inet;
- char *dot;
- {
- sprintf(dot, "%d.%d.%d.%d", inet.addr[0], inet.addr[1],
- inet.addr[2], inet.addr[3]);
- }
-
- dot_to_INET(dot, inet)
- char *dot;
- INET_ADDR *inet;
- {
- int bytes[4];
- int ret;
-
- ret = sscanf(dot,"%d.%d.%d.%d", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);
- if (ret != 4)
- return(0);
-
- inet->addr[0] = bytes[0];
- inet->addr[1] = bytes[1];
- inet->addr[2] = bytes[2];
- inet->addr[3] = bytes[3];
- return(1);
- }
-
-