diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-08-21 21:44:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-08-21 21:44:01 +0000 |
commit | a875dd285a96c19d3d71b95020f3a95d8e1f4408 (patch) | |
tree | 3683ebb7fa891295a2a210cddcdab5aa7ac13927 /src/transport/gnunet-nat-client.c | |
parent | ece75b9e2079a5ba993ce3f30158bc7ac2c01246 (diff) | |
download | gnunet-a875dd285a96c19d3d71b95020f3a95d8e1f4408.tar.gz gnunet-a875dd285a96c19d3d71b95020f3a95d8e1f4408.zip |
cleanup
Diffstat (limited to 'src/transport/gnunet-nat-client.c')
-rw-r--r-- | src/transport/gnunet-nat-client.c | 171 |
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 | */ |
73 | struct ip_packet | 73 | struct 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 | */ |
130 | struct icmp_packet | 130 | struct 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 | ||
141 | struct icmp_echo_packet | 143 | struct 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 | */ |
157 | struct udp_packet | 157 | struct 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 | */ |
189 | static uint16_t | 191 | static uint16_t |
190 | calc_checksum(const uint16_t *data, | 192 | calc_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 | |||
212 | send_icmp_udp (const struct in_addr *my_ip, | 214 | send_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 | |||
314 | send_icmp (const struct in_addr *my_ip, | 323 | send_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", |