aboutsummaryrefslogtreecommitdiffstats
path: root/src/kissattach.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kissattach.c')
-rw-r--r--src/kissattach.c137
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;
+}