mirror of
https://github.com/markqvist/tncattach.git
synced 2025-06-24 12:35:18 -04:00
Compare commits
26 Commits
ec9f6365d7
...
c6585c242e
Author | SHA1 | Date | |
---|---|---|---|
|
c6585c242e | ||
|
1c2b9858c6 | ||
|
005373b582 | ||
|
05bc0ae6ad | ||
|
3227ed232b | ||
|
64c18e6050 | ||
|
40f882489d | ||
|
6635336405 | ||
|
6c83aa468b | ||
|
da4fea1bc6 | ||
|
877bfcc0b0 | ||
|
439bce5e4d | ||
|
5223391129 | ||
|
1bb7da2d67 | ||
|
4aedc35f33 | ||
|
4c1cd7659d | ||
|
0d5ed2b5ad | ||
|
111621791a | ||
|
b74256bccc | ||
|
0d24b3a128 | ||
|
9272a16e52 | ||
|
d2bade8dcc | ||
|
175bb90a68 | ||
|
7024d05d0e | ||
|
f61b4a0193 | ||
|
4b0e006139 |
181
TAP.c
181
TAP.c
@ -1,18 +1,12 @@
|
|||||||
#include "TAP.h"
|
#include "TAP.h"
|
||||||
|
|
||||||
// Needed for in6_ifreq
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <linux/ipv6.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
char tap_name[IFNAMSIZ];
|
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_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;
|
||||||
@ -20,66 +14,10 @@ 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 char* ipv6_addr;
|
||||||
|
extern long ipv6_prefixLen;
|
||||||
extern char* netmask;
|
extern char* netmask;
|
||||||
extern void cleanup();
|
extern void cleanup();
|
||||||
|
|
||||||
#include<stdlib.h>
|
|
||||||
|
|
||||||
void localRand(struct in6_addr* ll_a)
|
|
||||||
{
|
|
||||||
for(int i = 2; i < 16; i++)
|
|
||||||
{
|
|
||||||
ll_a->s6_addr[i] = rand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include<time.h>
|
|
||||||
|
|
||||||
// TODO: Allow optional-arg for case where we must also generate the hwaddr
|
|
||||||
// (this would be the case whereby we are running without `--ethernet`)
|
|
||||||
struct in6_addr generateLinkLocal(char* interfaceName)
|
|
||||||
{
|
|
||||||
time_t t = time(NULL);
|
|
||||||
srand(t);
|
|
||||||
|
|
||||||
struct in6_addr ll_a;
|
|
||||||
memset(&ll_a, 0, sizeof(struct in6_addr));
|
|
||||||
ll_a.s6_addr[0] = 0xfe;
|
|
||||||
ll_a.s6_addr[1] = 0x80;
|
|
||||||
|
|
||||||
// TODO: Set the rest here
|
|
||||||
|
|
||||||
// TODO: Loop till we generate an address NOT in use
|
|
||||||
// (TODO, should not matter, link-local is interface scoped)
|
|
||||||
// TODO: Should tie it to mac address because of uniqueness
|
|
||||||
// on the lan it shall attach to (over lora)
|
|
||||||
localRand(&ll_a);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int dummySock = socket(AF_PACKET, SOCK_PACKET, 0);
|
|
||||||
if(dummySock < 0)
|
|
||||||
{
|
|
||||||
printf("Failed to open configuration socket in order to generate link-local address\n");
|
|
||||||
close(dummySock);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ifreq reqParams;
|
|
||||||
memset(&reqParams, 0, sizeof(reqParams));
|
|
||||||
strcpy(reqParams.ifr_name, interfaceName);
|
|
||||||
|
|
||||||
if(ioctl(dummySock, SIOCGIFHWADDR, &reqParams) < 0)
|
|
||||||
{
|
|
||||||
printf("Failed to fetch hardware address Failed to open configuration socket in order to generate link-local address\n");
|
|
||||||
close(dummySock);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ll_a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trySixSet
|
void trySixSet
|
||||||
(
|
(
|
||||||
@ -99,35 +37,40 @@ void trySixSet
|
|||||||
interfaceIndex
|
interfaceIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
int dummySock = socket(AF_INET6, SOCK_DGRAM, 0);
|
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;
|
struct in6_ifreq paramReq;
|
||||||
memset(¶mReq, 0, sizeof(struct in6_ifreq));
|
memset(¶mReq, 0, sizeof(struct in6_ifreq));
|
||||||
paramReq.ifr6_ifindex = interfaceIndex;
|
paramReq.ifr6_ifindex = interfaceIndex;
|
||||||
printf("paramReq.ifr6_ifindex: %d\n", paramReq.ifr6_ifindex);
|
|
||||||
paramReq.ifr6_prefixlen = prefixLen;
|
paramReq.ifr6_prefixlen = prefixLen;
|
||||||
paramReq.ifr6_addr = address;
|
paramReq.ifr6_addr = address;
|
||||||
|
|
||||||
|
|
||||||
|
// Try add the address
|
||||||
if(ioctl(dummySock, SIOCSIFADDR, ¶mReq) < 0)
|
if(ioctl(inet6, SIOCSIFADDR, ¶mReq) < 0)
|
||||||
{
|
{
|
||||||
// perror("Fokop");
|
printf
|
||||||
printf("Fokop\n");
|
(
|
||||||
|
"There was an errror assigning address '%s/%d' to if_index %d\n",
|
||||||
|
ip_str,
|
||||||
|
prefixLen,
|
||||||
|
interfaceIndex
|
||||||
|
);
|
||||||
cleanup();
|
cleanup();
|
||||||
close(dummySock);
|
close(inet6);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Sucessfully applied IPv6 configuration");
|
printf("Address '%s/%d' added\n", ip_str, prefixLen);
|
||||||
close(dummySock);
|
close(inet6);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include<string.h>
|
|
||||||
|
|
||||||
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);
|
||||||
@ -159,17 +102,9 @@ int open_tap(void) {
|
|||||||
strcpy(if_name, ifr.ifr_name);
|
strcpy(if_name, ifr.ifr_name);
|
||||||
|
|
||||||
|
|
||||||
int inet = socket(set_ipv4 ? AF_INET : AF_INET6, SOCK_DGRAM, 0);
|
int inet = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
printf("inet fd: %d\n", inet);
|
|
||||||
printf("tun/tap handle fd: %d\n", fd);
|
|
||||||
printf("set_ipv4: %d\n", set_ipv4);
|
|
||||||
printf("set_ipv6: %d\n", set_ipv6);
|
|
||||||
|
|
||||||
// inet=fd;
|
|
||||||
if (inet == -1) {
|
if (inet == -1) {
|
||||||
char err[100];
|
perror("Could not open control socket");
|
||||||
sprintf(err, "Could not open %s socket", set_ipv4 ? "AF_INET" : "AF_INET6");
|
|
||||||
perror(err);
|
|
||||||
cleanup();
|
cleanup();
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
@ -306,64 +241,52 @@ int open_tap(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(set_ipv6) {
|
if(set_ipv6 || set_linklocal)
|
||||||
printf("TODO: Implement set ipv6\n");
|
{
|
||||||
|
|
||||||
// Firstly, obtain the interface index by `ifr_name`
|
// Firstly, obtain the interface index by `ifr_name`
|
||||||
int dummySock = socket(AF_INET6, SOCK_DGRAM, 0);
|
int inet6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if(ioctl(dummySock, SIOCGIFINDEX, &ifr) < 0)
|
if(inet6 < 0)
|
||||||
{
|
{
|
||||||
printf("Could not get interface index for interface '%s'\n", ifr.ifr_name);
|
printf("Error opening control socket for adding IPv6 address to interface\n");
|
||||||
close(dummySock);
|
cleanup();
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char* ipPart = strtok(ipv6_addr, "/");
|
|
||||||
char* prefixPart_s = strtok(NULL, "/");
|
|
||||||
printf("ip part: %s\n", ipPart);
|
|
||||||
|
|
||||||
if(!prefixPart_s)
|
|
||||||
{
|
|
||||||
perror("No prefix length was provided"); // TODO: Move logic into arg parsing
|
|
||||||
close(dummySock);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("prefix part: %s\n", prefixPart_s);
|
|
||||||
|
|
||||||
long prefixLen_l = strtol(prefixPart_s, NULL, 10); // TODO: Add handling here for errors (using errno)
|
|
||||||
|
|
||||||
|
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
|
// Convert ASCII IPv6 address to ABI structure
|
||||||
struct in6_addr six_addr_itself;
|
struct in6_addr six_addr_itself;
|
||||||
memset(&six_addr_itself, 0, sizeof(struct in6_addr));
|
memset(&six_addr_itself, 0, sizeof(struct in6_addr));
|
||||||
if(inet_pton(AF_INET6, ipv6_addr, &six_addr_itself) < 0)
|
if(inet_pton(AF_INET6, ipv6_addr, &six_addr_itself) < 0)
|
||||||
{
|
{
|
||||||
printf("Error parsing IPv6 address '%s'", ipv6_addr);
|
printf("Error parsing IPv6 address '%s'\n", ipv6_addr);
|
||||||
close(dummySock);
|
close(inet6);
|
||||||
|
cleanup();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose stratergy for generating link-local address
|
|
||||||
if(device_type == IF_TAP)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add link-local address
|
|
||||||
trySixSet(ifr.ifr_ifindex, generateLinkLocal(if_name), 64);
|
|
||||||
|
|
||||||
// Add user's requested address
|
// Add user's requested address
|
||||||
trySixSet(ifr.ifr_ifindex, six_addr_itself, prefixLen_l);
|
trySixSet(ifr.ifr_ifindex, six_addr_itself, ipv6_prefixLen);
|
||||||
|
|
||||||
// FIXME: Allow the ipv6 to be empty and just do link-local
|
close(inet6);
|
||||||
|
|
||||||
printf("IPv6 settings SHOULD be done now\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
71
tncattach.c
71
tncattach.c
@ -35,12 +35,14 @@ bool noup = false;
|
|||||||
bool daemonize = false;
|
bool daemonize = false;
|
||||||
bool set_ipv4 = false;
|
bool set_ipv4 = false;
|
||||||
bool set_ipv6 = 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;
|
char* ipv6_addr;
|
||||||
|
long ipv6_prefixLen;
|
||||||
|
|
||||||
char* tcp_host;
|
char* tcp_host;
|
||||||
int tcp_port;
|
int tcp_port;
|
||||||
@ -273,15 +275,16 @@ static struct argp_option options[] = {
|
|||||||
{ "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},
|
||||||
{ "ipv6", '6', "IP6_ADDRESS", 0, "Configure an IPv6 address on interface", 4},
|
{ "ipv6", '6', "IP6_ADDRESS", 0, "Configure an IPv6 address on interface", 4},
|
||||||
{ "noipv6", 'n', 0, 0, "Filter IPv6 traffic from reaching TNC", 5},
|
{ "ll", 'l', 0, 0, "Add a link-local Ipv6 address", 5},
|
||||||
{ "noup", 1, 0, 0, "Only create interface, don't bring it up", 6},
|
{ "noipv6", 'n', 0, 0, "Filter IPv6 traffic from reaching TNC", 6},
|
||||||
{ "kisstcp", 'T', 0, 0, "Use KISS over TCP instead of serial port", 7},
|
{ "noup", 1, 0, 0, "Only create interface, don't bring it up", 7},
|
||||||
{ "tcphost", 'H', "TCP_HOST", 0, "Host to connect to when using KISS over TCP", 8},
|
{ "kisstcp", 'T', 0, 0, "Use KISS over TCP instead of serial port", 8},
|
||||||
{ "tcpport", 'P', "TCP_PORT", 0, "TCP port when using KISS over TCP", 9},
|
{ "tcphost", 'H', "TCP_HOST", 0, "Host to connect to when using KISS over TCP", 9},
|
||||||
{ "interval", 't', "SECONDS", 0, "Maximum interval between station identifications", 10},
|
{ "tcpport", 'P', "TCP_PORT", 0, "TCP port when using KISS over TCP", 10},
|
||||||
{ "id", 's', "CALLSIGN", 0, "Station identification data", 11},
|
{ "interval", 't', "SECONDS", 0, "Maximum interval between station identifications", 11},
|
||||||
{ "daemon", 'd', 0, 0, "Run tncattach as a daemon", 12},
|
{ "id", 's', "CALLSIGN", 0, "Station identification data", 12},
|
||||||
{ "verbose", 'v', 0, 0, "Enable verbose output", 13},
|
{ "daemon", 'd', 0, 0, "Run tncattach as a daemon", 13},
|
||||||
|
{ "verbose", 'v', 0, 0, "Enable verbose output", 14},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,6 +305,7 @@ struct arguments {
|
|||||||
bool set_ipv4;
|
bool set_ipv4;
|
||||||
bool set_netmask;
|
bool set_netmask;
|
||||||
bool set_ipv6;
|
bool set_ipv6;
|
||||||
|
bool link_local_v6;
|
||||||
bool set_netmask_v6;
|
bool set_netmask_v6;
|
||||||
bool noipv6;
|
bool noipv6;
|
||||||
bool noup;
|
bool noup;
|
||||||
@ -328,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':
|
||||||
@ -479,13 +490,46 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
perror("Sorry, but you had noipv6 set yet want to use ipv6?\n");
|
perror("Sorry, but you had noipv6 set yet want to use ipv6?\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
arguments->ipv6 = arg;
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
arguments->ipv6 = ipPart_s;
|
||||||
|
|
||||||
arguments->set_ipv6 = true;
|
arguments->set_ipv6 = true;
|
||||||
|
|
||||||
// Save to the global for other modules to access it
|
// Copy across global IPv6 address
|
||||||
ipv6_addr = malloc(strlen(arguments->ipv6)+1);
|
ipv6_addr = malloc(strlen(arguments->ipv6)+1);
|
||||||
strcpy(ipv6_addr, arguments->ipv6);
|
strcpy(ipv6_addr, arguments->ipv6);
|
||||||
printf("v6 now: %s\n", ipv6_addr);
|
|
||||||
|
// 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;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -586,6 +630,7 @@ int main(int argc, char **argv) {
|
|||||||
arguments.set_ipv4 = false;
|
arguments.set_ipv4 = false;
|
||||||
arguments.set_netmask = false;
|
arguments.set_netmask = false;
|
||||||
arguments.set_ipv6 = false;
|
arguments.set_ipv6 = false;
|
||||||
|
arguments.link_local_v6 = false;
|
||||||
arguments.set_netmask_v6 = false;
|
arguments.set_netmask_v6 = false;
|
||||||
arguments.noipv6 = false;
|
arguments.noipv6 = false;
|
||||||
arguments.daemon = false;
|
arguments.daemon = false;
|
||||||
@ -661,4 +706,4 @@ int main(int argc, char **argv) {
|
|||||||
read_loop();
|
read_loop();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user