/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2025 The TokTok team. * Copyright © 2013 Tox project. */ /** * Network traffic logging function. */ #include "net_log.h" #include "attributes.h" #include "logger.h" #include "network.h" #include "util.h" static uint32_t data_0(uint16_t buflen, const uint8_t *_Nonnull buffer) { uint32_t data = 0; if (buflen > 4) { net_unpack_u32(buffer + 1, &data); } return data; } static uint32_t data_1(uint16_t buflen, const uint8_t *_Nonnull buffer) { uint32_t data = 0; if (buflen > 8) { net_unpack_u32(buffer + 5, &data); } return data; } static const char *net_packet_type_name(Net_Packet_Type type) { switch (type) { case NET_PACKET_PING_REQUEST: return "PING_REQUEST"; case NET_PACKET_PING_RESPONSE: return "PING_RESPONSE"; case NET_PACKET_NODES_REQUEST: return "NODES_REQUEST"; case NET_PACKET_NODES_RESPONSE: return "NODES_RESPONSE"; case NET_PACKET_COOKIE_REQUEST: return "COOKIE_REQUEST"; case NET_PACKET_COOKIE_RESPONSE: return "COOKIE_RESPONSE"; case NET_PACKET_CRYPTO_HS: return "CRYPTO_HS"; case NET_PACKET_CRYPTO_DATA: return "CRYPTO_DATA"; case NET_PACKET_CRYPTO: return "CRYPTO"; case NET_PACKET_GC_HANDSHAKE: return "GC_HANDSHAKE"; case NET_PACKET_GC_LOSSLESS: return "GC_LOSSLESS"; case NET_PACKET_GC_LOSSY: return "GC_LOSSY"; case NET_PACKET_LAN_DISCOVERY: return "LAN_DISCOVERY"; case NET_PACKET_ONION_SEND_INITIAL: return "ONION_SEND_INITIAL"; case NET_PACKET_ONION_SEND_1: return "ONION_SEND_1"; case NET_PACKET_ONION_SEND_2: return "ONION_SEND_2"; case NET_PACKET_ANNOUNCE_REQUEST_OLD: return "ANNOUNCE_REQUEST_OLD"; case NET_PACKET_ANNOUNCE_RESPONSE_OLD: return "ANNOUNCE_RESPONSE_OLD"; case NET_PACKET_ONION_DATA_REQUEST: return "ONION_DATA_REQUEST"; case NET_PACKET_ONION_DATA_RESPONSE: return "ONION_DATA_RESPONSE"; case NET_PACKET_ANNOUNCE_REQUEST: return "ANNOUNCE_REQUEST"; case NET_PACKET_ANNOUNCE_RESPONSE: return "ANNOUNCE_RESPONSE"; case NET_PACKET_ONION_RECV_3: return "ONION_RECV_3"; case NET_PACKET_ONION_RECV_2: return "ONION_RECV_2"; case NET_PACKET_ONION_RECV_1: return "ONION_RECV_1"; case NET_PACKET_FORWARD_REQUEST: return "FORWARD_REQUEST"; case NET_PACKET_FORWARDING: return "FORWARDING"; case NET_PACKET_FORWARD_REPLY: return "FORWARD_REPLY"; case NET_PACKET_DATA_SEARCH_REQUEST: return "DATA_SEARCH_REQUEST"; case NET_PACKET_DATA_SEARCH_RESPONSE: return "DATA_SEARCH_RESPONSE"; case NET_PACKET_DATA_RETRIEVE_REQUEST: return "DATA_RETRIEVE_REQUEST"; case NET_PACKET_DATA_RETRIEVE_RESPONSE: return "DATA_RETRIEVE_RESPONSE"; case NET_PACKET_STORE_ANNOUNCE_REQUEST: return "STORE_ANNOUNCE_REQUEST"; case NET_PACKET_STORE_ANNOUNCE_RESPONSE: return "STORE_ANNOUNCE_RESPONSE"; case BOOTSTRAP_INFO_PACKET_ID: return "BOOTSTRAP_INFO"; case NET_PACKET_MAX: return "MAX"; } return ""; } void net_log_data(const Logger *log, const char *message, const uint8_t *buffer, uint16_t buflen, const IP_Port *ip_port, long res) { if (res < 0) { /* Windows doesn't necessarily know `%zu` */ Ip_Ntoa ip_str; const int error = net_error(); Net_Strerror error_str; LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%d: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, min_u16(buflen, 999), 'E', net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror(error, &error_str), data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]); } else if ((res > 0) && ((size_t)res <= buflen)) { Ip_Ntoa ip_str; LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%d: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, min_u16(res, 999), (size_t)res < buflen ? '<' : '=', net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK", data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]); } else { /* empty or overwrite */ Ip_Ntoa ip_str; LOGGER_TRACE(log, "[%02x = %-21s] %s %ld%c%u %s:%u (%d: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, res, res == 0 ? '!' : '>', buflen, net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK", data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]); } }