diff --git a/.gitignore b/.gitignore index 5c36314..851ee33 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ Makefile.in *.swo .vscode/ .idea/ +.cache/ # Debug outputs core diff --git a/src/packet_dump.c b/src/packet_dump.c index 6e40911..4085102 100644 --- a/src/packet_dump.c +++ b/src/packet_dump.c @@ -2,9 +2,35 @@ #include "../lib/debug_config.h" #include #include +#include +#include + +static const char* tcp_flags_to_str(uint8_t flags) { + static char buf[32]; + int pos = 0; + buf[0] = '\0'; + + if (flags & 0x01) { pos += snprintf(buf + pos, sizeof(buf) - pos, "FIN,"); } + if (flags & 0x02) { pos += snprintf(buf + pos, sizeof(buf) - pos, "SYN,"); } + if (flags & 0x04) { pos += snprintf(buf + pos, sizeof(buf) - pos, "RST,"); } + if (flags & 0x08) { pos += snprintf(buf + pos, sizeof(buf) - pos, "PSH,"); } + if (flags & 0x10) { pos += snprintf(buf + pos, sizeof(buf) - pos, "ACK,"); } + if (flags & 0x20) { pos += snprintf(buf + pos, sizeof(buf) - pos, "URG,"); } + if (flags & 0x40) { pos += snprintf(buf + pos, sizeof(buf) - pos, "ECE,"); } + if (flags & 0x80) { pos += snprintf(buf + pos, sizeof(buf) - pos, "CWR,"); } + + if (pos > 0 && buf[pos - 1] == ',') { + buf[pos - 1] = '\0'; + } + + if (buf[0] == '\0') { + return "none"; + } + return buf; +} char* dump_ip_packet_to_buffer(const uint8_t* data, size_t len) { - static char buffer[512]; + static char buffer[1024]; buffer[0] = '\0'; if (len < 20) { @@ -38,36 +64,109 @@ char* dump_ip_packet_to_buffer(const uint8_t* data, size_t len) { const char* proto_name = "UNKNOWN"; uint16_t src_port = 0, dst_port = 0; + char proto_info[128] = {'\0'}; + int is_special_proto = 0; - if (protocol == 6 && len > ihl + 4) { + if (protocol == 6 && len >= ihl + 20) { proto_name = "TCP"; src_port = (data[ihl] << 8) | data[ihl + 1]; dst_port = (data[ihl + 2] << 8) | data[ihl + 3]; - } else if (protocol == 17 && len > ihl + 4) { + + uint32_t seq_num = ((uint32_t)data[ihl + 4] << 24) | + ((uint32_t)data[ihl + 5] << 16) | + ((uint32_t)data[ihl + 6] << 8) | + ((uint32_t)data[ihl + 7]); + uint32_t ack_num = ((uint32_t)data[ihl + 8] << 24) | + ((uint32_t)data[ihl + 9] << 16) | + ((uint32_t)data[ihl + 10] << 8) | + ((uint32_t)data[ihl + 11]); + uint8_t flags = data[ihl + 13]; + uint16_t window = (data[ihl + 14] << 8) | data[ihl + 15]; + + snprintf(proto_info, sizeof(proto_info), "[%s] seq=%u ack=%u win=%u", + tcp_flags_to_str(flags), seq_num, ack_num, window); + is_special_proto = 1; + + } else if (protocol == 17 && len >= ihl + 8) { proto_name = "UDP"; src_port = (data[ihl] << 8) | data[ihl + 1]; dst_port = (data[ihl + 2] << 8) | data[ihl + 3]; - } else if (protocol == 1) { + uint16_t udp_len = (data[ihl + 4] << 8) | data[ihl + 5]; + + snprintf(proto_info, sizeof(proto_info), "len=%u", udp_len); + is_special_proto = 1; + + } else if (protocol == 1 && len >= ihl + 8) { proto_name = "ICMP"; + uint8_t icmp_type = data[ihl]; + uint16_t icmp_id = (data[ihl + 4] << 8) | data[ihl + 5]; + uint16_t icmp_seq = (data[ihl + 6] << 8) | data[ihl + 7]; + if (icmp_type == 0) { + snprintf(proto_info, sizeof(proto_info), "echo_reply seq=%u id=%u", icmp_seq, icmp_id); + } else if (icmp_type == 8) { + snprintf(proto_info, sizeof(proto_info), "echo_request seq=%u id=%u", icmp_seq, icmp_id); + } else { + snprintf(proto_info, sizeof(proto_info), "type=%u code=%u", icmp_type, data[ihl + 1]); + } + is_special_proto = 1; } - int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s:%d -> %s:%d (%zd bytes) data: " - "%02x%02x%02x%02x%02x%02x%02x%02x " - "%02x%02x%02x%02x%02x%02x%02x%02x " - "%02x%02x%02x%02x%02x%02x%02x%02x " - "%02x%02x%02x%02x%02x%02x%02x%02x", - proto_name, src_str, src_port, dst_str, dst_port, len, - data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3], - data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7], - data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11], - data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15], - data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19], - data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23], - data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27], - data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]); - - if (offset > 0 && offset < (int)sizeof(buffer)) { - buffer[offset] = '\0'; + if (is_special_proto && proto_info[0] != '\0') { + if (src_port > 0 && dst_port > 0) { + int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s:%d -> %s:%d (%zd bytes) %s", + proto_name, src_str, src_port, dst_str, dst_port, len, proto_info); + if (offset > 0 && offset < (int)sizeof(buffer) - 50) { + snprintf(buffer + offset, sizeof(buffer) - offset, " data: " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x", + data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3], + data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7], + data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11], + data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15], + data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19], + data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23], + data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27], + data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]); + } + } else { + int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s -> %s (%zd bytes) %s", + proto_name, src_str, dst_str, len, proto_info); + if (offset > 0 && offset < (int)sizeof(buffer) - 50) { + snprintf(buffer + offset, sizeof(buffer) - offset, " data: " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x", + data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3], + data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7], + data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11], + data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15], + data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19], + data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23], + data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27], + data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]); + } + } + } else { + int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s:%d -> %s:%d (%zd bytes) data: " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%02x%02x%02x%02x%02x%02x%02x%02x", + proto_name, src_str, src_port, dst_str, dst_port, len, + data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3], + data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7], + data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11], + data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15], + data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19], + data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23], + data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27], + data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]); + if (offset > 0 && offset < (int)sizeof(buffer)) { + buffer[offset] = '\0'; + } } return buffer; diff --git a/src/routing.c b/src/routing.c index d10a188..92c892b 100644 --- a/src/routing.c +++ b/src/routing.c @@ -157,20 +157,8 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry, ui // DEBUG: Show packet dump // DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "##########"); if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TRAFFIC)) { - // Dump the IP packet (skip cmd byte) - char hex_buf[513] = {'\0'}; - size_t hex_len = 0; - size_t show_len = (ip_len > 128) ? 128 : ip_len; - for (size_t i = 0; i < show_len && hex_len < 512 - 3; i++) { - hex_len += snprintf(hex_buf + hex_len, sizeof(hex_buf) - hex_len, "%02x", ip_data[i]); - if (i < show_len - 1 && (i + 1) % 32 == 0) { - hex_len += snprintf(hex_buf + hex_len, sizeof(hex_buf) - hex_len, " "); - } - } - if (ip_len > 128) { - hex_len += snprintf(hex_buf + hex_len, sizeof(hex_buf) - hex_len, "..."); - } - DEBUG_DEBUG(DEBUG_CATEGORY_TRAFFIC, "PACKET_DUMP: len=%zu hex=%s", ip_len, hex_buf); + char* packet_str = dump_ip_packet_to_buffer(ip_data, ip_len); + DEBUG_DEBUG(DEBUG_CATEGORY_TRAFFIC, "PACKET_DUMP: %s", packet_str); } DEBUG_INFO(DEBUG_CATEGORY_TRAFFIC, "NODE %016llx -> NODE %016llx", (unsigned long long)src_node_id, (unsigned long long)dst_node_id); diff --git a/src/utun.c b/src/utun.c index bb4dd2e..35eee69 100644 --- a/src/utun.c +++ b/src/utun.c @@ -242,12 +242,16 @@ static FILE* open_logfile(const char *logfile) { // Main function -static volatile sig_atomic_t g_running = 1; +static volatile sig_atomic_t g_shutdown = 0; +static volatile sig_atomic_t g_reload = 0; struct UASYNC* main_ua = NULL; static void signal_handler(int sig) { - (void)sig; - g_running = 0; + if (sig == SIGINT || sig == SIGTERM) { + g_shutdown = 1; + } else if (sig == SIGHUP) { + g_reload = 1; + } if (main_ua) { uasync_wakeup(main_ua); } @@ -379,12 +383,42 @@ int main(int argc, char *argv[]) { DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "Run mainloop"); - while (instance->running) uasync_poll(ua, 100); + while (instance && instance->running) { + uasync_poll(ua, 100); + + if (g_shutdown) { + instance->running = 0; + break; + } + + if (g_reload) { + utun_instance_destroy(instance); + + instance = utun_instance_create(ua, args.config_file); + if (!instance) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Reload failed: cannot create instance"); + break; + } + + if (utun_instance_init(instance) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Reload failed: cannot init instance"); + u_free(instance); + instance = NULL; + break; + } + + instance->running = 1; + g_reload = 0; + DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Config reloaded successfully"); + } + } // Cleanup DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Shutdown"); - utun_instance_destroy(instance); + if (instance) { + utun_instance_destroy(instance); + } // Destroy uasync instance after instance is destroyed if (ua) {