aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-helper-nat-client-windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/gnunet-helper-nat-client-windows.c')
-rw-r--r--src/nat/gnunet-helper-nat-client-windows.c303
1 files changed, 129 insertions, 174 deletions
diff --git a/src/nat/gnunet-helper-nat-client-windows.c b/src/nat/gnunet-helper-nat-client-windows.c
index 0717eecfe..0fa62ff7c 100644
--- a/src/nat/gnunet-helper-nat-client-windows.c
+++ b/src/nat/gnunet-helper-nat-client-windows.c
@@ -193,19 +193,14 @@ static uint16_t port;
193 * @return 1 on success 193 * @return 1 on success
194 */ 194 */
195static int 195static int
196inet_pton (int af, 196inet_pton (int af, const char *cp, struct in_addr *buf)
197 const char *cp,
198 struct in_addr *buf)
199{ 197{
200 buf->s_addr = inet_addr(cp); 198 buf->s_addr = inet_addr (cp);
201 if (buf->s_addr == INADDR_NONE) 199 if (buf->s_addr == INADDR_NONE)
202 { 200 {
203 fprintf(stderr, 201 fprintf (stderr, "Error %d handling address %s", WSAGetLastError (), cp);
204 "Error %d handling address %s", 202 return 0;
205 WSAGetLastError(), 203 }
206 cp);
207 return 0;
208 }
209 return 1; 204 return 1;
210} 205}
211 206
@@ -218,17 +213,16 @@ inet_pton (int af,
218 * @return the CRC 16. 213 * @return the CRC 16.
219 */ 214 */
220static uint16_t 215static uint16_t
221calc_checksum(const uint16_t *data, 216calc_checksum (const uint16_t * data, unsigned int bytes)
222 unsigned int bytes)
223{ 217{
224 uint32_t sum; 218 uint32_t sum;
225 unsigned int i; 219 unsigned int i;
226 220
227 sum = 0; 221 sum = 0;
228 for (i=0;i<bytes/2;i++) 222 for (i = 0; i < bytes / 2; i++)
229 sum += data[i]; 223 sum += data[i];
230 sum = (sum & 0xffff) + (sum >> 16); 224 sum = (sum & 0xffff) + (sum >> 16);
231 sum = htons(0xffff - sum); 225 sum = htons (0xffff - sum);
232 return sum; 226 return sum;
233} 227}
234 228
@@ -240,12 +234,11 @@ calc_checksum(const uint16_t *data,
240 * @param other target address 234 * @param other target address
241 */ 235 */
242static void 236static void
243send_icmp_udp (const struct in_addr *my_ip, 237send_icmp_udp (const struct in_addr *my_ip, const struct in_addr *other)
244 const struct in_addr *other)
245{ 238{
246 char packet[sizeof(struct ip_header) * 2 + 239 char packet[sizeof (struct ip_header) * 2 +
247 sizeof(struct icmp_ttl_exceeded_header) + 240 sizeof (struct icmp_ttl_exceeded_header) +
248 sizeof(struct udp_header)]; 241 sizeof (struct udp_header)];
249 struct ip_header ip_pkt; 242 struct ip_header ip_pkt;
250 struct icmp_ttl_exceeded_header icmp_pkt; 243 struct icmp_ttl_exceeded_header icmp_pkt;
251 struct udp_header udp_pkt; 244 struct udp_header udp_pkt;
@@ -257,86 +250,74 @@ send_icmp_udp (const struct in_addr *my_ip,
257 off = 0; 250 off = 0;
258 ip_pkt.vers_ihl = 0x45; 251 ip_pkt.vers_ihl = 0x45;
259 ip_pkt.tos = 0; 252 ip_pkt.tos = 0;
260 ip_pkt.pkt_len = htons(sizeof (packet)); 253 ip_pkt.pkt_len = htons (sizeof (packet));
261 ip_pkt.id = htons(256); 254 ip_pkt.id = htons (256);
262 ip_pkt.flags_frag_offset = 0; 255 ip_pkt.flags_frag_offset = 0;
263 ip_pkt.ttl = 128; 256 ip_pkt.ttl = 128;
264 ip_pkt.proto = IPPROTO_ICMP; 257 ip_pkt.proto = IPPROTO_ICMP;
265 ip_pkt.checksum = 0; 258 ip_pkt.checksum = 0;
266 ip_pkt.src_ip = my_ip->s_addr; 259 ip_pkt.src_ip = my_ip->s_addr;
267 ip_pkt.dst_ip = other->s_addr; 260 ip_pkt.dst_ip = other->s_addr;
268 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 261 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
269 sizeof (struct ip_header))); 262 sizeof (struct ip_header)));
270 memcpy(&packet[off], 263 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
271 &ip_pkt, 264 off += sizeof (struct ip_header);
272 sizeof(struct ip_header));
273 off += sizeof(struct ip_header);
274 265
275 icmp_pkt.type = ICMP_TIME_EXCEEDED; 266 icmp_pkt.type = ICMP_TIME_EXCEEDED;
276 icmp_pkt.code = 0; 267 icmp_pkt.code = 0;
277 icmp_pkt.checksum = 0; 268 icmp_pkt.checksum = 0;
278 icmp_pkt.unused = 0; 269 icmp_pkt.unused = 0;
279 memcpy(&packet[off], 270 memcpy (&packet[off], &icmp_pkt, sizeof (struct icmp_ttl_exceeded_header));
280 &icmp_pkt, 271 off += sizeof (struct icmp_ttl_exceeded_header);
281 sizeof(struct icmp_ttl_exceeded_header));
282 off += sizeof(struct icmp_ttl_exceeded_header);
283 272
284 /* ip header of the presumably 'lost' udp packet */ 273 /* ip header of the presumably 'lost' udp packet */
285 ip_pkt.vers_ihl = 0x45; 274 ip_pkt.vers_ihl = 0x45;
286 ip_pkt.tos = 0; 275 ip_pkt.tos = 0;
287 ip_pkt.pkt_len = htons(sizeof (struct ip_header) + 276 ip_pkt.pkt_len = htons (sizeof (struct ip_header) +
288 sizeof (struct udp_header)); 277 sizeof (struct udp_header));
289 ip_pkt.id = htons(0); 278 ip_pkt.id = htons (0);
290 ip_pkt.flags_frag_offset = 0; 279 ip_pkt.flags_frag_offset = 0;
291 ip_pkt.ttl = 128; 280 ip_pkt.ttl = 128;
292 ip_pkt.proto = IPPROTO_UDP; 281 ip_pkt.proto = IPPROTO_UDP;
293 ip_pkt.checksum = 0; 282 ip_pkt.checksum = 0;
294 ip_pkt.src_ip = other->s_addr; 283 ip_pkt.src_ip = other->s_addr;
295 ip_pkt.dst_ip = dummy.s_addr; 284 ip_pkt.dst_ip = dummy.s_addr;
296 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 285 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
297 sizeof (struct ip_header))); 286 sizeof (struct ip_header)));
298 memcpy(&packet[off], 287 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
299 &ip_pkt, 288 off += sizeof (struct ip_header);
300 sizeof(struct ip_header));
301 off += sizeof(struct ip_header);
302 289
303 /* build UDP header */ 290 /* build UDP header */
304 udp_pkt.src_port = htons(NAT_TRAV_PORT); 291 udp_pkt.src_port = htons (NAT_TRAV_PORT);
305 udp_pkt.dst_port = htons(NAT_TRAV_PORT); 292 udp_pkt.dst_port = htons (NAT_TRAV_PORT);
306 udp_pkt.length = htons (port); 293 udp_pkt.length = htons (port);
307 udp_pkt.crc = 0; 294 udp_pkt.crc = 0;
308 memcpy(&packet[off], 295 memcpy (&packet[off], &udp_pkt, sizeof (struct udp_header));
309 &udp_pkt, 296 off += sizeof (struct udp_header);
310 sizeof(struct udp_header));
311 off += sizeof(struct udp_header);
312 297
313 /* no go back to calculate ICMP packet checksum */ 298 /* no go back to calculate ICMP packet checksum */
314 icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[off], 299 icmp_pkt.checksum = htons (calc_checksum ((uint16_t *) & packet[off],
315 sizeof (struct icmp_ttl_exceeded_header) + 300 sizeof (struct
316 sizeof (struct ip_header) + 301 icmp_ttl_exceeded_header) +
317 sizeof (struct udp_header))); 302 sizeof (struct ip_header) +
318 memcpy (&packet[sizeof (struct ip_header)], 303 sizeof (struct udp_header)));
319 &icmp_pkt, 304 memcpy (&packet[sizeof (struct ip_header)], &icmp_pkt,
320 sizeof (struct icmp_ttl_exceeded_header)); 305 sizeof (struct icmp_ttl_exceeded_header));
321 306
322 memset (&dst, 0, sizeof (dst)); 307 memset (&dst, 0, sizeof (dst));
323 dst.sin_family = AF_INET; 308 dst.sin_family = AF_INET;
324 dst.sin_addr = *other; 309 dst.sin_addr = *other;
325 err = sendto(rawsock, 310 err = sendto (rawsock,
326 packet, 311 packet,
327 sizeof (packet), 0, 312 sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst));
328 (struct sockaddr*)&dst,
329 sizeof(dst));
330 if (err < 0) 313 if (err < 0)
331 { 314 {
332 fprintf(stderr, 315 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
333 "sendto failed: %s\n", strerror(errno)); 316 }
334 }
335 else if (sizeof (packet) != (size_t) err) 317 else if (sizeof (packet) != (size_t) err)
336 { 318 {
337 fprintf(stderr, 319 fprintf (stderr, "Error: partial send of ICMP message\n");
338 "Error: partial send of ICMP message\n"); 320 }
339 }
340} 321}
341 322
342 323
@@ -347,16 +328,15 @@ send_icmp_udp (const struct in_addr *my_ip,
347 * @param other target address 328 * @param other target address
348 */ 329 */
349static void 330static void
350send_icmp (const struct in_addr *my_ip, 331send_icmp (const struct in_addr *my_ip, const struct in_addr *other)
351 const struct in_addr *other)
352{ 332{
353 struct ip_header ip_pkt; 333 struct ip_header ip_pkt;
354 struct icmp_ttl_exceeded_header icmp_ttl; 334 struct icmp_ttl_exceeded_header icmp_ttl;
355 struct icmp_echo_header icmp_echo; 335 struct icmp_echo_header icmp_echo;
356 struct sockaddr_in dst; 336 struct sockaddr_in dst;
357 char packet[sizeof (struct ip_header) * 2 + 337 char packet[sizeof (struct ip_header) * 2 +
358 sizeof (struct icmp_ttl_exceeded_header) + 338 sizeof (struct icmp_ttl_exceeded_header) +
359 sizeof(struct icmp_echo_header)]; 339 sizeof (struct icmp_echo_header)];
360 size_t off; 340 size_t off;
361 int err; 341 int err;
362 342
@@ -365,88 +345,76 @@ send_icmp (const struct in_addr *my_ip,
365 ip_pkt.vers_ihl = 0x45; 345 ip_pkt.vers_ihl = 0x45;
366 ip_pkt.tos = 0; 346 ip_pkt.tos = 0;
367 ip_pkt.pkt_len = htons (sizeof (packet)); 347 ip_pkt.pkt_len = htons (sizeof (packet));
368 ip_pkt.id = htons(256); 348 ip_pkt.id = htons (256);
369 ip_pkt.flags_frag_offset = 0; 349 ip_pkt.flags_frag_offset = 0;
370 ip_pkt.ttl = IPDEFTTL; 350 ip_pkt.ttl = IPDEFTTL;
371 ip_pkt.proto = IPPROTO_ICMP; 351 ip_pkt.proto = IPPROTO_ICMP;
372 ip_pkt.checksum = 0; 352 ip_pkt.checksum = 0;
373 ip_pkt.src_ip = my_ip->s_addr; 353 ip_pkt.src_ip = my_ip->s_addr;
374 ip_pkt.dst_ip = other->s_addr; 354 ip_pkt.dst_ip = other->s_addr;
375 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 355 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
376 sizeof (struct ip_header))); 356 sizeof (struct ip_header)));
377 memcpy (&packet[off], 357 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
378 &ip_pkt,
379 sizeof (struct ip_header));
380 off += sizeof (ip_pkt); 358 off += sizeof (ip_pkt);
381 359
382 /* icmp reply: time exceeded */ 360 /* icmp reply: time exceeded */
383 icmp_ttl.type = ICMP_TIME_EXCEEDED; 361 icmp_ttl.type = ICMP_TIME_EXCEEDED;
384 icmp_ttl.code = 0; 362 icmp_ttl.code = 0;
385 icmp_ttl.checksum = 0; 363 icmp_ttl.checksum = 0;
386 icmp_ttl.unused = 0; 364 icmp_ttl.unused = 0;
387 memcpy (&packet[off], 365 memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header));
388 &icmp_ttl,
389 sizeof (struct icmp_ttl_exceeded_header));
390 off += sizeof (struct icmp_ttl_exceeded_header); 366 off += sizeof (struct icmp_ttl_exceeded_header);
391 367
392 /* ip header of the presumably 'lost' udp packet */ 368 /* ip header of the presumably 'lost' udp packet */
393 ip_pkt.vers_ihl = 0x45; 369 ip_pkt.vers_ihl = 0x45;
394 ip_pkt.tos = 0; 370 ip_pkt.tos = 0;
395 ip_pkt.pkt_len = htons(sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); 371 ip_pkt.pkt_len =
372 htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header));
396 ip_pkt.id = htons (256); 373 ip_pkt.id = htons (256);
397 ip_pkt.flags_frag_offset = 0; 374 ip_pkt.flags_frag_offset = 0;
398 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ 375 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
399 ip_pkt.proto = IPPROTO_ICMP; 376 ip_pkt.proto = IPPROTO_ICMP;
400 ip_pkt.src_ip = other->s_addr; 377 ip_pkt.src_ip = other->s_addr;
401 ip_pkt.dst_ip = dummy.s_addr; 378 ip_pkt.dst_ip = dummy.s_addr;
402 ip_pkt.checksum = 0; 379 ip_pkt.checksum = 0;
403 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 380 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
404 sizeof (struct ip_header))); 381 sizeof (struct ip_header)));
405 memcpy (&packet[off], 382 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
406 &ip_pkt,
407 sizeof (struct ip_header));
408 off += sizeof (struct ip_header); 383 off += sizeof (struct ip_header);
409 384
410 icmp_echo.type = ICMP_ECHO; 385 icmp_echo.type = ICMP_ECHO;
411 icmp_echo.code = 0; 386 icmp_echo.code = 0;
412 icmp_echo.reserved = htonl(port); 387 icmp_echo.reserved = htonl (port);
413 icmp_echo.checksum = 0; 388 icmp_echo.checksum = 0;
414 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, 389 icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo,
415 sizeof (struct icmp_echo_header))); 390 sizeof (struct icmp_echo_header)));
416 memcpy (&packet[off], 391 memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
417 &icmp_echo,
418 sizeof(struct icmp_echo_header));
419 392
420 /* no go back to calculate ICMP packet checksum */ 393 /* no go back to calculate ICMP packet checksum */
421 off = sizeof (struct ip_header); 394 off = sizeof (struct ip_header);
422 icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], 395 icmp_ttl.checksum = htons (calc_checksum ((uint16_t *) & packet[off],
423 sizeof (struct icmp_ttl_exceeded_header) + 396 sizeof (struct
424 sizeof (struct ip_header) + 397 icmp_ttl_exceeded_header) +
425 sizeof (struct icmp_echo_header))); 398 sizeof (struct ip_header) +
426 memcpy (&packet[off], 399 sizeof (struct icmp_echo_header)));
427 &icmp_ttl, 400 memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header));
428 sizeof (struct icmp_ttl_exceeded_header));
429 401
430 memset (&dst, 0, sizeof (dst)); 402 memset (&dst, 0, sizeof (dst));
431 dst.sin_family = AF_INET; 403 dst.sin_family = AF_INET;
432 dst.sin_addr = *other; 404 dst.sin_addr = *other;
433 405
434 err = sendto(rawsock, 406 err = sendto (rawsock,
435 packet, 407 packet,
436 sizeof (packet), 0, 408 sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst));
437 (struct sockaddr*)&dst,
438 sizeof(dst));
439 409
440 if (err < 0) 410 if (err < 0)
441 { 411 {
442 fprintf(stderr, 412 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
443 "sendto failed: %s\n", strerror(errno)); 413 }
444 }
445 else if (sizeof (packet) != (size_t) err) 414 else if (sizeof (packet) != (size_t) err)
446 { 415 {
447 fprintf(stderr, 416 fprintf (stderr, "Error: partial send of ICMP message\n");
448 "Error: partial send of ICMP message\n"); 417 }
449 }
450} 418}
451 419
452 420
@@ -459,34 +427,30 @@ static SOCKET
459make_raw_socket () 427make_raw_socket ()
460{ 428{
461 DWORD bOptVal = TRUE; 429 DWORD bOptVal = TRUE;
462 int bOptLen = sizeof(bOptVal); 430 int bOptLen = sizeof (bOptVal);
463 SOCKET ret; 431 SOCKET ret;
464 432
465 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); 433 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
466 if (INVALID_SOCKET == ret) 434 if (INVALID_SOCKET == ret)
467 { 435 {
468 fprintf (stderr, 436 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
469 "Error opening RAW socket: %s\n", 437 return INVALID_SOCKET;
470 strerror (errno)); 438 }
471 return INVALID_SOCKET; 439 if (0 !=
472 } 440 setsockopt (ret, SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, bOptLen))
473 if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen)) 441 {
474 { 442 fprintf (stderr,
475 fprintf(stderr, 443 "Error setting SO_BROADCAST to ON: %s\n", strerror (errno));
476 "Error setting SO_BROADCAST to ON: %s\n", 444 closesocket (rawsock);
477 strerror (errno)); 445 return INVALID_SOCKET;
478 closesocket(rawsock); 446 }
479 return INVALID_SOCKET; 447
480 } 448 if (0 != setsockopt (ret, IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen))
481 449 {
482 if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen)) 450 fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno));
483 { 451 closesocket (rawsock);
484 fprintf(stderr, 452 return INVALID_SOCKET;
485 "Error setting IP_HDRINCL to ON: %s\n", 453 }
486 strerror (errno));
487 closesocket(rawsock);
488 return INVALID_SOCKET;
489 }
490 return ret; 454 return ret;
491} 455}
492 456
@@ -501,47 +465,38 @@ main (int argc, char *const *argv)
501 unsigned int p; 465 unsigned int p;
502 466
503 if (argc != 4) 467 if (argc != 4)
504 { 468 {
505 fprintf (stderr, 469 fprintf (stderr,
506 "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); 470 "This program must be started with our IP, the targets external IP, and our port as arguments.\n");
507 return 1; 471 return 1;
508 } 472 }
509 if ( (1 != inet_pton (AF_INET, argv[1], &external)) || 473 if ((1 != inet_pton (AF_INET, argv[1], &external)) ||
510 (1 != inet_pton (AF_INET, argv[2], &target)) ) 474 (1 != inet_pton (AF_INET, argv[2], &target)))
511 { 475 {
512 fprintf (stderr, 476 fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno));
513 "Error parsing IPv4 address: %s\n", 477 return 1;
514 strerror (errno)); 478 }
515 return 1; 479 if ((1 != sscanf (argv[3], "%u", &p)) || (0 == p) || (0xFFFF < p))
516 } 480 {
517 if ( (1 != sscanf (argv[3], "%u", &p) ) || 481 fprintf (stderr, "Error parsing port value `%s'\n", argv[3]);
518 (0 == p) || 482 return 1;
519 (0xFFFF < p) ) 483 }
520 {
521 fprintf (stderr,
522 "Error parsing port value `%s'\n",
523 argv[3]);
524 return 1;
525 }
526 port = (uint16_t) p; 484 port = (uint16_t) p;
527 485
528 if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData)) 486 if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData))
529 { 487 {
530 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); 488 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
531 return 2; 489 return 2;
532 } 490 }
533 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) 491 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
534 { 492 {
535 fprintf (stderr, 493 fprintf (stderr, "Internal error converting dummy IP to binary.\n");
536 "Internal error converting dummy IP to binary.\n"); 494 return 2;
537 return 2; 495 }
538 } 496 if (-1 == (rawsock = make_raw_socket ()))
539 if (-1 == (rawsock = make_raw_socket()))
540 return 3; 497 return 3;
541 send_icmp (&external, 498 send_icmp (&external, &target);
542 &target); 499 send_icmp_udp (&external, &target);
543 send_icmp_udp (&external,
544 &target);
545 closesocket (rawsock); 500 closesocket (rawsock);
546 WSACleanup (); 501 WSACleanup ();
547 return 0; 502 return 0;