diff options
Diffstat (limited to 'src/nat/gnunet-helper-nat-server-windows.c')
-rw-r--r-- | src/nat/gnunet-helper-nat-server-windows.c | 433 |
1 files changed, 215 insertions, 218 deletions
diff --git a/src/nat/gnunet-helper-nat-server-windows.c b/src/nat/gnunet-helper-nat-server-windows.c index f1b4896e8..13a4d8e6f 100644 --- a/src/nat/gnunet-helper-nat-server-windows.c +++ b/src/nat/gnunet-helper-nat-server-windows.c | |||
@@ -11,12 +11,12 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file src/nat/gnunet-helper-nat-server-windows.c | 22 | * @file src/nat/gnunet-helper-nat-server-windows.c |
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | #define _GNU_SOURCE | 43 | #define _GNU_SOURCE |
44 | /* Instead of including gnunet_common.h */ | 44 | /* Instead of including gnunet_common.h */ |
45 | #define GNUNET_memcpy(dst,src,n) do { if (0 != n) { (void) memcpy (dst,src,n); } } while (0) | 45 | #define GNUNET_memcpy(dst, src, n) do { if (0 != n) { (void)memcpy(dst, src, n); } } while (0) |
46 | 46 | ||
47 | #define FD_SETSIZE 1024 | 47 | #define FD_SETSIZE 1024 |
48 | #include <winsock2.h> | 48 | #include <winsock2.h> |
@@ -94,9 +94,7 @@ | |||
94 | /** | 94 | /** |
95 | * IPv4 header. | 95 | * IPv4 header. |
96 | */ | 96 | */ |
97 | struct ip_header | 97 | struct ip_header { |
98 | { | ||
99 | |||
100 | /** | 98 | /** |
101 | * Version (4 bits) + Internet header length (4 bits) | 99 | * Version (4 bits) + Internet header length (4 bits) |
102 | */ | 100 | */ |
@@ -151,8 +149,7 @@ struct ip_header | |||
151 | /** | 149 | /** |
152 | * Format of ICMP packet. | 150 | * Format of ICMP packet. |
153 | */ | 151 | */ |
154 | struct icmp_ttl_exceeded_header | 152 | struct icmp_ttl_exceeded_header { |
155 | { | ||
156 | uint8_t type; | 153 | uint8_t type; |
157 | 154 | ||
158 | uint8_t code; | 155 | uint8_t code; |
@@ -164,8 +161,7 @@ struct icmp_ttl_exceeded_header | |||
164 | /* followed by original payload */ | 161 | /* followed by original payload */ |
165 | }; | 162 | }; |
166 | 163 | ||
167 | struct icmp_echo_header | 164 | struct icmp_echo_header { |
168 | { | ||
169 | uint8_t type; | 165 | uint8_t type; |
170 | 166 | ||
171 | uint8_t code; | 167 | uint8_t code; |
@@ -178,8 +174,7 @@ struct icmp_echo_header | |||
178 | /** | 174 | /** |
179 | * Beginning of UDP packet. | 175 | * Beginning of UDP packet. |
180 | */ | 176 | */ |
181 | struct udp_header | 177 | struct udp_header { |
182 | { | ||
183 | uint16_t src_port; | 178 | uint16_t src_port; |
184 | 179 | ||
185 | uint16_t dst_port; | 180 | uint16_t dst_port; |
@@ -223,7 +218,7 @@ static struct in_addr dummy; | |||
223 | * @return the CRC 16. | 218 | * @return the CRC 16. |
224 | */ | 219 | */ |
225 | static uint16_t | 220 | static uint16_t |
226 | calc_checksum (const uint16_t * data, unsigned int bytes) | 221 | calc_checksum(const uint16_t * data, unsigned int bytes) |
227 | { | 222 | { |
228 | uint32_t sum; | 223 | uint32_t sum; |
229 | unsigned int i; | 224 | unsigned int i; |
@@ -232,7 +227,7 @@ calc_checksum (const uint16_t * data, unsigned int bytes) | |||
232 | for (i = 0; i < bytes / 2; i++) | 227 | for (i = 0; i < bytes / 2; i++) |
233 | sum += data[i]; | 228 | sum += data[i]; |
234 | sum = (sum & 0xffff) + (sum >> 16); | 229 | sum = (sum & 0xffff) + (sum >> 16); |
235 | sum = htons (0xffff - sum); | 230 | sum = htons(0xffff - sum); |
236 | return sum; | 231 | return sum; |
237 | } | 232 | } |
238 | 233 | ||
@@ -246,14 +241,14 @@ calc_checksum (const uint16_t * data, unsigned int bytes) | |||
246 | * @return 1 on success | 241 | * @return 1 on success |
247 | */ | 242 | */ |
248 | static int | 243 | static int |
249 | inet_pton (int af, const char *cp, struct in_addr *buf) | 244 | inet_pton(int af, const char *cp, struct in_addr *buf) |
250 | { | 245 | { |
251 | buf->s_addr = inet_addr (cp); | 246 | buf->s_addr = inet_addr(cp); |
252 | if (buf->s_addr == INADDR_NONE) | 247 | if (buf->s_addr == INADDR_NONE) |
253 | { | 248 | { |
254 | fprintf (stderr, "Error %d handling address %s", WSAGetLastError (), cp); | 249 | fprintf(stderr, "Error %d handling address %s", WSAGetLastError(), cp); |
255 | return 0; | 250 | return 0; |
256 | } | 251 | } |
257 | return 1; | 252 | return 1; |
258 | } | 253 | } |
259 | 254 | ||
@@ -264,9 +259,9 @@ inet_pton (int af, const char *cp, struct in_addr *buf) | |||
264 | * @param my_ip source address (our ip address) | 259 | * @param my_ip source address (our ip address) |
265 | */ | 260 | */ |
266 | static void | 261 | static void |
267 | send_icmp_echo (const struct in_addr *my_ip) | 262 | send_icmp_echo(const struct in_addr *my_ip) |
268 | { | 263 | { |
269 | char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)]; | 264 | char packet[sizeof(struct ip_header) + sizeof(struct icmp_echo_header)]; |
270 | struct icmp_echo_header icmp_echo; | 265 | struct icmp_echo_header icmp_echo; |
271 | struct ip_header ip_pkt; | 266 | struct ip_header ip_pkt; |
272 | struct sockaddr_in dst; | 267 | struct sockaddr_in dst; |
@@ -276,8 +271,8 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
276 | off = 0; | 271 | off = 0; |
277 | ip_pkt.vers_ihl = 0x45; | 272 | ip_pkt.vers_ihl = 0x45; |
278 | ip_pkt.tos = 0; | 273 | ip_pkt.tos = 0; |
279 | ip_pkt.pkt_len = htons (sizeof (packet)); | 274 | ip_pkt.pkt_len = htons(sizeof(packet)); |
280 | ip_pkt.id = htons (PACKET_ID); | 275 | ip_pkt.id = htons(PACKET_ID); |
281 | ip_pkt.flags_frag_offset = 0; | 276 | ip_pkt.flags_frag_offset = 0; |
282 | ip_pkt.ttl = IPDEFTTL; | 277 | ip_pkt.ttl = IPDEFTTL; |
283 | ip_pkt.proto = IPPROTO_ICMP; | 278 | ip_pkt.proto = IPPROTO_ICMP; |
@@ -285,35 +280,35 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
285 | ip_pkt.src_ip = my_ip->s_addr; | 280 | ip_pkt.src_ip = my_ip->s_addr; |
286 | ip_pkt.dst_ip = dummy.s_addr; | 281 | ip_pkt.dst_ip = dummy.s_addr; |
287 | ip_pkt.checksum = | 282 | ip_pkt.checksum = |
288 | htons (calc_checksum ((uint16_t *) & ip_pkt, sizeof (struct ip_header))); | 283 | htons(calc_checksum((uint16_t *)&ip_pkt, sizeof(struct ip_header))); |
289 | GNUNET_memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); | 284 | GNUNET_memcpy(&packet[off], &ip_pkt, sizeof(struct ip_header)); |
290 | off += sizeof (struct ip_header); | 285 | off += sizeof(struct ip_header); |
291 | 286 | ||
292 | icmp_echo.type = ICMP_ECHO; | 287 | icmp_echo.type = ICMP_ECHO; |
293 | icmp_echo.code = 0; | 288 | icmp_echo.code = 0; |
294 | icmp_echo.reserved = 0; | 289 | icmp_echo.reserved = 0; |
295 | icmp_echo.checksum = 0; | 290 | icmp_echo.checksum = 0; |
296 | icmp_echo.checksum = | 291 | icmp_echo.checksum = |
297 | htons (calc_checksum | 292 | htons(calc_checksum |
298 | ((uint16_t *) & icmp_echo, sizeof (struct icmp_echo_header))); | 293 | ((uint16_t *)&icmp_echo, sizeof(struct icmp_echo_header))); |
299 | GNUNET_memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header)); | 294 | GNUNET_memcpy(&packet[off], &icmp_echo, sizeof(struct icmp_echo_header)); |
300 | off += sizeof (struct icmp_echo_header); | 295 | off += sizeof(struct icmp_echo_header); |
301 | 296 | ||
302 | memset (&dst, 0, sizeof (dst)); | 297 | memset(&dst, 0, sizeof(dst)); |
303 | dst.sin_family = AF_INET; | 298 | dst.sin_family = AF_INET; |
304 | dst.sin_addr = dummy; | 299 | dst.sin_addr = dummy; |
305 | err = | 300 | err = |
306 | sendto (rawsock, packet, off, 0, (struct sockaddr *) &dst, sizeof (dst)); | 301 | sendto(rawsock, packet, off, 0, (struct sockaddr *)&dst, sizeof(dst)); |
307 | if (err < 0) | 302 | if (err < 0) |
308 | { | 303 | { |
309 | #if VERBOSE | 304 | #if VERBOSE |
310 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); | 305 | fprintf(stderr, "sendto failed: %s\n", strerror(errno)); |
311 | #endif | 306 | #endif |
312 | } | 307 | } |
313 | else if (err != off) | 308 | else if (err != off) |
314 | { | 309 | { |
315 | fprintf (stderr, "Error: partial send of ICMP message\n"); | 310 | fprintf(stderr, "Error: partial send of ICMP message\n"); |
316 | } | 311 | } |
317 | } | 312 | } |
318 | 313 | ||
319 | 314 | ||
@@ -321,26 +316,26 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
321 | * Send a UDP message to the dummy IP. | 316 | * Send a UDP message to the dummy IP. |
322 | */ | 317 | */ |
323 | static void | 318 | static void |
324 | send_udp () | 319 | send_udp() |
325 | { | 320 | { |
326 | struct sockaddr_in dst; | 321 | struct sockaddr_in dst; |
327 | ssize_t err; | 322 | ssize_t err; |
328 | 323 | ||
329 | memset (&dst, 0, sizeof (dst)); | 324 | memset(&dst, 0, sizeof(dst)); |
330 | dst.sin_family = AF_INET; | 325 | dst.sin_family = AF_INET; |
331 | dst.sin_addr = dummy; | 326 | dst.sin_addr = dummy; |
332 | dst.sin_port = htons (NAT_TRAV_PORT); | 327 | dst.sin_port = htons(NAT_TRAV_PORT); |
333 | err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst)); | 328 | err = sendto(udpsock, NULL, 0, 0, (struct sockaddr *)&dst, sizeof(dst)); |
334 | if (err < 0) | 329 | if (err < 0) |
335 | { | 330 | { |
336 | #if VERBOSE | 331 | #if VERBOSE |
337 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); | 332 | fprintf(stderr, "sendto failed: %s\n", strerror(errno)); |
338 | #endif | 333 | #endif |
339 | } | 334 | } |
340 | else if (0 != err) | 335 | else if (0 != err) |
341 | { | 336 | { |
342 | fprintf (stderr, "Error: partial send of ICMP message\n"); | 337 | fprintf(stderr, "Error: partial send of ICMP message\n"); |
343 | } | 338 | } |
344 | } | 339 | } |
345 | 340 | ||
346 | 341 | ||
@@ -348,7 +343,7 @@ send_udp () | |||
348 | * We've received an ICMP response. Process it. | 343 | * We've received an ICMP response. Process it. |
349 | */ | 344 | */ |
350 | static void | 345 | static void |
351 | process_icmp_response () | 346 | process_icmp_response() |
352 | { | 347 | { |
353 | char buf[65536]; | 348 | char buf[65536]; |
354 | ssize_t have; | 349 | ssize_t have; |
@@ -361,78 +356,80 @@ process_icmp_response () | |||
361 | uint16_t port; | 356 | uint16_t port; |
362 | DWORD ssize; | 357 | DWORD ssize; |
363 | 358 | ||
364 | have = read (icmpsock, buf, sizeof (buf)); | 359 | have = read(icmpsock, buf, sizeof(buf)); |
365 | if (have == -1) | 360 | if (have == -1) |
366 | { | 361 | { |
367 | fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno)); | 362 | fprintf(stderr, "Error reading raw socket: %s\n", strerror(errno)); |
368 | return; | 363 | return; |
369 | } | 364 | } |
370 | #if VERBOSE | 365 | #if VERBOSE |
371 | fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have); | 366 | fprintf(stderr, "Received message of %u bytes\n", (unsigned int)have); |
372 | #endif | 367 | #endif |
373 | if (have < | 368 | if (have < |
374 | (ssize_t) (sizeof (struct ip_header) + | 369 | (ssize_t)(sizeof(struct ip_header) + |
375 | sizeof (struct icmp_ttl_exceeded_header) + | 370 | sizeof(struct icmp_ttl_exceeded_header) + |
376 | sizeof (struct ip_header))) | 371 | sizeof(struct ip_header))) |
377 | { | 372 | { |
378 | /* malformed */ | 373 | /* malformed */ |
379 | return; | 374 | return; |
380 | } | 375 | } |
381 | off = 0; | 376 | off = 0; |
382 | GNUNET_memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header)); | 377 | GNUNET_memcpy(&ip_pkt, &buf[off], sizeof(struct ip_header)); |
383 | off += sizeof (struct ip_header); | 378 | off += sizeof(struct ip_header); |
384 | GNUNET_memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip)); | 379 | GNUNET_memcpy(&source_ip, &ip_pkt.src_ip, sizeof(source_ip)); |
385 | GNUNET_memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header)); | 380 | GNUNET_memcpy(&icmp_ttl, &buf[off], sizeof(struct icmp_ttl_exceeded_header)); |
386 | off += sizeof (struct icmp_ttl_exceeded_header); | 381 | off += sizeof(struct icmp_ttl_exceeded_header); |
387 | if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code)) | 382 | if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code)) |
388 | { | ||
389 | /* different type than what we want */ | ||
390 | return; | ||
391 | } | ||
392 | /* skip 2nd IP header */ | ||
393 | GNUNET_memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header)); | ||
394 | off += sizeof (struct ip_header); | ||
395 | |||
396 | switch (ip_pkt.proto) | ||
397 | { | ||
398 | case IPPROTO_ICMP: | ||
399 | if (have != | ||
400 | (sizeof (struct ip_header) * 2 + | ||
401 | sizeof (struct icmp_ttl_exceeded_header) + | ||
402 | sizeof (struct icmp_echo_header))) | ||
403 | { | 383 | { |
404 | /* malformed */ | 384 | /* different type than what we want */ |
405 | return; | 385 | return; |
406 | } | 386 | } |
407 | /* grab ICMP ECHO content */ | 387 | /* skip 2nd IP header */ |
408 | GNUNET_memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header)); | 388 | GNUNET_memcpy(&ip_pkt, &buf[off], sizeof(struct ip_header)); |
409 | port = (uint16_t) ntohl (icmp_echo.reserved); | 389 | off += sizeof(struct ip_header); |
410 | break; | 390 | |
411 | case IPPROTO_UDP: | 391 | switch (ip_pkt.proto) |
412 | if (have != | ||
413 | (sizeof (struct ip_header) * 2 + | ||
414 | sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct udp_header))) | ||
415 | { | 392 | { |
416 | /* malformed */ | 393 | case IPPROTO_ICMP: |
394 | if (have != | ||
395 | (sizeof(struct ip_header) * 2 + | ||
396 | sizeof(struct icmp_ttl_exceeded_header) + | ||
397 | sizeof(struct icmp_echo_header))) | ||
398 | { | ||
399 | /* malformed */ | ||
400 | return; | ||
401 | } | ||
402 | /* grab ICMP ECHO content */ | ||
403 | GNUNET_memcpy(&icmp_echo, &buf[off], sizeof(struct icmp_echo_header)); | ||
404 | port = (uint16_t)ntohl(icmp_echo.reserved); | ||
405 | break; | ||
406 | |||
407 | case IPPROTO_UDP: | ||
408 | if (have != | ||
409 | (sizeof(struct ip_header) * 2 + | ||
410 | sizeof(struct icmp_ttl_exceeded_header) + sizeof(struct udp_header))) | ||
411 | { | ||
412 | /* malformed */ | ||
413 | return; | ||
414 | } | ||
415 | /* grab UDP content */ | ||
416 | GNUNET_memcpy(&udp_pkt, &buf[off], sizeof(struct udp_header)); | ||
417 | port = ntohs(udp_pkt.length); | ||
418 | break; | ||
419 | |||
420 | default: | ||
421 | /* different type than what we want */ | ||
417 | return; | 422 | return; |
418 | } | 423 | } |
419 | /* grab UDP content */ | 424 | |
420 | GNUNET_memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header)); | 425 | ssize = sizeof(buf); |
421 | port = ntohs (udp_pkt.length); | 426 | WSAAddressToString((LPSOCKADDR)&source_ip, sizeof(source_ip), NULL, buf, |
422 | break; | 427 | &ssize); |
423 | default: | ||
424 | /* different type than what we want */ | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | ssize = sizeof (buf); | ||
429 | WSAAddressToString ((LPSOCKADDR) & source_ip, sizeof (source_ip), NULL, buf, | ||
430 | &ssize); | ||
431 | if (port == 0) | 428 | if (port == 0) |
432 | fprintf (stdout, "%s\n", buf); | 429 | fprintf(stdout, "%s\n", buf); |
433 | else | 430 | else |
434 | fprintf (stdout, "%s:%u\n", buf, (unsigned int) port); | 431 | fprintf(stdout, "%s:%u\n", buf, (unsigned int)port); |
435 | fflush (stdout); | 432 | fflush(stdout); |
436 | } | 433 | } |
437 | 434 | ||
438 | 435 | ||
@@ -442,16 +439,16 @@ process_icmp_response () | |||
442 | * @return INVALID_SOCKET on error | 439 | * @return INVALID_SOCKET on error |
443 | */ | 440 | */ |
444 | static SOCKET | 441 | static SOCKET |
445 | make_icmp_socket () | 442 | make_icmp_socket() |
446 | { | 443 | { |
447 | SOCKET ret; | 444 | SOCKET ret; |
448 | 445 | ||
449 | ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 446 | ret = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); |
450 | if (INVALID_SOCKET == ret) | 447 | if (INVALID_SOCKET == ret) |
451 | { | 448 | { |
452 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); | 449 | fprintf(stderr, "Error opening RAW socket: %s\n", strerror(errno)); |
453 | return INVALID_SOCKET; | 450 | return INVALID_SOCKET; |
454 | } | 451 | } |
455 | return ret; | 452 | return ret; |
456 | } | 453 | } |
457 | 454 | ||
@@ -462,34 +459,34 @@ make_icmp_socket () | |||
462 | * @return INVALID_SOCKET on error | 459 | * @return INVALID_SOCKET on error |
463 | */ | 460 | */ |
464 | static SOCKET | 461 | static SOCKET |
465 | make_raw_socket () | 462 | make_raw_socket() |
466 | { | 463 | { |
467 | DWORD bOptVal = TRUE; | 464 | DWORD bOptVal = TRUE; |
468 | int bOptLen = sizeof (bOptVal); | 465 | int bOptLen = sizeof(bOptVal); |
469 | 466 | ||
470 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 467 | rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); |
471 | if (INVALID_SOCKET == rawsock) | 468 | if (INVALID_SOCKET == rawsock) |
472 | { | 469 | { |
473 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno)); | 470 | fprintf(stderr, "Error opening RAW socket: %s\n", strerror(errno)); |
474 | return INVALID_SOCKET; | 471 | return INVALID_SOCKET; |
475 | } | 472 | } |
476 | 473 | ||
477 | if (0 != | 474 | if (0 != |
478 | setsockopt (rawsock, SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, | 475 | setsockopt(rawsock, SOL_SOCKET, SO_BROADCAST, (char *)&bOptVal, |
479 | bOptLen)) | 476 | bOptLen)) |
480 | { | 477 | { |
481 | fprintf (stderr, "Error setting SO_BROADCAST to ON: %s\n", | 478 | fprintf(stderr, "Error setting SO_BROADCAST to ON: %s\n", |
482 | strerror (errno)); | 479 | strerror(errno)); |
483 | closesocket (rawsock); | 480 | closesocket(rawsock); |
484 | return INVALID_SOCKET; | 481 | return INVALID_SOCKET; |
485 | } | 482 | } |
486 | if (0 != | 483 | if (0 != |
487 | setsockopt (rawsock, IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen)) | 484 | setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, (char *)&bOptVal, bOptLen)) |
488 | { | 485 | { |
489 | fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno)); | 486 | fprintf(stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror(errno)); |
490 | closesocket (rawsock); | 487 | closesocket(rawsock); |
491 | return INVALID_SOCKET; | 488 | return INVALID_SOCKET; |
492 | } | 489 | } |
493 | return rawsock; | 490 | return rawsock; |
494 | } | 491 | } |
495 | 492 | ||
@@ -501,33 +498,33 @@ make_raw_socket () | |||
501 | * @return INVALID_SOCKET on error | 498 | * @return INVALID_SOCKET on error |
502 | */ | 499 | */ |
503 | static SOCKET | 500 | static SOCKET |
504 | make_udp_socket (const struct in_addr *my_ip) | 501 | make_udp_socket(const struct in_addr *my_ip) |
505 | { | 502 | { |
506 | SOCKET ret; | 503 | SOCKET ret; |
507 | struct sockaddr_in addr; | 504 | struct sockaddr_in addr; |
508 | 505 | ||
509 | ret = socket (AF_INET, SOCK_DGRAM, 0); | 506 | ret = socket(AF_INET, SOCK_DGRAM, 0); |
510 | if (INVALID_SOCKET == ret) | 507 | if (INVALID_SOCKET == ret) |
511 | { | 508 | { |
512 | fprintf (stderr, "Error opening UDP socket: %s\n", strerror (errno)); | 509 | fprintf(stderr, "Error opening UDP socket: %s\n", strerror(errno)); |
513 | return INVALID_SOCKET; | 510 | return INVALID_SOCKET; |
514 | } | 511 | } |
515 | memset (&addr, 0, sizeof (addr)); | 512 | memset(&addr, 0, sizeof(addr)); |
516 | addr.sin_family = AF_INET; | 513 | addr.sin_family = AF_INET; |
517 | addr.sin_addr = *my_ip; | 514 | addr.sin_addr = *my_ip; |
518 | addr.sin_port = htons (NAT_TRAV_PORT); | 515 | addr.sin_port = htons(NAT_TRAV_PORT); |
519 | if (0 != bind (ret, (struct sockaddr *) &addr, sizeof (addr))) | 516 | if (0 != bind(ret, (struct sockaddr *)&addr, sizeof(addr))) |
520 | { | 517 | { |
521 | fprintf (stderr, "Error binding UDP socket to port %u: %s\n", NAT_TRAV_PORT, | 518 | fprintf(stderr, "Error binding UDP socket to port %u: %s\n", NAT_TRAV_PORT, |
522 | strerror (errno)); | 519 | strerror(errno)); |
523 | /* likely problematic, but not certain, try to continue */ | 520 | /* likely problematic, but not certain, try to continue */ |
524 | } | 521 | } |
525 | return ret; | 522 | return ret; |
526 | } | 523 | } |
527 | 524 | ||
528 | 525 | ||
529 | int | 526 | int |
530 | main (int argc, char *const *argv) | 527 | main(int argc, char *const *argv) |
531 | { | 528 | { |
532 | struct in_addr external; | 529 | struct in_addr external; |
533 | fd_set rs; | 530 | fd_set rs; |
@@ -535,79 +532,79 @@ main (int argc, char *const *argv) | |||
535 | WSADATA wsaData; | 532 | WSADATA wsaData; |
536 | unsigned int alt = 0; | 533 | unsigned int alt = 0; |
537 | 534 | ||
538 | if ( (argc > 1) && (0 != strcmp (argv[1], "-d"))) | 535 | if ((argc > 1) && (0 != strcmp(argv[1], "-d"))) |
539 | { | 536 | { |
540 | privilege_testing = TRUE; | 537 | privilege_testing = TRUE; |
541 | fprintf (stderr, | 538 | fprintf(stderr, |
542 | "%s", | 539 | "%s", |
543 | "DEBUG: Running binary in privilege testing mode."); | 540 | "DEBUG: Running binary in privilege testing mode."); |
544 | argv++; | 541 | argv++; |
545 | argc--; | 542 | argc--; |
546 | } | 543 | } |
547 | 544 | ||
548 | if (2 != argc) | 545 | if (2 != argc) |
549 | { | ||
550 | fprintf (stderr, | ||
551 | "This program must be started with our (internal NAT) IP as the only argument.\n"); | ||
552 | return 1; | ||
553 | } | ||
554 | if (1 != inet_pton (AF_INET, argv[1], &external)) | ||
555 | { | ||
556 | fprintf (stderr, "Error parsing IPv4 address: %s, error %s\n", argv[1], | ||
557 | strerror (errno)); | ||
558 | return 1; | ||
559 | } | ||
560 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | ||
561 | { | ||
562 | fprintf (stderr, "Internal error converting dummy IP to binary.\n"); | ||
563 | return 2; | ||
564 | } | ||
565 | if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0) | ||
566 | { | ||
567 | fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); | ||
568 | return 2; | ||
569 | } | ||
570 | if (INVALID_SOCKET == (icmpsock = make_icmp_socket ())) | ||
571 | { | ||
572 | return 3; | ||
573 | } | ||
574 | if (INVALID_SOCKET == (make_raw_socket ())) | ||
575 | { | ||
576 | closesocket (icmpsock); | ||
577 | return 3; | ||
578 | } | ||
579 | if (INVALID_SOCKET == (udpsock = make_udp_socket (&external))) | ||
580 | { | ||
581 | closesocket (icmpsock); | ||
582 | closesocket (rawsock); | ||
583 | return 3; | ||
584 | } | ||
585 | |||
586 | while ( ! privilege_testing) | ||
587 | { | ||
588 | FD_ZERO (&rs); | ||
589 | FD_SET (icmpsock, &rs); | ||
590 | tv.tv_sec = 0; | ||
591 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | ||
592 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
593 | { | 546 | { |
594 | if (errno == EINTR) | 547 | fprintf(stderr, |
595 | continue; | 548 | "This program must be started with our (internal NAT) IP as the only argument.\n"); |
596 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | 549 | return 1; |
597 | break; | 550 | } |
551 | if (1 != inet_pton(AF_INET, argv[1], &external)) | ||
552 | { | ||
553 | fprintf(stderr, "Error parsing IPv4 address: %s, error %s\n", argv[1], | ||
554 | strerror(errno)); | ||
555 | return 1; | ||
556 | } | ||
557 | if (1 != inet_pton(AF_INET, DUMMY_IP, &dummy)) | ||
558 | { | ||
559 | fprintf(stderr, "Internal error converting dummy IP to binary.\n"); | ||
560 | return 2; | ||
561 | } | ||
562 | if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0) | ||
563 | { | ||
564 | fprintf(stderr, "Failed to find Winsock 2.1 or better.\n"); | ||
565 | return 2; | ||
566 | } | ||
567 | if (INVALID_SOCKET == (icmpsock = make_icmp_socket())) | ||
568 | { | ||
569 | return 3; | ||
570 | } | ||
571 | if (INVALID_SOCKET == (make_raw_socket())) | ||
572 | { | ||
573 | closesocket(icmpsock); | ||
574 | return 3; | ||
575 | } | ||
576 | if (INVALID_SOCKET == (udpsock = make_udp_socket(&external))) | ||
577 | { | ||
578 | closesocket(icmpsock); | ||
579 | closesocket(rawsock); | ||
580 | return 3; | ||
581 | } | ||
582 | |||
583 | while (!privilege_testing) | ||
584 | { | ||
585 | FD_ZERO(&rs); | ||
586 | FD_SET(icmpsock, &rs); | ||
587 | tv.tv_sec = 0; | ||
588 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | ||
589 | if (-1 == select(icmpsock + 1, &rs, NULL, NULL, &tv)) | ||
590 | { | ||
591 | if (errno == EINTR) | ||
592 | continue; | ||
593 | fprintf(stderr, "select failed: %s\n", strerror(errno)); | ||
594 | break; | ||
595 | } | ||
596 | if (FD_ISSET(icmpsock, &rs)) | ||
597 | process_icmp_response(); | ||
598 | if (0 == (++alt % 2)) | ||
599 | send_icmp_echo(&external); | ||
600 | else | ||
601 | send_udp(); | ||
598 | } | 602 | } |
599 | if (FD_ISSET (icmpsock, &rs)) | ||
600 | process_icmp_response (); | ||
601 | if (0 == (++alt % 2)) | ||
602 | send_icmp_echo (&external); | ||
603 | else | ||
604 | send_udp (); | ||
605 | } | ||
606 | /* select failed (internal error or OS out of resources) */ | 603 | /* select failed (internal error or OS out of resources) */ |
607 | closesocket (icmpsock); | 604 | closesocket(icmpsock); |
608 | closesocket (rawsock); | 605 | closesocket(rawsock); |
609 | closesocket (udpsock); | 606 | closesocket(udpsock); |
610 | WSACleanup (); | 607 | WSACleanup(); |
611 | if (privilege_testing) | 608 | if (privilege_testing) |
612 | return 0; | 609 | return 0; |
613 | return 4; | 610 | return 4; |