| 74 | } |
| 75 | |
| 76 | void routing_manager_base::log_network_state(bool _tcp, bool _only_external) const { |
| 77 | #ifndef __linux__ |
| 78 | (void)_tcp; |
| 79 | (void)_only_external; |
| 80 | #else |
| 81 | const std::string filename = _tcp ? "/proc/net/tcp" : "/proc/net/udp"; |
| 82 | |
| 83 | std::ifstream file(filename); |
| 84 | if (!file.is_open()) { |
| 85 | VSOMEIP_ERROR_P << "Could not open " << filename << " for reading"; |
| 86 | return; |
| 87 | } |
| 88 | |
| 89 | std::string line; |
| 90 | // skip header line |
| 91 | if (!std::getline(file, line)) { |
| 92 | VSOMEIP_ERROR_P << "Failed to read header from " << filename; |
| 93 | return; |
| 94 | } |
| 95 | |
| 96 | if (file.peek() == std::ifstream::traits_type::eof()) { |
| 97 | return; |
| 98 | } |
| 99 | |
| 100 | // compute external address in hex, same format as /proc/net/tcp |
| 101 | // e.g., 127.0.0.1 => 0100007F |
| 102 | auto external_addr = configuration_->get_unicast_address(); |
| 103 | std::ostringstream external_addr_stream; |
| 104 | external_addr_stream << std::uppercase << std::hex << std::setfill('0') << std::setw(8) |
| 105 | << (external_addr.is_v4() ? htonl(external_addr.to_v4().to_uint()) : 0); |
| 106 | std::string external_addr_hex = external_addr_stream.str(); |
| 107 | |
| 108 | VSOMEIP_INFO_P << (_tcp ? "TCP" : "UDP") << " connections"; |
| 109 | VSOMEIP_INFO << "idx, local_addr, remote_addr, state, tx_queue:rx_queue, timer_active:tm_when, retrnsmt, uid, unanswered, inode"; |
| 110 | while (std::getline(file, line)) { |
| 111 | std::istringstream iss(line); |
| 112 | std::string idx, local_addr, remote_addr, state, tx_rx_queue, timer, retrnsmt, uid, unanswered, inode; |
| 113 | |
| 114 | // see https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt |
| 115 | // NOTE: there are more fields (especially in /proc/net/udp), but we do not care about these |
| 116 | if (!(iss >> idx >> local_addr >> remote_addr >> state >> tx_rx_queue >> timer >> retrnsmt >> uid >> unanswered >> inode)) { |
| 117 | VSOMEIP_ERROR_P << "Failed to parse line: " << line; |
| 118 | continue; |
| 119 | } |
| 120 | |
| 121 | if (_only_external && local_addr.substr(0, external_addr_hex.length()) != external_addr_hex) { |
| 122 | continue; |
| 123 | } |
| 124 | |
| 125 | // parse local_addr/remote_addr, e.g., 0100007F:7424 to 127.0.0.1:29732 |
| 126 | try { |
| 127 | std::string local_ip = local_addr.substr(0, 8); |
| 128 | std::string local_port = local_addr.substr(9, 4); |
| 129 | std::string remote_ip = remote_addr.substr(0, 8); |
| 130 | std::string remote_port = remote_addr.substr(9, 4); |
| 131 | |
| 132 | // convert hex to decimal |
| 133 | unsigned int local_ip_int = htonl(static_cast<unsigned int>(std::stoul(local_ip, nullptr, 16))); |
nothing calls this directly
no test coverage detected