diff options
Diffstat (limited to 'src/nat/gnunet-helper-nat-server.c')
-rw-r--r-- | src/nat/gnunet-helper-nat-server.c | 583 |
1 files changed, 290 insertions, 293 deletions
diff --git a/src/nat/gnunet-helper-nat-server.c b/src/nat/gnunet-helper-nat-server.c index 78b926037..f087590c8 100644 --- a/src/nat/gnunet-helper-nat-server.c +++ b/src/nat/gnunet-helper-nat-server.c | |||
@@ -11,12 +11,12 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file src/nat/gnunet-helper-nat-server.c | 22 | * @file src/nat/gnunet-helper-nat-server.c |
@@ -79,7 +79,7 @@ | |||
79 | * @param src source of the copy, may be NULL if @a n is zero | 79 | * @param src source of the copy, may be NULL if @a n is zero |
80 | * @param n number of bytes to copy | 80 | * @param n number of bytes to copy |
81 | */ | 81 | */ |
82 | #define GNUNET_memcpy(dst,src,n) do { if (0 != n) { (void) memcpy (dst,src,n); } } while (0) | 82 | #define GNUNET_memcpy(dst, src, n) do { if (0 != n) { (void)memcpy(dst, src, n); } } while (0) |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * Should we print some debug output? | 85 | * Should we print some debug output? |
@@ -109,9 +109,7 @@ | |||
109 | /** | 109 | /** |
110 | * IPv4 header. | 110 | * IPv4 header. |
111 | */ | 111 | */ |
112 | struct ip_header | 112 | struct ip_header { |
113 | { | ||
114 | |||
115 | /** | 113 | /** |
116 | * Version (4 bits) + Internet header length (4 bits) | 114 | * Version (4 bits) + Internet header length (4 bits) |
117 | */ | 115 | */ |
@@ -166,8 +164,7 @@ struct ip_header | |||
166 | /** | 164 | /** |
167 | * Format of ICMP packet. | 165 | * Format of ICMP packet. |
168 | */ | 166 | */ |
169 | struct icmp_ttl_exceeded_header | 167 | struct icmp_ttl_exceeded_header { |
170 | { | ||
171 | uint8_t type; | 168 | uint8_t type; |
172 | 169 | ||
173 | uint8_t code; | 170 | uint8_t code; |
@@ -179,8 +176,7 @@ struct icmp_ttl_exceeded_header | |||
179 | /* followed by original payload */ | 176 | /* followed by original payload */ |
180 | }; | 177 | }; |
181 | 178 | ||
182 | struct icmp_echo_header | 179 | struct icmp_echo_header { |
183 | { | ||
184 | uint8_t type; | 180 | uint8_t type; |
185 | 181 | ||
186 | uint8_t code; | 182 | uint8_t code; |
@@ -194,8 +190,7 @@ struct icmp_echo_header | |||
194 | /** | 190 | /** |
195 | * Beginning of UDP packet. | 191 | * Beginning of UDP packet. |
196 | */ | 192 | */ |
197 | struct udp_header | 193 | struct udp_header { |
198 | { | ||
199 | uint16_t src_port; | 194 | uint16_t src_port; |
200 | 195 | ||
201 | uint16_t dst_port; | 196 | uint16_t dst_port; |
@@ -234,7 +229,7 @@ static struct in_addr dummy; | |||
234 | * @return the CRC 16. | 229 | * @return the CRC 16. |
235 | */ | 230 | */ |
236 | static uint16_t | 231 | static uint16_t |
237 | calc_checksum (const uint16_t * data, unsigned int bytes) | 232 | calc_checksum(const uint16_t * data, unsigned int bytes) |
238 | { | 233 | { |
239 | uint32_t sum; | 234 | uint32_t sum; |
240 | unsigned int i; | 235 | unsigned int i; |
@@ -243,7 +238,7 @@ calc_checksum (const uint16_t * data, unsigned int bytes) | |||
243 | for (i = 0; i < bytes / 2; i++) | 238 | for (i = 0; i < bytes / 2; i++) |
244 | sum += data[i]; | 239 | sum += data[i]; |
245 | sum = (sum & 0xffff) + (sum >> 16); | 240 | sum = (sum & 0xffff) + (sum >> 16); |
246 | sum = htons (0xffff - sum); | 241 | sum = htons(0xffff - sum); |
247 | return sum; | 242 | return sum; |
248 | } | 243 | } |
249 | 244 | ||
@@ -254,9 +249,9 @@ calc_checksum (const uint16_t * data, unsigned int bytes) | |||
254 | * @param my_ip source address (our ip address) | 249 | * @param my_ip source address (our ip address) |
255 | */ | 250 | */ |
256 | static void | 251 | static void |
257 | send_icmp_echo (const struct in_addr *my_ip) | 252 | send_icmp_echo(const struct in_addr *my_ip) |
258 | { | 253 | { |
259 | char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)]; | 254 | char packet[sizeof(struct ip_header) + sizeof(struct icmp_echo_header)]; |
260 | struct icmp_echo_header icmp_echo; | 255 | struct icmp_echo_header icmp_echo; |
261 | struct ip_header ip_pkt; | 256 | struct ip_header ip_pkt; |
262 | struct sockaddr_in dst; | 257 | struct sockaddr_in dst; |
@@ -266,8 +261,8 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
266 | off = 0; | 261 | off = 0; |
267 | ip_pkt.vers_ihl = 0x45; | 262 | ip_pkt.vers_ihl = 0x45; |
268 | ip_pkt.tos = 0; | 263 | ip_pkt.tos = 0; |
269 | ip_pkt.pkt_len = htons (sizeof (packet)); | 264 | ip_pkt.pkt_len = htons(sizeof(packet)); |
270 | ip_pkt.id = htons (PACKET_ID); | 265 | ip_pkt.id = htons(PACKET_ID); |
271 | ip_pkt.flags_frag_offset = 0; | 266 | ip_pkt.flags_frag_offset = 0; |
272 | ip_pkt.ttl = IPDEFTTL; | 267 | ip_pkt.ttl = IPDEFTTL; |
273 | ip_pkt.proto = IPPROTO_ICMP; | 268 | ip_pkt.proto = IPPROTO_ICMP; |
@@ -275,51 +270,51 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
275 | ip_pkt.src_ip = my_ip->s_addr; | 270 | ip_pkt.src_ip = my_ip->s_addr; |
276 | ip_pkt.dst_ip = dummy.s_addr; | 271 | ip_pkt.dst_ip = dummy.s_addr; |
277 | ip_pkt.checksum = | 272 | ip_pkt.checksum = |
278 | htons (calc_checksum ((uint16_t *) & ip_pkt, | 273 | htons(calc_checksum((uint16_t *)&ip_pkt, |
279 | sizeof (struct ip_header))); | 274 | sizeof(struct ip_header))); |
280 | GNUNET_memcpy (&packet[off], | 275 | GNUNET_memcpy(&packet[off], |
281 | &ip_pkt, | 276 | &ip_pkt, |
282 | sizeof (struct ip_header)); | 277 | sizeof(struct ip_header)); |
283 | off += sizeof (struct ip_header); | 278 | off += sizeof(struct ip_header); |
284 | 279 | ||
285 | icmp_echo.type = ICMP_ECHO; | 280 | icmp_echo.type = ICMP_ECHO; |
286 | icmp_echo.code = 0; | 281 | icmp_echo.code = 0; |
287 | icmp_echo.checksum = 0; | 282 | icmp_echo.checksum = 0; |
288 | icmp_echo.reserved = 0; | 283 | icmp_echo.reserved = 0; |
289 | icmp_echo.checksum = | 284 | icmp_echo.checksum = |
290 | htons (calc_checksum | 285 | htons(calc_checksum |
291 | ((uint16_t *) & icmp_echo, | 286 | ((uint16_t *)&icmp_echo, |
292 | sizeof (struct icmp_echo_header))); | 287 | sizeof(struct icmp_echo_header))); |
293 | GNUNET_memcpy (&packet[off], | 288 | GNUNET_memcpy(&packet[off], |
294 | &icmp_echo, | 289 | &icmp_echo, |
295 | sizeof (struct icmp_echo_header)); | 290 | sizeof(struct icmp_echo_header)); |
296 | off += sizeof (struct icmp_echo_header); | 291 | off += sizeof(struct icmp_echo_header); |
297 | 292 | ||
298 | memset (&dst, 0, sizeof (dst)); | 293 | memset(&dst, 0, sizeof(dst)); |
299 | dst.sin_family = AF_INET; | 294 | dst.sin_family = AF_INET; |
300 | #if HAVE_SOCKADDR_IN_SIN_LEN | 295 | #if HAVE_SOCKADDR_IN_SIN_LEN |
301 | dst.sin_len = sizeof (struct sockaddr_in); | 296 | dst.sin_len = sizeof(struct sockaddr_in); |
302 | #endif | 297 | #endif |
303 | dst.sin_addr = dummy; | 298 | dst.sin_addr = dummy; |
304 | err = sendto (rawsock, | 299 | err = sendto(rawsock, |
305 | packet, | 300 | packet, |
306 | off, | 301 | off, |
307 | 0, | 302 | 0, |
308 | (struct sockaddr *) &dst, | 303 | (struct sockaddr *)&dst, |
309 | sizeof (dst)); | 304 | sizeof(dst)); |
310 | if (err < 0) | 305 | if (err < 0) |
311 | { | 306 | { |
312 | #if VERBOSE | 307 | #if VERBOSE |
313 | fprintf (stderr, | 308 | fprintf(stderr, |
314 | "sendto failed: %s\n", | 309 | "sendto failed: %s\n", |
315 | strerror (errno)); | 310 | strerror(errno)); |
316 | #endif | 311 | #endif |
317 | } | 312 | } |
318 | else if (sizeof (packet) != err) | 313 | else if (sizeof(packet) != err) |
319 | { | 314 | { |
320 | fprintf (stderr, | 315 | fprintf(stderr, |
321 | "Error: partial send of ICMP message\n"); | 316 | "Error: partial send of ICMP message\n"); |
322 | } | 317 | } |
323 | } | 318 | } |
324 | 319 | ||
325 | 320 | ||
@@ -327,37 +322,37 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
327 | * Send a UDP message to the dummy IP. | 322 | * Send a UDP message to the dummy IP. |
328 | */ | 323 | */ |
329 | static void | 324 | static void |
330 | send_udp () | 325 | send_udp() |
331 | { | 326 | { |
332 | struct sockaddr_in dst; | 327 | struct sockaddr_in dst; |
333 | ssize_t err; | 328 | ssize_t err; |
334 | 329 | ||
335 | memset (&dst, 0, sizeof (dst)); | 330 | memset(&dst, 0, sizeof(dst)); |
336 | dst.sin_family = AF_INET; | 331 | dst.sin_family = AF_INET; |
337 | #if HAVE_SOCKADDR_IN_SIN_LEN | 332 | #if HAVE_SOCKADDR_IN_SIN_LEN |
338 | dst.sin_len = sizeof (struct sockaddr_in); | 333 | dst.sin_len = sizeof(struct sockaddr_in); |
339 | #endif | 334 | #endif |
340 | dst.sin_addr = dummy; | 335 | dst.sin_addr = dummy; |
341 | dst.sin_port = htons (NAT_TRAV_PORT); | 336 | dst.sin_port = htons(NAT_TRAV_PORT); |
342 | err = sendto (udpsock, | 337 | err = sendto(udpsock, |
343 | NULL, | 338 | NULL, |
344 | 0, | 339 | 0, |
345 | 0, | 340 | 0, |
346 | (struct sockaddr *) &dst, | 341 | (struct sockaddr *)&dst, |
347 | sizeof (dst)); | 342 | sizeof(dst)); |
348 | if (err < 0) | 343 | if (err < 0) |
349 | { | 344 | { |
350 | #if VERBOSE | 345 | #if VERBOSE |
351 | fprintf (stderr, | 346 | fprintf(stderr, |
352 | "sendto failed: %s\n", | 347 | "sendto failed: %s\n", |
353 | strerror (errno)); | 348 | strerror(errno)); |
354 | #endif | 349 | #endif |
355 | } | 350 | } |
356 | else if (0 != err) | 351 | else if (0 != err) |
357 | { | 352 | { |
358 | fprintf (stderr, | 353 | fprintf(stderr, |
359 | "Error: partial send of ICMP message\n"); | 354 | "Error: partial send of ICMP message\n"); |
360 | } | 355 | } |
361 | } | 356 | } |
362 | 357 | ||
363 | 358 | ||
@@ -365,7 +360,7 @@ send_udp () | |||
365 | * We've received an ICMP response. Process it. | 360 | * We've received an ICMP response. Process it. |
366 | */ | 361 | */ |
367 | static void | 362 | static void |
368 | process_icmp_response () | 363 | process_icmp_response() |
369 | { | 364 | { |
370 | char buf[65536]; | 365 | char buf[65536]; |
371 | ssize_t have; | 366 | ssize_t have; |
@@ -377,94 +372,96 @@ process_icmp_response () | |||
377 | size_t off; | 372 | size_t off; |
378 | uint16_t port; | 373 | uint16_t port; |
379 | 374 | ||
380 | have = read (icmpsock, buf, sizeof (buf)); | 375 | have = read(icmpsock, buf, sizeof(buf)); |
381 | if (-1 == have) | 376 | if (-1 == have) |
382 | { | 377 | { |
383 | fprintf (stderr, | 378 | fprintf(stderr, |
384 | "Error reading raw socket: %s\n", | 379 | "Error reading raw socket: %s\n", |
385 | strerror (errno)); | 380 | strerror(errno)); |
386 | return; | 381 | return; |
387 | } | 382 | } |
388 | #if VERBOSE | 383 | #if VERBOSE |
389 | fprintf (stderr, | 384 | fprintf(stderr, |
390 | "Received message of %u bytes\n", | 385 | "Received message of %u bytes\n", |
391 | (unsigned int) have); | 386 | (unsigned int)have); |
392 | #endif | 387 | #endif |
393 | if (have < | 388 | if (have < |
394 | (ssize_t) (sizeof (struct ip_header) + | 389 | (ssize_t)(sizeof(struct ip_header) + |
395 | sizeof (struct icmp_ttl_exceeded_header) + | 390 | sizeof(struct icmp_ttl_exceeded_header) + |
396 | sizeof (struct ip_header))) | 391 | sizeof(struct ip_header))) |
397 | { | 392 | { |
398 | /* malformed */ | 393 | /* malformed */ |
399 | return; | 394 | return; |
400 | } | 395 | } |
401 | off = 0; | 396 | off = 0; |
402 | GNUNET_memcpy (&ip_pkt, | 397 | GNUNET_memcpy(&ip_pkt, |
403 | &buf[off], | 398 | &buf[off], |
404 | sizeof (struct ip_header)); | 399 | sizeof(struct ip_header)); |
405 | off += sizeof (struct ip_header); | 400 | off += sizeof(struct ip_header); |
406 | GNUNET_memcpy (&icmp_ttl, | 401 | GNUNET_memcpy(&icmp_ttl, |
407 | &buf[off], | 402 | &buf[off], |
408 | sizeof (struct icmp_ttl_exceeded_header)); | 403 | sizeof(struct icmp_ttl_exceeded_header)); |
409 | off += sizeof (struct icmp_ttl_exceeded_header); | 404 | off += sizeof(struct icmp_ttl_exceeded_header); |
410 | if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code)) | 405 | if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code)) |
411 | { | 406 | { |
412 | /* different type than what we want */ | 407 | /* different type than what we want */ |
413 | return; | 408 | return; |
414 | } | 409 | } |
415 | /* grab source IP of 1st IP header */ | 410 | /* grab source IP of 1st IP header */ |
416 | source_ip.s_addr = ip_pkt.src_ip; | 411 | source_ip.s_addr = ip_pkt.src_ip; |
417 | 412 | ||
418 | /* skip 2nd IP header */ | 413 | /* skip 2nd IP header */ |
419 | GNUNET_memcpy (&ip_pkt, | 414 | GNUNET_memcpy(&ip_pkt, |
420 | &buf[off], | 415 | &buf[off], |
421 | sizeof (struct ip_header)); | 416 | sizeof(struct ip_header)); |
422 | off += sizeof (struct ip_header); | 417 | off += sizeof(struct ip_header); |
423 | 418 | ||
424 | switch (ip_pkt.proto) | 419 | switch (ip_pkt.proto) |
425 | { | ||
426 | case IPPROTO_ICMP: | ||
427 | if (have != | ||
428 | (sizeof (struct ip_header) * 2 + | ||
429 | sizeof (struct icmp_ttl_exceeded_header) + | ||
430 | sizeof (struct icmp_echo_header))) | ||
431 | { | 420 | { |
432 | /* malformed */ | 421 | case IPPROTO_ICMP: |
433 | return; | 422 | if (have != |
434 | } | 423 | (sizeof(struct ip_header) * 2 + |
435 | /* grab ICMP ECHO content */ | 424 | sizeof(struct icmp_ttl_exceeded_header) + |
436 | GNUNET_memcpy (&icmp_echo, | 425 | sizeof(struct icmp_echo_header))) |
437 | &buf[off], | 426 | { |
438 | sizeof (struct icmp_echo_header)); | 427 | /* malformed */ |
439 | port = (uint16_t) ntohl (icmp_echo.reserved); | 428 | return; |
440 | break; | 429 | } |
441 | case IPPROTO_UDP: | 430 | /* grab ICMP ECHO content */ |
442 | if (have != | 431 | GNUNET_memcpy(&icmp_echo, |
443 | (sizeof (struct ip_header) * 2 + | 432 | &buf[off], |
444 | sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct udp_header))) | 433 | sizeof(struct icmp_echo_header)); |
445 | { | 434 | port = (uint16_t)ntohl(icmp_echo.reserved); |
446 | /* malformed */ | 435 | break; |
436 | |||
437 | case IPPROTO_UDP: | ||
438 | if (have != | ||
439 | (sizeof(struct ip_header) * 2 + | ||
440 | sizeof(struct icmp_ttl_exceeded_header) + sizeof(struct udp_header))) | ||
441 | { | ||
442 | /* malformed */ | ||
443 | return; | ||
444 | } | ||
445 | /* grab UDP content */ | ||
446 | GNUNET_memcpy(&udp_pkt, | ||
447 | &buf[off], | ||
448 | sizeof(struct udp_header)); | ||
449 | port = ntohs(udp_pkt.length); | ||
450 | break; | ||
451 | |||
452 | default: | ||
453 | /* different type than what we want */ | ||
447 | return; | 454 | return; |
448 | } | 455 | } |
449 | /* grab UDP content */ | ||
450 | GNUNET_memcpy (&udp_pkt, | ||
451 | &buf[off], | ||
452 | sizeof (struct udp_header)); | ||
453 | port = ntohs (udp_pkt.length); | ||
454 | break; | ||
455 | default: | ||
456 | /* different type than what we want */ | ||
457 | return; | ||
458 | } | ||
459 | 456 | ||
460 | if (port == 0) | 457 | if (port == 0) |
461 | fprintf (stdout, "%s\n", | 458 | fprintf(stdout, "%s\n", |
462 | inet_ntop (AF_INET, &source_ip, buf, sizeof (buf))); | 459 | inet_ntop(AF_INET, &source_ip, buf, sizeof(buf))); |
463 | else | 460 | else |
464 | fprintf (stdout, "%s:%u\n", | 461 | fprintf(stdout, "%s:%u\n", |
465 | inet_ntop (AF_INET, &source_ip, buf, sizeof (buf)), | 462 | inet_ntop(AF_INET, &source_ip, buf, sizeof(buf)), |
466 | (unsigned int) port); | 463 | (unsigned int)port); |
467 | fflush (stdout); | 464 | fflush(stdout); |
468 | } | 465 | } |
469 | 466 | ||
470 | 467 | ||
@@ -474,34 +471,34 @@ process_icmp_response () | |||
474 | * @return -1 on error, 0 on success | 471 | * @return -1 on error, 0 on success |
475 | */ | 472 | */ |
476 | static int | 473 | static int |
477 | setup_raw_socket () | 474 | setup_raw_socket() |
478 | { | 475 | { |
479 | const int one = 1; | 476 | const int one = 1; |
480 | 477 | ||
481 | if (-1 == | 478 | if (-1 == |
482 | setsockopt (rawsock, | 479 | setsockopt(rawsock, |
483 | SOL_SOCKET, | 480 | SOL_SOCKET, |
484 | SO_BROADCAST, | 481 | SO_BROADCAST, |
485 | (char *) &one, | 482 | (char *)&one, |
486 | sizeof (one))) | 483 | sizeof(one))) |
487 | { | 484 | { |
488 | fprintf (stderr, | 485 | fprintf(stderr, |
489 | "setsockopt failed: %s\n", | 486 | "setsockopt failed: %s\n", |
490 | strerror (errno)); | 487 | strerror(errno)); |
491 | return -1; | 488 | return -1; |
492 | } | 489 | } |
493 | if (-1 == | 490 | if (-1 == |
494 | setsockopt (rawsock, | 491 | setsockopt(rawsock, |
495 | IPPROTO_IP, | 492 | IPPROTO_IP, |
496 | IP_HDRINCL, | 493 | IP_HDRINCL, |
497 | (char *) &one, | 494 | (char *)&one, |
498 | sizeof (one))) | 495 | sizeof(one))) |
499 | { | 496 | { |
500 | fprintf (stderr, | 497 | fprintf(stderr, |
501 | "setsockopt failed: %s\n", | 498 | "setsockopt failed: %s\n", |
502 | strerror (errno)); | 499 | strerror(errno)); |
503 | return -1; | 500 | return -1; |
504 | } | 501 | } |
505 | return 0; | 502 | return 0; |
506 | } | 503 | } |
507 | 504 | ||
@@ -513,45 +510,45 @@ setup_raw_socket () | |||
513 | * @return -1 on error | 510 | * @return -1 on error |
514 | */ | 511 | */ |
515 | static int | 512 | static int |
516 | make_udp_socket (const struct in_addr *my_ip) | 513 | make_udp_socket(const struct in_addr *my_ip) |
517 | { | 514 | { |
518 | int ret; | 515 | int ret; |
519 | struct sockaddr_in addr; | 516 | struct sockaddr_in addr; |
520 | 517 | ||
521 | ret = socket (AF_INET, SOCK_DGRAM, 0); | 518 | ret = socket(AF_INET, SOCK_DGRAM, 0); |
522 | if (-1 == ret) | 519 | if (-1 == ret) |
523 | { | 520 | { |
524 | fprintf (stderr, | 521 | fprintf(stderr, |
525 | "Error opening UDP socket: %s\n", | 522 | "Error opening UDP socket: %s\n", |
526 | strerror (errno)); | 523 | strerror(errno)); |
527 | return -1; | 524 | return -1; |
528 | } | 525 | } |
529 | memset (&addr, 0, sizeof (addr)); | 526 | memset(&addr, 0, sizeof(addr)); |
530 | addr.sin_family = AF_INET; | 527 | addr.sin_family = AF_INET; |
531 | #if HAVE_SOCKADDR_IN_SIN_LEN | 528 | #if HAVE_SOCKADDR_IN_SIN_LEN |
532 | addr.sin_len = sizeof (struct sockaddr_in); | 529 | addr.sin_len = sizeof(struct sockaddr_in); |
533 | #endif | 530 | #endif |
534 | addr.sin_addr = *my_ip; | 531 | addr.sin_addr = *my_ip; |
535 | addr.sin_port = htons (NAT_TRAV_PORT); | 532 | addr.sin_port = htons(NAT_TRAV_PORT); |
536 | 533 | ||
537 | if (0 != bind (ret, | 534 | if (0 != bind(ret, |
538 | (struct sockaddr *) &addr, | 535 | (struct sockaddr *)&addr, |
539 | sizeof (addr))) | 536 | sizeof(addr))) |
540 | { | 537 | { |
541 | fprintf (stderr, | 538 | fprintf(stderr, |
542 | "Error binding UDP socket to port %u: %s\n", | 539 | "Error binding UDP socket to port %u: %s\n", |
543 | NAT_TRAV_PORT, | 540 | NAT_TRAV_PORT, |
544 | strerror (errno)); | 541 | strerror(errno)); |
545 | (void) close (ret); | 542 | (void)close(ret); |
546 | return -1; | 543 | return -1; |
547 | } | 544 | } |
548 | return ret; | 545 | return ret; |
549 | } | 546 | } |
550 | 547 | ||
551 | 548 | ||
552 | int | 549 | int |
553 | main (int argc, | 550 | main(int argc, |
554 | char *const *argv) | 551 | char *const *argv) |
555 | { | 552 | { |
556 | struct in_addr external; | 553 | struct in_addr external; |
557 | fd_set rs; | 554 | fd_set rs; |
@@ -563,147 +560,147 @@ main (int argc, | |||
563 | int global_ret; | 560 | int global_ret; |
564 | 561 | ||
565 | /* Create an ICMP raw socket for reading (we'll check errors later) */ | 562 | /* Create an ICMP raw socket for reading (we'll check errors later) */ |
566 | icmpsock = socket (AF_INET, | 563 | icmpsock = socket(AF_INET, |
567 | SOCK_RAW, | 564 | SOCK_RAW, |
568 | IPPROTO_ICMP); | 565 | IPPROTO_ICMP); |
569 | icmp_eno = errno; | 566 | icmp_eno = errno; |
570 | 567 | ||
571 | /* Create an (ICMP) raw socket for writing (we'll check errors later) */ | 568 | /* Create an (ICMP) raw socket for writing (we'll check errors later) */ |
572 | rawsock = socket (AF_INET, | 569 | rawsock = socket(AF_INET, |
573 | SOCK_RAW, | 570 | SOCK_RAW, |
574 | IPPROTO_RAW); | 571 | IPPROTO_RAW); |
575 | raw_eno = errno; | 572 | raw_eno = errno; |
576 | udpsock = -1; | 573 | udpsock = -1; |
577 | 574 | ||
578 | /* drop root rights */ | 575 | /* drop root rights */ |
579 | uid = getuid (); | 576 | uid = getuid(); |
580 | #ifdef HAVE_SETRESUID | 577 | #ifdef HAVE_SETRESUID |
581 | if (0 != setresuid (uid, uid, uid)) | 578 | if (0 != setresuid(uid, uid, uid)) |
582 | { | 579 | { |
583 | fprintf (stderr, | 580 | fprintf(stderr, |
584 | "Failed to setresuid: %s\n", | 581 | "Failed to setresuid: %s\n", |
585 | strerror (errno)); | 582 | strerror(errno)); |
586 | global_ret = 1; | 583 | global_ret = 1; |
587 | goto error_exit; | 584 | goto error_exit; |
588 | } | 585 | } |
589 | #else | 586 | #else |
590 | if (0 != (setuid (uid) | seteuid (uid))) | 587 | if (0 != (setuid(uid) | seteuid(uid))) |
591 | { | 588 | { |
592 | fprintf (stderr, | 589 | fprintf(stderr, |
593 | "Failed to setuid: %s\n", | 590 | "Failed to setuid: %s\n", |
594 | strerror (errno)); | 591 | strerror(errno)); |
595 | global_ret = 2; | 592 | global_ret = 2; |
596 | goto error_exit; | 593 | goto error_exit; |
597 | } | 594 | } |
598 | #endif | 595 | #endif |
599 | 596 | ||
600 | /* Now that we run without root rights, we can do error checking... */ | 597 | /* Now that we run without root rights, we can do error checking... */ |
601 | if (2 != argc) | 598 | if (2 != argc) |
602 | { | 599 | { |
603 | fprintf (stderr, | 600 | fprintf(stderr, |
604 | "This program must be started with our (internal NAT) IP as the only argument.\n"); | 601 | "This program must be started with our (internal NAT) IP as the only argument.\n"); |
605 | global_ret = 3; | 602 | global_ret = 3; |
606 | goto error_exit; | 603 | goto error_exit; |
607 | } | 604 | } |
608 | if (1 != inet_pton (AF_INET, argv[1], &external)) | 605 | if (1 != inet_pton(AF_INET, argv[1], &external)) |
609 | { | 606 | { |
610 | fprintf (stderr, | 607 | fprintf(stderr, |
611 | "Error parsing IPv4 address: %s\n", | 608 | "Error parsing IPv4 address: %s\n", |
612 | strerror (errno)); | 609 | strerror(errno)); |
613 | global_ret = 4; | 610 | global_ret = 4; |
614 | goto error_exit; | 611 | goto error_exit; |
615 | } | 612 | } |
616 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 613 | if (1 != inet_pton(AF_INET, DUMMY_IP, &dummy)) |
617 | { | 614 | { |
618 | fprintf (stderr, | 615 | fprintf(stderr, |
619 | "Internal error converting dummy IP to binary.\n"); | 616 | "Internal error converting dummy IP to binary.\n"); |
620 | global_ret = 5; | 617 | global_ret = 5; |
621 | goto error_exit; | 618 | goto error_exit; |
622 | } | 619 | } |
623 | 620 | ||
624 | /* error checking icmpsock */ | 621 | /* error checking icmpsock */ |
625 | if (-1 == icmpsock) | 622 | if (-1 == icmpsock) |
626 | { | 623 | { |
627 | fprintf (stderr, | 624 | fprintf(stderr, |
628 | "Error opening RAW socket: %s\n", | 625 | "Error opening RAW socket: %s\n", |
629 | strerror (icmp_eno)); | 626 | strerror(icmp_eno)); |
630 | global_ret = 6; | 627 | global_ret = 6; |
631 | goto error_exit; | 628 | goto error_exit; |
632 | } | 629 | } |
633 | if (icmpsock >= FD_SETSIZE) | 630 | if (icmpsock >= FD_SETSIZE) |
634 | { | 631 | { |
635 | /* this could happen if we were started with a large number of already-open | 632 | /* this could happen if we were started with a large number of already-open |
636 | file descriptors... */ | 633 | file descriptors... */ |
637 | fprintf (stderr, | 634 | fprintf(stderr, |
638 | "Socket number too large (%d > %u)\n", | 635 | "Socket number too large (%d > %u)\n", |
639 | icmpsock, | 636 | icmpsock, |
640 | (unsigned int) FD_SETSIZE); | 637 | (unsigned int)FD_SETSIZE); |
641 | global_ret = 7; | 638 | global_ret = 7; |
642 | goto error_exit; | 639 | goto error_exit; |
643 | } | 640 | } |
644 | 641 | ||
645 | /* error checking rawsock */ | 642 | /* error checking rawsock */ |
646 | if (-1 == rawsock) | 643 | if (-1 == rawsock) |
647 | { | 644 | { |
648 | fprintf (stderr, | 645 | fprintf(stderr, |
649 | "Error opening RAW socket: %s\n", | 646 | "Error opening RAW socket: %s\n", |
650 | strerror (raw_eno)); | 647 | strerror(raw_eno)); |
651 | global_ret = 8; | 648 | global_ret = 8; |
652 | goto error_exit; | 649 | goto error_exit; |
653 | } | 650 | } |
654 | /* no need to check 'rawsock' against FD_SETSIZE as it is never used | 651 | /* no need to check 'rawsock' against FD_SETSIZE as it is never used |
655 | with 'select' */ | 652 | with 'select' */ |
656 | 653 | ||
657 | if (0 != setup_raw_socket ()) | 654 | if (0 != setup_raw_socket()) |
658 | { | 655 | { |
659 | global_ret = 9; | 656 | global_ret = 9; |
660 | goto error_exit; | 657 | goto error_exit; |
661 | } | 658 | } |
662 | 659 | ||
663 | if (-1 == (udpsock = make_udp_socket (&external))) | 660 | if (-1 == (udpsock = make_udp_socket(&external))) |
664 | { | 661 | { |
665 | global_ret = 10; | 662 | global_ret = 10; |
666 | goto error_exit; | 663 | goto error_exit; |
667 | } | 664 | } |
668 | 665 | ||
669 | alt = 0; | 666 | alt = 0; |
670 | while (1) | 667 | while (1) |
671 | { | ||
672 | FD_ZERO (&rs); | ||
673 | FD_SET (icmpsock, &rs); | ||
674 | tv.tv_sec = 0; | ||
675 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | ||
676 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
677 | { | ||
678 | if (errno == EINTR) | ||
679 | continue; | ||
680 | fprintf (stderr, | ||
681 | "select failed: %s\n", | ||
682 | strerror (errno)); | ||
683 | break; | ||
684 | } | ||
685 | if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */ | ||
686 | break; | ||
687 | if (FD_ISSET (icmpsock, &rs)) | ||
688 | { | 668 | { |
689 | process_icmp_response (); | 669 | FD_ZERO(&rs); |
690 | continue; | 670 | FD_SET(icmpsock, &rs); |
671 | tv.tv_sec = 0; | ||
672 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | ||
673 | if (-1 == select(icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
674 | { | ||
675 | if (errno == EINTR) | ||
676 | continue; | ||
677 | fprintf(stderr, | ||
678 | "select failed: %s\n", | ||
679 | strerror(errno)); | ||
680 | break; | ||
681 | } | ||
682 | if (1 == getppid()) /* Check the parent process id, if 1 the parent has died, so we should die too */ | ||
683 | break; | ||
684 | if (FD_ISSET(icmpsock, &rs)) | ||
685 | { | ||
686 | process_icmp_response(); | ||
687 | continue; | ||
688 | } | ||
689 | if (0 == (++alt % 2)) | ||
690 | send_icmp_echo(&external); | ||
691 | else | ||
692 | send_udp(); | ||
691 | } | 693 | } |
692 | if (0 == (++alt % 2)) | ||
693 | send_icmp_echo (&external); | ||
694 | else | ||
695 | send_udp (); | ||
696 | } | ||
697 | 694 | ||
698 | /* select failed (internal error or OS out of resources) */ | 695 | /* select failed (internal error or OS out of resources) */ |
699 | global_ret = 11; | 696 | global_ret = 11; |
700 | error_exit: | 697 | error_exit: |
701 | if (-1 != icmpsock) | 698 | if (-1 != icmpsock) |
702 | (void) close (icmpsock); | 699 | (void)close(icmpsock); |
703 | if (-1 != rawsock) | 700 | if (-1 != rawsock) |
704 | (void) close (rawsock); | 701 | (void)close(rawsock); |
705 | if (-1 != udpsock) | 702 | if (-1 != udpsock) |
706 | (void) close (udpsock); | 703 | (void)close(udpsock); |
707 | return global_ret; | 704 | return global_ret; |
708 | } | 705 | } |
709 | 706 | ||