aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-nat-server-windows.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-08-21 22:34:17 +0000
committerChristian Grothoff <christian@grothoff.org>2010-08-21 22:34:17 +0000
commit1355ed0acd88356beccc25dfc710ef0d458b5b96 (patch)
tree9f9b038f4313c39cc7360d9d7a73ca824da0bc83 /src/transport/gnunet-nat-server-windows.c
parent59303b47a266fa1b40da6725f2cac5f29f358cbe (diff)
downloadgnunet-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.c236
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 */
85struct ip_packet 85struct 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 */
142struct icmp_packet 142struct 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
155struct 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 */
156struct udp_packet 169struct 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,
240static void 255static void
241send_icmp_echo (const struct in_addr *my_ip) 256send_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 */
303static void 319static void
304send_udp (const struct in_addr *my_ip) 320send_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 */
515static SOCKET 536static SOCKET
516make_udp_socket () 537make_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);