mirror of
https://github.com/markqvist/tncattach.git
synced 2025-07-01 16:05:17 -04:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c910421796 | ||
|
bb4b1917d5 | ||
|
54b4ae14f8 | ||
|
d9b3d2b6ae | ||
|
bb9ff10158 | ||
|
5129dda626 | ||
|
b4a80a1e7a | ||
|
8944821ba8 | ||
|
ef700b3244 | ||
|
015f8a73fb | ||
|
5bdc5d5ccc |
@ -133,4 +133,11 @@ On some versions of Raspbian (and probably other operating systems), the DHCP cl
|
|||||||
# of /etc/dhcpcd.conf to prevent dhcpcd from changing MTU
|
# of /etc/dhcpcd.conf to prevent dhcpcd from changing MTU
|
||||||
|
|
||||||
denyinterfaces tnc0
|
denyinterfaces tnc0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Support tncattach development
|
||||||
|
You can help support the continued development of open, free and private communications systems by donating via one of the following channels:
|
||||||
|
|
||||||
|
- Ethereum: 0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
|
||||||
|
- Bitcoin: 3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq
|
||||||
|
- Ko-Fi: https://ko-fi.com/markqvist
|
||||||
|
110
TAP.c
110
TAP.c
@ -5,15 +5,72 @@ char tap_name[IFNAMSIZ];
|
|||||||
extern bool verbose;
|
extern bool verbose;
|
||||||
extern bool noipv6;
|
extern bool noipv6;
|
||||||
extern bool set_ipv4;
|
extern bool set_ipv4;
|
||||||
|
extern bool set_ipv6;
|
||||||
|
extern bool set_linklocal;
|
||||||
extern bool set_netmask;
|
extern bool set_netmask;
|
||||||
extern bool noup;
|
extern bool noup;
|
||||||
extern int mtu;
|
extern int mtu;
|
||||||
extern int device_type;
|
extern int device_type;
|
||||||
extern char if_name[IFNAMSIZ];
|
extern char if_name[IFNAMSIZ];
|
||||||
extern char* ipv4_addr;
|
extern char* ipv4_addr;
|
||||||
|
extern char* ipv6_addr;
|
||||||
|
extern long ipv6_prefixLen;
|
||||||
extern char* netmask;
|
extern char* netmask;
|
||||||
extern void cleanup();
|
extern void cleanup();
|
||||||
|
|
||||||
|
|
||||||
|
void trySixSet
|
||||||
|
(
|
||||||
|
int interfaceIndex,
|
||||||
|
struct in6_addr address,
|
||||||
|
int prefixLen
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char ip_str[INET6_ADDRSTRLEN+1];
|
||||||
|
inet_ntop(AF_INET6, &address, ip_str, INET6_ADDRSTRLEN+1);
|
||||||
|
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"Adding IPv6 address of '%s/%d' to interface at if_index %d\n",
|
||||||
|
ip_str,
|
||||||
|
prefixLen,
|
||||||
|
interfaceIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
int inet6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
if(inet6 < 0)
|
||||||
|
{
|
||||||
|
printf("Error opening control socket for adding IPv6 address to interface\n");
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct in6_ifreq paramReq;
|
||||||
|
memset(¶mReq, 0, sizeof(struct in6_ifreq));
|
||||||
|
paramReq.ifr6_ifindex = interfaceIndex;
|
||||||
|
paramReq.ifr6_prefixlen = prefixLen;
|
||||||
|
paramReq.ifr6_addr = address;
|
||||||
|
|
||||||
|
|
||||||
|
// Try add the address
|
||||||
|
if(ioctl(inet6, SIOCSIFADDR, ¶mReq) < 0)
|
||||||
|
{
|
||||||
|
printf
|
||||||
|
(
|
||||||
|
"There was an errror assigning address '%s/%d' to if_index %d\n",
|
||||||
|
ip_str,
|
||||||
|
prefixLen,
|
||||||
|
interfaceIndex
|
||||||
|
);
|
||||||
|
cleanup();
|
||||||
|
close(inet6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Address '%s/%d' added\n", ip_str, prefixLen);
|
||||||
|
close(inet6);
|
||||||
|
}
|
||||||
|
|
||||||
int open_tap(void) {
|
int open_tap(void) {
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int fd = open("/dev/net/tun", O_RDWR);
|
int fd = open("/dev/net/tun", O_RDWR);
|
||||||
@ -43,10 +100,11 @@ int open_tap(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
strcpy(if_name, ifr.ifr_name);
|
strcpy(if_name, ifr.ifr_name);
|
||||||
|
|
||||||
|
|
||||||
int inet = socket(AF_INET, SOCK_DGRAM, 0);
|
int inet = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (inet == -1) {
|
if (inet == -1) {
|
||||||
perror("Could not open AF_INET socket");
|
perror("Could not open control socket");
|
||||||
cleanup();
|
cleanup();
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
@ -182,6 +240,54 @@ int open_tap(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(set_ipv6 || set_linklocal)
|
||||||
|
{
|
||||||
|
// Firstly, obtain the interface index by `ifr_name`
|
||||||
|
int inet6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
if(inet6 < 0)
|
||||||
|
{
|
||||||
|
printf("Error opening control socket for adding IPv6 address to interface\n");
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ioctl(inet6, SIOCGIFINDEX, &ifr) < 0)
|
||||||
|
{
|
||||||
|
printf("Could not get interface index for interface '%s'\n", ifr.ifr_name);
|
||||||
|
close(inet6);
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if link-local was NOT requested and interface
|
||||||
|
// has been up'd -> then kernel would have added
|
||||||
|
// a link-local already, this removes it
|
||||||
|
if(!set_linklocal & !noup)
|
||||||
|
{
|
||||||
|
// TODO: Get all addresses that start with fe80
|
||||||
|
}
|
||||||
|
// Else it could have been no-up; hence you will have to remove
|
||||||
|
// the link-local yourself
|
||||||
|
// Other else is link-local was requested, then we don't care (whether
|
||||||
|
// up'd or not as it will inevitably be added by the kernel)
|
||||||
|
|
||||||
|
// Convert ASCII IPv6 address to ABI structure
|
||||||
|
struct in6_addr six_addr_itself;
|
||||||
|
memset(&six_addr_itself, 0, sizeof(struct in6_addr));
|
||||||
|
if(inet_pton(AF_INET6, ipv6_addr, &six_addr_itself) < 0)
|
||||||
|
{
|
||||||
|
printf("Error parsing IPv6 address '%s'\n", ipv6_addr);
|
||||||
|
close(inet6);
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add user's requested address
|
||||||
|
trySixSet(ifr.ifr_ifindex, six_addr_itself, ipv6_prefixLen);
|
||||||
|
|
||||||
|
close(inet6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,4 +301,4 @@ int open_tap(void) {
|
|||||||
|
|
||||||
int close_tap(int tap_fd) {
|
int close_tap(int tap_fd) {
|
||||||
return close(tap_fd);
|
return close(tap_fd);
|
||||||
}
|
}
|
||||||
|
1
TAP.h
1
TAP.h
@ -9,6 +9,7 @@
|
|||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <linux/ipv6.h>
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
|
|
||||||
int open_tap(void);
|
int open_tap(void);
|
||||||
|
25
makefile
25
makefile
@ -1,26 +1,35 @@
|
|||||||
.DEFAULT_GOAL := all
|
.DEFAULT_GOAL := all
|
||||||
.PHONY: all clean install uninstall tncattach
|
.PHONY: all clean install uninstall tncattach
|
||||||
|
|
||||||
compiler = gcc
|
RM ?= rm
|
||||||
flags = -Wall -std=gnu11 -static-libgcc
|
INSTALL ?= install
|
||||||
|
CC ?= gcc
|
||||||
|
CFLAGS ?= -Wall -std=gnu11 -static-libgcc
|
||||||
|
LDFLAGS ?=
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
|
||||||
all: tncattach
|
all: tncattach
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@echo "Cleaning tncattach build..."
|
@echo "Cleaning tncattach build..."
|
||||||
@rm -f tncattach
|
$(RM) -f tncattach
|
||||||
|
|
||||||
tncattach:
|
tncattach:
|
||||||
@echo "Making tncattach..."
|
@echo "Making tncattach..."
|
||||||
@echo "Compiling with: ${compiler}"
|
@echo "Compiling with: $(CC)"
|
||||||
${compiler} ${flags} tncattach.c Serial.c TCP.c KISS.c TAP.c -o tncattach -Wall
|
$(CC) $(CFLAGS) $(LDFLAGS) tncattach.c Serial.c TCP.c KISS.c TAP.c -o tncattach
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@echo "Installing tncattach..."
|
@echo "Installing tncattach..."
|
||||||
chmod a+x tncattach
|
$(INSTALL) -d $(DESTDIR)/$(PREFIX)/bin
|
||||||
cp ./tncattach /usr/local/sbin/
|
$(INSTALL) -Dm755 tncattach $(DESTDIR)/$(PREFIX)/bin/tncattach
|
||||||
|
@echo "Installing man page..."
|
||||||
|
gzip -9 tncattach.8
|
||||||
|
$(INSTALL) -d $(DESTDIR)/$(PREFIX)/share/man/man8
|
||||||
|
$(INSTALL) -Dm644 tncattach.8.gz $(DESTDIR)/$(PREFIX)/share/man/man8/tncattach.8.gz
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@echo "Uninstalling tncattach"
|
@echo "Uninstalling tncattach"
|
||||||
rm /usr/local/sbin/tncattach
|
$(RM) $(DESTDIR)/$(PREFIX)/bin/tncattach
|
||||||
|
$(RM) $(DESTDIR)/$(PREFIX)/share/man/man8/tncattach.8.gz
|
||||||
|
165
tncattach.8
Normal file
165
tncattach.8
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
.TH tncattach 8 "September 12, 2020"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
.
|
||||||
|
.
|
||||||
|
tncattach \- Attach TNC devices as system network interfaces
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.
|
||||||
|
.
|
||||||
|
\f[B]tncattach\f[R] [OPTION...] port baudrate
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Attach KISS TNC devices as network interfaces in Linux. This program allows you to attach TNCs or any KISS-compatible device as a network interface. This program does not need any kernel modules, and has no external dependencies outside the standard Linux and GNU C libraries.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-m, \-\-mtu=MTU
|
||||||
|
.
|
||||||
|
Specify interface MTU
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-e, \-\-ethernet
|
||||||
|
Create a full ethernet device
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-i, \-\-ipv4=IP_ADDRESS
|
||||||
|
Configure an IPv4 address on interface
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-n, \-\-noipv6
|
||||||
|
Filter IPv6 traffic from reaching TNC
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-\-noup
|
||||||
|
Only create interface, don't bring it up
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-T, \-\-kisstcp
|
||||||
|
Use KISS over TCP instead of serial port
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-H, \-\-tcphost=TCP_HOST
|
||||||
|
Host to connect to when using KISS over TCP
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-P, \-\-tcpport=TCP_PORT
|
||||||
|
TCP port when using KISS over TCP
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-t, \-\-interval=SECONDS
|
||||||
|
Maximum interval between station identifications
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B \-s, \-\-id=CALLSIGN
|
||||||
|
Station identification data
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-d, \-\-daemon
|
||||||
|
Run tncattach as a daemon
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-v, \-\-verbose
|
||||||
|
Enable verbose output
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-?, \-\-help
|
||||||
|
Show help
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-\-usage
|
||||||
|
Give a short usage message
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BI \-V, \-\-version
|
||||||
|
Print program version
|
||||||
|
.
|
||||||
|
.
|
||||||
|
|
||||||
|
.SH USAGE
|
||||||
|
The program supports attaching TNCs as point-to-point tunnel devices, or generic ethernet devices. The ethernet mode is suitable for point-to-multipoint setups, and can be enabled with the corresponding command line switch. If you only need point-to-point links, it is advisable to just use the standard point-to-point mode, since it doesn't incur the ethernet header overhead on each packet.
|
||||||
|
.P
|
||||||
|
If you want to connect to a virtual KISS TNC over a TCP connection, you can use the -T option, along with the -H and -P options to specify the host and port.
|
||||||
|
.P
|
||||||
|
Additionally, it is worth noting that tncattach can filter out IPv6 packets from reaching the TNC. Most operating systems attempts to autoconfigure IPv6 when an interface is brought up, which results in a substantial amount of IPv6 traffic generated by router solicitations and similar, which is usually unwanted for packet radio links and similar.
|
||||||
|
.P
|
||||||
|
If you intend to use tncattach on a system with mDNS services enabled (avahi-daemon, for example), you may want to consider modifying your mDNS setup to exclude TNC interfaces, or turning it off entirely, since it will generate a lot of traffic that might be unwanted.
|
||||||
|
|
||||||
|
.SH STATION IDENTIFICATION
|
||||||
|
|
||||||
|
You can configure tncattach to automatically transmit station identification beacons according to a given interval, by using the --id and --interval options. Identification will be transmitted as raw data frames with whatever content has been specified in the --id option. Useful for amateur radio use, or other areas where station identification is necessary.
|
||||||
|
.P
|
||||||
|
Identification beacons will be transmitted when:
|
||||||
|
.P
|
||||||
|
.IP
|
||||||
|
There is outgoing data to send, and the specified interval has elapsed.
|
||||||
|
.IP
|
||||||
|
The specified interval elapses, and data has been sent since the last ID beacon.
|
||||||
|
.IP
|
||||||
|
The program exits, if any data frames have been transmitted since the last ID beacon.
|
||||||
|
.P
|
||||||
|
The above methodology should comply with station identification rules for amateur radio in most parts of the world, and complies with US Part 97 rules.
|
||||||
|
|
||||||
|
.SH EXAMPLES
|
||||||
|
.
|
||||||
|
Create an ethernet device with a USB-connected TNC, set the MTU, filter IPv6 traffic, and set an IPv4 address:
|
||||||
|
.IP
|
||||||
|
sudo tncattach /dev/ttyUSB0 115200 --ethernet --mtu 576 --noipv6 --ipv4 10.92.0.10/24
|
||||||
|
.P
|
||||||
|
Create an ethernet device with a TCP-connected TNC, set the MTU, filter IPv6 traffic, and set an IPv4 address:
|
||||||
|
.IP
|
||||||
|
sudo tncattach -T -H localhost -P 8001 --ethernet --mtu 576 --noipv6 --ipv4 10.92.0.10/24
|
||||||
|
.P
|
||||||
|
You can interact with the interface like any other using the ip or ifconfig utilities.
|
||||||
|
.p
|
||||||
|
Check interface is running:
|
||||||
|
.P
|
||||||
|
# ifconfig
|
||||||
|
.br
|
||||||
|
tnc0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 400
|
||||||
|
.br
|
||||||
|
inet 10.93.0.1 netmask 255.255.255.255 destination 10.93.0.2
|
||||||
|
.br
|
||||||
|
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
|
||||||
|
.br
|
||||||
|
RX packets 0 bytes 0 (0.0 B)
|
||||||
|
.br
|
||||||
|
RX errors 0 dropped 0 overruns 0 frame 0
|
||||||
|
.br
|
||||||
|
TX packets 0 bytes 0 (0.0 B)
|
||||||
|
.br
|
||||||
|
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||||
|
.P
|
||||||
|
.SH WORTH KNOWING ON RASPBIAN
|
||||||
|
On some versions of Raspbian (and probably other operating systems), the DHCP client daemon dhcpcd interferes with TNC interfaces, by overriding their MTU and trying to auto-configure link-local addresses. You probably don't want this, and it can be disabled by editing the /etc/dhcpcd.conf file, adding a statement telling dhcpcd to ignore your TNC interface:
|
||||||
|
.P
|
||||||
|
# Add the following statement somewhere at the beginning
|
||||||
|
.br
|
||||||
|
# of /etc/dhcpcd.conf to prevent dhcpcd from changing MTU
|
||||||
|
.br
|
||||||
|
denyinterfaces tnc0
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
|
||||||
|
rnodeconfigutil(8)
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
|
||||||
|
Mark Qvist
|
106
tncattach.c
106
tncattach.c
@ -34,11 +34,16 @@ bool noipv6 = false;
|
|||||||
bool noup = false;
|
bool noup = false;
|
||||||
bool daemonize = false;
|
bool daemonize = false;
|
||||||
bool set_ipv4 = false;
|
bool set_ipv4 = false;
|
||||||
|
bool set_ipv6 = false;
|
||||||
|
bool set_linklocal = false;
|
||||||
bool set_netmask = false;
|
bool set_netmask = false;
|
||||||
bool kiss_over_tcp = false;
|
bool kiss_over_tcp = false;
|
||||||
char* ipv4_addr;
|
char* ipv4_addr;
|
||||||
char* netmask;
|
char* netmask;
|
||||||
|
|
||||||
|
char* ipv6_addr;
|
||||||
|
long ipv6_prefixLen;
|
||||||
|
|
||||||
char* tcp_host;
|
char* tcp_host;
|
||||||
int tcp_port;
|
int tcp_port;
|
||||||
|
|
||||||
@ -261,7 +266,7 @@ void read_loop(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *argp_program_version = "tncattach 0.1.8";
|
const char *argp_program_version = "tncattach 0.1.9";
|
||||||
const char *argp_program_bug_address = "<mark@unsigned.io>";
|
const char *argp_program_bug_address = "<mark@unsigned.io>";
|
||||||
static char doc[] = "\r\nAttach TNC devices as system network interfaces\vTo attach the TNC connected to /dev/ttyUSB0 as an ethernet device with an MTU of 512 bytes and assign an IPv4 address, while filtering IPv6 traffic, use:\r\n\r\n\ttncattach /dev/ttyUSB0 115200 -m 512 -e --noipv6 --ipv4 10.0.0.1/24\r\n\r\nStation identification can be performed automatically to comply with Part 97 rules. See the README for a complete description. Use the --id and --interval options, which should commonly be set to your callsign, and 600 seconds.";
|
static char doc[] = "\r\nAttach TNC devices as system network interfaces\vTo attach the TNC connected to /dev/ttyUSB0 as an ethernet device with an MTU of 512 bytes and assign an IPv4 address, while filtering IPv6 traffic, use:\r\n\r\n\ttncattach /dev/ttyUSB0 115200 -m 512 -e --noipv6 --ipv4 10.0.0.1/24\r\n\r\nStation identification can be performed automatically to comply with Part 97 rules. See the README for a complete description. Use the --id and --interval options, which should commonly be set to your callsign, and 600 seconds.";
|
||||||
static char args_doc[] = "port baudrate";
|
static char args_doc[] = "port baudrate";
|
||||||
@ -269,15 +274,17 @@ static struct argp_option options[] = {
|
|||||||
{ "mtu", 'm', "MTU", 0, "Specify interface MTU", 1},
|
{ "mtu", 'm', "MTU", 0, "Specify interface MTU", 1},
|
||||||
{ "ethernet", 'e', 0, 0, "Create a full ethernet device", 2},
|
{ "ethernet", 'e', 0, 0, "Create a full ethernet device", 2},
|
||||||
{ "ipv4", 'i', "IP_ADDRESS", 0, "Configure an IPv4 address on interface", 3},
|
{ "ipv4", 'i', "IP_ADDRESS", 0, "Configure an IPv4 address on interface", 3},
|
||||||
{ "noipv6", 'n', 0, 0, "Filter IPv6 traffic from reaching TNC", 4},
|
{ "ipv6", '6', "IP6_ADDRESS", 0, "Configure an IPv6 address on interface", 4},
|
||||||
{ "noup", 1, 0, 0, "Only create interface, don't bring it up", 5},
|
{ "ll", 'l', 0, 0, "Add a link-local Ipv6 address", 5},
|
||||||
{ "kisstcp", 'T', 0, 0, "Use KISS over TCP instead of serial port", 6},
|
{ "noipv6", 'n', 0, 0, "Filter IPv6 traffic from reaching TNC", 6},
|
||||||
{ "tcphost", 'H', "TCP_HOST", 0, "Host to connect to when using KISS over TCP", 7},
|
{ "noup", 1, 0, 0, "Only create interface, don't bring it up", 7},
|
||||||
{ "tcpport", 'P', "TCP_PORT", 0, "TCP port when using KISS over TCP", 8},
|
{ "kisstcp", 'T', 0, 0, "Use KISS over TCP instead of serial port", 8},
|
||||||
{ "interval", 't', "SECONDS", 0, "Maximum interval between station identifications", 9},
|
{ "tcphost", 'H', "TCP_HOST", 0, "Host to connect to when using KISS over TCP", 9},
|
||||||
{ "id", 's', "CALLSIGN", 0, "Station identification data", 10},
|
{ "tcpport", 'P', "TCP_PORT", 0, "TCP port when using KISS over TCP", 10},
|
||||||
{ "daemon", 'd', 0, 0, "Run tncattach as a daemon", 11},
|
{ "interval", 't', "SECONDS", 0, "Maximum interval between station identifications", 11},
|
||||||
{ "verbose", 'v', 0, 0, "Enable verbose output", 12},
|
{ "id", 's', "CALLSIGN", 0, "Station identification data", 12},
|
||||||
|
{ "daemon", 'd', 0, 0, "Run tncattach as a daemon", 13},
|
||||||
|
{ "verbose", 'v', 0, 0, "Enable verbose output", 14},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -285,6 +292,7 @@ static struct argp_option options[] = {
|
|||||||
struct arguments {
|
struct arguments {
|
||||||
char *args[N_ARGS];
|
char *args[N_ARGS];
|
||||||
char *ipv4;
|
char *ipv4;
|
||||||
|
char *ipv6;
|
||||||
char *id;
|
char *id;
|
||||||
bool valid_id;
|
bool valid_id;
|
||||||
int id_interval;
|
int id_interval;
|
||||||
@ -296,6 +304,9 @@ struct arguments {
|
|||||||
bool verbose;
|
bool verbose;
|
||||||
bool set_ipv4;
|
bool set_ipv4;
|
||||||
bool set_netmask;
|
bool set_netmask;
|
||||||
|
bool set_ipv6;
|
||||||
|
bool link_local_v6;
|
||||||
|
bool set_netmask_v6;
|
||||||
bool noipv6;
|
bool noipv6;
|
||||||
bool noup;
|
bool noup;
|
||||||
bool kiss_over_tcp;
|
bool kiss_over_tcp;
|
||||||
@ -321,6 +332,13 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
printf("Error: Invalid MTU specified\r\n\r\n");
|
printf("Error: Invalid MTU specified\r\n\r\n");
|
||||||
argp_usage(state);
|
argp_usage(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((arguments->set_ipv6 || arguments->link_local_v6) && arguments->mtu < 1280)
|
||||||
|
{
|
||||||
|
printf("IPv6 and/or link-local IPv6 was requested, but the MTU provided is lower than 1280\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
@ -466,9 +484,70 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case '6':
|
||||||
|
if(arguments->noipv6)
|
||||||
|
{
|
||||||
|
perror("Sorry, but you had noipv6 set yet want to use ipv6?\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ipPart_s = strtok(arg, "/");
|
||||||
|
char* prefixPart_s = strtok(NULL, "/");
|
||||||
|
printf("ipPart_s: %s\n", ipPart_s);
|
||||||
|
|
||||||
|
if(!prefixPart_s)
|
||||||
|
{
|
||||||
|
printf("No prefix length was provided\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("prefixPart_s: %s\n", prefixPart_s);
|
||||||
|
|
||||||
|
long prefixLen_l = strtol(prefixPart_s, NULL, 10); // TODO: Add handling here for errors (using errno)
|
||||||
|
|
||||||
|
if(prefixLen_l == 0) {
|
||||||
|
printf("Prefix length '%s' is not numeric\n", prefixPart_s);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if(!(prefixLen_l >= 0 && prefixLen_l <= 128))
|
||||||
|
{
|
||||||
|
printf("Prefix length '%s' is not within valid range of 0-128\n", prefixPart_s);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments->ipv6 = ipPart_s;
|
||||||
|
|
||||||
|
arguments->set_ipv6 = true;
|
||||||
|
|
||||||
|
// Copy across global IPv6 address
|
||||||
|
ipv6_addr = malloc(strlen(arguments->ipv6)+1);
|
||||||
|
strcpy(ipv6_addr, arguments->ipv6);
|
||||||
|
|
||||||
|
// Set global IPv6 prefix length
|
||||||
|
ipv6_prefixLen = prefixLen_l;
|
||||||
|
|
||||||
|
printf("MTU was %d, setting to minimum of %d as is required for IPv6\n", arguments->mtu, 1280);
|
||||||
|
arguments->mtu = 1280;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
if(arguments->noipv6)
|
||||||
|
{
|
||||||
|
perror("Sorry, but you had noipv6 set yet want to use ipv6 link-local?\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
arguments->link_local_v6 = true;
|
||||||
|
|
||||||
|
printf("MTU was %d, setting to minimum of %d as is required for IPv6\n", arguments->mtu, 1280);
|
||||||
|
arguments->mtu = 1280;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
arguments->noipv6 = true;
|
arguments->noipv6 = true;
|
||||||
|
if(arguments->set_ipv6)
|
||||||
|
{
|
||||||
|
printf("Requested no IPv6 yet you have set the IPv6 to '%s'\n", arguments->ipv6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -559,11 +638,15 @@ int main(int argc, char **argv) {
|
|||||||
arguments.verbose = false;
|
arguments.verbose = false;
|
||||||
arguments.set_ipv4 = false;
|
arguments.set_ipv4 = false;
|
||||||
arguments.set_netmask = false;
|
arguments.set_netmask = false;
|
||||||
|
arguments.set_ipv6 = false;
|
||||||
|
arguments.link_local_v6 = false;
|
||||||
|
arguments.set_netmask_v6 = false;
|
||||||
arguments.noipv6 = false;
|
arguments.noipv6 = false;
|
||||||
arguments.daemon = false;
|
arguments.daemon = false;
|
||||||
arguments.noup = false;
|
arguments.noup = false;
|
||||||
arguments.id_interval = -1;
|
arguments.id_interval = -1;
|
||||||
arguments.valid_id = false;
|
arguments.valid_id = false;
|
||||||
|
arguments.kiss_over_tcp = false;
|
||||||
|
|
||||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||||
|
|
||||||
@ -585,6 +668,7 @@ int main(int argc, char **argv) {
|
|||||||
if (arguments.noipv6) noipv6 = true;
|
if (arguments.noipv6) noipv6 = true;
|
||||||
if (arguments.set_ipv4) set_ipv4 = true;
|
if (arguments.set_ipv4) set_ipv4 = true;
|
||||||
if (arguments.set_netmask) set_netmask = true;
|
if (arguments.set_netmask) set_netmask = true;
|
||||||
|
if (arguments.set_ipv6) set_ipv6 = true;
|
||||||
if (arguments.noup) noup = true;
|
if (arguments.noup) noup = true;
|
||||||
mtu = arguments.mtu;
|
mtu = arguments.mtu;
|
||||||
|
|
||||||
@ -631,4 +715,4 @@ int main(int argc, char **argv) {
|
|||||||
read_loop();
|
read_loop();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user