aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-nat-client.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-08-21 21:44:01 +0000
committerChristian Grothoff <christian@grothoff.org>2010-08-21 21:44:01 +0000
commita875dd285a96c19d3d71b95020f3a95d8e1f4408 (patch)
tree3683ebb7fa891295a2a210cddcdab5aa7ac13927 /src/transport/gnunet-nat-client.c
parentece75b9e2079a5ba993ce3f30158bc7ac2c01246 (diff)
downloadgnunet-a875dd285a96c19d3d71b95020f3a95d8e1f4408.tar.gz
gnunet-a875dd285a96c19d3d71b95020f3a95d8e1f4408.zip
cleanup
Diffstat (limited to 'src/transport/gnunet-nat-client.c')
-rw-r--r--src/transport/gnunet-nat-client.c171
1 files changed, 94 insertions, 77 deletions
diff --git a/src/transport/gnunet-nat-client.c b/src/transport/gnunet-nat-client.c
index d38f3bcdf..c5e000d6a 100644
--- a/src/transport/gnunet-nat-client.c
+++ b/src/transport/gnunet-nat-client.c
@@ -70,7 +70,7 @@
70/** 70/**
71 * IPv4 header. 71 * IPv4 header.
72 */ 72 */
73struct ip_packet 73struct ip_header
74{ 74{
75 75
76 /** 76 /**
@@ -127,7 +127,7 @@ struct ip_packet
127/** 127/**
128 * Format of ICMP packet. 128 * Format of ICMP packet.
129 */ 129 */
130struct icmp_packet 130struct icmp_ttl_exceeded_header
131{ 131{
132 uint8_t type; 132 uint8_t type;
133 133
@@ -135,10 +135,12 @@ struct icmp_packet
135 135
136 uint16_t checksum; 136 uint16_t checksum;
137 137
138 uint32_t reserved; 138 uint32_t unused;
139
140 /* followed by original payload */
139}; 141};
140 142
141struct icmp_echo_packet 143struct icmp_echo_header
142{ 144{
143 uint8_t type; 145 uint8_t type;
144 146
@@ -147,20 +149,20 @@ struct icmp_echo_packet
147 uint16_t checksum; 149 uint16_t checksum;
148 150
149 uint32_t reserved; 151 uint32_t reserved;
150
151 uint32_t data;
152}; 152};
153 153
154/** 154/**
155 * Beginning of UDP packet. 155 * Beginning of UDP packet.
156 */ 156 */
157struct udp_packet 157struct udp_header
158{ 158{
159 uint16_t src_port; 159 uint16_t src_port;
160 160
161 uint16_t dst_port; 161 uint16_t dst_port;
162 162
163 uint32_t length; 163 uint16_t length;
164
165 uint16_t crc;
164}; 166};
165 167
166/** 168/**
@@ -187,8 +189,8 @@ static uint16_t port;
187 * @return the CRC 16. 189 * @return the CRC 16.
188 */ 190 */
189static uint16_t 191static uint16_t
190calc_checksum(const uint16_t *data, 192calc_checksum (const uint16_t *data,
191 unsigned int bytes) 193 unsigned int bytes)
192{ 194{
193 uint32_t sum; 195 uint32_t sum;
194 unsigned int i; 196 unsigned int i;
@@ -212,19 +214,18 @@ static void
212send_icmp_udp (const struct in_addr *my_ip, 214send_icmp_udp (const struct in_addr *my_ip,
213 const struct in_addr *other) 215 const struct in_addr *other)
214{ 216{
215 struct ip_packet ip_pkt; 217 char packet[sizeof(struct ip_header) * 2 +
216 struct icmp_packet icmp_pkt; 218 sizeof(struct icmp_ttl_exceeded_header) +
217 struct udp_packet udp_pkt; 219 sizeof(struct udp_header)];
218 220 struct ip_header ip_pkt;
221 struct icmp_ttl_exceeded_header icmp_pkt;
222 struct udp_header udp_pkt;
219 struct sockaddr_in dst; 223 struct sockaddr_in dst;
220 char packet[sizeof(ip_pkt) * 2 + sizeof(icmp_pkt) * 2 + sizeof(uint32_t)];
221
222 size_t off; 224 size_t off;
223 int err; 225 int err;
224 226
225 /* ip header: send to (known) ip address */ 227 /* ip header: send to (known) ip address */
226 off = 0; 228 off = 0;
227 memset(&ip_pkt, 0, sizeof(ip_pkt));
228 ip_pkt.vers_ihl = 0x45; 229 ip_pkt.vers_ihl = 0x45;
229 ip_pkt.tos = 0; 230 ip_pkt.tos = 0;
230 ip_pkt.pkt_len = htons(sizeof (packet)); 231 ip_pkt.pkt_len = htons(sizeof (packet));
@@ -235,27 +236,27 @@ send_icmp_udp (const struct in_addr *my_ip,
235 ip_pkt.checksum = 0; 236 ip_pkt.checksum = 0;
236 ip_pkt.src_ip = my_ip->s_addr; 237 ip_pkt.src_ip = my_ip->s_addr;
237 ip_pkt.dst_ip = other->s_addr; 238 ip_pkt.dst_ip = other->s_addr;
238 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (ip_pkt))); 239 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
239 memcpy(&packet[off], &ip_pkt, sizeof(ip_pkt)); 240 sizeof (struct ip_header)));
240 off += sizeof(ip_pkt); 241 memcpy(&packet[off],
242 &ip_pkt,
243 sizeof(struct ip_header));
244 off += sizeof(struct ip_header);
241 245
242 /* ip header of the presumably 'lost' udp packet */ 246 icmp_pkt.type = ICMP_TIME_EXCEEDED;
243 ip_pkt.vers_ihl = 0x45;
244 ip_pkt.tos = 0;
245 ip_pkt.pkt_len = (sizeof (struct ip_packet) + sizeof (struct icmp_echo_packet));
246
247 icmp_pkt.type = 11; /* TTL exceeded */
248 icmp_pkt.code = 0; 247 icmp_pkt.code = 0;
249 icmp_pkt.checksum = 0; 248 icmp_pkt.checksum = 0;
250 icmp_pkt.reserved = 0; 249 icmp_pkt.unused = 0;
251 memcpy(&packet[off], &icmp_pkt, sizeof(icmp_pkt)); 250 memcpy(&packet[off],
252 off += sizeof(icmp_pkt); 251 &icmp_pkt,
252 sizeof(struct icmp_ttl_exceeded_header));
253 off += sizeof(struct icmp_ttl_exceeded_header);
253 254
254 /* build inner IP header */ 255 /* ip header of the presumably 'lost' udp packet */
255 memset(&ip_pkt, 0, sizeof(ip_pkt));
256 ip_pkt.vers_ihl = 0x45; 256 ip_pkt.vers_ihl = 0x45;
257 ip_pkt.tos = 0; 257 ip_pkt.tos = 0;
258 ip_pkt.pkt_len = htons(sizeof (ip_pkt) + sizeof(udp_pkt)); 258 ip_pkt.pkt_len = htons(sizeof (struct ip_header) +
259 sizeof(struct udp_header));
259 ip_pkt.id = htons(0); 260 ip_pkt.id = htons(0);
260 ip_pkt.flags_frag_offset = 0; 261 ip_pkt.flags_frag_offset = 0;
261 ip_pkt.ttl = 128; 262 ip_pkt.ttl = 128;
@@ -263,40 +264,48 @@ send_icmp_udp (const struct in_addr *my_ip,
263 ip_pkt.checksum = 0; 264 ip_pkt.checksum = 0;
264 ip_pkt.src_ip = other->s_addr; 265 ip_pkt.src_ip = other->s_addr;
265 ip_pkt.dst_ip = dummy.s_addr; 266 ip_pkt.dst_ip = dummy.s_addr;
266 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (ip_pkt))); 267 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
267 memcpy(&packet[off], &ip_pkt, sizeof(ip_pkt)); 268 sizeof (struct ip_header)));
268 off += sizeof(ip_pkt); 269 memcpy(&packet[off],
270 &ip_pkt,
271 sizeof(struct ip_header));
272 off += sizeof(struct ip_header);
269 273
270 /* build UDP header */ 274 /* build UDP header */
271 udp_pkt.src_port = htons(NAT_TRAV_PORT); 275 udp_pkt.src_port = htons(NAT_TRAV_PORT);
272 udp_pkt.dst_port = htons(NAT_TRAV_PORT); 276 udp_pkt.dst_port = htons(NAT_TRAV_PORT);
273 277 udp_pkt.length = htons (sizeof (struct udp_header));
274 memset(&udp_pkt.length, 0, sizeof(uint32_t)); 278 udp_pkt.crc = htons (port);
275 udp_pkt.length = htons (port); 279 memcpy(&packet[off],
276 memcpy(&packet[off], &udp_pkt, sizeof(udp_pkt)); 280 &udp_pkt,
277 off += sizeof(udp_pkt); 281 sizeof(struct udp_header));
282 off += sizeof(struct udp_header);
278 283
279 /* set ICMP checksum */ 284 /* set ICMP checksum */
280 icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[sizeof(ip_pkt)], 285 icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[sizeof(struct ip_header)],
281 sizeof (icmp_pkt) + sizeof(ip_pkt) + sizeof(udp_pkt))); 286 sizeof (struct icmp_ttl_exceeded_header) +
282 memcpy (&packet[sizeof(ip_pkt)], &icmp_pkt, sizeof (icmp_pkt)); 287 sizeof (struct ip_header) +
283 288 sizeof (struct udp_header)));
284 289 memcpy (&packet[sizeof(struct ip_header)],
290 &icmp_pkt,
291 sizeof (struct icmp_ttl_exceeded_header));
285 memset (&dst, 0, sizeof (dst)); 292 memset (&dst, 0, sizeof (dst));
286 dst.sin_family = AF_INET; 293 dst.sin_family = AF_INET;
294#if HAVE_SOCKADDR_IN_SIN_LEN
295 dst.sin_len = sizeof (struct sockaddr_in);
296#endif
287 dst.sin_addr = *other; 297 dst.sin_addr = *other;
288 err = sendto(rawsock, 298 err = sendto(rawsock,
289 packet, 299 packet,
290 off, 0, 300 off, 0,
291 (struct sockaddr*)&dst, 301 (struct sockaddr*)&dst,
292 sizeof(dst)); 302 sizeof(dst));
293
294 if (err < 0) 303 if (err < 0)
295 { 304 {
296 fprintf(stderr, 305 fprintf(stderr,
297 "sendto failed: %s\n", strerror(errno)); 306 "sendto failed: %s\n", strerror(errno));
298 } 307 }
299 else if (err != off) 308 else if (off != (size_t) err)
300 { 309 {
301 fprintf(stderr, 310 fprintf(stderr,
302 "Error: partial send of ICMP message\n"); 311 "Error: partial send of ICMP message\n");
@@ -314,12 +323,13 @@ static void
314send_icmp (const struct in_addr *my_ip, 323send_icmp (const struct in_addr *my_ip,
315 const struct in_addr *other) 324 const struct in_addr *other)
316{ 325{
317 struct ip_packet ip_pkt; 326 struct ip_header ip_pkt;
318 struct icmp_packet icmp_pkt; 327 struct icmp_ttl_exceeded_header icmp_pkt;
319 struct icmp_echo_packet icmp_echo; 328 struct icmp_echo_header icmp_echo;
320 struct sockaddr_in dst; 329 struct sockaddr_in dst;
321 char packet[sizeof (struct ip_packet)*2 + sizeof (struct icmp_packet) + sizeof(struct icmp_echo_packet)]; 330 char packet[sizeof (struct ip_header) * 2 +
322 331 sizeof (struct icmp_ttl_exceeded_header) +
332 sizeof (struct icmp_echo_header)];
323 size_t off; 333 size_t off;
324 int err; 334 int err;
325 335
@@ -327,7 +337,7 @@ send_icmp (const struct in_addr *my_ip,
327 off = 0; 337 off = 0;
328 ip_pkt.vers_ihl = 0x45; 338 ip_pkt.vers_ihl = 0x45;
329 ip_pkt.tos = 0; 339 ip_pkt.tos = 0;
330 ip_pkt.pkt_len = sizeof (packet); /* huh? */ 340 ip_pkt.pkt_len = sizeof (packet);
331 ip_pkt.id = 1; 341 ip_pkt.id = 1;
332 ip_pkt.flags_frag_offset = 0; 342 ip_pkt.flags_frag_offset = 0;
333 ip_pkt.ttl = IPDEFTTL; 343 ip_pkt.ttl = IPDEFTTL;
@@ -335,24 +345,27 @@ send_icmp (const struct in_addr *my_ip,
335 ip_pkt.checksum = 0; 345 ip_pkt.checksum = 0;
336 ip_pkt.src_ip = my_ip->s_addr; 346 ip_pkt.src_ip = my_ip->s_addr;
337 ip_pkt.dst_ip = other->s_addr; 347 ip_pkt.dst_ip = other->s_addr;
338 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (struct ip_packet))); 348 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
339 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_packet)); 349 sizeof (struct ip_header)));
350 memcpy (&packet[off],
351 &ip_pkt,
352 sizeof (struct ip_header));
340 off = sizeof (ip_pkt); 353 off = sizeof (ip_pkt);
341 354
342 /* icmp reply: time exceeded */ 355 /* icmp reply: time exceeded */
343 icmp_pkt.type = ICMP_TIME_EXCEEDED; 356 icmp_pkt.type = ICMP_TIME_EXCEEDED;
344 icmp_pkt.code = 0; 357 icmp_pkt.code = 0;
345 icmp_pkt.reserved = 0;
346 icmp_pkt.checksum = 0; 358 icmp_pkt.checksum = 0;
359 icmp_pkt.unused = 0;
347 memcpy (&packet[off], 360 memcpy (&packet[off],
348 &icmp_pkt, 361 &icmp_pkt,
349 sizeof (struct icmp_packet)); 362 sizeof (struct icmp_ttl_exceeded_header));
350 off += sizeof (struct icmp_packet); 363 off += sizeof (struct icmp_ttl_exceeded_header);
351 364
352 /* ip header of the presumably 'lost' udp packet */ 365 /* ip header of the presumably 'lost' udp packet */
353 ip_pkt.vers_ihl = 0x45; 366 ip_pkt.vers_ihl = 0x45;
354 ip_pkt.tos = 0; 367 ip_pkt.tos = 0;
355 ip_pkt.pkt_len = (sizeof (struct ip_packet) + sizeof (struct icmp_echo_packet)); 368 ip_pkt.pkt_len = (sizeof (struct ip_header) + sizeof (struct icmp_echo_header));
356 ip_pkt.id = 1; 369 ip_pkt.id = 1;
357 ip_pkt.flags_frag_offset = 0; 370 ip_pkt.flags_frag_offset = 0;
358 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ 371 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
@@ -360,28 +373,32 @@ send_icmp (const struct in_addr *my_ip,
360 ip_pkt.src_ip = other->s_addr; 373 ip_pkt.src_ip = other->s_addr;
361 ip_pkt.dst_ip = dummy.s_addr; 374 ip_pkt.dst_ip = dummy.s_addr;
362 ip_pkt.checksum = 0; 375 ip_pkt.checksum = 0;
363 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (struct ip_packet))); 376 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
364 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_packet)); 377 sizeof (struct ip_header)));
365 off += sizeof (struct ip_packet); 378 memcpy (&packet[off],
379 &ip_pkt,
380 sizeof (struct ip_header));
381 off += sizeof (struct ip_header);
366 382
367 icmp_echo.type = ICMP_ECHO; 383 icmp_echo.type = ICMP_ECHO;
368 icmp_echo.code = 0; 384 icmp_echo.code = 0;
369 icmp_echo.reserved = 0; 385 icmp_echo.reserved = htonl (port);
370 icmp_echo.checksum = 0; 386 icmp_echo.checksum = 0;
371 icmp_echo.data = htons(port);
372 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, 387 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo,
373 sizeof (struct icmp_echo_packet))); 388 sizeof (struct icmp_echo_header)));
374 memcpy (&packet[off], 389 memcpy (&packet[off],
375 &icmp_echo, 390 &icmp_echo,
376 sizeof(struct icmp_echo_packet)); 391 sizeof(struct icmp_echo_header));
377 392
378 /* no go back to calculate ICMP packet checksum */ 393 /* no go back to calculate ICMP packet checksum */
379 off = sizeof (ip_pkt); 394 off = sizeof (struct ip_header);
380 icmp_pkt.checksum = htons(calc_checksum((uint16_t*) &packet[off], 395 icmp_pkt.checksum = htons(calc_checksum((uint16_t*) &packet[off],
381 sizeof (struct icmp_packet) + sizeof(struct ip_packet) + sizeof(struct icmp_echo_packet))); 396 sizeof (struct icmp_ttl_exceeded_header) +
397 sizeof(struct ip_header) +
398 sizeof(struct icmp_echo_header)));
382 memcpy (&packet[off], 399 memcpy (&packet[off],
383 &icmp_pkt, 400 &icmp_pkt,
384 sizeof (struct icmp_packet)); 401 sizeof (struct icmp_ttl_exceeded_header));
385 402
386 /* prepare for transmission */ 403 /* prepare for transmission */
387 memset (&dst, 0, sizeof (dst)); 404 memset (&dst, 0, sizeof (dst));
@@ -400,7 +417,7 @@ send_icmp (const struct in_addr *my_ip,
400 fprintf(stderr, 417 fprintf(stderr,
401 "sendto failed: %s\n", strerror(errno)); 418 "sendto failed: %s\n", strerror(errno));
402 } 419 }
403 else if (err != sizeof (packet)) 420 else if (sizeof (packet) != (size_t) err)
404 { 421 {
405 fprintf(stderr, 422 fprintf(stderr,
406 "Error: partial send of ICMP message\n"); 423 "Error: partial send of ICMP message\n");
@@ -427,8 +444,8 @@ make_raw_socket ()
427 strerror (errno)); 444 strerror (errno));
428 return -1; 445 return -1;
429 } 446 }
430 if (setsockopt(ret, SOL_SOCKET, SO_BROADCAST, 447 if (-1 == setsockopt(ret, SOL_SOCKET, SO_BROADCAST,
431 (char *)&one, sizeof(one)) == -1) 448 (char *)&one, sizeof(one)))
432 { 449 {
433 fprintf(stderr, 450 fprintf(stderr,
434 "setsockopt failed: %s\n", 451 "setsockopt failed: %s\n",
@@ -436,8 +453,8 @@ make_raw_socket ()
436 close (ret); 453 close (ret);
437 return -1; 454 return -1;
438 } 455 }
439 if (setsockopt(ret, IPPROTO_IP, IP_HDRINCL, 456 if (-1 == setsockopt(ret, IPPROTO_IP, IP_HDRINCL,
440 (char *)&one, sizeof(one)) == -1) 457 (char *)&one, sizeof(one)))
441 { 458 {
442 fprintf(stderr, 459 fprintf(stderr,
443 "setsockopt failed: %s\n", 460 "setsockopt failed: %s\n",
@@ -457,7 +474,7 @@ main (int argc, char *const *argv)
457 uid_t uid; 474 uid_t uid;
458 unsigned int p; 475 unsigned int p;
459 476
460 if (argc != 4) 477 if (4 != argc)
461 { 478 {
462 fprintf (stderr, 479 fprintf (stderr,
463 "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); 480 "This program must be started with our IP, the targets external IP, and our port as arguments.\n");
@@ -472,8 +489,8 @@ main (int argc, char *const *argv)
472 return 1; 489 return 1;
473 } 490 }
474 if ( (1 != sscanf (argv[3], "%u", &p) ) || 491 if ( (1 != sscanf (argv[3], "%u", &p) ) ||
475 (p == 0) || 492 (0 == p) ||
476 (p > 0xFFFF) ) 493 (0xFFFF < p) )
477 { 494 {
478 fprintf (stderr, 495 fprintf (stderr,
479 "Error parsing port value `%s'\n", 496 "Error parsing port value `%s'\n",