diff options
Diffstat (limited to 'src/kissattach.c')
-rw-r--r-- | src/kissattach.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/kissattach.c b/src/kissattach.c new file mode 100644 index 0000000..74d4efb --- /dev/null +++ b/src/kissattach.c @@ -0,0 +1,137 @@ +// Taken from ax25-tools 0.0.10-rc4 kissattach.c +// SPDX-License-Identifier: GPL-2.0-only +#include <stdio.h> +#define __USE_XOPEN +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <termios.h> +#include <fcntl.h> +#include <signal.h> +#include <ctype.h> +#include <netdb.h> +#include <syslog.h> +#include <errno.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/ioctl.h> + +#include <net/if.h> +#include <netax25/ax25.h> +#include <netrose/rose.h> + +#include <netax25/daemon.h> +#include <netax25/axlib.h> +#include <netax25/ttyutils.h> + + +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("SIOCSIFHWADDR"); + return FALSE; + } + + return TRUE; +} + + +static int startiface(char *dev, int mtu, int allow_broadcast) +{ + struct ifreq ifr; + int fd; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + return FALSE; + } + + strcpy(ifr.ifr_name, dev); + + ifr.ifr_mtu = mtu; + + if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { + perror("SIOCSIFMTU"); + return FALSE; + } + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + perror("SIOCGIFFLAGS"); + return FALSE; + } + + ifr.ifr_flags &= IFF_NOARP; + ifr.ifr_flags |= IFF_UP; + ifr.ifr_flags |= IFF_RUNNING; + if (allow_broadcast) + ifr.ifr_flags |= IFF_BROADCAST; /* samba broadcasts are a pain.. */ + else + ifr.ifr_flags &= ~(IFF_BROADCAST); /* samba broadcasts are a pain.. */ + + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + perror("SIOCSIFFLAGS"); + return FALSE; + } + + close(fd); + + return TRUE; +} + +int32_t kissattach( + char *callsign, + int32_t speed, + int32_t mtu, + char *kttyname, + int32_t allow_broadcast) +{ + int fd; + int disc = N_AX25; + char dev[64]; + + if ((fd = open(kttyname, O_RDONLY | O_NONBLOCK)) == -1) { + perror("open"); + return 0; + } + + if (speed != 0 && !tty_speed(fd, speed)) + return 0; + + if (ioctl(fd, TIOCSETD, &disc) == -1) { + //Error setting line discipline + perror("TIOCSETD"); + fprintf(stderr, "Are you sure you have enabled %s support in the kernel\n", + disc == N_AX25 ? "MKISS" : "6PACK"); + fprintf(stderr, "or, if you made it a module, that the module is loaded?\n"); + return 0; + } + + if (ioctl(fd, SIOCGIFNAME, dev) == -1) { + perror("SIOCGIFNAME"); + return 0; + } + + if (!setifcall(fd, callsign)) + return 0; + + /* Now set the encapsulation */ + int v = 4; + if (ioctl(fd, SIOCSIFENCAP, &v) == -1) { + perror("SIOCSIFENCAP"); + return 0; + } + + /* ax25 ifaces should not really need to have an IP address assigned to */ + if (!startiface(dev, mtu, allow_broadcast)) + return 0; + + return 1; +} |