diff --git a/KISS.c b/KISS.c index 95a481f..40fc495 100644 --- a/KISS.c +++ b/KISS.c @@ -19,67 +19,67 @@ extern int device_type; extern void cleanup(void); void kiss_frame_received(int frame_len) { - if ( (device_type == IF_TUN && frame_len >= TUN_MIN_FRAME_SIZE) || (device_type == IF_TAP && frame_len >= ETHERNET_MIN_FRAME_SIZE) ) { - int written = write(attached_if, frame_buffer, frame_len); - if (written == -1) { - if (verbose && !daemonize) printf("Could not write received KISS frame (%d bytes) to network interface, is the interface up?\r\n", frame_len); - } else if (written != frame_len) { - if (!daemonize) printf("Error: Could only write %d of %d bytes to interface", written, frame_len); - cleanup(); - exit(1); - } - if (verbose && !daemonize) printf("Got %d bytes from TNC, wrote %d bytes to interface\r\n", frame_len, written); - } + if ( (device_type == IF_TUN && frame_len >= TUN_MIN_FRAME_SIZE) || (device_type == IF_TAP && frame_len >= ETHERNET_MIN_FRAME_SIZE) ) { + int written = write(attached_if, frame_buffer, frame_len); + if (written == -1) { + if (verbose && !daemonize) printf("Could not write received KISS frame (%d bytes) to network interface, is the interface up?\r\n", frame_len); + } else if (written != frame_len) { + if (!daemonize) printf("Error: Could only write %d of %d bytes to interface", written, frame_len); + cleanup(); + exit(1); + } + if (verbose && !daemonize) printf("Got %d bytes from TNC, wrote %d bytes to interface\r\n", frame_len, written); + } } void kiss_serial_read(uint8_t sbyte) { - if (IN_FRAME && sbyte == FEND && kiss_command == CMD_DATA) { - IN_FRAME = false; - kiss_frame_received(frame_len); - } else if (sbyte == FEND) { - IN_FRAME = true; - kiss_command = CMD_UNKNOWN; - frame_len = 0; - } else if (IN_FRAME && frame_len < MAX_PAYLOAD) { - // Have a look at the command byte first - if (frame_len == 0 && kiss_command == CMD_UNKNOWN) { - // Strip of port nibble - kiss_command = sbyte & 0x0F; - } else if (kiss_command == CMD_DATA) { - if (sbyte == FESC) { - ESCAPE = true; - } else { - if (ESCAPE) { - if (sbyte == TFEND) sbyte = FEND; - if (sbyte == TFESC) sbyte = FESC; - ESCAPE = false; - } + if (IN_FRAME && sbyte == FEND && kiss_command == CMD_DATA) { + IN_FRAME = false; + kiss_frame_received(frame_len); + } else if (sbyte == FEND) { + IN_FRAME = true; + kiss_command = CMD_UNKNOWN; + frame_len = 0; + } else if (IN_FRAME && frame_len < MAX_PAYLOAD) { + // Have a look at the command byte first + if (frame_len == 0 && kiss_command == CMD_UNKNOWN) { + // Strip of port nibble + kiss_command = sbyte & 0x0F; + } else if (kiss_command == CMD_DATA) { + if (sbyte == FESC) { + ESCAPE = true; + } else { + if (ESCAPE) { + if (sbyte == TFEND) sbyte = FEND; + if (sbyte == TFESC) sbyte = FESC; + ESCAPE = false; + } - if (frame_len < MAX_PAYLOAD) { - frame_buffer[frame_len++] = sbyte; - } - } - } - } + if (frame_len < MAX_PAYLOAD) { + frame_buffer[frame_len++] = sbyte; + } + } + } + } } int kiss_write_frame(int serial_port, uint8_t* buffer, int frame_len) { - int write_len = 0; - write_buffer[write_len++] = FEND; - write_buffer[write_len++] = CMD_DATA; - for (int i = 0; i < frame_len; i++) { - uint8_t byte = buffer[i]; - if (byte == FEND) { - write_buffer[write_len++] = FESC; - write_buffer[write_len++] = TFEND; - } else if (byte == FESC) { - write_buffer[write_len++] = FESC; - write_buffer[write_len++] = TFESC; - } else { - write_buffer[write_len++] = byte; - } - } - write_buffer[write_len++] = FEND; + int write_len = 0; + write_buffer[write_len++] = FEND; + write_buffer[write_len++] = CMD_DATA; + for (int i = 0; i < frame_len; i++) { + uint8_t byte = buffer[i]; + if (byte == FEND) { + write_buffer[write_len++] = FESC; + write_buffer[write_len++] = TFEND; + } else if (byte == FESC) { + write_buffer[write_len++] = FESC; + write_buffer[write_len++] = TFESC; + } else { + write_buffer[write_len++] = byte; + } + } + write_buffer[write_len++] = FEND; - return write(serial_port, write_buffer, write_len); + return write(serial_port, write_buffer, write_len); } \ No newline at end of file diff --git a/Serial.c b/Serial.c index ef91c03..09b0fa8 100644 --- a/Serial.c +++ b/Serial.c @@ -3,172 +3,172 @@ extern void cleanup(); int open_port(char* port) { - int fd; - fd = open(port, O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY); + int fd; + fd = open(port, O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY); - if (fd == -1) { - perror("The serial port could not be opened"); - cleanup(); - exit(1); - } else { - fcntl(fd, F_SETFL, 0); - } + if (fd == -1) { + perror("The serial port could not be opened"); + cleanup(); + exit(1); + } else { + fcntl(fd, F_SETFL, 0); + } - return fd; + return fd; } int close_port(int fd) { - return close(fd); + return close(fd); } void set_speed(void *tty_s, int speed) { - cfsetospeed(tty_s, speed); - cfsetispeed(tty_s, speed); + cfsetospeed(tty_s, speed); + cfsetispeed(tty_s, speed); } bool setup_port(int fd, int speed) { - struct termios tty; - if (tcgetattr(fd, &tty) != 0) { - perror("Error setting port speed, could not read port parameters"); - return false; - } + struct termios tty; + if (tcgetattr(fd, &tty) != 0) { + perror("Error setting port speed, could not read port parameters"); + return false; + } - switch (speed) { - case 0: - set_speed(&tty, B0); - break; - case 50: - set_speed(&tty, B50); - break; - case 75: - set_speed(&tty, B75); - break; - case 110: - set_speed(&tty, B110); - break; - case 134: - set_speed(&tty, B134); - break; - case 150: - set_speed(&tty, B150); - break; - case 200: - set_speed(&tty, B200); - break; - case 300: - set_speed(&tty, B300); - break; - case 600: - set_speed(&tty, B600); - break; - case 1200: - set_speed(&tty, B1200); - break; - case 2400: - set_speed(&tty, B2400); - break; - case 4800: - set_speed(&tty, B4800); - break; - case 9600: - set_speed(&tty, B9600); - break; - case 19200: - set_speed(&tty, B19200); - break; - case 38400: - set_speed(&tty, B38400); - break; - case 57600: - set_speed(&tty, B57600); - break; - case 115200: - set_speed(&tty, B115200); - break; - case 230400: - set_speed(&tty, B230400); - break; - default: - printf("Error: Invalid port speed %d specified\r\n", speed); - cleanup(); - exit(1); - return false; - } + switch (speed) { + case 0: + set_speed(&tty, B0); + break; + case 50: + set_speed(&tty, B50); + break; + case 75: + set_speed(&tty, B75); + break; + case 110: + set_speed(&tty, B110); + break; + case 134: + set_speed(&tty, B134); + break; + case 150: + set_speed(&tty, B150); + break; + case 200: + set_speed(&tty, B200); + break; + case 300: + set_speed(&tty, B300); + break; + case 600: + set_speed(&tty, B600); + break; + case 1200: + set_speed(&tty, B1200); + break; + case 2400: + set_speed(&tty, B2400); + break; + case 4800: + set_speed(&tty, B4800); + break; + case 9600: + set_speed(&tty, B9600); + break; + case 19200: + set_speed(&tty, B19200); + break; + case 38400: + set_speed(&tty, B38400); + break; + case 57600: + set_speed(&tty, B57600); + break; + case 115200: + set_speed(&tty, B115200); + break; + case 230400: + set_speed(&tty, B230400); + break; + default: + printf("Error: Invalid port speed %d specified\r\n", speed); + cleanup(); + exit(1); + return false; + } - // Set 8-bit characters, no parity, one stop bit - tty.c_cflag |= CS8; - tty.c_cflag &= ~PARENB; - tty.c_cflag &= ~CSTOPB; + // Set 8-bit characters, no parity, one stop bit + tty.c_cflag |= CS8; + tty.c_cflag &= ~PARENB; + tty.c_cflag &= ~CSTOPB; - // Disable hardware flow control - tty.c_cflag &= ~CRTSCTS; + // Disable hardware flow control + tty.c_cflag &= ~CRTSCTS; - // Enable reading and ignore modem - // control lines - tty.c_cflag |= CREAD | CLOCAL; + // Enable reading and ignore modem + // control lines + tty.c_cflag |= CREAD | CLOCAL; - // Disable canonical mode, echo - // and signal characters. - tty.c_lflag &= ~ICANON; - tty.c_lflag &= ~ECHO; - tty.c_lflag &= ~ECHOE; - tty.c_lflag &= ~ECHONL; - tty.c_lflag &= ~ISIG; + // Disable canonical mode, echo + // and signal characters. + tty.c_lflag &= ~ICANON; + tty.c_lflag &= ~ECHO; + tty.c_lflag &= ~ECHOE; + tty.c_lflag &= ~ECHONL; + tty.c_lflag &= ~ISIG; - // Disable processing of input, - // just pass the raw data. - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); + // Disable processing of input, + // just pass the raw data. + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); - // Disable XON/XOFF software flow control. - tty.c_iflag &= ~(IXON | IXOFF | IXANY); + // Disable XON/XOFF software flow control. + tty.c_iflag &= ~(IXON | IXOFF | IXANY); - // Disable processing output bytes - // and new line conversions - tty.c_oflag &= ~OPOST; - tty.c_oflag &= ~ONLCR; + // Disable processing output bytes + // and new line conversions + tty.c_oflag &= ~OPOST; + tty.c_oflag &= ~ONLCR; - // Block forever until at least one byte is read. - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; + // Block forever until at least one byte is read. + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; - // TODO: Check these - // Prevent conversion of tabs to spaces (NOT PRESENT IN LINUX) - // tty.c_oflag &= ~OXTABS; - // Prevent removal of C-d chars (0x004) in output (NOT PRESENT IN LINUX) - // tty.c_oflag &= ~ONOEOT; + // TODO: Check these + // Prevent conversion of tabs to spaces (NOT PRESENT IN LINUX) + // tty.c_oflag &= ~OXTABS; + // Prevent removal of C-d chars (0x004) in output (NOT PRESENT IN LINUX) + // tty.c_oflag &= ~ONOEOT; - if (tcsetattr(fd, TCSANOW, &tty) != 0) { - perror("Could not configure serial port parameters"); - return false; - } else { - return true; - } + if (tcsetattr(fd, TCSANOW, &tty) != 0) { + perror("Could not configure serial port parameters"); + return false; + } else { + return true; + } } bool set_port_blocking(int fd, bool should_block) { - struct termios tty; - memset(&tty, 0, sizeof tty); + struct termios tty; + memset(&tty, 0, sizeof tty); - if (tcgetattr(fd, &tty) != 0) { - perror("Error configuring port blocking behaviour, could not read port parameters"); - return false; - } else { - // TODO: Implement this correctly - if (should_block) { - // Block forever until at least one byte is read. - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - } else { - // Never block, always return immediately with - // whatever is available. - tty.c_cc[VMIN] = 0; - tty.c_cc[VTIME] = 0; - } - if (tcsetattr(fd, TCSANOW, &tty) != 0) { - perror("Could not set port parameters while configuring blocking behaviour"); - return false; - } else { - return true; - } - } + if (tcgetattr(fd, &tty) != 0) { + perror("Error configuring port blocking behaviour, could not read port parameters"); + return false; + } else { + // TODO: Implement this correctly + if (should_block) { + // Block forever until at least one byte is read. + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + } else { + // Never block, always return immediately with + // whatever is available. + tty.c_cc[VMIN] = 0; + tty.c_cc[VTIME] = 0; + } + if (tcsetattr(fd, TCSANOW, &tty) != 0) { + perror("Could not set port parameters while configuring blocking behaviour"); + return false; + } else { + return true; + } + } } \ No newline at end of file diff --git a/TAP.c b/TAP.c index e5db123..5b0477f 100644 --- a/TAP.c +++ b/TAP.c @@ -15,184 +15,184 @@ extern char* netmask; extern void cleanup(); int open_tap(void) { - struct ifreq ifr; - int fd = open("/dev/net/tun", O_RDWR); + struct ifreq ifr; + int fd = open("/dev/net/tun", O_RDWR); - if (fd < 0) { - perror("Could not open clone device"); - exit(1); - } else { - memset(&ifr, 0, sizeof(ifr)); - // TODO: Enable PI header again? + if (fd < 0) { + perror("Could not open clone device"); + exit(1); + } else { + memset(&ifr, 0, sizeof(ifr)); + // TODO: Enable PI header again? - if (device_type == IF_TAP) { - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - } else if (device_type == IF_TUN) { - ifr.ifr_flags = IFF_TUN; - } else { - printf("Error: Unsupported interface type\r\n"); - cleanup(); - exit(1); - } + if (device_type == IF_TAP) { + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + } else if (device_type == IF_TUN) { + ifr.ifr_flags = IFF_TUN; + } else { + printf("Error: Unsupported interface type\r\n"); + cleanup(); + exit(1); + } - strcpy(tap_name, "tnc%d"); - strncpy(ifr.ifr_name, tap_name, IFNAMSIZ); + strcpy(tap_name, "tnc%d"); + strncpy(ifr.ifr_name, tap_name, IFNAMSIZ); - if (ioctl(fd, TUNSETIFF, &ifr) < 0) { - perror("Could not configure network interface"); - exit(1); - } else { - strcpy(if_name, ifr.ifr_name); - - int inet = socket(AF_INET, SOCK_DGRAM, 0); - if (inet == -1) { - perror("Could not open AF_INET socket"); - cleanup(); - exit(1); - } else { - if (ioctl(inet, SIOCGIFMTU, &ifr) < 0) { - perror("Could not get interface flags from kernel"); - close(inet); - cleanup(); - exit(1); - } else { - ifr.ifr_mtu = mtu; - if (ioctl(inet, SIOCSIFMTU, &ifr) < 0) { - perror("Could not configure interface MTU"); - close(inet); - cleanup(); - exit(1); - } + if (ioctl(fd, TUNSETIFF, &ifr) < 0) { + perror("Could not configure network interface"); + exit(1); + } else { + strcpy(if_name, ifr.ifr_name); + + int inet = socket(AF_INET, SOCK_DGRAM, 0); + if (inet == -1) { + perror("Could not open AF_INET socket"); + cleanup(); + exit(1); + } else { + if (ioctl(inet, SIOCGIFMTU, &ifr) < 0) { + perror("Could not get interface flags from kernel"); + close(inet); + cleanup(); + exit(1); + } else { + ifr.ifr_mtu = mtu; + if (ioctl(inet, SIOCSIFMTU, &ifr) < 0) { + perror("Could not configure interface MTU"); + close(inet); + cleanup(); + exit(1); + } - // Configure TX queue length - if (ioctl(inet, SIOCGIFTXQLEN, &ifr) < 0) { - perror("Could not get interface flags from kernel"); - close(inet); - cleanup(); - exit(1); - } else { - ifr.ifr_qlen = TXQUEUELEN; - if (ioctl(inet, SIOCSIFTXQLEN, &ifr) < 0) { - perror("Could not set interface TX queue length"); - close(inet); - cleanup(); - exit(1); - } - } + // Configure TX queue length + if (ioctl(inet, SIOCGIFTXQLEN, &ifr) < 0) { + perror("Could not get interface flags from kernel"); + close(inet); + cleanup(); + exit(1); + } else { + ifr.ifr_qlen = TXQUEUELEN; + if (ioctl(inet, SIOCSIFTXQLEN, &ifr) < 0) { + perror("Could not set interface TX queue length"); + close(inet); + cleanup(); + exit(1); + } + } - // Configure ARP characteristics - char path_buf[256]; - if (device_type == IF_TAP) { - snprintf(path_buf, sizeof(path_buf), "/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", ifr.ifr_name); - int arp_fd = open(path_buf, O_WRONLY); - if (arp_fd < 0) { - perror("Could not open proc entry for ARP parameters"); - close(inet); - cleanup(); - exit(1); - } else { - if (dprintf(arp_fd, "%d", ARP_BASE_REACHABLE_TIME*1000) <= 0) { - perror("Could not configure interface ARP parameter base_reachable_time_ms"); - close(inet); - close(arp_fd); - cleanup(); - exit(1); - } else { - close(arp_fd); - } - } + // Configure ARP characteristics + char path_buf[256]; + if (device_type == IF_TAP) { + snprintf(path_buf, sizeof(path_buf), "/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", ifr.ifr_name); + int arp_fd = open(path_buf, O_WRONLY); + if (arp_fd < 0) { + perror("Could not open proc entry for ARP parameters"); + close(inet); + cleanup(); + exit(1); + } else { + if (dprintf(arp_fd, "%d", ARP_BASE_REACHABLE_TIME*1000) <= 0) { + perror("Could not configure interface ARP parameter base_reachable_time_ms"); + close(inet); + close(arp_fd); + cleanup(); + exit(1); + } else { + close(arp_fd); + } + } - snprintf(path_buf, sizeof(path_buf), "/proc/sys/net/ipv4/neigh/%s/retrans_time_ms", ifr.ifr_name); - arp_fd = open(path_buf, O_WRONLY); - if (arp_fd < 0) { - perror("Could not open proc entry for ARP parameters"); - close(inet); - cleanup(); - exit(1); - } else { - if (dprintf(arp_fd, "%d", ARP_RETRANS_TIME*1000) <= 0) { - perror("Could not configure interface ARP parameter retrans_time_ms"); - close(inet); - close(arp_fd); - cleanup(); - exit(1); - } else { - close(arp_fd); - } - } - } + snprintf(path_buf, sizeof(path_buf), "/proc/sys/net/ipv4/neigh/%s/retrans_time_ms", ifr.ifr_name); + arp_fd = open(path_buf, O_WRONLY); + if (arp_fd < 0) { + perror("Could not open proc entry for ARP parameters"); + close(inet); + cleanup(); + exit(1); + } else { + if (dprintf(arp_fd, "%d", ARP_RETRANS_TIME*1000) <= 0) { + perror("Could not configure interface ARP parameter retrans_time_ms"); + close(inet); + close(arp_fd); + cleanup(); + exit(1); + } else { + close(arp_fd); + } + } + } - // Bring up if requested - if (!noup) { - if (ioctl(inet, SIOCGIFFLAGS, &ifr) < 0) { - perror("Could not get interface flags from kernel"); - close(inet); - cleanup(); - exit(1); - } else { - ifr.ifr_flags |= IFF_UP | IFF_RUNNING; - if (ioctl(inet, SIOCSIFFLAGS, &ifr) < 0) { - perror("Could not bring up interface"); - close(inet); - cleanup(); - exit(1); - } else { - if (set_ipv4) { - struct ifreq a_ifr; - struct sockaddr_in addr, snm; + // Bring up if requested + if (!noup) { + if (ioctl(inet, SIOCGIFFLAGS, &ifr) < 0) { + perror("Could not get interface flags from kernel"); + close(inet); + cleanup(); + exit(1); + } else { + ifr.ifr_flags |= IFF_UP | IFF_RUNNING; + if (ioctl(inet, SIOCSIFFLAGS, &ifr) < 0) { + perror("Could not bring up interface"); + close(inet); + cleanup(); + exit(1); + } else { + if (set_ipv4) { + struct ifreq a_ifr; + struct sockaddr_in addr, snm; - memset(&a_ifr, 0, sizeof(a_ifr)); - memset(&addr, 0, sizeof(addr)); - memset(&snm, 0, sizeof(addr)); - strncpy(a_ifr.ifr_name, ifr.ifr_name, IFNAMSIZ); - addr.sin_family = AF_INET; - snm.sin_family = AF_INET; + memset(&a_ifr, 0, sizeof(a_ifr)); + memset(&addr, 0, sizeof(addr)); + memset(&snm, 0, sizeof(addr)); + strncpy(a_ifr.ifr_name, ifr.ifr_name, IFNAMSIZ); + addr.sin_family = AF_INET; + snm.sin_family = AF_INET; - int addr_conversion = inet_pton(AF_INET, ipv4_addr, &(addr.sin_addr)); - if (addr_conversion != 1) { - printf("Error: Invalid IPv4 address specified\r\n"); - close(inet); - cleanup(); - exit(1); - } else { - a_ifr.ifr_addr = *(struct sockaddr*)&addr; - if (ioctl(inet, SIOCSIFADDR, &a_ifr) < 0) { - perror("Could not set IP-address"); - close(inet); - cleanup(); - exit(1); - } else { - if (set_netmask) { - int snm_conversion = inet_pton(AF_INET, netmask, &(snm.sin_addr)); - if (snm_conversion != 1) { - printf("Error: Invalid subnet mask specified\r\n"); - close(inet); - cleanup(); - exit(1); - } else { - a_ifr.ifr_addr = *(struct sockaddr*)&snm; - if (ioctl(inet, SIOCSIFNETMASK, &a_ifr) < 0) { - perror("Could not set subnet mask"); - close(inet); - cleanup(); - exit(1); - } - } - } - } - } - } - } - } - } - } - } + int addr_conversion = inet_pton(AF_INET, ipv4_addr, &(addr.sin_addr)); + if (addr_conversion != 1) { + printf("Error: Invalid IPv4 address specified\r\n"); + close(inet); + cleanup(); + exit(1); + } else { + a_ifr.ifr_addr = *(struct sockaddr*)&addr; + if (ioctl(inet, SIOCSIFADDR, &a_ifr) < 0) { + perror("Could not set IP-address"); + close(inet); + cleanup(); + exit(1); + } else { + if (set_netmask) { + int snm_conversion = inet_pton(AF_INET, netmask, &(snm.sin_addr)); + if (snm_conversion != 1) { + printf("Error: Invalid subnet mask specified\r\n"); + close(inet); + cleanup(); + exit(1); + } else { + a_ifr.ifr_addr = *(struct sockaddr*)&snm; + if (ioctl(inet, SIOCSIFNETMASK, &a_ifr) < 0) { + perror("Could not set subnet mask"); + close(inet); + cleanup(); + exit(1); + } + } + } + } + } + } + } + } + } + } + } - return fd; - } - } + return fd; + } + } } int close_tap(int tap_fd) { - return close(tap_fd); + return close(tap_fd); } \ No newline at end of file diff --git a/TCP.c b/TCP.c index 5ca898e..ce92651 100644 --- a/TCP.c +++ b/TCP.c @@ -33,5 +33,5 @@ int open_tcp(char* ip, int port) { } int close_tcp(int fd) { - return close(fd); + return close(fd); } \ No newline at end of file diff --git a/tncattach.c b/tncattach.c index d46b866..30e9a25 100644 --- a/tncattach.c +++ b/tncattach.c @@ -51,214 +51,214 @@ time_t last_id = 0; bool tx_since_last_id = false; void cleanup(void) { - if (kiss_over_tcp) { - 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.8"; @@ -266,219 +266,219 @@ 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 baudrate"; static struct argp_option options[] = { - { "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 } + { "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 baudrate; + 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; + 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; - break; + switch (key) { + case 'v': + arguments->verbose = true; + break; - case 'e': - arguments->tap = 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 '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 '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 '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; + 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; + 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); - } + 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); - } + arguments->set_netmask = true; + } else { + arguments->set_netmask = false; + ipv4_addr = (char*)malloc(strlen(arg)+1); + strcpy(ipv4_addr, arg); + } - break; + break; - case 'n': - arguments->noipv6 = true; - break; + case 'n': + arguments->noipv6 = true; + break; - case 'd': - arguments->daemon = true; - arguments->verbose = false; - break; + case 'd': + arguments->daemon = true; + arguments->verbose = false; + break; - case 'T': - arguments->kiss_over_tcp = true; - break; + case 'T': + arguments->kiss_over_tcp = true; + break; case 'H': arguments->set_tcp_host = true; @@ -491,81 +491,81 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { tcp_port = atoi(arg); break; - case 1: - arguments->noup = 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); + 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; + // 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 (!arguments->kiss_over_tcp && state->arg_num < N_ARGS) argp_usage(state); + 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); // Check if text arguments were given when // KISS over TCP was specified if (arguments->kiss_over_tcp && state->arg_num != 0) argp_usage(state); - break; + break; - default: - return ARGP_ERR_UNKNOWN; - } + 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.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; + 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); + argp_parse(&argp, argc, argv, 0, 0, &arguments); if (arguments.kiss_over_tcp) kiss_over_tcp = true; @@ -578,57 +578,57 @@ int main(int argc, char **argv) { 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.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); - } + 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(); + attached_if = open_tap(); - if (!arguments.kiss_over_tcp) { - attached_tnc = open_port(arguments.args[0]); + 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; } - } else { + } else { attached_tnc = open_tcp(tcp_host, tcp_port); - } + } - printf("TNC interface configured as %s\r\n", if_name); + 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; - + 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"); - } + become_daemon(); + syslog(LOG_NOTICE, "tncattach daemon running"); + } - read_loop(); + read_loop(); - return 0; -} + return 0; +} \ No newline at end of file