diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-08-20 12:44:16 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-08-20 12:44:16 +0000 |
commit | 65ae20b0c21ac4e872d6b460df5ed80cd35d9bd3 (patch) | |
tree | b8fc15fa35125cac88932df324e08de85be09ed8 /src/transport/gnunet-nat-server-windows.c | |
parent | 3f2f615ad7e8101d9dfef94dc26a027581bc0d8f (diff) | |
download | gnunet-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.c | 270 |
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 | |||
57 | typedef unsigned int uid_t; | 63 | typedef unsigned int uid_t; |
58 | typedef SOCKET Socket; | 64 | typedef SOCKET Socket; |
59 | typedef unsigned short ushort; | 65 | typedef 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 | */ | ||
76 | struct ip_packet | 83 | struct 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 | */ | ||
101 | struct icmp_packet | 140 | struct 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 | */ | ||
109 | struct udp_packet | 151 | struct udp_packet |
110 | { | 152 | { |
111 | uint16_t src_port; | 153 | uint16_t src_port; |
@@ -121,6 +163,9 @@ static Socket rawsock; | |||
121 | 163 | ||
122 | static struct in_addr dummy; | 164 | static struct in_addr dummy; |
123 | 165 | ||
166 | /** | ||
167 | * CRC-16 for IP/ICMP headers. | ||
168 | */ | ||
124 | static uint16_t | 169 | static uint16_t |
125 | calc_checksum(const uint16_t *data, | 170 | calc_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 | */ |
144 | static int inet_pton (int af, char *cp, struct in_addr *buf) | 191 | static int |
192 | inet_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 | |||
157 | static void | ||
158 | make_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 | ||
365 | int | 439 | int |
366 | main (int argc, char *const *argv) | 440 | main (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 | ||