aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-nat-client-windows.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-08-20 13:55:33 +0000
committerChristian Grothoff <christian@grothoff.org>2010-08-20 13:55:33 +0000
commitf01828317d0644494687d4a60c922bde8b0826cb (patch)
tree16030141a9ce95da11659b30c602ff50813a3a18 /src/transport/gnunet-nat-client-windows.c
parentf315048145045606a012cc737e892bcd06d39ea5 (diff)
downloadgnunet-f01828317d0644494687d4a60c922bde8b0826cb.tar.gz
gnunet-f01828317d0644494687d4a60c922bde8b0826cb.zip
more code cleanup
Diffstat (limited to 'src/transport/gnunet-nat-client-windows.c')
-rw-r--r--src/transport/gnunet-nat-client-windows.c180
1 files changed, 138 insertions, 42 deletions
diff --git a/src/transport/gnunet-nat-client-windows.c b/src/transport/gnunet-nat-client-windows.c
index 2f5c2753a..0c920cc2a 100644
--- a/src/transport/gnunet-nat-client-windows.c
+++ b/src/transport/gnunet-nat-client-windows.c
@@ -56,9 +56,6 @@
56#include <time.h> 56#include <time.h>
57 57
58 58
59typedef unsigned int uid_t;
60typedef SOCKET Socket;
61typedef unsigned short ushort;
62#define ICMP_ECHO 8 59#define ICMP_ECHO 8
63#define IPDEFTTL 64 60#define IPDEFTTL 64
64#define ICMP_TIME_EXCEEDED 11 61#define ICMP_TIME_EXCEEDED 11
@@ -70,27 +67,76 @@ typedef unsigned short ushort;
70 67
71#define NAT_TRAV_PORT 22225 68#define NAT_TRAV_PORT 22225
72 69
70/**
71 * IPv4 header.
72 */
73struct ip_packet 73struct ip_packet
74{ 74{
75 uint8_t vers_ihl; 75
76 uint8_t tos; 76 /**
77 uint16_t pkt_len; 77 * Version (4 bits) + Internet header length (4 bits)
78 uint16_t id; 78 */
79 uint16_t flags_frag_offset; 79 uint8_t vers_ihl;
80 uint8_t ttl; 80
81 uint8_t proto; 81 /**
82 uint16_t checksum; 82 * Type of service
83 uint32_t src_ip; 83 */
84 uint32_t dst_ip; 84 uint8_t tos;
85
86 /**
87 * Total length
88 */
89 uint16_t pkt_len;
90
91 /**
92 * Identification
93 */
94 uint16_t id;
95
96 /**
97 * Flags (3 bits) + Fragment offset (13 bits)
98 */
99 uint16_t flags_frag_offset;
100
101 /**
102 * Time to live
103 */
104 uint8_t ttl;
105
106 /**
107 * Protocol
108 */
109 uint8_t proto;
110
111 /**
112 * Header checksum
113 */
114 uint16_t checksum;
115
116 /**
117 * Source address
118 */
119 uint32_t src_ip;
120
121 /**
122 * Destination address
123 */
124 uint32_t dst_ip;
85}; 125};
86 126
127
128/**
129 * Format of ICMP packet.
130 */
87struct icmp_packet 131struct icmp_packet
88{ 132{
89 uint8_t type; 133 uint8_t type;
134
90 uint8_t code; 135 uint8_t code;
136
91 uint16_t checksum; 137 uint16_t checksum;
92 uint32_t reserved;
93 138
139 uint32_t reserved;
94}; 140};
95 141
96struct icmp_echo_packet 142struct icmp_echo_packet
@@ -102,6 +148,9 @@ struct icmp_echo_packet
102 uint32_t data; 148 uint32_t data;
103}; 149};
104 150
151/**
152 * Beginning of UDP packet.
153 */
105struct udp_packet 154struct udp_packet
106{ 155{
107 uint16_t src_port; 156 uint16_t src_port;
@@ -111,29 +160,54 @@ struct udp_packet
111 uint32_t length; 160 uint32_t length;
112}; 161};
113 162
114static Socket rawsock;
115 163
164/**
165 * Socket we use to send our ICMP packets.
166 */
167static SOCKET rawsock;
168
169/**
170 * Target "dummy" address.
171 */
116static struct in_addr dummy; 172static struct in_addr dummy;
117 173
118static uint32_t port; 174static uint32_t port;
119 175
176
177
120/** 178/**
179 * Convert IPv4 address from text to binary form.
180 *
121 * @param af address family 181 * @param af address family
122 * @param cp the address to print 182 * @param cp the address to print
123 * @param buf where to write the address result 183 * @param buf where to write the address result
184 * @return 1 on success
124 */ 185 */
125static int inet_pton (int af, char *cp, struct in_addr *buf) 186static int
187inet_pton (int af,
188 const char *cp,
189 struct in_addr *buf)
126{ 190{
127 buf->s_addr = inet_addr(cp); 191 buf->s_addr = inet_addr(cp);
128 if (buf->s_addr == INADDR_NONE) 192 if (buf->s_addr == INADDR_NONE)
129 { 193 {
130 fprintf(stderr, "Error %d handling address %s", WSAGetLastError(), cp); 194 fprintf(stderr,
195 "Error %d handling address %s",
196 WSAGetLastError(),
197 cp);
131 return 0; 198 return 0;
132 } 199 }
133 else 200 return 1;
134 return 1;
135} 201}
136 202
203
204/**
205 * CRC-16 for IP/ICMP headers.
206 *
207 * @param data what to calculate the CRC over
208 * @param bytes number of bytes in data (must be multiple of 2)
209 * @return the CRC 16.
210 */
137static uint16_t 211static uint16_t
138calc_checksum(const uint16_t *data, 212calc_checksum(const uint16_t *data,
139 unsigned int bytes) 213 unsigned int bytes)
@@ -358,27 +432,43 @@ send_icmp (const struct in_addr *my_ip,
358} 432}
359 433
360 434
361static Socket 435/**
436 * Create an ICMP raw socket.
437 *
438 * @return INVALID_SOCKET on error
439 */
440static SOCKET
362make_raw_socket () 441make_raw_socket ()
363{ 442{
364 DWORD bOptVal = TRUE; 443 DWORD bOptVal = TRUE;
365 int bOptLen = sizeof(bOptVal); 444 int bOptLen = sizeof(bOptVal);
366 Socket ret; 445 SOCKET ret;
367 446
368 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); 447 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
369 if (-1 == ret) 448 if (INVALID_SOCKET == ret)
370 { 449 {
371 fprintf (stderr, 450 fprintf (stderr,
372 "Error opening RAW socket: %s\n", 451 "Error opening RAW socket: %s\n",
373 strerror (errno)); 452 strerror (errno));
374 return -1; 453 return INVALID_SOCKET;
375 } 454 }
376 if (setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen) != 0) 455 if (setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen) != 0)
377 fprintf(stderr, "Error setting SO_BROADCAST: ON\n"); 456 {
457 fprintf(stderr,
458 "Error setting SO_BROADCAST to ON: %s\n",
459 strerror (errno));
460 closesocket(rawsock);
461 return INVALID_SOCKET;
462 }
378 463
379 if (setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen) != 0) 464 if (setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen) != 0)
380 fprintf(stderr, "Error setting IP_HDRINCL: ON\n"); 465 {
381 466 fprintf(stderr,
467 "Error setting IP_HDRINCL to ON: %s\n",
468 strerror (errno));
469 closesocket(rawsock);
470 return INVALID_SOCKET;
471 }
382 return ret; 472 return ret;
383} 473}
384 474
@@ -388,16 +478,9 @@ main (int argc, char *const *argv)
388{ 478{
389 struct in_addr external; 479 struct in_addr external;
390 struct in_addr target; 480 struct in_addr target;
391
392 WSADATA wsaData; 481 WSADATA wsaData;
393 if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
394 {
395 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
396 return 4;
397 }
398 482
399 if (-1 == (rawsock = make_raw_socket())) 483 unsigned int p;
400 return 1;
401 484
402 if (argc != 4) 485 if (argc != 4)
403 { 486 {
@@ -405,8 +488,6 @@ main (int argc, char *const *argv)
405 "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); 488 "This program must be started with our IP, the targets external IP, and our port as arguments.\n");
406 return 1; 489 return 1;
407 } 490 }
408 port = atoi(argv[3]);
409
410 if ( (1 != inet_pton (AF_INET, argv[1], &external)) || 491 if ( (1 != inet_pton (AF_INET, argv[1], &external)) ||
411 (1 != inet_pton (AF_INET, argv[2], &target)) ) 492 (1 != inet_pton (AF_INET, argv[2], &target)) )
412 { 493 {
@@ -415,21 +496,36 @@ main (int argc, char *const *argv)
415 strerror (errno)); 496 strerror (errno));
416 return 1; 497 return 1;
417 } 498 }
418 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) 499 if ( (1 != sscanf (argv[3], "%u", &p) ) ||
500 (p == 0) ||
501 (p > 0xFFFF) )
419 { 502 {
420 fprintf (stderr, 503 fprintf (stderr,
421 "Error parsing IPv4 address: %s\n", 504 "Error parsing port value `%s'\n",
422 strerror (errno)); 505 argv[3]);
423 abort (); 506 return 1;
424 } 507 }
508 port = (uint16_t) p;
425 509
510 if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
511 {
512 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
513 return 2;
514 }
515 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
516 {
517 fprintf (stderr,
518 "Internal error converting dummy IP to binary.\n");
519 return 2;
520 }
521 if (-1 == (rawsock = make_raw_socket()))
522 return 3;
426 send_icmp (&external, 523 send_icmp (&external,
427 &target); 524 &target);
428 send_icmp_udp (&external, 525 send_icmp_udp (&external,
429 &target); 526 &target);
430
431 WSACleanup ();
432 closesocket (rawsock); 527 closesocket (rawsock);
528 WSACleanup ();
433 return 0; 529 return 0;
434} 530}
435 531