From 17287576555a5c46fa23549e2e5f073660dccb70 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 21 Apr 1999 09:51:03 +0200 Subject: Import ax25-tools 0.0.1 from tarball --- kiss/kissattach.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 kiss/kissattach.c (limited to 'kiss/kissattach.c') diff --git a/kiss/kissattach.c b/kiss/kissattach.c new file mode 100644 index 0000000..149c2bd --- /dev/null +++ b/kiss/kissattach.c @@ -0,0 +1,289 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "../pathnames.h" + +static char *callsign; +static int speed = 0; +static int mtu = 0; +static int logging = FALSE; + +static void terminate(int sig) +{ + if (logging) { + syslog(LOG_INFO, "terminating on SIGTERM\n"); + closelog(); + } + + exit(0); +} + +static int readconfig(char *port) +{ + FILE *fp; + char buffer[90], *s; + int n = 0; + + if ((fp = fopen(CONF_AXPORTS_FILE, "r")) == NULL) { + fprintf(stderr, "kissattach: cannot open axports file\n"); + return FALSE; + } + + while (fgets(buffer, 90, fp) != NULL) { + n++; + + if ((s = strchr(buffer, '\n')) != NULL) + *s = '\0'; + + if (strlen(buffer) > 0 && *buffer == '#') + continue; + + if ((s = strtok(buffer, " \t\r\n")) == NULL) { + fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + return FALSE; + } + + if (strcmp(s, port) != 0) + continue; + + if ((s = strtok(NULL, " \t\r\n")) == NULL) { + fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + return FALSE; + } + + callsign = strdup(s); + + if ((s = strtok(NULL, " \t\r\n")) == NULL) { + fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + return FALSE; + } + + speed = atoi(s); + + if ((s = strtok(NULL, " \t\r\n")) == NULL) { + fprintf(stderr, "kissattach: unable to parse line %d of the axports file\n", n); + return FALSE; + } + + if (mtu == 0) { + if ((mtu = atoi(s)) <= 0) { + fprintf(stderr, "kissattach: invalid paclen setting\n"); + return FALSE; + } + } + + fclose(fp); + + return TRUE; + } + + fclose(fp); + + fprintf(stderr, "kissattach: cannot find port %s in axports\n", port); + + return FALSE; +} + + +static int setifcall(int fd, char *name) +{ + char call[7]; + + if (ax25_aton_entry(name, call) == -1) + return FALSE; + + if (ioctl(fd, SIOCSIFHWADDR, call) != 0) { + close(fd); + perror("kissattach: SIOCSIFHWADDR"); + return FALSE; + } + + return TRUE; +} + + +static int startiface(char *dev, struct hostent *hp) +{ + struct ifreq ifr; + int fd; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("kissattach: socket"); + return FALSE; + } + + strcpy(ifr.ifr_name, dev); + + if (hp != NULL) { + ifr.ifr_addr.sa_family = AF_INET; + + ifr.ifr_addr.sa_data[0] = 0; + ifr.ifr_addr.sa_data[1] = 0; + ifr.ifr_addr.sa_data[2] = hp->h_addr_list[0][0]; + ifr.ifr_addr.sa_data[3] = hp->h_addr_list[0][1]; + ifr.ifr_addr.sa_data[4] = hp->h_addr_list[0][2]; + ifr.ifr_addr.sa_data[5] = hp->h_addr_list[0][3]; + ifr.ifr_addr.sa_data[6] = 0; + + if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { + perror("kissattach: SIOCSIFADDR"); + return FALSE; + } + } + + ifr.ifr_mtu = mtu; + + if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { + perror("kissattach: SIOCSIFMTU"); + return FALSE; + } + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + perror("kissattach: SIOCGIFFLAGS"); + return FALSE; + } + + ifr.ifr_flags &= IFF_NOARP; + ifr.ifr_flags |= IFF_UP; + ifr.ifr_flags |= IFF_RUNNING; + + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + perror("kissattach: SIOCSIFFLAGS"); + return FALSE; + } + + close(fd); + + return TRUE; +} + + +int main(int argc, char *argv[]) +{ + int fd; + int disc = N_AX25; + char dev[64]; + int v = 4; + struct hostent *hp = NULL; + + while ((fd = getopt(argc, argv, "i:lm:v")) != -1) { + switch (fd) { + case 'i': + if ((hp = gethostbyname(optarg)) == NULL) { + fprintf(stderr, "kissattach: invalid internet name/address - %s\n", optarg); + return 1; + } + break; + case 'l': + logging = TRUE; + break; + case 'm': + if ((mtu = atoi(optarg)) <= 0) { + fprintf(stderr, "kissattach: invalid mtu size - %s\n", optarg); + return 1; + } + break; + case 'v': + printf("kissattach: %s\n", VERSION); + return 0; + case ':': + case '?': + fprintf(stderr, "usage: kissattach [-i inetaddr] [-l] [-m mtu] [-v] ttyinterface port\n"); + return 1; + } + } + + if ((argc - optind) != 2) { + fprintf(stderr, "usage: kissattach [-i inetaddr] [-l] [-m mtu] [-v] ttyinterface port\n"); + return 1; + } + + if (tty_is_locked(argv[optind])) { + fprintf(stderr, "kissattach: device %s already in use\n", argv[optind]); + return 1; + } + + if (!readconfig(argv[optind + 1])) + return 1; + + if ((fd = open(argv[optind], O_RDONLY | O_NONBLOCK)) == -1) { + perror("kissattach: open"); + return 1; + } + + if (speed != 0 && !tty_speed(fd, speed)) + return 1; + + if (ioctl(fd, TIOCSETD, &disc) == -1) { + perror("kissattach: TIOCSETD"); + return 1; + } + + if (ioctl(fd, SIOCGIFNAME, dev) == -1) { + perror("kissattach: SIOCGIFNAME"); + return 1; + } + + if (!setifcall(fd, callsign)) + return 1; + + /* Now set the encapsulation */ + if (ioctl(fd, SIOCSIFENCAP, &v) == -1) { + perror("kissattach: SIOCSIFENCAP"); + return 1; + } + + if (!startiface(dev, hp)) + return 1; + + printf("AX.25 port %s bound to device %s\n", argv[optind + 1], dev); + + if (logging) { + openlog("kissattach", LOG_PID, LOG_DAEMON); + syslog(LOG_INFO, "AX.25 port %s bound to device %s\n", argv[optind + 1], dev); + } + + signal(SIGHUP, SIG_IGN); + signal(SIGTERM, terminate); + + /* + * Become a daemon if we can. + */ + if (!daemon_start(FALSE)) { + fprintf(stderr, "kissattach: cannot become a daemon\n"); + return 1; + } + + if (!tty_lock(argv[optind])) + return 1; + + while (1) + sleep(10000); + + /* NOT REACHED */ + return 0; +} -- cgit v1.2.3