From 0fceb64d25ff3d9586549bb43d971c5eef904330 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 7 Jun 1999 10:23:42 +0200 Subject: Import ax25-apps 0.0.1 from tarball --- ax25rtd/config.c | 736 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 736 insertions(+) create mode 100644 ax25rtd/config.c (limited to 'ax25rtd/config.c') diff --git a/ax25rtd/config.c b/ax25rtd/config.c new file mode 100644 index 0000000..1306d2a --- /dev/null +++ b/ax25rtd/config.c @@ -0,0 +1,736 @@ +/* $Id: config.c,v 1.7 1997/06/05 18:55:51 oe1kib Exp oe1kib $ + * + * Copyright (c) 1996 Jörg Reuter (jreuter@poboxes.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../pathnames.h" +#include "ax25rtd.h" + +ax25_address *asc2ax(char *call) +{ + static ax25_address callsign; + + ax25_aton_entry(call, (char *)&callsign); + + return &callsign; +} + +static long asc2ip(char *s) +{ + struct in_addr addr; + + if (!inet_aton(s, &addr)) + return 0; + + return addr.s_addr; +} + + +char * prepare_cmdline(char *buf) +{ + char *p; + for (p = buf; *p; p++) + { + if (*p == '\t') *p = ' '; + *p = tolower(*p); + + if (*p == '\n') + { + *p = '\0'; + break; + } + + if (*p == '#') + { + *p = '\0'; + break; + } + } + + return buf; +} + +char * get_next_arg(char **p) +{ + char *p2; + + if (p == NULL || *p == NULL) + return NULL; + + p2 = *p; + for (; *p2 && *p2 == ' '; p2++) ; + if (!*p2) + return NULL; + + *p = strchr(p2, ' '); + if (*p != NULL) + { + **p = '\0'; + (*p)++; + } + + return p2; +} + +static inline void invalid_arg(char *c, char *p) +{ + fprintf(stderr, "%s: invalid argument %s\n", c, p); +} + +static inline void missing_arg(char *c) +{ + fprintf(stderr, "%s: argument missing\n", c); +} + +static int yesno(char *arg) +{ + if (!arg) + return 0; + if (!strcmp(arg, "yes") || !strcmp(arg, "1")) + return 1; + if (!strcmp(arg, "no") || !strcmp(arg, "0")) + return 0; + return -1; +} + +static ax25_address *get_mycall(char *port) +{ + char *addr; + + if ((addr = ax25_config_get_addr(port)) == NULL) + return NULL; + + return asc2ax(addr); +} + + +void load_ports(void) +{ + config *config, *cfg, *ncfg; + char buf[1024]; + struct ifconf ifc; + struct ifreq ifr, *ifrp; + int k, fd; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + fprintf(stderr, "Unable to open socket\n"); + exit(1); + } + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) + { + fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno)); + return; + } + + ifrp = ifc.ifc_req; + for (k = ifc.ifc_len / sizeof(struct ifreq); k > 0; k--, ifrp++) + { + strcpy(ifr.ifr_name, ifrp->ifr_name); + if (strcmp(ifr.ifr_name, "lo") == 0) continue; + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) + { + fprintf(stderr, "SIOCGIFFLAGS: %s\n", strerror(errno)); + exit(1); + } + + if (!(ifr.ifr_flags & IFF_UP)) continue; + + ioctl(fd, SIOCGIFHWADDR, &ifr); + + if (ifr.ifr_hwaddr.sa_family != ARPHRD_AX25) + continue; + + for (config = Config; config; config = config->next) + if (!memcmp(&config->mycalls[0], ifr.ifr_hwaddr.sa_data, AXLEN) && !*config->dev) + { + strcpy(config->dev, ifr.ifr_name); + ioctl(fd, SIOCGIFADDR, &ifr); + config->ip = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr; + strcpy(ifr.ifr_name, config->dev); + ioctl(fd, SIOCGIFNETMASK, &ifr); + config->netmask = ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr; + break; + } + } + close(fd); + + config = cfg = Config; + + while(config) + { + if (!*config->dev) + { + if (config == Config) + { + Config = config->next; + cfg = Config; + } else + cfg->next = config->next; + ncfg = config->next; + free(config); + config = ncfg; + } else { + cfg = config; + config = config->next; + } + } +} + +void load_listeners(void) +{ + config *config; + char buf[1024], device[14], call[10], dcall[10]; + int k; + FILE *fp; + ax25_address *axcall; + + + fp = fopen(PROC_AX25_FILE, "r"); + + if (fp == NULL) + { + fprintf(stderr, "No AX.25 in kernel. Tss, tss...\n"); + exit(1); + } + + while (fgets(buf, sizeof(buf)-1, fp) != NULL) + { + k = sscanf(buf, "%s %s %s", dcall, call, device); + if (k == 3 && !strcmp(dcall, "*")) + { + axcall = asc2ax(call); + if (!strcmp("???", device)) + { + for (config = Config; config; config = config->next) + { + if (call_is_mycall(config, axcall) || config->nmycalls > AX25_MAXCALLS) + continue; + memcpy(&config->mycalls[config->nmycalls++], axcall, AXLEN); + } + } else { + config = dev_get_config(device); + if (config == NULL || call_is_mycall(config, axcall) || config->nmycalls > AX25_MAXCALLS) + continue; + + memcpy(&config->mycalls[config->nmycalls++], axcall, AXLEN); + } + } + } + fclose(fp); +} + +void load_config() +{ + FILE *fp; + char buf[1024], *p, *cmd, *arg; + config *config, *cfg; + ax25_address *axcall; + + config = NULL; + + fp = fopen(CONF_AX25ROUTED_FILE, "r"); + + if (fp == NULL) + { + fprintf(stderr, "config file %s not found\n", CONF_AX25ROUTED_FILE); + exit(1); + } + + while(fgets(buf, sizeof(buf)-1, fp) != NULL) + { + p = prepare_cmdline(buf); + if (!*p) + continue; + + cmd = get_next_arg(&p); + if (cmd == NULL) + continue; + arg = get_next_arg(&p); + + if (*cmd == '[') + { + cmd++; + p = strrchr(cmd, ']'); + if (p == NULL) + { + fprintf(stderr, "syntax error: [%s\n", cmd); + continue; + } + *p = '\0'; + + axcall = get_mycall(cmd); + if (axcall == NULL) + continue; + + cfg = (struct config_ *) malloc(sizeof(struct config_)); + if (cfg == NULL) + { + fprintf(stderr, "out of memory\n"); + exit(1); + } + memset(cfg, 0, sizeof(struct config_)); + + if (config) + config->next = cfg; + else + Config = cfg; + + cfg->next = NULL; + config = cfg; + strcpy(config->port, cmd); + memcpy(&config->mycalls[0], axcall, AXLEN); + config->nmycalls = 1; + } else + if (config && !strcmp(cmd, "ax25-learn-routes")) + { + /* ax25-learn-routes no|yes: learn digipeater path */ + if (arg) + { + int k = yesno(arg); + + if (k == -1) + { + invalid_arg(cmd, arg); + continue; + } else { + config->ax25_add_route = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "ax25-learn-only-mine")) + { + /* ax25-learn-only-mine no|yes: learn only if addressed to me */ + if (arg) + { + int k = yesno(arg); + + if (k == -1) + { + invalid_arg(cmd, arg); + continue; + } else { + config->ax25_for_me = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "ax25-add-path")) + { + /* ax25-add-path [no|]: add digis if digi-less frame rvd */ + int k = 0; + if (!arg || (arg && yesno(arg) == 0)) + continue; + + config->ax25_add_default = 1; + while (arg && k < AX25_MAX_DIGIS) + { + memcpy(&config->ax25_default_path.fsa_digipeater[k], asc2ax(arg), AXLEN); + arg = get_next_arg(&p); + k++; + } + config->ax25_default_path.fsa_ax25.sax25_ndigis = k; + } else + if (config && !strcmp(cmd, "ax25-more-mycalls")) + { + /* ax25-more-mycalls call1 call2: frames to this calls are for "me", too. */ + if (arg) + { + while(arg && config->nmycalls < AX25_MAXCALLS) + { + axcall = asc2ax(arg); + if (call_is_mycall(config, axcall)) + continue; + memcpy(&config->mycalls[config->nmycalls++], axcall, AXLEN); + arg = get_next_arg(&p); + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "ip-learn-routes")) + { + /* ip-learn-routes no|yes: learn ip routes */ + if (arg) + { + int k = yesno(arg); + + if (k == -1) + { + invalid_arg(cmd, arg); + continue; + } else { + config->ip_add_route = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "irtt")) + { + /* irtt : new routes will get this IRTT in msec */ + if (arg) + { + int k = atoi(arg); + + if (k == 0) + { + invalid_arg(cmd, arg); + continue; + } else { + config->tcp_irtt = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "dg-mtu")) + { + /* dg-mtu : MTU for datagram mode routes (unused) */ + if (arg) + { + int k = atoi(arg); + + if (k == 0) + { + invalid_arg(cmd, arg); + continue; + } else { + config->dg_mtu = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "vc-mtu")) + { + /* vc-mtu : MTU for virtual connect mode routes (unused) */ + if (arg) + { + int k = atoi(arg); + + if (k == 0) + { + invalid_arg(cmd, arg); + continue; + } else { + config->vc_mtu = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "ip-adjust-mode")) + { + /* ip-adjust-mode no|yes: adjust ip-mode? (dg or vc) */ + if (arg) + { + int k = yesno(arg); + + if (k == -1) + { + invalid_arg(cmd, arg); + continue; + } else { + config->ip_adjust_mode = k; + } + } else + missing_arg(cmd); + } else + if (config && !strcmp(cmd, "arp-add")) + { + /* arp-add no|yes: adjust arp table? */ + if (arg) + { + int k = yesno(arg); + + if (k == -1) + { + invalid_arg(cmd, arg); + continue; + } else { + config->ip_add_arp = k; + } + } else + missing_arg(cmd); + } else + if (!strcmp(cmd, "ax25-maxroutes")) + { + if (arg) + ax25_maxroutes = atoi(arg); + else + missing_arg(cmd); + } else + if (!strcmp(cmd, "ip-maxroutes")) + { + if (arg) + ax25_maxroutes = atoi(arg); + else + missing_arg(cmd); + + } else + fprintf(stderr, "invalid command %s\n", cmd); + } + fclose(fp); + + load_ports(); + load_listeners(); + + reload = 0; +} + +void reload_config(void) +{ + config *cfg, *config = Config; + + while(config) + { + cfg = config->next; + free(config); + config = cfg; + } + Config = NULL; + + load_config(); +} + + +/* commands: + --------- + + add ax25