aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-08-22 13:36:33 +0000
committerChristian Grothoff <christian@grothoff.org>2010-08-22 13:36:33 +0000
commitb4e21c6afcb6cd772c66b2c0ae3199f193c972c7 (patch)
tree10cf25bb37ee491ac5d083d93678944e0e510f1c /src
parent1355ed0acd88356beccc25dfc710ef0d458b5b96 (diff)
downloadgnunet-b4e21c6afcb6cd772c66b2c0ae3199f193c972c7.tar.gz
gnunet-b4e21c6afcb6cd772c66b2c0ae3199f193c972c7.zip
audit
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-nat-client.c101
-rw-r--r--src/transport/gnunet-nat-server.c125
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 */
73struct ip_header 74struct 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 */
130struct icmp_ttl_exceeded_header 131struct 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 */
176static struct in_addr dummy; 177static 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 */
191static uint16_t 192static uint16_t
192calc_checksum (const uint16_t *data, 193calc_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
214send_icmp_udp (const struct in_addr *my_ip, 215send_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 */
89struct ip_header 90struct 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 */
146struct icmp_ttl_exceeded_header 147struct 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 */
213static uint16_t 214static uint16_t
214calc_checksum(const uint16_t *data, 215calc_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
565int 566int
566main (int argc, 567main (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);