From c2beeee94441434655a1b200050548bfe951db74 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Wed, 24 Jun 2020 14:15:49 +0200 Subject: [PATCH] Cleaned up TCP options --- tncattach.c | 981 +++++++++++++++++++++++++++------------------------- 1 file changed, 510 insertions(+), 471 deletions(-) diff --git a/tncattach.c b/tncattach.c index a4d66dc..d46b866 100644 --- a/tncattach.c +++ b/tncattach.c @@ -8,8 +8,8 @@ #include #include "Constants.h" #include "Serial.h" -#include "Tcp.h" #include "KISS.h" +#include "TCP.h" #include "TAP.h" #define BAUDRATE_DEFAULT 0 @@ -35,9 +35,13 @@ bool noup = false; bool daemonize = false; bool set_ipv4 = false; bool set_netmask = false; -bool use_net_kiss = false; +bool kiss_over_tcp = false; char* ipv4_addr; char* netmask; + +char* tcp_host; +int tcp_port; + int mtu; int device_type = IF_TUN; @@ -47,549 +51,584 @@ time_t last_id = 0; bool tx_since_last_id = false; void cleanup(void) { - if (use_net_kiss) { - close_tcp(attached_tnc); - } else { - close_port(attached_tnc); - } - close_tap(attached_if); + if (kiss_over_tcp) { + close_tcp(attached_tnc); + } else { + close_port(attached_tnc); + } + close_tap(attached_if); } bool is_ipv6(uint8_t* frame) { - if (device_type == IF_TAP) { - if (frame[12] == 0x86 && frame[13] == 0xdd) { - return true; - } else { - return false; - } - } else if (device_type == IF_TUN) { - if (frame[2] == 0x86 && frame[3] == 0xdd) { - return true; - } else { - return false; - } - } else { - printf("Error: Unsupported interface type\r\n"); - cleanup(); - exit(1); - } + if (device_type == IF_TAP) { + if (frame[12] == 0x86 && frame[13] == 0xdd) { + return true; + } else { + return false; + } + } else if (device_type == IF_TUN) { + if (frame[2] == 0x86 && frame[3] == 0xdd) { + return true; + } else { + return false; + } + } else { + printf("Error: Unsupported interface type\r\n"); + cleanup(); + exit(1); + } } time_t time_now(void) { - time_t now = time(NULL); - if (now == -1) { - if (daemonize) { - syslog(LOG_ERR, "Could not get system time, exiting now"); - } else { - printf("Error: Could not get system time, exiting now\r\n"); - } - cleanup(); - exit(1); - } else { - return now; - } + time_t now = time(NULL); + if (now == -1) { + if (daemonize) { + syslog(LOG_ERR, "Could not get system time, exiting now"); + } else { + printf("Error: Could not get system time, exiting now\r\n"); + } + cleanup(); + exit(1); + } else { + return now; + } } void transmit_id(void) { - time_t now = time(NULL); - int id_len = strlen(id); - if (verbose) { - if (!daemonize) { - printf("Transmitting %d bytes of identification data on %s: %s\r\n", id_len, if_name, id); - } - } + time_t now = time(NULL); + int id_len = strlen(id); + if (verbose) { + if (!daemonize) { + printf("Transmitting %d bytes of identification data on %s: %s\r\n", id_len, if_name, id); + } + } - uint8_t* id_frame = malloc(strlen(id)); - memcpy(id_frame, id, id_len); - kiss_write_frame(attached_tnc, id_frame, id_len); - last_id = now; - tx_since_last_id = false; + uint8_t* id_frame = malloc(strlen(id)); + memcpy(id_frame, id, id_len); + kiss_write_frame(attached_tnc, id_frame, id_len); + last_id = now; + tx_since_last_id = false; } bool should_id(void) { - if (id_interval != -1) { - time_t now = time_now(); - return now > last_id + id_interval; - } else { - return false; - } + if (id_interval != -1) { + time_t now = time_now(); + return now > last_id + id_interval; + } else { + return false; + } } void signal_handler(int signal) { - if (daemonize) syslog(LOG_NOTICE, "tncattach daemon exiting"); + if (daemonize) syslog(LOG_NOTICE, "tncattach daemon exiting"); - // Transmit final ID if necessary - if (id_interval != -1 && tx_since_last_id) transmit_id(); + // Transmit final ID if necessary + if (id_interval != -1 && tx_since_last_id) transmit_id(); - cleanup(); - exit(0); + cleanup(); + exit(0); } void read_loop(void) { - bool should_continue = true; - int min_frame_size; - if (device_type == IF_TAP) { - min_frame_size = ETHERNET_MIN_FRAME_SIZE; - } else if (device_type == IF_TUN) { - min_frame_size = TUN_MIN_FRAME_SIZE; - } else { - if (daemonize) { - syslog(LOG_ERR, "Unsupported interface type"); - } else { - printf("Error: Unsupported interface type\r\n"); - } + bool should_continue = true; + int min_frame_size; + if (device_type == IF_TAP) { + min_frame_size = ETHERNET_MIN_FRAME_SIZE; + } else if (device_type == IF_TUN) { + min_frame_size = TUN_MIN_FRAME_SIZE; + } else { + if (daemonize) { + syslog(LOG_ERR, "Unsupported interface type"); + } else { + printf("Error: Unsupported interface type\r\n"); + } - cleanup(); - exit(1); - } + cleanup(); + exit(1); + } - int poll_timeout = 1000; - while (should_continue) { - int poll_result = poll(fds, 2, poll_timeout); - if (poll_result != -1) { - if (poll_result == 0) { - // No resources are ready for reading, - // run scheduled tasks instead. - if (id_interval != -1 && tx_since_last_id) { - time_t now = time_now(); - if (now > last_id + id_interval) transmit_id(); - } - } else { - for (int fdi = 0; fdi < N_FDS; fdi++) { - if (fds[fdi].revents != 0) { - // Check for hangup event - if (fds[fdi].revents & POLLHUP) { - if (fdi == IF_FD_INDEX) { - if (daemonize) { - syslog(LOG_ERR, "Received hangup from interface"); - } else { - printf("Received hangup from interface\r\n"); - } - cleanup(); - exit(1); - } - if (fdi == TNC_FD_INDEX) { - if (daemonize) { - syslog(LOG_ERR, "Received hangup from TNC"); - } else { - printf("Received hangup from TNC\r\n"); - } - cleanup(); - exit(1); - } - } + int poll_timeout = 1000; + while (should_continue) { + int poll_result = poll(fds, 2, poll_timeout); + if (poll_result != -1) { + if (poll_result == 0) { + // No resources are ready for reading, + // run scheduled tasks instead. + if (id_interval != -1 && tx_since_last_id) { + time_t now = time_now(); + if (now > last_id + id_interval) transmit_id(); + } + } else { + for (int fdi = 0; fdi < N_FDS; fdi++) { + if (fds[fdi].revents != 0) { + // Check for hangup event + if (fds[fdi].revents & POLLHUP) { + if (fdi == IF_FD_INDEX) { + if (daemonize) { + syslog(LOG_ERR, "Received hangup from interface"); + } else { + printf("Received hangup from interface\r\n"); + } + cleanup(); + exit(1); + } + if (fdi == TNC_FD_INDEX) { + if (daemonize) { + syslog(LOG_ERR, "Received hangup from TNC"); + } else { + printf("Received hangup from TNC\r\n"); + } + cleanup(); + exit(1); + } + } - // Check for error event - if (fds[fdi].revents & POLLERR) { - if (fdi == IF_FD_INDEX) { - if (daemonize) { - syslog(LOG_ERR, "Received error event from interface"); - } else { - perror("Received error event from interface\r\n"); - } - cleanup(); - exit(1); - } - if (fdi == TNC_FD_INDEX) { - if (daemonize) { - syslog(LOG_ERR, "Received error event from TNC"); - } else { - perror("Received error event from TNC\r\n"); - } - cleanup(); - exit(1); - } - } + // Check for error event + if (fds[fdi].revents & POLLERR) { + if (fdi == IF_FD_INDEX) { + if (daemonize) { + syslog(LOG_ERR, "Received error event from interface"); + } else { + perror("Received error event from interface\r\n"); + } + cleanup(); + exit(1); + } + if (fdi == TNC_FD_INDEX) { + if (daemonize) { + syslog(LOG_ERR, "Received error event from TNC"); + } else { + perror("Received error event from TNC\r\n"); + } + cleanup(); + exit(1); + } + } - // If data is ready, read it - if (fds[fdi].revents & POLLIN) { - if (fdi == IF_FD_INDEX) { - int if_len = read(attached_if, if_buffer, sizeof(if_buffer)); - if (if_len > 0) { - if (if_len >= min_frame_size) { - if (!noipv6 || (noipv6 && !is_ipv6(if_buffer))) { + // If data is ready, read it + if (fds[fdi].revents & POLLIN) { + if (fdi == IF_FD_INDEX) { + int if_len = read(attached_if, if_buffer, sizeof(if_buffer)); + if (if_len > 0) { + if (if_len >= min_frame_size) { + if (!noipv6 || (noipv6 && !is_ipv6(if_buffer))) { - int tnc_written = kiss_write_frame(attached_tnc, if_buffer, if_len); - if (verbose && !daemonize) printf("Got %d bytes from interface, wrote %d bytes (KISS-framed and escaped) to TNC\r\n", if_len, tnc_written); - tx_since_last_id = true; + int tnc_written = kiss_write_frame(attached_tnc, if_buffer, if_len); + if (verbose && !daemonize) printf("Got %d bytes from interface, wrote %d bytes (KISS-framed and escaped) to TNC\r\n", if_len, tnc_written); + tx_since_last_id = true; - if (should_id()) transmit_id(); - } - } - } else { - if (daemonize) { - syslog(LOG_ERR, "Could not read from network interface, exiting now"); - } else { - printf("Error: Could not read from network interface, exiting now\r\n"); - } - cleanup(); - exit(1); - } - } + if (should_id()) transmit_id(); + } + } + } else { + if (daemonize) { + syslog(LOG_ERR, "Could not read from network interface, exiting now"); + } else { + printf("Error: Could not read from network interface, exiting now\r\n"); + } + cleanup(); + exit(1); + } + } - if (fdi == TNC_FD_INDEX) { - int tnc_len = read(attached_tnc, serial_buffer, sizeof(serial_buffer)); - if (tnc_len > 0) { - for (int i = 0; i < tnc_len; i++) { - kiss_serial_read(serial_buffer[i]); - } - } else { - if (daemonize) { - syslog(LOG_ERR, "Could not read from TNC, exiting now"); - } else { - printf("Error: Could not read from TNC, exiting now\r\n"); - } + if (fdi == TNC_FD_INDEX) { + int tnc_len = read(attached_tnc, serial_buffer, sizeof(serial_buffer)); + if (tnc_len > 0) { + for (int i = 0; i < tnc_len; i++) { + kiss_serial_read(serial_buffer[i]); + } + } else { + if (daemonize) { + syslog(LOG_ERR, "Could not read from TNC, exiting now"); + } else { + printf("Error: Could not read from TNC, exiting now\r\n"); + } - cleanup(); - exit(1); - } - } - } - } - } - } - } else { - should_continue = false; - } - } - cleanup(); - exit(1); + cleanup(); + exit(1); + } + } + } + } + } + } + } else { + should_continue = false; + } + } + cleanup(); + exit(1); } -const char *argp_program_version = "tncattach 0.1.7"; +const char *argp_program_version = "tncattach 0.1.8"; const char *argp_program_bug_address = ""; 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 baudrateOrPort"; +static char args_doc[] = "port baudrate"; static struct argp_option options[] = { - { "mtu", 'm', "MTU", 0, "Specify interface MTU"}, - { "daemon", 'd', 0, 0, "Run tncattach as a daemon"}, - { "ethernet", 'e', 0, 0, "Create a full ethernet device"}, - { "ipv4", 'i', "IP_ADDRESS", 0, "Configure an IPv4 address on interface"}, - { "noipv6", 'n', 0, 0, "Filter IPv6 traffic from reaching TNC"}, - { "noup", 1, 0, 0, "Only create interface, don't bring it up"}, - { "interval", 't', "SECONDS", 0, "Maximum interval between station identifications"}, - { "id", 's', "CALLSIGN", 0, "Station identification data"}, - { "verbose", 'v', 0, 0, "Enable verbose output"}, - { "kisstcp", 'o', 0, 0, "Does not use Serial but TCP connexion"}, - { 0 } + { "mtu", 'm', "MTU", 0, "Specify interface MTU", 1}, + { "ethernet", 'e', 0, 0, "Create a full ethernet device", 2}, + { "ipv4", 'i', "IP_ADDRESS", 0, "Configure an IPv4 address on interface", 3}, + { "noipv6", 'n', 0, 0, "Filter IPv6 traffic from reaching TNC", 4}, + { "noup", 1, 0, 0, "Only create interface, don't bring it up", 5}, + { "kisstcp", 'T', 0, 0, "Use KISS over TCP instead of serial port", 6}, + { "tcphost", 'H', "TCP_HOST", 0, "Host to connect to when using KISS over TCP", 7}, + { "tcpport", 'P', "TCP_PORT", 0, "TCP port when using KISS over TCP", 8}, + { "interval", 't', "SECONDS", 0, "Maximum interval between station identifications", 9}, + { "id", 's', "CALLSIGN", 0, "Station identification data", 10}, + { "daemon", 'd', 0, 0, "Run tncattach as a daemon", 11}, + { "verbose", 'v', 0, 0, "Enable verbose output", 12}, + { 0 } }; #define N_ARGS 2 struct arguments { - char *args[N_ARGS]; - char *ipv4; - char *id; - bool valid_id; - int id_interval; - int baudrateOrPort; - int mtu; - bool tap; - bool daemon; - bool verbose; - bool set_ipv4; - bool set_netmask; - bool noipv6; - bool noup; - bool useNetKiss; + char *args[N_ARGS]; + char *ipv4; + char *id; + bool valid_id; + int id_interval; + int baudrate; + int tcpport; + int mtu; + bool tap; + bool daemon; + bool verbose; + bool set_ipv4; + bool set_netmask; + bool noipv6; + bool noup; + bool kiss_over_tcp; + bool set_tcp_host; + bool set_tcp_port; }; static error_t parse_opt(int key, char *arg, struct argp_state *state) { - struct arguments *arguments = state->input; + struct arguments *arguments = state->input; - switch (key) { - case 'v': - arguments->verbose = true; + switch (key) { + case 'v': + arguments->verbose = true; + break; + + case 'e': + arguments->tap = true; + break; + + case 'm': + arguments->mtu = atoi(arg); + if (arguments->mtu < MTU_MIN || arguments->mtu > MTU_MAX) { + printf("Error: Invalid MTU specified\r\n\r\n"); + argp_usage(state); + } + break; + + case 't': + arguments->id_interval = atoi(arg); + if (arguments->id_interval < 0) { + printf("Error: Invalid identification interval specified\r\n\r\n"); + argp_usage(state); + } + break; + + case 's': + arguments->id = arg; + if (strlen(arg) < 1 || strlen(arg) > arguments->mtu) { + printf("Error: Invalid identification string specified\r\n\r\n"); + argp_usage(state); + } else { + arguments->valid_id = true; + } + break; + + case 'i': + arguments->ipv4 = arg; + arguments->set_ipv4 = true; + + if (strchr(arg, '/')) { + char* net = strchr(arg, '/'); + int pos = net-arg; + ipv4_addr = (char*)malloc(pos+1); + int mask = atoi(net+1); + strncpy(ipv4_addr, arg, pos); + switch (mask) { + case 0: + netmask = "0.0.0.0"; + break; + case 1: + netmask = "128.0.0.0"; + break; + case 2: + netmask = "192.0.0.0"; + break; + case 3: + netmask = "224.0.0.0"; + break; + case 4: + netmask = "240.0.0.0"; + break; + case 5: + netmask = "248.0.0.0"; + break; + case 6: + netmask = "252.0.0.0"; + break; + case 7: + netmask = "254.0.0.0"; + break; + case 8: + netmask = "255.0.0.0"; + break; + case 9: + netmask = "255.128.0.0"; + break; + case 10: + netmask = "255.192.0.0"; + break; + case 11: + netmask = "255.224.0.0"; + break; + case 12: + netmask = "255.240.0.0"; + break; + case 13: + netmask = "255.248.0.0"; + break; + case 14: + netmask = "255.252.0.0"; + break; + case 15: + netmask = "255.254.0.0"; + break; + case 16: + netmask = "255.255.0.0"; + break; + case 17: + netmask = "255.255.128.0"; + break; + case 18: + netmask = "255.255.192.0"; + break; + case 19: + netmask = "255.255.224.0"; + break; + case 20: + netmask = "255.255.240.0"; + break; + case 21: + netmask = "255.255.248.0"; + break; + case 22: + netmask = "255.255.252.0"; + break; + case 23: + netmask = "255.255.254.0"; + break; + case 24: + netmask = "255.255.255.0"; + break; + case 25: + netmask = "255.255.255.128"; + break; + case 26: + netmask = "255.255.255.192"; + break; + case 27: + netmask = "255.255.255.224"; + break; + case 28: + netmask = "255.255.255.240"; + break; + case 29: + netmask = "255.255.255.248"; + break; + case 30: + netmask = "255.255.255.252"; + break; + case 31: + netmask = "255.255.255.254"; + break; + case 32: + netmask = "255.255.255.255"; + break; + + default: + printf("Error: Invalid subnet mask specified\r\n"); + cleanup(); + exit(1); + } + + arguments->set_netmask = true; + } else { + arguments->set_netmask = false; + ipv4_addr = (char*)malloc(strlen(arg)+1); + strcpy(ipv4_addr, arg); + } + + break; + + case 'n': + arguments->noipv6 = true; + break; + + case 'd': + arguments->daemon = true; + arguments->verbose = false; + break; + + case 'T': + arguments->kiss_over_tcp = true; + break; + + case 'H': + arguments->set_tcp_host = true; + tcp_host = (char*)malloc(strlen(arg)+1); + strcpy(tcp_host, arg); break; - case 'e': - arguments->tap = true; + case 'P': + arguments->set_tcp_port = true; + tcp_port = atoi(arg); break; - case 'm': - arguments->mtu = atoi(arg); - if (arguments->mtu < MTU_MIN || arguments->mtu > MTU_MAX) { - printf("Error: Invalid MTU specified\r\n\r\n"); - argp_usage(state); - } - break; + case 1: + arguments->noup = true; + break; - case 't': - arguments->id_interval = atoi(arg); - if (arguments->id_interval < 0) { - printf("Error: Invalid identification interval specified\r\n\r\n"); - argp_usage(state); - } - break; + case ARGP_KEY_ARG: + // Check if there's now too many text arguments + if (state->arg_num >= N_ARGS) argp_usage(state); - case 's': - arguments->id = arg; - if (strlen(arg) < 1 || strlen(arg) > arguments->mtu) { - printf("Error: Invalid identification string specified\r\n\r\n"); - argp_usage(state); - } else { - arguments->valid_id = true; - } - break; + // If not add to args + arguments->args[state->arg_num] = arg; + break; - case 'i': - arguments->ipv4 = arg; - arguments->set_ipv4 = true; + case ARGP_KEY_END: + // Check if there's too few text arguments + if (!arguments->kiss_over_tcp && state->arg_num < N_ARGS) argp_usage(state); - if (strchr(arg, '/')) { - char* net = strchr(arg, '/'); - int pos = net-arg; - ipv4_addr = (char*)malloc(pos+1); - int mask = atoi(net+1); - strncpy(ipv4_addr, arg, pos); - switch (mask) { - case 0: - netmask = "0.0.0.0"; - break; - case 1: - netmask = "128.0.0.0"; - break; - case 2: - netmask = "192.0.0.0"; - break; - case 3: - netmask = "224.0.0.0"; - break; - case 4: - netmask = "240.0.0.0"; - break; - case 5: - netmask = "248.0.0.0"; - break; - case 6: - netmask = "252.0.0.0"; - break; - case 7: - netmask = "254.0.0.0"; - break; - case 8: - netmask = "255.0.0.0"; - break; - case 9: - netmask = "255.128.0.0"; - break; - case 10: - netmask = "255.192.0.0"; - break; - case 11: - netmask = "255.224.0.0"; - break; - case 12: - netmask = "255.240.0.0"; - break; - case 13: - netmask = "255.248.0.0"; - break; - case 14: - netmask = "255.252.0.0"; - break; - case 15: - netmask = "255.254.0.0"; - break; - case 16: - netmask = "255.255.0.0"; - break; - case 17: - netmask = "255.255.128.0"; - break; - case 18: - netmask = "255.255.192.0"; - break; - case 19: - netmask = "255.255.224.0"; - break; - case 20: - netmask = "255.255.240.0"; - break; - case 21: - netmask = "255.255.248.0"; - break; - case 22: - netmask = "255.255.252.0"; - break; - case 23: - netmask = "255.255.254.0"; - break; - case 24: - netmask = "255.255.255.0"; - break; - case 25: - netmask = "255.255.255.128"; - break; - case 26: - netmask = "255.255.255.192"; - break; - case 27: - netmask = "255.255.255.224"; - break; - case 28: - netmask = "255.255.255.240"; - break; - case 29: - netmask = "255.255.255.248"; - break; - case 30: - netmask = "255.255.255.252"; - break; - case 31: - netmask = "255.255.255.254"; - break; - case 32: - netmask = "255.255.255.255"; - break; + // Check if text arguments were given when + // KISS over TCP was specified + if (arguments->kiss_over_tcp && state->arg_num != 0) argp_usage(state); - default: - printf("Error: Invalid subnet mask specified\r\n"); - cleanup(); - exit(1); - } + break; - arguments->set_netmask = true; - } else { - arguments->set_netmask = false; - ipv4_addr = (char*)malloc(strlen(arg)+1); - strcpy(ipv4_addr, arg); - } + default: + return ARGP_ERR_UNKNOWN; + } - break; - - case 'n': - arguments->noipv6 = true; - break; - - case 'd': - arguments->daemon = true; - arguments->verbose = false; - break; - - case 'o': - arguments->useNetKiss = true; - break; - - case 1: - arguments->noup = true; - break; - - case ARGP_KEY_ARG: - // Check if there's now too many text arguments - if (state->arg_num >= N_ARGS) argp_usage(state); - - // If not add to args - arguments->args[state->arg_num] = arg; - break; - - case ARGP_KEY_END: - // Check if there's too few text arguments - if (state->arg_num < N_ARGS) argp_usage(state); - break; - - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; + return 0; } static void become_daemon() { - pid_t pid; - pid = fork(); + pid_t pid; + pid = fork(); - if (pid < 0) { - perror("Fork failed"); - exit(EXIT_FAILURE); - } + if (pid < 0) { + perror("Fork failed"); + exit(EXIT_FAILURE); + } - if (pid > 0) { - exit(0); - } + if (pid > 0) { + exit(0); + } - if (setsid() < 0) exit(1); + if (setsid() < 0) exit(1); - signal(SIGCHLD, signal_handler); - signal(SIGHUP, signal_handler); + signal(SIGCHLD, signal_handler); + signal(SIGHUP, signal_handler); - pid = fork(); - if (pid < 0) exit(1); - if (pid > 0) exit(0); + pid = fork(); + if (pid < 0) exit(1); + if (pid > 0) exit(0); - umask(0); - chdir("/"); + umask(0); + chdir("/"); - openlog("tncattach", LOG_PID, LOG_DAEMON); + openlog("tncattach", LOG_PID, LOG_DAEMON); } static struct argp argp = {options, parse_opt, args_doc, doc}; int main(int argc, char **argv) { - struct arguments arguments; - signal(SIGINT, signal_handler); + struct arguments arguments; + signal(SIGINT, signal_handler); - arguments.baudrateOrPort = BAUDRATE_DEFAULT; - arguments.mtu = MTU_DEFAULT; - arguments.tap = false; - arguments.verbose = false; - arguments.set_ipv4 = false; - arguments.set_netmask = false; - arguments.noipv6 = false; - arguments.daemon = false; - arguments.noup = false; - arguments.id_interval = -1; - arguments.valid_id = false; + arguments.baudrate = BAUDRATE_DEFAULT; + arguments.mtu = MTU_DEFAULT; + arguments.tap = false; + arguments.verbose = false; + arguments.set_ipv4 = false; + arguments.set_netmask = false; + arguments.noipv6 = false; + arguments.daemon = false; + arguments.noup = false; + arguments.id_interval = -1; + arguments.valid_id = false; - argp_parse(&argp, argc, argv, 0, 0, &arguments); - arguments.baudrateOrPort = atoi(arguments.args[1]); + argp_parse(&argp, argc, argv, 0, 0, &arguments); - if (arguments.daemon) daemonize = true; - if (arguments.verbose) verbose = true; - if (arguments.tap) device_type = IF_TAP; - if (arguments.noipv6) noipv6 = true; - if (arguments.set_ipv4) set_ipv4 = true; - if (arguments.set_netmask) set_netmask = true; - if (arguments.noup) noup = true; - if (arguments.useNetKiss) use_net_kiss = true; - mtu = arguments.mtu; + if (arguments.kiss_over_tcp) kiss_over_tcp = true; - if (arguments.id_interval >= 0) { - if (!arguments.valid_id) { - printf("Error: Periodic identification requested, but no valid indentification data specified\r\n"); - cleanup(); - exit(1); - } else { - id_interval = arguments.id_interval; - id = malloc(strlen(arguments.id)); - strcpy(id, arguments.id); - } - } else if (arguments.valid_id && arguments.id_interval == -1) { - printf("Error: Periodic identification requested, but no indentification interval specified\r\n"); - cleanup(); - exit(1); - } - - attached_if = open_tap(); - - if (arguments.useNetKiss) { - attached_tnc = open_tcp(arguments.args[0], arguments.baudrateOrPort); + if (!kiss_over_tcp) { + arguments.baudrate = atoi(arguments.args[1]); } else { - attached_tnc = open_port(arguments.args[0]); - if (!setup_port(attached_tnc, arguments.baudrateOrPort)) { + if (!(arguments.set_tcp_host && arguments.set_tcp_port)) { + if (!arguments.set_tcp_host) printf("Error: KISS over TCP was requested, but no host was specified\r\n"); + if (!arguments.set_tcp_port) printf("Error: KISS over TCP was requested, but no port was specified\r\n"); + exit(1); + } + } + + if (arguments.daemon) daemonize = true; + if (arguments.verbose) verbose = true; + if (arguments.tap) device_type = IF_TAP; + if (arguments.noipv6) noipv6 = true; + if (arguments.set_ipv4) set_ipv4 = true; + if (arguments.set_netmask) set_netmask = true; + if (arguments.noup) noup = true; + mtu = arguments.mtu; + + if (arguments.id_interval >= 0) { + if (!arguments.valid_id) { + printf("Error: Periodic identification requested, but no valid indentification data specified\r\n"); + cleanup(); + exit(1); + } else { + id_interval = arguments.id_interval; + id = malloc(strlen(arguments.id)); + strcpy(id, arguments.id); + } + } else if (arguments.valid_id && arguments.id_interval == -1) { + printf("Error: Periodic identification requested, but no indentification interval specified\r\n"); + cleanup(); + exit(1); + } + + attached_if = open_tap(); + + if (!arguments.kiss_over_tcp) { + attached_tnc = open_port(arguments.args[0]); + if (!setup_port(attached_tnc, arguments.baudrate)) { printf("Error during serial port setup"); return 0; } - } - printf("TNC interface configured as %s\r\n", if_name); - fds[IF_FD_INDEX].fd = attached_if; - fds[IF_FD_INDEX].events = POLLIN; - fds[TNC_FD_INDEX].fd = attached_tnc; - fds[TNC_FD_INDEX].events = POLLIN; - if (daemonize) { - become_daemon(); - syslog(LOG_NOTICE, "tncattach daemon running"); - } - read_loop(); + } else { + attached_tnc = open_tcp(tcp_host, tcp_port); + } - return 0; -} \ No newline at end of file + printf("TNC interface configured as %s\r\n", if_name); + + fds[IF_FD_INDEX].fd = attached_if; + fds[IF_FD_INDEX].events = POLLIN; + fds[TNC_FD_INDEX].fd = attached_tnc; + fds[TNC_FD_INDEX].events = POLLIN; + + if (daemonize) { + become_daemon(); + syslog(LOG_NOTICE, "tncattach daemon running"); + } + + read_loop(); + + return 0; +}