aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-nat-server-windows.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-08-20 12:44:16 +0000
committerChristian Grothoff <christian@grothoff.org>2010-08-20 12:44:16 +0000
commit65ae20b0c21ac4e872d6b460df5ed80cd35d9bd3 (patch)
treeb8fc15fa35125cac88932df324e08de85be09ed8 /src/transport/gnunet-nat-server-windows.c
parent3f2f615ad7e8101d9dfef94dc26a027581bc0d8f (diff)
downloadgnunet-65ae20b0c21ac4e872d6b460df5ed80cd35d9bd3.tar.gz
gnunet-65ae20b0c21ac4e872d6b460df5ed80cd35d9bd3.zip
code cleanup
Diffstat (limited to 'src/transport/gnunet-nat-server-windows.c')
-rw-r--r--src/transport/gnunet-nat-server-windows.c270
1 files changed, 177 insertions, 93 deletions
diff --git a/src/transport/gnunet-nat-server-windows.c b/src/transport/gnunet-nat-server-windows.c
index 8eb795c7b..b05690e88 100644
--- a/src/transport/gnunet-nat-server-windows.c
+++ b/src/transport/gnunet-nat-server-windows.c
@@ -54,6 +54,12 @@
54#include <stdint.h> 54#include <stdint.h>
55#include <time.h> 55#include <time.h>
56 56
57/**
58 * Should we print some debug output?
59 */
60#define VERBOSE 0
61
62
57typedef unsigned int uid_t; 63typedef unsigned int uid_t;
58typedef SOCKET Socket; 64typedef SOCKET Socket;
59typedef unsigned short ushort; 65typedef unsigned short ushort;
@@ -66,38 +72,71 @@ typedef unsigned short ushort;
66 */ 72 */
67#define DUMMY_IP "192.0.2.86" 73#define DUMMY_IP "192.0.2.86"
68 74
69#define VERBOSE 1
70
71/** 75/**
72 * How often do we send our ICMP messages to receive replies? 76 * How often do we send our ICMP messages to receive replies?
73 */ 77 */
74#define ICMP_SEND_FREQUENCY_MS 500 78#define ICMP_SEND_FREQUENCY_MS 500
75 79
80/**
81 * IPv4 header.
82 */
76struct ip_packet 83struct ip_packet
77{ 84{
78 /*uint8_t vers_ihl; 85
79 uint8_t tos; 86 /**
80 uint16_t pkt_len; 87 * Version (4 bits) + Internet header length (4 bits)
81 uint16_t id; 88 */
82 uint16_t flags_frag_offset; 89 u_char vers_ihl;
83 uint8_t ttl; 90
84 uint8_t proto; 91 /**
85 uint16_t checksum; 92 * Type of service
86 uint32_t src_ip; 93 */
87 uint32_t dst_ip;*/ 94 u_char tos;
88 95
89 u_char vers_ihl; // Version (4 bits) + Internet header length (4 bits) 96 /**
90 u_char tos; // Type of service 97 * Total length
91 u_short pkt_len; // Total length 98 */
92 u_short id; // Identification 99 u_short pkt_len;
93 u_short flags_frag_offset; // Flags (3 bits) + Fragment offset (13 bits) 100
94 u_char ttl; // Time to live 101 /**
95 u_char proto; // Protocol 102 * Identification
96 u_short checksum; // Header checksum 103 */
97 u_long src_ip; // Source address 104 u_short id;
98 u_long dst_ip; // Destination address 105
106 /**
107 * Flags (3 bits) + Fragment offset (13 bits)
108 */
109 u_short flags_frag_offset;
110
111 /**
112 * Time to live
113 */
114 u_char ttl;
115
116 /**
117 * Protocol
118 */
119 u_char proto;
120
121 /**
122 * Header checksum
123 */
124 u_short checksum;
125
126 /**
127 * Source address
128 */
129 u_long src_ip;
130
131 /**
132 * Destination address
133 */
134 u_long dst_ip;
99}; 135};
100 136
137/**
138 * Format of ICMP packet.
139 */
101struct icmp_packet 140struct icmp_packet
102{ 141{
103 uint8_t type; 142 uint8_t type;
@@ -106,6 +145,9 @@ struct icmp_packet
106 uint32_t reserved; 145 uint32_t reserved;
107}; 146};
108 147
148/**
149 * Beginning of UDP packet.
150 */
109struct udp_packet 151struct udp_packet
110{ 152{
111 uint16_t src_port; 153 uint16_t src_port;
@@ -121,6 +163,9 @@ static Socket rawsock;
121 163
122static struct in_addr dummy; 164static struct in_addr dummy;
123 165
166/**
167 * CRC-16 for IP/ICMP headers.
168 */
124static uint16_t 169static uint16_t
125calc_checksum(const uint16_t *data, 170calc_checksum(const uint16_t *data,
126 unsigned int bytes) 171 unsigned int bytes)
@@ -137,33 +182,27 @@ calc_checksum(const uint16_t *data,
137} 182}
138 183
139/** 184/**
185 * Convert IPv4 address from text to binary form.
186 *
140 * @param af address family 187 * @param af address family
141 * @param cp the address to print 188 * @param cp the address to print
142 * @param buf where to write the address result 189 * @param buf where to write the address result
143 */ 190 */
144static int inet_pton (int af, char *cp, struct in_addr *buf) 191static int
192inet_pton (int af,
193 const char *cp,
194 struct in_addr *buf)
145{ 195{
146 //ret = WSAStringToAddress (cp, af, NULL, (LPSOCKADDR)buf, &ssize);
147 buf->s_addr = inet_addr(cp); 196 buf->s_addr = inet_addr(cp);
148 if (buf->s_addr == INADDR_NONE) 197 if (buf->s_addr == INADDR_NONE)
149 { 198 {
150 fprintf(stderr, "Error %d handling address %s", WSAGetLastError(), cp); 199 fprintf(stderr,
200 "Error %d handling address %s",
201 WSAGetLastError(),
202 cp);
151 return 0; 203 return 0;
152 } 204 }
153 else 205 return 1;
154 return 1;
155}
156
157static void
158make_echo (const struct in_addr *src_ip,
159 struct icmp_packet *echo)
160{
161 memset(echo, 0, sizeof(struct icmp_packet));
162 echo->type = ICMP_ECHO;
163 echo->code = 0;
164 echo->reserved = 0;
165 echo->checksum = 0;
166 echo->checksum = htons(calc_checksum((uint16_t*)echo, sizeof (struct icmp_packet)));
167} 206}
168 207
169 208
@@ -199,7 +238,12 @@ send_icmp_echo (const struct in_addr *my_ip)
199 memcpy (packet, &ip_pkt, sizeof (ip_pkt)); 238 memcpy (packet, &ip_pkt, sizeof (ip_pkt));
200 off += sizeof (ip_pkt); 239 off += sizeof (ip_pkt);
201 240
202 make_echo (my_ip, &icmp_echo); 241 icmp_echo.type = ICMP_ECHO;
242 icmp_echo.code = 0;
243 icmp_echo.reserved = 0;
244 icmp_echo.checksum = 0;
245 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo,
246 sizeof (struct icmp_packet)));
203 memcpy (&packet[off], &icmp_echo, sizeof (icmp_echo)); 247 memcpy (&packet[off], &icmp_echo, sizeof (icmp_echo));
204 off += sizeof (icmp_echo); 248 off += sizeof (icmp_echo);
205 249
@@ -238,6 +282,7 @@ process_icmp_response ()
238 int have_port; 282 int have_port;
239 int have_udp; 283 int have_udp;
240 uint32_t port; 284 uint32_t port;
285
241 have = read (icmpsock, buf, sizeof (buf)); 286 have = read (icmpsock, buf, sizeof (buf));
242 if (have == -1) 287 if (have == -1)
243 { 288 {
@@ -280,37 +325,54 @@ process_icmp_response ()
280 memcpy(&sip, 325 memcpy(&sip,
281 &ip_pkt.src_ip, 326 &ip_pkt.src_ip,
282 sizeof (sip)); 327 sizeof (sip));
283
284 memcpy (&ip_pkt, &buf[off], sizeof (ip_pkt)); 328 memcpy (&ip_pkt, &buf[off], sizeof (ip_pkt));
285 off += sizeof (ip_pkt); 329 off += sizeof (ip_pkt);
286 330 have_udp = (ip_pkt.proto == IPPROTO_UDP);
287 have_udp = 0;
288 if (ip_pkt.proto == IPPROTO_UDP)
289 {
290 have_udp = 1;
291 }
292 331
293 if (have_port) 332 if (have_port)
294 { 333 {
295 memcpy(&port, &buf[sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2], sizeof(uint32_t)); 334 memcpy(&port,
335 &buf[sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2],
336 sizeof(uint32_t));
296 port = ntohs(port); 337 port = ntohs(port);
297 DWORD ssize = sizeof(buf); 338 DWORD ssize = sizeof(buf);
298 WSAAddressToString((LPSOCKADDR)&sip, sizeof(sip), NULL, buf, &ssize); 339 WSAAddressToString((LPSOCKADDR)&sip,
299 fprintf (stdout, "%s:%d\n", buf, port); 340 sizeof(sip),
300 341 NULL,
342 buf,
343 &ssize);
344 fprintf (stdout,
345 "%s:%d\n",
346 buf,
347 port);
301 } 348 }
302 else if (have_udp) 349 else if (have_udp)
303 { 350 {
304 memcpy(&udp_pkt, &buf[off], sizeof(udp_pkt)); 351 memcpy(&udp_pkt,
352 &buf[off],
353 sizeof(udp_pkt));
305 DWORD ssize = sizeof(buf); 354 DWORD ssize = sizeof(buf);
306 WSAAddressToString((LPSOCKADDR)&sip, sizeof(sip), NULL, buf, &ssize); 355 WSAAddressToString((LPSOCKADDR)&sip,
307 fprintf (stdout, "%s:%d\n", buf, ntohs((int)udp_pkt.length)); 356 sizeof(sip),
357 NULL,
358 buf,
359 &ssize);
360 fprintf (stdout,
361 "%s:%d\n",
362 buf,
363 ntohs((int)udp_pkt.length));
308 } 364 }
309 else 365 else
310 { 366 {
311 DWORD ssize = sizeof(buf); 367 DWORD ssize = sizeof(buf);
312 WSAAddressToString((LPSOCKADDR)&sip, sizeof(sip), NULL, buf, &ssize); 368 WSAAddressToString((LPSOCKADDR)&sip,
313 fprintf (stdout, "%s\n", buf); 369 sizeof(sip),
370 NULL,
371 buf,
372 &ssize);
373 fprintf (stdout,
374 "%s\n",
375 buf);
314 } 376 }
315 fflush (stdout); 377 fflush (stdout);
316} 378}
@@ -322,18 +384,13 @@ make_icmp_socket ()
322 Socket ret; 384 Socket ret;
323 385
324 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 386 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
325 if (-1 == ret) 387 if (INVALID_SOCKET == ret)
326 { 388 {
327 fprintf (stderr, 389 fprintf (stderr,
328 "Error opening RAW socket: %s\n", 390 "Error opening RAW socket: %s\n",
329 strerror (errno)); 391 strerror (errno));
330 return -1; 392 return -1;
331 } 393 }
332 if (ret == INVALID_SOCKET)
333 {
334 fprintf (stderr, "Invalid socket %d!\n", ret);
335 closesocket (ret);
336 }
337 return ret; 394 return ret;
338} 395}
339 396
@@ -345,45 +402,48 @@ make_raw_socket ()
345 int bOptLen = sizeof(bOptVal); 402 int bOptLen = sizeof(bOptVal);
346 403
347 rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 404 rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
348 if (-1 == rawsock) 405 if (INVALID_SOCKET == rawsock)
349 { 406 {
350 fprintf (stderr, 407 fprintf (stderr,
351 "Error opening RAW socket: %s\n", 408 "Error opening RAW socket: %s\n",
352 strerror (errno)); 409 strerror (errno));
353 return -1; 410 return INVALID_SOCKET;
354 } 411 }
355 412
356 if (setsockopt(rawsock, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen) != 0) 413 if (setsockopt(rawsock,
357 fprintf(stderr, "Error setting SO_BROADCAST: ON\n"); 414 SOL_SOCKET,
358 415 SO_BROADCAST,
359 if (setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen) != 0) 416 (char*)&bOptVal, bOptLen) != 0)
360 fprintf(stderr, "Error setting IP_HDRINCL: ON\n"); 417 {
418 fprintf(stderr,
419 "Error setting SO_BROADCAST to ON: %s\n",
420 strerror (errno));
421 closesocket(rawsock);
422 return INVALID_SOCKET;
423 }
424 if (setsockopt(rawsock,
425 IPPROTO_IP,
426 IP_HDRINCL,
427 (char*)&bOptVal, bOptLen) != 0)
428 {
429 fprintf(stderr,
430 "Error setting IP_HDRINCL to ON: %s\n",
431 strerror (errno));
432 closesocket(rawsock);
433 return INVALID_SOCKET;
434 }
361 return rawsock; 435 return rawsock;
362} 436}
363 437
364 438
365int 439int
366main (int argc, char *const *argv) 440main (int argc,
441 char *const *argv)
367{ 442{
368 struct in_addr external; 443 struct in_addr external;
369 fd_set rs; 444 fd_set rs;
370 struct timeval tv; 445 struct timeval tv;
371
372 // WSA startup
373 WSADATA wsaData; 446 WSADATA wsaData;
374 if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
375 {
376 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
377 return 4; // ERROR
378 }
379
380 if (-1 == (icmpsock = make_icmp_socket()))
381 return 1;
382 if (-1 == (make_raw_socket()))
383 {
384 close (icmpsock);
385 return 1;
386 }
387 447
388 if (argc != 2) 448 if (argc != 2)
389 { 449 {
@@ -391,7 +451,6 @@ main (int argc, char *const *argv)
391 "This program must be started with our (internal NAT) IP as the only argument.\n"); 451 "This program must be started with our (internal NAT) IP as the only argument.\n");
392 return 1; 452 return 1;
393 } 453 }
394
395 if (1 != inet_pton (AF_INET, argv[1], &external)) 454 if (1 != inet_pton (AF_INET, argv[1], &external))
396 { 455 {
397 fprintf (stderr, 456 fprintf (stderr,
@@ -399,24 +458,49 @@ main (int argc, char *const *argv)
399 argv[1], strerror (errno)); 458 argv[1], strerror (errno));
400 return 1; 459 return 1;
401 } 460 }
402 461 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
403 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) abort (); 462 {
463 fprintf (stderr,
464 "Internal error converting dummy IP to binary.\n");
465 return 2;
466 }
467 if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
468 {
469 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
470 return 2;
471 }
472 if (-1 == (icmpsock = make_icmp_socket()))
473 {
474 return 3;
475 }
476 if (-1 == (make_raw_socket()))
477 {
478 closesocket (icmpsock);
479 return 3;
480 }
404 while (1) 481 while (1)
405 { 482 {
406 FD_ZERO (&rs); 483 FD_ZERO (&rs);
407 FD_SET (icmpsock, &rs); 484 FD_SET (icmpsock, &rs);
408 tv.tv_sec = 0; 485 tv.tv_sec = 0;
409 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; 486 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
410 select (icmpsock + 1, &rs, NULL, NULL, &tv); 487 if (0 != select (icmpsock + 1, &rs, NULL, NULL, &tv))
488 {
489 if (errno == EINTR)
490 continue;
491 fprintf (stderr,
492 "select failed: %s\n",
493 strerror (errno));
494 break;
495 }
411 if (FD_ISSET (icmpsock, &rs)) 496 if (FD_ISSET (icmpsock, &rs))
412 process_icmp_response (); 497 process_icmp_response ();
413 send_icmp_echo (&external); 498 send_icmp_echo (&external);
414 } 499 }
415
416 closesocket(icmpsock); 500 closesocket(icmpsock);
417 closesocket(rawsock); 501 closesocket(rawsock);
418 WSACleanup (); 502 WSACleanup ();
419 return 0; 503 return 4; /* select failed! */
420} 504}
421 505
422 506