librats 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,350 +35,9 @@
35
35
  namespace librats {
36
36
  namespace network_utils {
37
37
 
38
- std::string resolve_hostname(const std::string& hostname) {
39
- LOG_NETUTILS_DEBUG("Resolving hostname: " << hostname);
40
-
41
- // Handle empty string
42
- if (hostname.empty()) {
43
- LOG_NETUTILS_DEBUG("Empty hostname provided");
44
- return "";
45
- }
46
-
47
- // Check if it's already an IP address
48
- if (is_valid_ipv4(hostname)) {
49
- LOG_NETUTILS_DEBUG("Already an IP address: " << hostname);
50
- return hostname;
51
- }
52
-
53
- // Resolve hostname using getaddrinfo
54
- struct addrinfo hints, *result;
55
- memset(&hints, 0, sizeof(hints));
56
- hints.ai_family = AF_INET; // IPv4
57
- hints.ai_socktype = SOCK_DGRAM; // UDP
58
-
59
- int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
60
- if (status != 0) {
61
- #ifdef _WIN32
62
- LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << ": " << WSAGetLastError());
63
- #else
64
- LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << ": " << gai_strerror(status));
65
- #endif
66
- return "";
67
- }
68
-
69
- char ip_str[INET_ADDRSTRLEN];
70
- struct sockaddr_in* addr_in = (struct sockaddr_in*)result->ai_addr;
71
- inet_ntop(AF_INET, &addr_in->sin_addr, ip_str, INET_ADDRSTRLEN);
72
-
73
- freeaddrinfo(result);
74
-
75
- LOG_NETUTILS_INFO("Resolved " << hostname << " to " << ip_str);
76
- return std::string(ip_str);
77
- }
78
-
79
- std::string resolve_hostname_v6(const std::string& hostname) {
80
- LOG_NETUTILS_DEBUG("Resolving hostname to IPv6: " << hostname);
81
-
82
- // Handle empty string
83
- if (hostname.empty()) {
84
- LOG_NETUTILS_DEBUG("Empty hostname provided");
85
- return "";
86
- }
87
-
88
- // Check if it's already an IPv6 address
89
- if (is_valid_ipv6(hostname)) {
90
- LOG_NETUTILS_DEBUG("Already an IPv6 address: " << hostname);
91
- return hostname;
92
- }
93
-
94
- // Resolve hostname using getaddrinfo
95
- struct addrinfo hints, *result;
96
- memset(&hints, 0, sizeof(hints));
97
- hints.ai_family = AF_INET6; // IPv6
98
- hints.ai_socktype = SOCK_DGRAM; // UDP
99
-
100
- int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
101
- if (status != 0) {
102
- #ifdef _WIN32
103
- LOG_NETUTILS_DEBUG("Failed to resolve hostname " << hostname << " to IPv6: " << WSAGetLastError());
104
- #else
105
- LOG_NETUTILS_DEBUG("Failed to resolve hostname " << hostname << " to IPv6: " << gai_strerror(status));
106
- #endif
107
- return "";
108
- }
109
-
110
- char ip_str[INET6_ADDRSTRLEN];
111
- struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)result->ai_addr;
112
- inet_ntop(AF_INET6, &addr_in6->sin6_addr, ip_str, INET6_ADDRSTRLEN);
113
-
114
- freeaddrinfo(result);
115
-
116
- LOG_NETUTILS_DEBUG("Resolved " << hostname << " to IPv6 " << ip_str);
117
- return std::string(ip_str);
118
- }
119
-
120
- bool is_valid_ipv4(const std::string& ip_str) {
121
- #ifdef __APPLE__
122
- // macOS-specific validation to handle inet_pton() accepting leading zeros
123
- // inet_pton() behaves differently on macOS vs Linux/Windows for leading zeros
124
-
125
- // Split the IP string into octets
126
- std::vector<std::string> octets;
127
- std::string current_octet;
128
-
129
- for (char c : ip_str) {
130
- if (c == '.') {
131
- octets.push_back(current_octet);
132
- current_octet.clear();
133
- } else {
134
- current_octet += c;
135
- }
136
- }
137
-
138
- // Add the last octet
139
- if (!current_octet.empty()) {
140
- octets.push_back(current_octet);
141
- }
142
-
143
- // Must have exactly 4 octets
144
- if (octets.size() != 4) {
145
- return false;
146
- }
147
-
148
- // Check each octet for validity
149
- for (const std::string& octet : octets) {
150
- // Empty octet is invalid
151
- if (octet.empty()) {
152
- return false;
153
- }
154
-
155
- // Check for leading zeros (invalid except for "0")
156
- if (octet.length() > 1 && octet[0] == '0') {
157
- return false;
158
- }
159
-
160
- // Check that all characters are digits
161
- for (char c : octet) {
162
- if (c < '0' || c > '9') {
163
- return false;
164
- }
165
- }
166
-
167
- // Check range (0-255)
168
- int value = std::stoi(octet);
169
- if (value < 0 || value > 255) {
170
- return false;
171
- }
172
- }
173
- #endif
174
- // Linux/Windows: inet_pton() already rejects leading zeros correctly
175
- struct sockaddr_in sa;
176
- return inet_pton(AF_INET, ip_str.c_str(), &sa.sin_addr) == 1;
177
- }
178
-
179
- bool is_valid_ipv6(const std::string& ip_str) {
180
- struct sockaddr_in6 sa;
181
- return inet_pton(AF_INET6, ip_str.c_str(), &sa.sin6_addr) == 1;
182
- }
183
-
184
- bool is_hostname(const std::string& str) {
185
- // First check if it's an IP address - if so, it's not a hostname
186
- if (is_valid_ipv4(str) || is_valid_ipv6(str)) {
187
- return false;
188
- }
189
-
190
- // Check basic validation rules
191
- if (str.empty() || str.length() > 253) {
192
- return false;
193
- }
194
-
195
- // Check for invalid characters at start/end
196
- if (str.front() == '.' || str.back() == '.') {
197
- return false;
198
- }
199
-
200
- if (str.front() == '-' || str.back() == '-') {
201
- return false;
202
- }
203
-
204
- // Check for invalid patterns
205
- if (str.find("..") != std::string::npos) {
206
- return false;
207
- }
208
-
209
- if (str == ".") {
210
- return false;
211
- }
212
-
213
- // Check for invalid characters
214
- for (char c : str) {
215
- if (c == ' ' || c == '@' || c == '#' || c == '$' || c == '%' ||
216
- c == '^' || c == '&' || c == '*' || c == '(' || c == ')' ||
217
- c == '+' || c == '=' || c == '[' || c == ']' || c == '{' ||
218
- c == '}' || c == '|' || c == '\\' || c == '/' || c == '?' ||
219
- c == '<' || c == '>' || c == ',' || c == ';' || c == ':' ||
220
- c == '"' || c == '\'' || c == '`' || c == '~' || c == '!') {
221
- return false;
222
- }
223
- }
224
-
225
- return true;
226
- }
227
-
228
- std::string to_ip_address(const std::string& host) {
229
- return resolve_hostname(host);
230
- }
231
-
232
- std::vector<std::string> resolve_all_addresses(const std::string& hostname) {
233
- LOG_NETUTILS_DEBUG("Resolving all addresses for hostname: " << hostname);
234
-
235
- std::vector<std::string> addresses;
236
-
237
- // Check if it's already an IP address
238
- if (is_valid_ipv4(hostname)) {
239
- LOG_NETUTILS_DEBUG("Already an IP address: " << hostname);
240
- addresses.push_back(hostname);
241
- return addresses;
242
- }
243
-
244
- // Resolve hostname using getaddrinfo
245
- struct addrinfo hints, *result, *rp;
246
- memset(&hints, 0, sizeof(hints));
247
- hints.ai_family = AF_INET; // IPv4
248
- hints.ai_socktype = SOCK_DGRAM; // UDP
249
-
250
- int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
251
- if (status != 0) {
252
- #ifdef _WIN32
253
- LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << ": " << WSAGetLastError());
254
- #else
255
- LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << ": " << gai_strerror(status));
256
- #endif
257
- return addresses;
258
- }
259
-
260
- // Iterate through all addresses
261
- for (rp = result; rp != nullptr; rp = rp->ai_next) {
262
- char ip_str[INET_ADDRSTRLEN];
263
- struct sockaddr_in* addr_in = (struct sockaddr_in*)rp->ai_addr;
264
- inet_ntop(AF_INET, &addr_in->sin_addr, ip_str, INET_ADDRSTRLEN);
265
-
266
- std::string ip_address(ip_str);
267
- addresses.push_back(ip_address);
268
- LOG_NETUTILS_DEBUG("Found address: " << ip_address);
269
- }
270
-
271
- freeaddrinfo(result);
272
-
273
- LOG_NETUTILS_INFO("Resolved " << hostname << " to " << addresses.size() << " addresses");
274
- return addresses;
275
- }
276
-
277
- std::vector<std::string> resolve_all_addresses_v6(const std::string& hostname) {
278
- LOG_NETUTILS_DEBUG("Resolving all IPv6 addresses for hostname: " << hostname);
279
-
280
- std::vector<std::string> addresses;
281
-
282
- // Check if it's already an IPv6 address
283
- if (is_valid_ipv6(hostname)) {
284
- LOG_NETUTILS_DEBUG("Already an IPv6 address: " << hostname);
285
- addresses.push_back(hostname);
286
- return addresses;
287
- }
288
-
289
- // Resolve hostname using getaddrinfo
290
- struct addrinfo hints, *result, *rp;
291
- memset(&hints, 0, sizeof(hints));
292
- hints.ai_family = AF_INET6; // IPv6
293
- hints.ai_socktype = SOCK_DGRAM; // UDP
294
-
295
- int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
296
- if (status != 0) {
297
- #ifdef _WIN32
298
- LOG_NETUTILS_DEBUG("Failed to resolve hostname " << hostname << " to IPv6: " << WSAGetLastError());
299
- #else
300
- LOG_NETUTILS_DEBUG("Failed to resolve hostname " << hostname << " to IPv6: " << gai_strerror(status));
301
- #endif
302
- return addresses;
303
- }
304
-
305
- // Iterate through all addresses
306
- for (rp = result; rp != nullptr; rp = rp->ai_next) {
307
- char ip_str[INET6_ADDRSTRLEN];
308
- struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)rp->ai_addr;
309
- inet_ntop(AF_INET6, &addr_in6->sin6_addr, ip_str, INET6_ADDRSTRLEN);
310
-
311
- std::string ip_address(ip_str);
312
- addresses.push_back(ip_address);
313
- LOG_NETUTILS_DEBUG("Found IPv6 address: " << ip_address);
314
- }
315
-
316
- freeaddrinfo(result);
317
-
318
- LOG_NETUTILS_INFO("Resolved " << hostname << " to " << addresses.size() << " IPv6 addresses");
319
- return addresses;
320
- }
38
+ // ── Internal helpers (not exposed in header) ────────────────────────────────
321
39
 
322
- std::vector<std::string> resolve_all_addresses_dual(const std::string& hostname) {
323
- LOG_NETUTILS_DEBUG("Resolving all addresses (dual stack) for hostname: " << hostname);
324
-
325
- std::vector<std::string> addresses;
326
-
327
- // Check if it's already an IP address
328
- if (is_valid_ipv4(hostname)) {
329
- LOG_NETUTILS_DEBUG("Already an IPv4 address: " << hostname);
330
- addresses.push_back(hostname);
331
- return addresses;
332
- }
333
-
334
- if (is_valid_ipv6(hostname)) {
335
- LOG_NETUTILS_DEBUG("Already an IPv6 address: " << hostname);
336
- addresses.push_back(hostname);
337
- return addresses;
338
- }
339
-
340
- // Resolve hostname using getaddrinfo with dual stack
341
- struct addrinfo hints, *result, *rp;
342
- memset(&hints, 0, sizeof(hints));
343
- hints.ai_family = AF_UNSPEC; // Both IPv4 and IPv6
344
- hints.ai_socktype = SOCK_DGRAM; // UDP
345
-
346
- int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
347
- if (status != 0) {
348
- #ifdef _WIN32
349
- LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << " (dual stack): " << WSAGetLastError());
350
- #else
351
- LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << " (dual stack): " << gai_strerror(status));
352
- #endif
353
- return addresses;
354
- }
355
-
356
- // Iterate through all addresses
357
- for (rp = result; rp != nullptr; rp = rp->ai_next) {
358
- if (rp->ai_family == AF_INET) {
359
- char ip_str[INET_ADDRSTRLEN];
360
- struct sockaddr_in* addr_in = (struct sockaddr_in*)rp->ai_addr;
361
- inet_ntop(AF_INET, &addr_in->sin_addr, ip_str, INET_ADDRSTRLEN);
362
-
363
- std::string ip_address(ip_str);
364
- addresses.push_back(ip_address);
365
- LOG_NETUTILS_DEBUG("Found IPv4 address: " << ip_address);
366
- } else if (rp->ai_family == AF_INET6) {
367
- char ip_str[INET6_ADDRSTRLEN];
368
- struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)rp->ai_addr;
369
- inet_ntop(AF_INET6, &addr_in6->sin6_addr, ip_str, INET6_ADDRSTRLEN);
370
-
371
- std::string ip_address(ip_str);
372
- addresses.push_back(ip_address);
373
- LOG_NETUTILS_DEBUG("Found IPv6 address: " << ip_address);
374
- }
375
- }
376
-
377
- freeaddrinfo(result);
378
-
379
- LOG_NETUTILS_INFO("Resolved " << hostname << " to " << addresses.size() << " addresses (dual stack)");
380
- return addresses;
381
- }
40
+ namespace {
382
41
 
383
42
  std::vector<std::string> get_local_interface_addresses_v4() {
384
43
  LOG_NETUTILS_DEBUG("Getting local IPv4 interface addresses");
@@ -386,7 +45,6 @@ std::vector<std::string> get_local_interface_addresses_v4() {
386
45
  std::vector<std::string> addresses;
387
46
 
388
47
  #ifdef _WIN32
389
- // Windows implementation using GetAdaptersAddresses
390
48
  DWORD dwRetVal = 0;
391
49
  ULONG outBufLen = 15000;
392
50
  ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
@@ -438,7 +96,6 @@ std::vector<std::string> get_local_interface_addresses_v4() {
438
96
  }
439
97
 
440
98
  #else
441
- // Linux/Unix implementation using getifaddrs
442
99
  struct ifaddrs *ifaddr, *ifa;
443
100
 
444
101
  if (getifaddrs(&ifaddr) == -1) {
@@ -472,7 +129,6 @@ std::vector<std::string> get_local_interface_addresses_v6() {
472
129
  std::vector<std::string> addresses;
473
130
 
474
131
  #ifdef _WIN32
475
- // Windows implementation using GetAdaptersAddresses
476
132
  DWORD dwRetVal = 0;
477
133
  ULONG outBufLen = 15000;
478
134
  ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
@@ -524,7 +180,6 @@ std::vector<std::string> get_local_interface_addresses_v6() {
524
180
  }
525
181
 
526
182
  #else
527
- // Linux/Unix implementation using getifaddrs
528
183
  struct ifaddrs *ifaddr, *ifa;
529
184
 
530
185
  if (getifaddrs(&ifaddr) == -1) {
@@ -552,16 +207,186 @@ std::vector<std::string> get_local_interface_addresses_v6() {
552
207
  return addresses;
553
208
  }
554
209
 
210
+ } // anonymous namespace
211
+
212
+ // ── Public API ──────────────────────────────────────────────────────────────
213
+
214
+ std::string resolve_hostname(const std::string& hostname) {
215
+ LOG_NETUTILS_DEBUG("Resolving hostname: " << hostname);
216
+
217
+ if (hostname.empty()) {
218
+ LOG_NETUTILS_DEBUG("Empty hostname provided");
219
+ return "";
220
+ }
221
+
222
+ if (is_valid_ipv4(hostname)) {
223
+ LOG_NETUTILS_DEBUG("Already an IP address: " << hostname);
224
+ return hostname;
225
+ }
226
+
227
+ struct addrinfo hints, *result;
228
+ memset(&hints, 0, sizeof(hints));
229
+ hints.ai_family = AF_INET;
230
+ hints.ai_socktype = SOCK_DGRAM;
231
+
232
+ int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
233
+ if (status != 0) {
234
+ #ifdef _WIN32
235
+ LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << ": " << WSAGetLastError());
236
+ #else
237
+ LOG_NETUTILS_ERROR("Failed to resolve hostname " << hostname << ": " << gai_strerror(status));
238
+ #endif
239
+ return "";
240
+ }
241
+
242
+ char ip_str[INET_ADDRSTRLEN];
243
+ struct sockaddr_in* addr_in = (struct sockaddr_in*)result->ai_addr;
244
+ inet_ntop(AF_INET, &addr_in->sin_addr, ip_str, INET_ADDRSTRLEN);
245
+
246
+ freeaddrinfo(result);
247
+
248
+ LOG_NETUTILS_INFO("Resolved " << hostname << " to " << ip_str);
249
+ return std::string(ip_str);
250
+ }
251
+
252
+ std::string resolve_hostname_v6(const std::string& hostname) {
253
+ LOG_NETUTILS_DEBUG("Resolving hostname to IPv6: " << hostname);
254
+
255
+ if (hostname.empty()) {
256
+ LOG_NETUTILS_DEBUG("Empty hostname provided");
257
+ return "";
258
+ }
259
+
260
+ if (is_valid_ipv6(hostname)) {
261
+ LOG_NETUTILS_DEBUG("Already an IPv6 address: " << hostname);
262
+ return hostname;
263
+ }
264
+
265
+ struct addrinfo hints, *result;
266
+ memset(&hints, 0, sizeof(hints));
267
+ hints.ai_family = AF_INET6;
268
+ hints.ai_socktype = SOCK_DGRAM;
269
+
270
+ int status = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);
271
+ if (status != 0) {
272
+ #ifdef _WIN32
273
+ LOG_NETUTILS_DEBUG("Failed to resolve hostname " << hostname << " to IPv6: " << WSAGetLastError());
274
+ #else
275
+ LOG_NETUTILS_DEBUG("Failed to resolve hostname " << hostname << " to IPv6: " << gai_strerror(status));
276
+ #endif
277
+ return "";
278
+ }
279
+
280
+ char ip_str[INET6_ADDRSTRLEN];
281
+ struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)result->ai_addr;
282
+ inet_ntop(AF_INET6, &addr_in6->sin6_addr, ip_str, INET6_ADDRSTRLEN);
283
+
284
+ freeaddrinfo(result);
285
+
286
+ LOG_NETUTILS_DEBUG("Resolved " << hostname << " to IPv6 " << ip_str);
287
+ return std::string(ip_str);
288
+ }
289
+
290
+ bool is_valid_ipv4(const std::string& ip_str) {
291
+ #ifdef __APPLE__
292
+ // macOS-specific validation to handle inet_pton() accepting leading zeros
293
+ std::vector<std::string> octets;
294
+ std::string current_octet;
295
+
296
+ for (char c : ip_str) {
297
+ if (c == '.') {
298
+ octets.push_back(current_octet);
299
+ current_octet.clear();
300
+ } else {
301
+ current_octet += c;
302
+ }
303
+ }
304
+
305
+ if (!current_octet.empty()) {
306
+ octets.push_back(current_octet);
307
+ }
308
+
309
+ if (octets.size() != 4) {
310
+ return false;
311
+ }
312
+
313
+ for (const std::string& octet : octets) {
314
+ if (octet.empty()) {
315
+ return false;
316
+ }
317
+
318
+ if (octet.length() > 1 && octet[0] == '0') {
319
+ return false;
320
+ }
321
+
322
+ for (char c : octet) {
323
+ if (c < '0' || c > '9') {
324
+ return false;
325
+ }
326
+ }
327
+
328
+ int value = std::stoi(octet);
329
+ if (value < 0 || value > 255) {
330
+ return false;
331
+ }
332
+ }
333
+ #endif
334
+ struct sockaddr_in sa;
335
+ return inet_pton(AF_INET, ip_str.c_str(), &sa.sin_addr) == 1;
336
+ }
337
+
338
+ bool is_valid_ipv6(const std::string& ip_str) {
339
+ struct sockaddr_in6 sa;
340
+ return inet_pton(AF_INET6, ip_str.c_str(), &sa.sin6_addr) == 1;
341
+ }
342
+
343
+ bool is_hostname(const std::string& str) {
344
+ if (is_valid_ipv4(str) || is_valid_ipv6(str)) {
345
+ return false;
346
+ }
347
+
348
+ if (str.empty() || str.length() > 253) {
349
+ return false;
350
+ }
351
+
352
+ if (str.front() == '.' || str.back() == '.') {
353
+ return false;
354
+ }
355
+
356
+ if (str.front() == '-' || str.back() == '-') {
357
+ return false;
358
+ }
359
+
360
+ if (str.find("..") != std::string::npos) {
361
+ return false;
362
+ }
363
+
364
+ if (str == ".") {
365
+ return false;
366
+ }
367
+
368
+ for (char c : str) {
369
+ if (c == ' ' || c == '@' || c == '#' || c == '$' || c == '%' ||
370
+ c == '^' || c == '&' || c == '*' || c == '(' || c == ')' ||
371
+ c == '+' || c == '=' || c == '[' || c == ']' || c == '{' ||
372
+ c == '}' || c == '|' || c == '\\' || c == '/' || c == '?' ||
373
+ c == '<' || c == '>' || c == ',' || c == ';' || c == ':' ||
374
+ c == '"' || c == '\'' || c == '`' || c == '~' || c == '!') {
375
+ return false;
376
+ }
377
+ }
378
+
379
+ return true;
380
+ }
381
+
555
382
  std::vector<std::string> get_local_interface_addresses() {
556
383
  LOG_NETUTILS_DEBUG("Getting all local interface addresses (IPv4 and IPv6)");
557
384
 
558
385
  std::vector<std::string> addresses;
559
386
 
560
- // Get IPv4 addresses
561
387
  auto ipv4_addresses = get_local_interface_addresses_v4();
562
388
  addresses.insert(addresses.end(), ipv4_addresses.begin(), ipv4_addresses.end());
563
389
 
564
- // Get IPv6 addresses
565
390
  auto ipv6_addresses = get_local_interface_addresses_v6();
566
391
  addresses.insert(addresses.end(), ipv6_addresses.begin(), ipv6_addresses.end());
567
392
 
@@ -571,28 +396,5 @@ std::vector<std::string> get_local_interface_addresses() {
571
396
  return addresses;
572
397
  }
573
398
 
574
- bool is_local_interface_address(const std::string& ip_address) {
575
- LOG_NETUTILS_DEBUG("Checking if " << ip_address << " is a local interface address");
576
-
577
- // Get all local addresses and check if the given address is in the list
578
- auto local_addresses = get_local_interface_addresses();
579
-
580
- for (const auto& local_addr : local_addresses) {
581
- if (local_addr == ip_address) {
582
- LOG_NETUTILS_DEBUG(ip_address << " is a local interface address");
583
- return true;
584
- }
585
- }
586
-
587
- // Also check common localhost addresses
588
- if (ip_address == "127.0.0.1" || ip_address == "::1" || ip_address == "localhost") {
589
- LOG_NETUTILS_DEBUG(ip_address << " is a localhost address");
590
- return true;
591
- }
592
-
593
- LOG_NETUTILS_DEBUG(ip_address << " is not a local interface address");
594
- return false;
595
- }
596
-
597
399
  } // namespace network_utils
598
- } // namespace librats
400
+ } // namespace librats