diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-08-22 13:36:33 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-08-22 13:36:33 +0000 |
commit | b4e21c6afcb6cd772c66b2c0ae3199f193c972c7 (patch) | |
tree | 10cf25bb37ee491ac5d083d93678944e0e510f1c | |
parent | 1355ed0acd88356beccc25dfc710ef0d458b5b96 (diff) | |
download | gnunet-b4e21c6afcb6cd772c66b2c0ae3199f193c972c7.tar.gz gnunet-b4e21c6afcb6cd772c66b2c0ae3199f193c972c7.zip |
audit
-rw-r--r-- | src/transport/gnunet-nat-client.c | 101 | ||||
-rw-r--r-- | src/transport/gnunet-nat-server.c | 125 |
2 files changed, 114 insertions, 112 deletions
diff --git a/src/transport/gnunet-nat-client.c b/src/transport/gnunet-nat-client.c index bff86cc93..3e35aa8f4 100644 --- a/src/transport/gnunet-nat-client.c +++ b/src/transport/gnunet-nat-client.c | |||
@@ -21,7 +21,7 @@ | |||
21 | /** | 21 | /** |
22 | * @file src/transport/gnunet-nat-client.c | 22 | * @file src/transport/gnunet-nat-client.c |
23 | * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do) | 23 | * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do) |
24 | * This code will work under GNU/Linux only. | 24 | * This code will work under GNU/Linux only. |
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
26 | * | 26 | * |
27 | * This program will send ONE ICMP message using RAW sockets | 27 | * This program will send ONE ICMP message using RAW sockets |
@@ -39,6 +39,7 @@ | |||
39 | * | 39 | * |
40 | * - Christian Grothoff | 40 | * - Christian Grothoff |
41 | * - Nathan Evans | 41 | * - Nathan Evans |
42 | * - Benjamin Kuperman (22 Aug 2010) | ||
42 | */ | 43 | */ |
43 | #if HAVE_CONFIG_H | 44 | #if HAVE_CONFIG_H |
44 | /* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */ | 45 | /* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */ |
@@ -46,7 +47,7 @@ | |||
46 | #else | 47 | #else |
47 | #define _GNU_SOURCE | 48 | #define _GNU_SOURCE |
48 | #endif | 49 | #endif |
49 | #include <sys/types.h> | 50 | #include <sys/types.h> |
50 | #include <sys/socket.h> | 51 | #include <sys/socket.h> |
51 | #include <arpa/inet.h> | 52 | #include <arpa/inet.h> |
52 | #include <sys/types.h> | 53 | #include <sys/types.h> |
@@ -58,7 +59,7 @@ | |||
58 | #include <stdint.h> | 59 | #include <stdint.h> |
59 | #include <netinet/ip.h> | 60 | #include <netinet/ip.h> |
60 | #include <netinet/ip_icmp.h> | 61 | #include <netinet/ip_icmp.h> |
61 | #include <netinet/in.h> | 62 | #include <netinet/in.h> |
62 | 63 | ||
63 | /** | 64 | /** |
64 | * Must match IP given in the server. | 65 | * Must match IP given in the server. |
@@ -70,11 +71,11 @@ | |||
70 | /** | 71 | /** |
71 | * IPv4 header. | 72 | * IPv4 header. |
72 | */ | 73 | */ |
73 | struct ip_header | 74 | struct ip_header |
74 | { | 75 | { |
75 | 76 | ||
76 | /** | 77 | /** |
77 | * Version (4 bits) + Internet header length (4 bits) | 78 | * Version (4 bits) + Internet header length (4 bits) |
78 | */ | 79 | */ |
79 | uint8_t vers_ihl; | 80 | uint8_t vers_ihl; |
80 | 81 | ||
@@ -104,10 +105,10 @@ struct ip_header | |||
104 | uint8_t ttl; | 105 | uint8_t ttl; |
105 | 106 | ||
106 | /** | 107 | /** |
107 | * Protocol | 108 | * Protocol |
108 | */ | 109 | */ |
109 | uint8_t proto; | 110 | uint8_t proto; |
110 | 111 | ||
111 | /** | 112 | /** |
112 | * Header checksum | 113 | * Header checksum |
113 | */ | 114 | */ |
@@ -119,7 +120,7 @@ struct ip_header | |||
119 | uint32_t src_ip; | 120 | uint32_t src_ip; |
120 | 121 | ||
121 | /** | 122 | /** |
122 | * Destination address | 123 | * Destination address |
123 | */ | 124 | */ |
124 | uint32_t dst_ip; | 125 | uint32_t dst_ip; |
125 | }; | 126 | }; |
@@ -127,7 +128,7 @@ struct ip_header | |||
127 | /** | 128 | /** |
128 | * Format of ICMP packet. | 129 | * Format of ICMP packet. |
129 | */ | 130 | */ |
130 | struct icmp_ttl_exceeded_header | 131 | struct icmp_ttl_exceeded_header |
131 | { | 132 | { |
132 | uint8_t type; | 133 | uint8_t type; |
133 | 134 | ||
@@ -161,7 +162,7 @@ struct udp_header | |||
161 | uint16_t dst_port; | 162 | uint16_t dst_port; |
162 | 163 | ||
163 | uint16_t length; | 164 | uint16_t length; |
164 | 165 | ||
165 | uint16_t crc; | 166 | uint16_t crc; |
166 | }; | 167 | }; |
167 | 168 | ||
@@ -174,7 +175,7 @@ static int rawsock; | |||
174 | * Target "dummy" address of the packet we pretend to respond to. | 175 | * Target "dummy" address of the packet we pretend to respond to. |
175 | */ | 176 | */ |
176 | static struct in_addr dummy; | 177 | static struct in_addr dummy; |
177 | 178 | ||
178 | /** | 179 | /** |
179 | * Our "source" port. | 180 | * Our "source" port. |
180 | */ | 181 | */ |
@@ -188,16 +189,16 @@ static uint16_t port; | |||
188 | * @param bytes number of bytes in data (must be multiple of 2) | 189 | * @param bytes number of bytes in data (must be multiple of 2) |
189 | * @return the CRC 16. | 190 | * @return the CRC 16. |
190 | */ | 191 | */ |
191 | static uint16_t | 192 | static uint16_t |
192 | calc_checksum (const uint16_t *data, | 193 | calc_checksum (const uint16_t *data, |
193 | unsigned int bytes) | 194 | unsigned int bytes) |
194 | { | 195 | { |
195 | uint32_t sum; | 196 | uint32_t sum; |
196 | unsigned int i; | 197 | unsigned int i; |
197 | 198 | ||
198 | sum = 0; | 199 | sum = 0; |
199 | for (i=0;i<bytes/2;i++) | 200 | for (i=0;i<bytes/2;i++) |
200 | sum += data[i]; | 201 | sum += data[i]; |
201 | sum = (sum & 0xffff) + (sum >> 16); | 202 | sum = (sum & 0xffff) + (sum >> 16); |
202 | sum = htons(0xffff - sum); | 203 | sum = htons(0xffff - sum); |
203 | return sum; | 204 | return sum; |
@@ -214,8 +215,8 @@ static void | |||
214 | send_icmp_udp (const struct in_addr *my_ip, | 215 | send_icmp_udp (const struct in_addr *my_ip, |
215 | const struct in_addr *other) | 216 | const struct in_addr *other) |
216 | { | 217 | { |
217 | char packet[sizeof(struct ip_header) * 2 + | 218 | char packet[sizeof(struct ip_header) * 2 + |
218 | sizeof(struct icmp_ttl_exceeded_header) + | 219 | sizeof(struct icmp_ttl_exceeded_header) + |
219 | sizeof(struct udp_header)]; | 220 | sizeof(struct udp_header)]; |
220 | struct ip_header ip_pkt; | 221 | struct ip_header ip_pkt; |
221 | struct icmp_ttl_exceeded_header icmp_pkt; | 222 | struct icmp_ttl_exceeded_header icmp_pkt; |
@@ -236,10 +237,10 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
236 | ip_pkt.checksum = 0; | 237 | ip_pkt.checksum = 0; |
237 | ip_pkt.src_ip = my_ip->s_addr; | 238 | ip_pkt.src_ip = my_ip->s_addr; |
238 | ip_pkt.dst_ip = other->s_addr; | 239 | ip_pkt.dst_ip = other->s_addr; |
239 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 240 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, |
240 | sizeof (struct ip_header))); | 241 | sizeof (struct ip_header))); |
241 | memcpy(&packet[off], | 242 | memcpy(&packet[off], |
242 | &ip_pkt, | 243 | &ip_pkt, |
243 | sizeof(struct ip_header)); | 244 | sizeof(struct ip_header)); |
244 | off += sizeof(struct ip_header); | 245 | off += sizeof(struct ip_header); |
245 | 246 | ||
@@ -248,7 +249,7 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
248 | icmp_pkt.checksum = 0; | 249 | icmp_pkt.checksum = 0; |
249 | icmp_pkt.unused = 0; | 250 | icmp_pkt.unused = 0; |
250 | memcpy(&packet[off], | 251 | memcpy(&packet[off], |
251 | &icmp_pkt, | 252 | &icmp_pkt, |
252 | sizeof(struct icmp_ttl_exceeded_header)); | 253 | sizeof(struct icmp_ttl_exceeded_header)); |
253 | off += sizeof(struct icmp_ttl_exceeded_header); | 254 | off += sizeof(struct icmp_ttl_exceeded_header); |
254 | 255 | ||
@@ -266,8 +267,8 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
266 | ip_pkt.dst_ip = dummy.s_addr; | 267 | ip_pkt.dst_ip = dummy.s_addr; |
267 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 268 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, |
268 | sizeof (struct ip_header))); | 269 | sizeof (struct ip_header))); |
269 | memcpy(&packet[off], | 270 | memcpy(&packet[off], |
270 | &ip_pkt, | 271 | &ip_pkt, |
271 | sizeof(struct ip_header)); | 272 | sizeof(struct ip_header)); |
272 | off += sizeof(struct ip_header); | 273 | off += sizeof(struct ip_header); |
273 | 274 | ||
@@ -276,7 +277,7 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
276 | udp_pkt.dst_port = htons(NAT_TRAV_PORT); | 277 | udp_pkt.dst_port = htons(NAT_TRAV_PORT); |
277 | udp_pkt.length = htons (port); | 278 | udp_pkt.length = htons (port); |
278 | udp_pkt.crc = 0; | 279 | udp_pkt.crc = 0; |
279 | memcpy(&packet[off], | 280 | memcpy(&packet[off], |
280 | &udp_pkt, | 281 | &udp_pkt, |
281 | sizeof(struct udp_header)); | 282 | sizeof(struct udp_header)); |
282 | off += sizeof(struct udp_header); | 283 | off += sizeof(struct udp_header); |
@@ -286,9 +287,9 @@ send_icmp_udp (const struct in_addr *my_ip, | |||
286 | sizeof (struct icmp_ttl_exceeded_header) + | 287 | sizeof (struct icmp_ttl_exceeded_header) + |
287 | sizeof (struct ip_header) + | 288 | sizeof (struct ip_header) + |
288 | sizeof (struct udp_header))); | 289 | sizeof (struct udp_header))); |
289 | memcpy (&packet[sizeof(struct ip_header)], | 290 | memcpy (&packet[sizeof(struct ip_header)], |
290 | &icmp_pkt, | 291 | &icmp_pkt, |
291 | sizeof (struct icmp_ttl_exceeded_header)); | 292 | sizeof (struct icmp_ttl_exceeded_header)); |
292 | 293 | ||
293 | memset (&dst, 0, sizeof (dst)); | 294 | memset (&dst, 0, sizeof (dst)); |
294 | dst.sin_family = AF_INET; | 295 | dst.sin_family = AF_INET; |
@@ -339,23 +340,23 @@ send_icmp (const struct in_addr *my_ip, | |||
339 | ip_pkt.vers_ihl = 0x45; | 340 | ip_pkt.vers_ihl = 0x45; |
340 | ip_pkt.tos = 0; | 341 | ip_pkt.tos = 0; |
341 | ip_pkt.pkt_len = htons (sizeof (packet)); | 342 | ip_pkt.pkt_len = htons (sizeof (packet)); |
342 | ip_pkt.id = htons (256); | 343 | ip_pkt.id = htons (256); |
343 | ip_pkt.flags_frag_offset = 0; | 344 | ip_pkt.flags_frag_offset = 0; |
344 | ip_pkt.ttl = IPDEFTTL; | 345 | ip_pkt.ttl = IPDEFTTL; |
345 | ip_pkt.proto = IPPROTO_ICMP; | 346 | ip_pkt.proto = IPPROTO_ICMP; |
346 | ip_pkt.checksum = 0; | 347 | ip_pkt.checksum = 0; |
347 | ip_pkt.src_ip = my_ip->s_addr; | 348 | ip_pkt.src_ip = my_ip->s_addr; |
348 | ip_pkt.dst_ip = other->s_addr; | 349 | ip_pkt.dst_ip = other->s_addr; |
349 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 350 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, |
350 | sizeof (struct ip_header))); | 351 | sizeof (struct ip_header))); |
351 | memcpy (&packet[off], | 352 | memcpy (&packet[off], |
352 | &ip_pkt, | 353 | &ip_pkt, |
353 | sizeof (struct ip_header)); | 354 | sizeof (struct ip_header)); |
354 | off = sizeof (ip_pkt); | 355 | off = sizeof (ip_pkt); |
355 | 356 | ||
356 | /* icmp reply: time exceeded */ | 357 | /* icmp reply: time exceeded */ |
357 | icmp_ttl.type = ICMP_TIME_EXCEEDED; | 358 | icmp_ttl.type = ICMP_TIME_EXCEEDED; |
358 | icmp_ttl.code = 0; | 359 | icmp_ttl.code = 0; |
359 | icmp_ttl.checksum = 0; | 360 | icmp_ttl.checksum = 0; |
360 | icmp_ttl.unused = 0; | 361 | icmp_ttl.unused = 0; |
361 | memcpy (&packet[off], | 362 | memcpy (&packet[off], |
@@ -367,7 +368,7 @@ send_icmp (const struct in_addr *my_ip, | |||
367 | ip_pkt.vers_ihl = 0x45; | 368 | ip_pkt.vers_ihl = 0x45; |
368 | ip_pkt.tos = 0; | 369 | ip_pkt.tos = 0; |
369 | ip_pkt.pkt_len = htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); | 370 | ip_pkt.pkt_len = htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); |
370 | ip_pkt.id = htons (256); | 371 | ip_pkt.id = htons (256); |
371 | ip_pkt.flags_frag_offset = 0; | 372 | ip_pkt.flags_frag_offset = 0; |
372 | ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ | 373 | ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ |
373 | ip_pkt.proto = IPPROTO_ICMP; | 374 | ip_pkt.proto = IPPROTO_ICMP; |
@@ -375,9 +376,9 @@ send_icmp (const struct in_addr *my_ip, | |||
375 | ip_pkt.dst_ip = dummy.s_addr; | 376 | ip_pkt.dst_ip = dummy.s_addr; |
376 | ip_pkt.checksum = 0; | 377 | ip_pkt.checksum = 0; |
377 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 378 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, |
378 | sizeof (struct ip_header))); | 379 | sizeof (struct ip_header))); |
379 | memcpy (&packet[off], | 380 | memcpy (&packet[off], |
380 | &ip_pkt, | 381 | &ip_pkt, |
381 | sizeof (struct ip_header)); | 382 | sizeof (struct ip_header)); |
382 | off += sizeof (struct ip_header); | 383 | off += sizeof (struct ip_header); |
383 | 384 | ||
@@ -385,17 +386,17 @@ send_icmp (const struct in_addr *my_ip, | |||
385 | icmp_echo.code = 0; | 386 | icmp_echo.code = 0; |
386 | icmp_echo.reserved = htonl (port); | 387 | icmp_echo.reserved = htonl (port); |
387 | icmp_echo.checksum = 0; | 388 | icmp_echo.checksum = 0; |
388 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, | 389 | icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, |
389 | sizeof (struct icmp_echo_header))); | 390 | sizeof (struct icmp_echo_header))); |
390 | memcpy (&packet[off], | 391 | memcpy (&packet[off], |
391 | &icmp_echo, | 392 | &icmp_echo, |
392 | sizeof(struct icmp_echo_header)); | 393 | sizeof(struct icmp_echo_header)); |
393 | 394 | ||
394 | /* no go back to calculate ICMP packet checksum */ | 395 | /* no go back to calculate ICMP packet checksum */ |
395 | off = sizeof (struct ip_header); | 396 | off = sizeof (struct ip_header); |
396 | icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], | 397 | icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], |
397 | sizeof (struct icmp_ttl_exceeded_header) + | 398 | sizeof (struct icmp_ttl_exceeded_header) + |
398 | sizeof (struct ip_header) + | 399 | sizeof (struct ip_header) + |
399 | sizeof (struct icmp_echo_header))); | 400 | sizeof (struct icmp_echo_header))); |
400 | memcpy (&packet[off], | 401 | memcpy (&packet[off], |
401 | &icmp_ttl, | 402 | &icmp_ttl, |
@@ -408,17 +409,17 @@ send_icmp (const struct in_addr *my_ip, | |||
408 | dst.sin_len = sizeof (struct sockaddr_in); | 409 | dst.sin_len = sizeof (struct sockaddr_in); |
409 | #endif | 410 | #endif |
410 | dst.sin_addr = *other; | 411 | dst.sin_addr = *other; |
411 | err = sendto(rawsock, | 412 | err = sendto(rawsock, |
412 | packet, | 413 | packet, |
413 | sizeof (packet), 0, | 414 | sizeof (packet), 0, |
414 | (struct sockaddr*)&dst, | 415 | (struct sockaddr*)&dst, |
415 | sizeof(dst)); | 416 | sizeof(dst)); |
416 | if (err < 0) | 417 | if (err < 0) |
417 | { | 418 | { |
418 | fprintf(stderr, | 419 | fprintf(stderr, |
419 | "sendto failed: %s\n", strerror(errno)); | 420 | "sendto failed: %s\n", strerror(errno)); |
420 | } | 421 | } |
421 | else if (sizeof (packet) != (size_t) err) | 422 | else if (sizeof (packet) != (size_t) err) |
422 | { | 423 | { |
423 | fprintf(stderr, | 424 | fprintf(stderr, |
424 | "Error: partial send of ICMP message\n"); | 425 | "Error: partial send of ICMP message\n"); |
@@ -444,7 +445,7 @@ make_raw_socket () | |||
444 | "Error opening RAW socket: %s\n", | 445 | "Error opening RAW socket: %s\n", |
445 | strerror (errno)); | 446 | strerror (errno)); |
446 | return -1; | 447 | return -1; |
447 | } | 448 | } |
448 | if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, | 449 | if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, |
449 | (char *)&one, sizeof(one))) | 450 | (char *)&one, sizeof(one))) |
450 | { | 451 | { |
@@ -499,14 +500,14 @@ main (int argc, char *const *argv) | |||
499 | return 1; | 500 | return 1; |
500 | } | 501 | } |
501 | port = (uint16_t) p; | 502 | port = (uint16_t) p; |
502 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 503 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
503 | { | 504 | { |
504 | fprintf (stderr, | 505 | fprintf (stderr, |
505 | "Internal error converting dummy IP to binary.\n"); | 506 | "Internal error converting dummy IP to binary.\n"); |
506 | return 2; | 507 | return 2; |
507 | } | 508 | } |
508 | if (-1 == (rawsock = make_raw_socket())) | 509 | if (-1 == (rawsock = make_raw_socket())) |
509 | return 2; | 510 | return 2; |
510 | uid = getuid (); | 511 | uid = getuid (); |
511 | if (0 != setresuid (uid, uid, uid)) | 512 | if (0 != setresuid (uid, uid, uid)) |
512 | { | 513 | { |
diff --git a/src/transport/gnunet-nat-server.c b/src/transport/gnunet-nat-server.c index 5cedb35e3..7892d8f93 100644 --- a/src/transport/gnunet-nat-server.c +++ b/src/transport/gnunet-nat-server.c | |||
@@ -39,6 +39,7 @@ | |||
39 | * | 39 | * |
40 | * - Christian Grothoff | 40 | * - Christian Grothoff |
41 | * - Nathan Evans | 41 | * - Nathan Evans |
42 | * - Benjamin Kuperman (22 Aug 2010) | ||
42 | */ | 43 | */ |
43 | #if HAVE_CONFIG_H | 44 | #if HAVE_CONFIG_H |
44 | /* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */ | 45 | /* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */ |
@@ -46,7 +47,7 @@ | |||
46 | #else | 47 | #else |
47 | #define _GNU_SOURCE | 48 | #define _GNU_SOURCE |
48 | #endif | 49 | #endif |
49 | #include <sys/types.h> | 50 | #include <sys/types.h> |
50 | #include <sys/socket.h> | 51 | #include <sys/socket.h> |
51 | #include <arpa/inet.h> | 52 | #include <arpa/inet.h> |
52 | #include <sys/select.h> | 53 | #include <sys/select.h> |
@@ -61,7 +62,7 @@ | |||
61 | #include <time.h> | 62 | #include <time.h> |
62 | #include <netinet/ip.h> | 63 | #include <netinet/ip.h> |
63 | #include <netinet/ip_icmp.h> | 64 | #include <netinet/ip_icmp.h> |
64 | #include <netinet/in.h> | 65 | #include <netinet/in.h> |
65 | 66 | ||
66 | /** | 67 | /** |
67 | * Should we print some debug output? | 68 | * Should we print some debug output? |
@@ -75,7 +76,7 @@ | |||
75 | 76 | ||
76 | /** | 77 | /** |
77 | * Port for UDP | 78 | * Port for UDP |
78 | */ | 79 | */ |
79 | #define NAT_TRAV_PORT 22225 | 80 | #define NAT_TRAV_PORT 22225 |
80 | 81 | ||
81 | /** | 82 | /** |
@@ -86,11 +87,11 @@ | |||
86 | /** | 87 | /** |
87 | * IPv4 header. | 88 | * IPv4 header. |
88 | */ | 89 | */ |
89 | struct ip_header | 90 | struct ip_header |
90 | { | 91 | { |
91 | 92 | ||
92 | /** | 93 | /** |
93 | * Version (4 bits) + Internet header length (4 bits) | 94 | * Version (4 bits) + Internet header length (4 bits) |
94 | */ | 95 | */ |
95 | uint8_t vers_ihl; | 96 | uint8_t vers_ihl; |
96 | 97 | ||
@@ -120,10 +121,10 @@ struct ip_header | |||
120 | uint8_t ttl; | 121 | uint8_t ttl; |
121 | 122 | ||
122 | /** | 123 | /** |
123 | * Protocol | 124 | * Protocol |
124 | */ | 125 | */ |
125 | uint8_t proto; | 126 | uint8_t proto; |
126 | 127 | ||
127 | /** | 128 | /** |
128 | * Header checksum | 129 | * Header checksum |
129 | */ | 130 | */ |
@@ -135,7 +136,7 @@ struct ip_header | |||
135 | uint32_t src_ip; | 136 | uint32_t src_ip; |
136 | 137 | ||
137 | /** | 138 | /** |
138 | * Destination address | 139 | * Destination address |
139 | */ | 140 | */ |
140 | uint32_t dst_ip; | 141 | uint32_t dst_ip; |
141 | }; | 142 | }; |
@@ -143,7 +144,7 @@ struct ip_header | |||
143 | /** | 144 | /** |
144 | * Format of ICMP packet. | 145 | * Format of ICMP packet. |
145 | */ | 146 | */ |
146 | struct icmp_ttl_exceeded_header | 147 | struct icmp_ttl_exceeded_header |
147 | { | 148 | { |
148 | uint8_t type; | 149 | uint8_t type; |
149 | 150 | ||
@@ -210,16 +211,16 @@ static struct in_addr dummy; | |||
210 | * @param bytes number of bytes in data (must be multiple of 2) | 211 | * @param bytes number of bytes in data (must be multiple of 2) |
211 | * @return the CRC 16. | 212 | * @return the CRC 16. |
212 | */ | 213 | */ |
213 | static uint16_t | 214 | static uint16_t |
214 | calc_checksum(const uint16_t *data, | 215 | calc_checksum(const uint16_t *data, |
215 | unsigned int bytes) | 216 | unsigned int bytes) |
216 | { | 217 | { |
217 | uint32_t sum; | 218 | uint32_t sum; |
218 | unsigned int i; | 219 | unsigned int i; |
219 | 220 | ||
220 | sum = 0; | 221 | sum = 0; |
221 | for (i=0;i<bytes/2;i++) | 222 | for (i=0;i<bytes/2;i++) |
222 | sum += data[i]; | 223 | sum += data[i]; |
223 | sum = (sum & 0xffff) + (sum >> 16); | 224 | sum = (sum & 0xffff) + (sum >> 16); |
224 | sum = htons(0xffff - sum); | 225 | sum = htons(0xffff - sum); |
225 | return sum; | 226 | return sum; |
@@ -240,7 +241,7 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
240 | struct sockaddr_in dst; | 241 | struct sockaddr_in dst; |
241 | size_t off; | 242 | size_t off; |
242 | int err; | 243 | int err; |
243 | 244 | ||
244 | off = 0; | 245 | off = 0; |
245 | ip_pkt.vers_ihl = 0x45; | 246 | ip_pkt.vers_ihl = 0x45; |
246 | ip_pkt.tos = 0; | 247 | ip_pkt.tos = 0; |
@@ -249,13 +250,13 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
249 | ip_pkt.flags_frag_offset = 0; | 250 | ip_pkt.flags_frag_offset = 0; |
250 | ip_pkt.ttl = IPDEFTTL; | 251 | ip_pkt.ttl = IPDEFTTL; |
251 | ip_pkt.proto = IPPROTO_ICMP; | 252 | ip_pkt.proto = IPPROTO_ICMP; |
252 | ip_pkt.checksum = 0; | 253 | ip_pkt.checksum = 0; |
253 | ip_pkt.src_ip = my_ip->s_addr; | 254 | ip_pkt.src_ip = my_ip->s_addr; |
254 | ip_pkt.dst_ip = dummy.s_addr; | 255 | ip_pkt.dst_ip = dummy.s_addr; |
255 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, | 256 | ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, |
256 | sizeof (struct ip_header))); | 257 | sizeof (struct ip_header))); |
257 | memcpy (&packet[off], | 258 | memcpy (&packet[off], |
258 | &ip_pkt, | 259 | &ip_pkt, |
259 | sizeof (struct ip_header)); | 260 | sizeof (struct ip_header)); |
260 | off += sizeof (struct ip_header); | 261 | off += sizeof (struct ip_header); |
261 | 262 | ||
@@ -263,31 +264,31 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
263 | icmp_echo.code = 0; | 264 | icmp_echo.code = 0; |
264 | icmp_echo.checksum = 0; | 265 | icmp_echo.checksum = 0; |
265 | icmp_echo.reserved = 0; | 266 | icmp_echo.reserved = 0; |
266 | icmp_echo.checksum = htons(calc_checksum((uint16_t*)&icmp_echo, | 267 | icmp_echo.checksum = htons(calc_checksum((uint16_t*)&icmp_echo, |
267 | sizeof (struct icmp_echo_header))); | 268 | sizeof (struct icmp_echo_header))); |
268 | memcpy (&packet[off], | 269 | memcpy (&packet[off], |
269 | &icmp_echo, | 270 | &icmp_echo, |
270 | sizeof (struct icmp_echo_header)); | 271 | sizeof (struct icmp_echo_header)); |
271 | off += sizeof (struct icmp_echo_header); | 272 | off += sizeof (struct icmp_echo_header); |
272 | 273 | ||
273 | memset (&dst, 0, sizeof (dst)); | 274 | memset (&dst, 0, sizeof (dst)); |
274 | dst.sin_family = AF_INET; | 275 | dst.sin_family = AF_INET; |
275 | #if HAVE_SOCKADDR_IN_SIN_LEN | 276 | #if HAVE_SOCKADDR_IN_SIN_LEN |
276 | dst.sin_len = sizeof (struct sockaddr_in); | 277 | dst.sin_len = sizeof (struct sockaddr_in); |
277 | #endif | 278 | #endif |
278 | dst.sin_addr = dummy; | 279 | dst.sin_addr = dummy; |
279 | err = sendto(rawsock, | 280 | err = sendto(rawsock, |
280 | packet, off, 0, | 281 | packet, off, 0, |
281 | (struct sockaddr*)&dst, | 282 | (struct sockaddr*)&dst, |
282 | sizeof(dst)); | 283 | sizeof(dst)); |
283 | if (err < 0) | 284 | if (err < 0) |
284 | { | 285 | { |
285 | #if VERBOSE | 286 | #if VERBOSE |
286 | fprintf(stderr, | 287 | fprintf(stderr, |
287 | "sendto failed: %s\n", strerror(errno)); | 288 | "sendto failed: %s\n", strerror(errno)); |
288 | #endif | 289 | #endif |
289 | } | 290 | } |
290 | else if (sizeof (packet) != err) | 291 | else if (sizeof (packet) != err) |
291 | { | 292 | { |
292 | fprintf(stderr, | 293 | fprintf(stderr, |
293 | "Error: partial send of ICMP message\n"); | 294 | "Error: partial send of ICMP message\n"); |
@@ -303,7 +304,7 @@ send_udp () | |||
303 | { | 304 | { |
304 | struct sockaddr_in dst; | 305 | struct sockaddr_in dst; |
305 | ssize_t err; | 306 | ssize_t err; |
306 | 307 | ||
307 | memset (&dst, 0, sizeof (dst)); | 308 | memset (&dst, 0, sizeof (dst)); |
308 | dst.sin_family = AF_INET; | 309 | dst.sin_family = AF_INET; |
309 | #if HAVE_SOCKADDR_IN_SIN_LEN | 310 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -311,18 +312,18 @@ send_udp () | |||
311 | #endif | 312 | #endif |
312 | dst.sin_addr = dummy; | 313 | dst.sin_addr = dummy; |
313 | dst.sin_port = htons (NAT_TRAV_PORT); | 314 | dst.sin_port = htons (NAT_TRAV_PORT); |
314 | err = sendto(udpsock, | 315 | err = sendto(udpsock, |
315 | NULL, 0, 0, | 316 | NULL, 0, 0, |
316 | (struct sockaddr*)&dst, | 317 | (struct sockaddr*)&dst, |
317 | sizeof(dst)); | 318 | sizeof(dst)); |
318 | if (err < 0) | 319 | if (err < 0) |
319 | { | 320 | { |
320 | #if VERBOSE | 321 | #if VERBOSE |
321 | fprintf(stderr, | 322 | fprintf(stderr, |
322 | "sendto failed: %s\n", strerror(errno)); | 323 | "sendto failed: %s\n", strerror(errno)); |
323 | #endif | 324 | #endif |
324 | } | 325 | } |
325 | else if (0 != err) | 326 | else if (0 != err) |
326 | { | 327 | { |
327 | fprintf(stderr, | 328 | fprintf(stderr, |
328 | "Error: partial send of ICMP message\n"); | 329 | "Error: partial send of ICMP message\n"); |
@@ -345,14 +346,14 @@ process_icmp_response () | |||
345 | struct udp_header udp_pkt; | 346 | struct udp_header udp_pkt; |
346 | size_t off; | 347 | size_t off; |
347 | uint16_t port; | 348 | uint16_t port; |
348 | 349 | ||
349 | have = read (icmpsock, buf, sizeof (buf)); | 350 | have = read (icmpsock, buf, sizeof (buf)); |
350 | if (-1 == have) | 351 | if (-1 == have) |
351 | { | 352 | { |
352 | fprintf (stderr, | 353 | fprintf (stderr, |
353 | "Error reading raw socket: %s\n", | 354 | "Error reading raw socket: %s\n", |
354 | strerror (errno)); | 355 | strerror (errno)); |
355 | return; | 356 | return; |
356 | } | 357 | } |
357 | #if VERBOSE | 358 | #if VERBOSE |
358 | fprintf (stderr, | 359 | fprintf (stderr, |
@@ -366,17 +367,17 @@ process_icmp_response () | |||
366 | } | 367 | } |
367 | off = 0; | 368 | off = 0; |
368 | memcpy (&ip_pkt, | 369 | memcpy (&ip_pkt, |
369 | &buf[off], | 370 | &buf[off], |
370 | sizeof (struct ip_header)); | 371 | sizeof (struct ip_header)); |
371 | off += sizeof (struct ip_header); | 372 | off += sizeof (struct ip_header); |
372 | memcpy(&source_ip, | 373 | memcpy(&source_ip, |
373 | &ip_pkt.src_ip, | 374 | &ip_pkt.src_ip, |
374 | sizeof (source_ip)); | 375 | sizeof (source_ip)); |
375 | memcpy (&icmp_ttl, | 376 | memcpy (&icmp_ttl, |
376 | &buf[off], | 377 | &buf[off], |
377 | sizeof (struct icmp_ttl_exceeded_header)); | 378 | sizeof (struct icmp_ttl_exceeded_header)); |
378 | off += sizeof (struct icmp_ttl_exceeded_header); | 379 | off += sizeof (struct icmp_ttl_exceeded_header); |
379 | if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || | 380 | if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || |
380 | (0 != icmp_ttl.code) ) | 381 | (0 != icmp_ttl.code) ) |
381 | { | 382 | { |
382 | /* different type than what we want */ | 383 | /* different type than what we want */ |
@@ -384,15 +385,15 @@ process_icmp_response () | |||
384 | } | 385 | } |
385 | /* skip 2nd IP header */ | 386 | /* skip 2nd IP header */ |
386 | memcpy (&ip_pkt, | 387 | memcpy (&ip_pkt, |
387 | &buf[off], | 388 | &buf[off], |
388 | sizeof (struct ip_header)); | 389 | sizeof (struct ip_header)); |
389 | off += sizeof (struct ip_header); | 390 | off += sizeof (struct ip_header); |
390 | 391 | ||
391 | switch (ip_pkt.proto) | 392 | switch (ip_pkt.proto) |
392 | { | 393 | { |
393 | case IPPROTO_ICMP: | 394 | case IPPROTO_ICMP: |
394 | if (have != (sizeof (struct ip_header) * 2 + | 395 | if (have != (sizeof (struct ip_header) * 2 + |
395 | sizeof (struct icmp_ttl_exceeded_header) + | 396 | sizeof (struct icmp_ttl_exceeded_header) + |
396 | sizeof (struct icmp_echo_header)) ) | 397 | sizeof (struct icmp_echo_header)) ) |
397 | { | 398 | { |
398 | /* malformed */ | 399 | /* malformed */ |
@@ -405,8 +406,8 @@ process_icmp_response () | |||
405 | port = (uint16_t) ntohl (icmp_echo.reserved); | 406 | port = (uint16_t) ntohl (icmp_echo.reserved); |
406 | break; | 407 | break; |
407 | case IPPROTO_UDP: | 408 | case IPPROTO_UDP: |
408 | if (have != (sizeof (struct ip_header) * 2 + | 409 | if (have != (sizeof (struct ip_header) * 2 + |
409 | sizeof (struct icmp_ttl_exceeded_header) + | 410 | sizeof (struct icmp_ttl_exceeded_header) + |
410 | sizeof (struct udp_header)) ) | 411 | sizeof (struct udp_header)) ) |
411 | { | 412 | { |
412 | /* malformed */ | 413 | /* malformed */ |
@@ -418,7 +419,7 @@ process_icmp_response () | |||
418 | sizeof (struct udp_header)); | 419 | sizeof (struct udp_header)); |
419 | port = ntohs (udp_pkt.length); | 420 | port = ntohs (udp_pkt.length); |
420 | break; | 421 | break; |
421 | default: | 422 | default: |
422 | /* different type than what we want */ | 423 | /* different type than what we want */ |
423 | return; | 424 | return; |
424 | } | 425 | } |
@@ -436,7 +437,7 @@ process_icmp_response () | |||
436 | inet_ntop (AF_INET, | 437 | inet_ntop (AF_INET, |
437 | &source_ip, | 438 | &source_ip, |
438 | buf, | 439 | buf, |
439 | sizeof (buf)), | 440 | sizeof (buf)), |
440 | (unsigned int) port); | 441 | (unsigned int) port); |
441 | fflush (stdout); | 442 | fflush (stdout); |
442 | } | 443 | } |
@@ -459,8 +460,8 @@ make_icmp_socket () | |||
459 | "Error opening RAW socket: %s\n", | 460 | "Error opening RAW socket: %s\n", |
460 | strerror (errno)); | 461 | strerror (errno)); |
461 | return -1; | 462 | return -1; |
462 | } | 463 | } |
463 | if (ret >= FD_SETSIZE) | 464 | if (ret >= FD_SETSIZE) |
464 | { | 465 | { |
465 | fprintf (stderr, | 466 | fprintf (stderr, |
466 | "Socket number too large (%d > %u)\n", | 467 | "Socket number too large (%d > %u)\n", |
@@ -491,9 +492,9 @@ make_raw_socket () | |||
491 | "Error opening RAW socket: %s\n", | 492 | "Error opening RAW socket: %s\n", |
492 | strerror (errno)); | 493 | strerror (errno)); |
493 | return -1; | 494 | return -1; |
494 | } | 495 | } |
495 | if (-1 == setsockopt(ret, | 496 | if (-1 == setsockopt(ret, |
496 | SOL_SOCKET, | 497 | SOL_SOCKET, |
497 | SO_BROADCAST, | 498 | SO_BROADCAST, |
498 | (char *)&one, sizeof(one))) | 499 | (char *)&one, sizeof(one))) |
499 | { | 500 | { |
@@ -503,8 +504,8 @@ make_raw_socket () | |||
503 | close (ret); | 504 | close (ret); |
504 | return -1; | 505 | return -1; |
505 | } | 506 | } |
506 | if (-1 == setsockopt(ret, | 507 | if (-1 == setsockopt(ret, |
507 | IPPROTO_IP, | 508 | IPPROTO_IP, |
508 | IP_HDRINCL, | 509 | IP_HDRINCL, |
509 | (char *)&one, sizeof(one))) | 510 | (char *)&one, sizeof(one))) |
510 | { | 511 | { |
@@ -538,8 +539,8 @@ make_udp_socket (const struct in_addr *my_ip) | |||
538 | strerror (errno)); | 539 | strerror (errno)); |
539 | return -1; | 540 | return -1; |
540 | } | 541 | } |
541 | memset (&addr, | 542 | memset (&addr, |
542 | 0, | 543 | 0, |
543 | sizeof (addr)); | 544 | sizeof (addr)); |
544 | addr.sin_family = AF_INET; | 545 | addr.sin_family = AF_INET; |
545 | #if HAVE_SOCKADDR_IN_SIN_LEN | 546 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -563,7 +564,7 @@ make_udp_socket (const struct in_addr *my_ip) | |||
563 | 564 | ||
564 | 565 | ||
565 | int | 566 | int |
566 | main (int argc, | 567 | main (int argc, |
567 | char *const *argv) | 568 | char *const *argv) |
568 | { | 569 | { |
569 | struct in_addr external; | 570 | struct in_addr external; |
@@ -585,7 +586,7 @@ main (int argc, | |||
585 | strerror (errno)); | 586 | strerror (errno)); |
586 | return 1; | 587 | return 1; |
587 | } | 588 | } |
588 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 589 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
589 | { | 590 | { |
590 | fprintf (stderr, | 591 | fprintf (stderr, |
591 | "Internal error converting dummy IP to binary.\n"); | 592 | "Internal error converting dummy IP to binary.\n"); |
@@ -593,26 +594,26 @@ main (int argc, | |||
593 | } | 594 | } |
594 | if (-1 == (icmpsock = make_icmp_socket())) | 595 | if (-1 == (icmpsock = make_icmp_socket())) |
595 | { | 596 | { |
596 | return 3; | 597 | return 3; |
597 | } | 598 | } |
598 | if (-1 == (rawsock = make_raw_socket())) | 599 | if (-1 == (rawsock = make_raw_socket())) |
599 | { | 600 | { |
600 | close (icmpsock); | 601 | close (icmpsock); |
601 | return 3; | 602 | return 3; |
602 | } | 603 | } |
603 | uid = getuid (); | 604 | uid = getuid (); |
604 | if (0 != setresuid (uid, uid, uid)) | 605 | if (0 != setresuid (uid, uid, uid)) |
605 | { | 606 | { |
606 | fprintf (stderr, | 607 | fprintf (stderr, |
607 | "Failed to setresuid: %s\n", | 608 | "Failed to setresuid: %s\n", |
608 | strerror (errno)); | 609 | strerror (errno)); |
609 | /* not critical, continue anyway */ | 610 | /* not critical, continue anyway */ |
610 | } | 611 | } |
611 | if (-1 == (udpsock = make_udp_socket(&external))) | 612 | if (-1 == (udpsock = make_udp_socket(&external))) |
612 | { | 613 | { |
613 | close (icmpsock); | 614 | close (icmpsock); |
614 | close (rawsock); | 615 | close (rawsock); |
615 | return 3; | 616 | return 3; |
616 | } | 617 | } |
617 | alt = 0; | 618 | alt = 0; |
618 | while (1) | 619 | while (1) |
@@ -620,7 +621,7 @@ main (int argc, | |||
620 | FD_ZERO (&rs); | 621 | FD_ZERO (&rs); |
621 | FD_SET (icmpsock, &rs); | 622 | FD_SET (icmpsock, &rs); |
622 | tv.tv_sec = 0; | 623 | tv.tv_sec = 0; |
623 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; | 624 | tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; |
624 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) | 625 | if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv)) |
625 | { | 626 | { |
626 | if (errno == EINTR) | 627 | if (errno == EINTR) |
@@ -636,7 +637,7 @@ main (int argc, | |||
636 | send_icmp_echo (&external); | 637 | send_icmp_echo (&external); |
637 | else | 638 | else |
638 | send_udp (); | 639 | send_udp (); |
639 | } | 640 | } |
640 | /* select failed (internal error or OS out of resources) */ | 641 | /* select failed (internal error or OS out of resources) */ |
641 | close (icmpsock); | 642 | close (icmpsock); |
642 | close (rawsock); | 643 | close (rawsock); |