diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-08-21 22:34:17 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-08-21 22:34:17 +0000 |
commit | 1355ed0acd88356beccc25dfc710ef0d458b5b96 (patch) | |
tree | 9f9b038f4313c39cc7360d9d7a73ca824da0bc83 /src/transport/gnunet-nat-server-windows.c | |
parent | 59303b47a266fa1b40da6725f2cac5f29f358cbe (diff) | |
download | gnunet-1355ed0acd88356beccc25dfc710ef0d458b5b96.tar.gz gnunet-1355ed0acd88356beccc25dfc710ef0d458b5b96.zip |
cleaning
Diffstat (limited to 'src/transport/gnunet-nat-server-windows.c')
-rw-r--r-- | src/transport/gnunet-nat-server-windows.c | 236 |
1 files changed, 128 insertions, 108 deletions
diff --git a/src/transport/gnunet-nat-server-windows.c b/src/transport/gnunet-nat-server-windows.c index bb135ed08..11c63aa9d 100644 --- a/src/transport/gnunet-nat-server-windows.c +++ b/src/transport/gnunet-nat-server-windows.c | |||
@@ -72,7 +72,7 @@ | |||
72 | 72 | ||
73 | #define ICMP_ECHO 8 | 73 | #define ICMP_ECHO 8 |
74 | 74 | ||
75 | #define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ | 75 | #define ICMP_TIME_EXCEEDED 11 |
76 | 76 | ||
77 | /** | 77 | /** |
78 | * How often do we send our ICMP messages to receive replies? | 78 | * How often do we send our ICMP messages to receive replies? |
@@ -82,7 +82,7 @@ | |||
82 | /** | 82 | /** |
83 | * IPv4 header. | 83 | * IPv4 header. |
84 | */ | 84 | */ |
85 | struct ip_packet | 85 | struct ip_header |
86 | { | 86 | { |
87 | 87 | ||
88 | /** | 88 | /** |
@@ -139,7 +139,20 @@ struct ip_packet | |||
139 | /** | 139 | /** |
140 | * Format of ICMP packet. | 140 | * Format of ICMP packet. |
141 | */ | 141 | */ |
142 | struct icmp_packet | 142 | struct icmp_ttl_exceeded_header |
143 | { | ||
144 | uint8_t type; | ||
145 | |||
146 | uint8_t code; | ||
147 | |||
148 | uint16_t checksum; | ||
149 | |||
150 | uint32_t unused; | ||
151 | |||
152 | /* followed by original payload */ | ||
153 | }; | ||
154 | |||
155 | struct icmp_echo_header | ||
143 | { | 156 | { |
144 | uint8_t type; | 157 | uint8_t type; |
145 | 158 | ||
@@ -153,13 +166,15 @@ struct icmp_packet | |||
153 | /** | 166 | /** |
154 | * Beginning of UDP packet. | 167 | * Beginning of UDP packet. |
155 | */ | 168 | */ |
156 | struct udp_packet | 169 | struct udp_header |
157 | { | 170 | { |
158 | uint16_t src_port; | 171 | uint16_t src_port; |
159 | 172 | ||
160 | uint16_t dst_port; | 173 | uint16_t dst_port; |
161 | 174 | ||
162 | uint32_t length; | 175 | uint16_t length; |
176 | |||
177 | uint16_t crc; | ||
163 | }; | 178 | }; |
164 | 179 | ||
165 | /** | 180 | /** |
@@ -240,19 +255,17 @@ inet_pton (int af, | |||
240 | static void | 255 | static void |
241 | send_icmp_echo (const struct in_addr *my_ip) | 256 | send_icmp_echo (const struct in_addr *my_ip) |
242 | { | 257 | { |
243 | struct icmp_packet icmp_echo; | 258 | char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)]; |
259 | struct icmp_ttl_exceeded_header icmp_echo; | ||
260 | struct ip_header ip_pkt; | ||
244 | struct sockaddr_in dst; | 261 | struct sockaddr_in dst; |
245 | size_t off; | 262 | size_t off; |
246 | int err; | 263 | int err; |
247 | struct ip_packet ip_pkt; | ||
248 | struct icmp_packet icmp_pkt; | ||
249 | char packet[sizeof (ip_pkt) + sizeof (icmp_pkt)]; | ||
250 | 264 | ||
251 | off = 0; | 265 | off = 0; |
252 | memset(&ip_pkt, 0, sizeof(ip_pkt)); | ||
253 | ip_pkt.vers_ihl = 0x45; | 266 | ip_pkt.vers_ihl = 0x45; |
254 | ip_pkt.tos = 0; | 267 | ip_pkt.tos = 0; |
255 | ip_pkt.pkt_len = sizeof (packet); | 268 | ip_pkt.pkt_len = htons (sizeof (packet)); |
256 | ip_pkt.id = htons (256); | 269 | ip_pkt.id = htons (256); |
257 | ip_pkt.flags_frag_offset = 0; | 270 | ip_pkt.flags_frag_offset = 0; |
258 | ip_pkt.ttl = IPDEFTTL; | 271 | ip_pkt.ttl = IPDEFTTL; |
@@ -260,18 +273,23 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
260 | ip_pkt.checksum = 0; | 273 | ip_pkt.checksum = 0; |
261 | ip_pkt.src_ip = my_ip->s_addr; | 274 | ip_pkt.src_ip = my_ip->s_addr; |
262 | ip_pkt.dst_ip = dummy.s_addr; | 275 | ip_pkt.dst_ip = dummy.s_addr; |
263 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (ip_pkt))); | 276 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, |
264 | memcpy (&packet[off], &ip_pkt, sizeof (ip_pkt)); | 277 | sizeof (struct ip_header))); |
265 | off += sizeof (ip_pkt); | 278 | memcpy (&packet[off], |
279 | &ip_pkt, | ||
280 | sizeof (struct ip_header)); | ||
281 | off += sizeof (struct ip_header); | ||
266 | 282 | ||
267 | icmp_echo.type = ICMP_ECHO; | 283 | icmp_echo.type = ICMP_ECHO; |
268 | icmp_echo.code = 0; | 284 | icmp_echo.code = 0; |
269 | icmp_echo.reserved = 0; | 285 | icmp_echo.reserved = 0; |
270 | icmp_echo.checksum = 0; | 286 | icmp_echo.checksum = 0; |
271 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, | 287 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, |
272 | sizeof (struct icmp_packet))); | 288 | sizeof (struct icmp_echo_header))); |
273 | memcpy (&packet[off], &icmp_echo, sizeof (icmp_echo)); | 289 | memcpy (&packet[off], |
274 | off += sizeof (icmp_echo); | 290 | &icmp_echo, |
291 | sizeof (struct icmp_echo_header)); | ||
292 | off += sizeof (struct icmp_echo_header); | ||
275 | 293 | ||
276 | memset (&dst, 0, sizeof (dst)); | 294 | memset (&dst, 0, sizeof (dst)); |
277 | dst.sin_family = AF_INET; | 295 | dst.sin_family = AF_INET; |
@@ -297,11 +315,9 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
297 | 315 | ||
298 | /** | 316 | /** |
299 | * Send a UDP message to the dummy IP. | 317 | * Send a UDP message to the dummy IP. |
300 | * | ||
301 | * @param my_ip source address (our ip address) | ||
302 | */ | 318 | */ |
303 | static void | 319 | static void |
304 | send_udp (const struct in_addr *my_ip) | 320 | send_udp () |
305 | { | 321 | { |
306 | struct sockaddr_in dst; | 322 | struct sockaddr_in dst; |
307 | ssize_t err; | 323 | ssize_t err; |
@@ -321,7 +337,7 @@ send_udp (const struct in_addr *my_ip) | |||
321 | "sendto failed: %s\n", strerror(errno)); | 337 | "sendto failed: %s\n", strerror(errno)); |
322 | #endif | 338 | #endif |
323 | } | 339 | } |
324 | else if (err != 0) | 340 | else if (0 != err) |
325 | { | 341 | { |
326 | fprintf(stderr, | 342 | fprintf(stderr, |
327 | "Error: partial send of ICMP message\n"); | 343 | "Error: partial send of ICMP message\n"); |
@@ -337,13 +353,14 @@ process_icmp_response () | |||
337 | { | 353 | { |
338 | char buf[65536]; | 354 | char buf[65536]; |
339 | ssize_t have; | 355 | ssize_t have; |
340 | struct in_addr sip; | 356 | struct in_addr source_ip; |
341 | struct ip_packet ip_pkt; | 357 | struct ip_header ip_pkt; |
342 | struct icmp_packet icmp_pkt; | 358 | struct icmp_ttl_exceeded_header icmp_pkt; |
343 | struct udp_packet udp_pkt; | 359 | struct icmp_echo_header icmp_echo; |
360 | struct udp_header udp_pkt; | ||
344 | size_t off; | 361 | size_t off; |
345 | int have_port; | 362 | uint16_t port; |
346 | uint32_t port; | 363 | DWORD ssize; |
347 | 364 | ||
348 | have = read (icmpsock, buf, sizeof (buf)); | 365 | have = read (icmpsock, buf, sizeof (buf)); |
349 | if (have == -1) | 366 | if (have == -1) |
@@ -359,82 +376,85 @@ process_icmp_response () | |||
359 | "Received message of %u bytes\n", | 376 | "Received message of %u bytes\n", |
360 | (unsigned int) have); | 377 | (unsigned int) have); |
361 | #endif | 378 | #endif |
362 | if (have == sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2 + sizeof(uint32_t)) | 379 | if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header))) |
363 | { | 380 | { |
364 | have_port = 1; | 381 | /* malformed */ |
365 | } | ||
366 | else if (have != sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2) | ||
367 | { | ||
368 | #if VERBOSE | ||
369 | fprintf (stderr, | ||
370 | "Received ICMP message of unexpected size: %u bytes\n", | ||
371 | (unsigned int) have); | ||
372 | #endif | ||
373 | return; | 382 | return; |
374 | } | 383 | } |
375 | off = 0; | 384 | off = 0; |
376 | memcpy (&ip_pkt, &buf[off], sizeof (ip_pkt)); | 385 | memcpy (&ip_pkt, |
377 | off += sizeof (ip_pkt); | 386 | &buf[off], |
378 | memcpy (&icmp_pkt, &buf[off], sizeof (icmp_pkt)); | 387 | sizeof (struct ip_header)); |
379 | off += sizeof (icmp_pkt); | 388 | off += sizeof (struct ip_header); |
380 | if ( ((ip_pkt.proto != IPPROTO_ICMP) && (ip_pkt.proto != IPPROTO_UDP)) || | 389 | memcpy(&source_ip, |
381 | (icmp_pkt.type != ICMP_TIME_EXCEEDED) || | ||
382 | (icmp_pkt.code != 0) ) | ||
383 | { | ||
384 | /* maybe we got an actual reply back... */ | ||
385 | return; | ||
386 | } | ||
387 | memcpy(&sip, | ||
388 | &ip_pkt.src_ip, | 390 | &ip_pkt.src_ip, |
389 | sizeof (sip)); | 391 | sizeof (source_ip)); |
390 | memcpy (&ip_pkt, &buf[off], sizeof (ip_pkt)); | 392 | memcpy (&icmp_ttl, |
391 | off += sizeof (ip_pkt); | 393 | &buf[off], |
392 | 394 | sizeof (struct icmp_ttl_exceeded_header)); | |
393 | if (have_port) | 395 | off += sizeof (struct icmp_ttl_exceeded_header); |
396 | if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || | ||
397 | (0 != icmp_ttl.code) ) | ||
394 | { | 398 | { |
395 | memcpy(&port, | 399 | /* different type than what we want */ |
396 | &buf[sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2], | 400 | return; |
397 | sizeof(uint32_t)); | ||
398 | port = ntohs(port); | ||
399 | DWORD ssize = sizeof(buf); | ||
400 | WSAAddressToString((LPSOCKADDR)&sip, | ||
401 | sizeof(sip), | ||
402 | NULL, | ||
403 | buf, | ||
404 | &ssize); | ||
405 | fprintf (stdout, | ||
406 | "%s:%d\n", | ||
407 | buf, | ||
408 | port); | ||
409 | } | 401 | } |
410 | else if (ip_pkt.proto == IPPROTO_UDP) | 402 | /* skip 2nd IP header */ |
403 | memcpy (&ip_pkt, | ||
404 | &buf[off], | ||
405 | sizeof (struct ip_header)); | ||
406 | off += sizeof (struct ip_header); | ||
407 | |||
408 | switch (ip_pkt.proto) | ||
411 | { | 409 | { |
412 | memcpy(&udp_pkt, | 410 | case IPPROTO_ICMP: |
413 | &buf[off], | 411 | if (have != (sizeof (struct ip_header) * 2 + |
414 | sizeof(udp_pkt)); | 412 | sizeof (struct icmp_ttl_exceeded_header) + |
415 | DWORD ssize = sizeof(buf); | 413 | sizeof (struct icmp_echo_header)) ) |
416 | WSAAddressToString((LPSOCKADDR)&sip, | 414 | { |
417 | sizeof(sip), | 415 | /* malformed */ |
418 | NULL, | 416 | return; |
419 | buf, | 417 | } |
420 | &ssize); | 418 | /* grab ICMP ECHO content */ |
421 | fprintf (stdout, | 419 | memcpy (&icmp_echo, |
422 | "%s:%d\n", | 420 | &buf[off], |
423 | buf, | 421 | sizeof (struct icmp_echo_header)); |
424 | ntohs((uint16_t)udp_pkt.length)); | 422 | port = (uint16_t) ntohl (icmp_echo.reserved); |
423 | break; | ||
424 | case IPPROTO_UDP: | ||
425 | if (have != (sizeof (struct ip_header) * 2 + | ||
426 | sizeof (struct icmp_ttl_exceeded_header) + | ||
427 | sizeof (struct udp_header)) ) | ||
428 | { | ||
429 | /* malformed */ | ||
430 | return; | ||
431 | } | ||
432 | /* grab UDP content */ | ||
433 | memcpy (&udp_pkt, | ||
434 | &buf[off], | ||
435 | sizeof (struct udp_header)); | ||
436 | port = ntohs (udp_pkt.length); | ||
437 | break; | ||
438 | default: | ||
439 | /* different type than what we want */ | ||
440 | return; | ||
425 | } | 441 | } |
442 | |||
443 | ssize = sizeof(buf); | ||
444 | WSAAddressToString((LPSOCKADDR)&source_ip, | ||
445 | sizeof(source_ip), | ||
446 | NULL, | ||
447 | buf, | ||
448 | &ssize); | ||
449 | if (port == 0) | ||
450 | fprintf (stdout, | ||
451 | "%s\n", | ||
452 | buf); | ||
426 | else | 453 | else |
427 | { | 454 | fprintf (stdout, |
428 | DWORD ssize = sizeof(buf); | 455 | "%s:%u\n", |
429 | WSAAddressToString((LPSOCKADDR)&sip, | 456 | buf, |
430 | sizeof(sip), | 457 | (unsigned int) port); |
431 | NULL, | ||
432 | buf, | ||
433 | &ssize); | ||
434 | fprintf (stdout, | ||
435 | "%s\n", | ||
436 | buf); | ||
437 | } | ||
438 | fflush (stdout); | 458 | fflush (stdout); |
439 | } | 459 | } |
440 | 460 | ||
@@ -481,10 +501,10 @@ make_raw_socket () | |||
481 | return INVALID_SOCKET; | 501 | return INVALID_SOCKET; |
482 | } | 502 | } |
483 | 503 | ||
484 | if (setsockopt(rawsock, | 504 | if (0 != setsockopt(rawsock, |
485 | SOL_SOCKET, | 505 | SOL_SOCKET, |
486 | SO_BROADCAST, | 506 | SO_BROADCAST, |
487 | (char*)&bOptVal, bOptLen) != 0) | 507 | (char*)&bOptVal, bOptLen)) |
488 | { | 508 | { |
489 | fprintf(stderr, | 509 | fprintf(stderr, |
490 | "Error setting SO_BROADCAST to ON: %s\n", | 510 | "Error setting SO_BROADCAST to ON: %s\n", |
@@ -492,10 +512,10 @@ make_raw_socket () | |||
492 | closesocket(rawsock); | 512 | closesocket(rawsock); |
493 | return INVALID_SOCKET; | 513 | return INVALID_SOCKET; |
494 | } | 514 | } |
495 | if (setsockopt(rawsock, | 515 | if (0 != setsockopt(rawsock, |
496 | IPPROTO_IP, | 516 | IPPROTO_IP, |
497 | IP_HDRINCL, | 517 | IP_HDRINCL, |
498 | (char*)&bOptVal, bOptLen) != 0) | 518 | (char*)&bOptVal, bOptLen)) |
499 | { | 519 | { |
500 | fprintf(stderr, | 520 | fprintf(stderr, |
501 | "Error setting IP_HDRINCL to ON: %s\n", | 521 | "Error setting IP_HDRINCL to ON: %s\n", |
@@ -510,10 +530,11 @@ make_raw_socket () | |||
510 | /** | 530 | /** |
511 | * Create a UDP socket for writinging. | 531 | * Create a UDP socket for writinging. |
512 | * | 532 | * |
513 | * @return -1 on error | 533 | * @param my_ip source address (our ip address) |
534 | * @return INVALID_SOCKET on error | ||
514 | */ | 535 | */ |
515 | static SOCKET | 536 | static SOCKET |
516 | make_udp_socket () | 537 | make_udp_socket (const struct in_addr *my_ip) |
517 | { | 538 | { |
518 | SOCKET ret; | 539 | SOCKET ret; |
519 | struct sockaddr_in addr; | 540 | struct sockaddr_in addr; |
@@ -528,9 +549,8 @@ make_udp_socket () | |||
528 | } | 549 | } |
529 | memset (&addr, 0, sizeof (addr)); | 550 | memset (&addr, 0, sizeof (addr)); |
530 | addr.sin_family = AF_INET; | 551 | addr.sin_family = AF_INET; |
531 | /* addr.sin_addr zero == ours (hopefully...) */ | 552 | addr.sin_addr = *my_ip; |
532 | addr.sin_port = htons (NAT_TRAV_PORT); | 553 | addr.sin_port = htons (NAT_TRAV_PORT); |
533 | |||
534 | if (0 != bind (ret, | 554 | if (0 != bind (ret, |
535 | &addr, | 555 | &addr, |
536 | sizeof(addr))) | 556 | sizeof(addr))) |
@@ -555,7 +575,7 @@ main (int argc, | |||
555 | WSADATA wsaData; | 575 | WSADATA wsaData; |
556 | unsigned int alt; | 576 | unsigned int alt; |
557 | 577 | ||
558 | if (argc != 2) | 578 | if (2 != argc) |
559 | { | 579 | { |
560 | fprintf (stderr, | 580 | fprintf (stderr, |
561 | "This program must be started with our (internal NAT) IP as the only argument.\n"); | 581 | "This program must be started with our (internal NAT) IP as the only argument.\n"); |
@@ -588,7 +608,7 @@ main (int argc, | |||
588 | closesocket (icmpsock); | 608 | closesocket (icmpsock); |
589 | return 3; | 609 | return 3; |
590 | } | 610 | } |
591 | if (INVALID_SOCKET == (udpsock = make_udp_socket())) | 611 | if (INVALID_SOCKET == (udpsock = make_udp_socket(&external))) |
592 | { | 612 | { |
593 | closesocket (icmpsock); | 613 | closesocket (icmpsock); |
594 | closesocket (rawsock); | 614 | closesocket (rawsock); |
@@ -614,7 +634,7 @@ main (int argc, | |||
614 | if (0 == (++alt % 2)) | 634 | if (0 == (++alt % 2)) |
615 | send_icmp_echo (&external); | 635 | send_icmp_echo (&external); |
616 | else | 636 | else |
617 | send_udp (&external); | 637 | send_udp (); |
618 | } | 638 | } |
619 | /* select failed (internal error or OS out of resources) */ | 639 | /* select failed (internal error or OS out of resources) */ |
620 | closesocket(icmpsock); | 640 | closesocket(icmpsock); |