diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-17 20:19:03 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-17 20:19:03 +0000 |
commit | 11cbed2558f43f11a4329266ecfb46bf916c5a4a (patch) | |
tree | 632f52a2a7afc8b2c53d9be44a9417e12def8bc6 | |
parent | 0e9f40d2a5470c648f26effdb155a392a4b4be1b (diff) | |
download | gnunet-11cbed2558f43f11a4329266ecfb46bf916c5a4a.tar.gz gnunet-11cbed2558f43f11a4329266ecfb46bf916c5a4a.zip |
-moving remaining checksum calculations to tun library, fixing #2066
-rw-r--r-- | src/dns/gnunet-service-dns.c | 70 | ||||
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 45 | ||||
-rw-r--r-- | src/include/gnunet_tun_lib.h | 45 | ||||
-rw-r--r-- | src/tun/tun.c | 116 | ||||
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 58 |
5 files changed, 212 insertions, 122 deletions
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 288304600..690b4887e 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file dns/gnunet-service-dns.c | 22 | * @file dns/gnunet-service-dns.c |
23 | * @brief service to intercept and modify DNS queries (and replies) of this system | ||
23 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
24 | */ | 25 | */ |
25 | #include "platform.h" | 26 | #include "platform.h" |
@@ -351,7 +352,8 @@ request_done (struct RequestRecord *rr) | |||
351 | { | 352 | { |
352 | char buf[reply_len]; | 353 | char buf[reply_len]; |
353 | size_t off; | 354 | size_t off; |
354 | uint32_t udp_crc_sum; | 355 | struct GNUNET_TUN_IPv4Header ip4; |
356 | struct GNUNET_TUN_IPv6Header ip6; | ||
355 | 357 | ||
356 | /* first, GNUnet message header */ | 358 | /* first, GNUnet message header */ |
357 | hdr = (struct GNUNET_MessageHeader*) buf; | 359 | hdr = (struct GNUNET_MessageHeader*) buf; |
@@ -373,71 +375,38 @@ request_done (struct RequestRecord *rr) | |||
373 | } | 375 | } |
374 | 376 | ||
375 | /* now IP header */ | 377 | /* now IP header */ |
376 | udp_crc_sum = 0; | ||
377 | switch (rr->src_addr.ss_family) | 378 | switch (rr->src_addr.ss_family) |
378 | { | 379 | { |
379 | case AF_INET: | 380 | case AF_INET: |
380 | { | 381 | { |
381 | struct sockaddr_in *src = (struct sockaddr_in *) &rr->src_addr; | 382 | struct sockaddr_in *src = (struct sockaddr_in *) &rr->src_addr; |
382 | struct sockaddr_in *dst = (struct sockaddr_in *) &rr->dst_addr; | 383 | struct sockaddr_in *dst = (struct sockaddr_in *) &rr->dst_addr; |
383 | struct GNUNET_TUN_IPv4Header ip; | ||
384 | 384 | ||
385 | spt = dst->sin_port; | 385 | spt = dst->sin_port; |
386 | dpt = src->sin_port; | 386 | dpt = src->sin_port; |
387 | GNUNET_TUN_initialize_ipv4_header (&ip, | 387 | GNUNET_TUN_initialize_ipv4_header (&ip4, |
388 | IPPROTO_UDP, | 388 | IPPROTO_UDP, |
389 | reply_len - off - sizeof (struct GNUNET_TUN_IPv4Header), | 389 | reply_len - off - sizeof (struct GNUNET_TUN_IPv4Header), |
390 | &dst->sin_addr, | 390 | &dst->sin_addr, |
391 | &src->sin_addr); | 391 | &src->sin_addr); |
392 | 392 | memcpy (&buf[off], &ip4, sizeof (ip4)); | |
393 | 393 | off += sizeof (ip4); | |
394 | |||
395 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | ||
396 | &ip.source_address, | ||
397 | sizeof (struct in_addr) * 2); | ||
398 | { | ||
399 | uint16_t tmp; | ||
400 | |||
401 | tmp = htons (IPPROTO_UDP); | ||
402 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | ||
403 | &tmp, | ||
404 | sizeof (uint16_t)); | ||
405 | tmp = htons (rr->payload_length + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
406 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | ||
407 | &tmp, | ||
408 | sizeof (uint16_t)); | ||
409 | } | ||
410 | memcpy (&buf[off], &ip, sizeof (ip)); | ||
411 | off += sizeof (ip); | ||
412 | } | 394 | } |
413 | break; | 395 | break; |
414 | case AF_INET6: | 396 | case AF_INET6: |
415 | { | 397 | { |
416 | struct sockaddr_in6 *src = (struct sockaddr_in6 *) &rr->src_addr; | 398 | struct sockaddr_in6 *src = (struct sockaddr_in6 *) &rr->src_addr; |
417 | struct sockaddr_in6 *dst = (struct sockaddr_in6 *) &rr->dst_addr; | 399 | struct sockaddr_in6 *dst = (struct sockaddr_in6 *) &rr->dst_addr; |
418 | struct GNUNET_TUN_IPv6Header ip; | ||
419 | 400 | ||
420 | spt = dst->sin6_port; | 401 | spt = dst->sin6_port; |
421 | dpt = src->sin6_port; | 402 | dpt = src->sin6_port; |
422 | GNUNET_TUN_initialize_ipv6_header (&ip, | 403 | GNUNET_TUN_initialize_ipv6_header (&ip6, |
423 | IPPROTO_UDP, | 404 | IPPROTO_UDP, |
424 | reply_len - sizeof (struct GNUNET_TUN_IPv6Header), | 405 | reply_len - sizeof (struct GNUNET_TUN_IPv6Header), |
425 | &dst->sin6_addr, | 406 | &dst->sin6_addr, |
426 | &src->sin6_addr); | 407 | &src->sin6_addr); |
427 | { | 408 | memcpy (&buf[off], &ip6, sizeof (ip6)); |
428 | uint32_t tmp; | 409 | off += sizeof (ip6); |
429 | |||
430 | tmp = htons (rr->payload_length + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
431 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | ||
432 | &tmp, | ||
433 | sizeof (uint32_t)); | ||
434 | tmp = htons (IPPROTO_UDP); | ||
435 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | ||
436 | &tmp, | ||
437 | sizeof (uint32_t)); | ||
438 | } | ||
439 | memcpy (&buf[off], &ip, sizeof (ip)); | ||
440 | off += sizeof (ip); | ||
441 | } | 410 | } |
442 | break; | 411 | break; |
443 | default: | 412 | default: |
@@ -451,17 +420,20 @@ request_done (struct RequestRecord *rr) | |||
451 | udp.spt = spt; | 420 | udp.spt = spt; |
452 | udp.dpt = dpt; | 421 | udp.dpt = dpt; |
453 | udp.len = htons (reply_len - off); | 422 | udp.len = htons (reply_len - off); |
454 | udp.crc = 0; | 423 | if (AF_INET == rr->src_addr.ss_family) |
455 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | 424 | GNUNET_TUN_calculate_udp4_checksum (&ip4, |
456 | &udp, | 425 | &udp, |
457 | sizeof (udp)); | 426 | rr->payload, |
458 | udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, | 427 | rr->payload_length); |
459 | rr->payload, | 428 | else |
460 | rr->payload_length); | 429 | GNUNET_TUN_calculate_udp6_checksum (&ip6, |
461 | udp.crc = GNUNET_CRYPTO_crc16_finish (udp_crc_sum); | 430 | &udp, |
431 | rr->payload, | ||
432 | rr->payload_length); | ||
462 | memcpy (&buf[off], &udp, sizeof (udp)); | 433 | memcpy (&buf[off], &udp, sizeof (udp)); |
463 | off += sizeof (udp); | 434 | off += sizeof (udp); |
464 | } | 435 | } |
436 | |||
465 | /* now DNS payload */ | 437 | /* now DNS payload */ |
466 | { | 438 | { |
467 | memcpy (&buf[off], rr->payload, rr->payload_length); | 439 | memcpy (&buf[off], rr->payload, rr->payload_length); |
@@ -1273,4 +1245,4 @@ main (int argc, char *const *argv) | |||
1273 | } | 1245 | } |
1274 | 1246 | ||
1275 | 1247 | ||
1276 | /* end of gnunet-service-dns_new.c */ | 1248 | /* end of gnunet-service-dns.c */ |
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 482eaae7e..2a8c746f2 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -27,9 +27,6 @@ | |||
27 | * TODO: | 27 | * TODO: |
28 | * - test | 28 | * - test |
29 | * | 29 | * |
30 | * Code cleanup: | ||
31 | * - factor out crc computations from DNS/EXIT/VPN into shared library? | ||
32 | * | ||
33 | * Design: | 30 | * Design: |
34 | * - which code should advertise services? the service model is right | 31 | * - which code should advertise services? the service model is right |
35 | * now a bit odd, especially as this code DOES the exit and knows | 32 | * now a bit odd, especially as this code DOES the exit and knows |
@@ -1078,8 +1075,10 @@ prepare_ipv4_packet (const void *payload, size_t payload_length, | |||
1078 | 1075 | ||
1079 | pkt4_udp->spt = htons (src_address->port); | 1076 | pkt4_udp->spt = htons (src_address->port); |
1080 | pkt4_udp->dpt = htons (dst_address->port); | 1077 | pkt4_udp->dpt = htons (dst_address->port); |
1081 | pkt4_udp->crc = 0; /* Optional for IPv4 */ | ||
1082 | pkt4_udp->len = htons ((uint16_t) payload_length); | 1078 | pkt4_udp->len = htons ((uint16_t) payload_length); |
1079 | GNUNET_TUN_calculate_udp4_checksum (pkt4, | ||
1080 | pkt4_udp, | ||
1081 | payload, payload_length); | ||
1083 | memcpy (&pkt4_udp[1], payload, payload_length); | 1082 | memcpy (&pkt4_udp[1], payload, payload_length); |
1084 | } | 1083 | } |
1085 | break; | 1084 | break; |
@@ -1088,19 +1087,13 @@ prepare_ipv4_packet (const void *payload, size_t payload_length, | |||
1088 | struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1]; | 1087 | struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1]; |
1089 | 1088 | ||
1090 | memcpy (pkt4_tcp, tcp_header, sizeof (struct GNUNET_TUN_TcpHeader)); | 1089 | memcpy (pkt4_tcp, tcp_header, sizeof (struct GNUNET_TUN_TcpHeader)); |
1091 | memcpy (&pkt4_tcp[1], payload, payload_length); | ||
1092 | pkt4_tcp->spt = htons (src_address->port); | 1090 | pkt4_tcp->spt = htons (src_address->port); |
1093 | pkt4_tcp->dpt = htons (dst_address->port); | 1091 | pkt4_tcp->dpt = htons (dst_address->port); |
1094 | 1092 | GNUNET_TUN_calculate_tcp4_checksum (pkt4, | |
1095 | pkt4_tcp->crc = 0; | 1093 | pkt4_tcp, |
1096 | uint32_t sum = 0; | 1094 | payload, |
1097 | sum = GNUNET_CRYPTO_crc16_step (sum, | 1095 | payload_length); |
1098 | &pkt4->source_address, | 1096 | memcpy (&pkt4_tcp[1], payload, payload_length); |
1099 | sizeof (struct in_addr) * 2); | ||
1100 | uint32_t tmp = htonl ((protocol << 16) | (0xffff & len)); | ||
1101 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, sizeof (uint32_t)); | ||
1102 | sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, len); | ||
1103 | pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1104 | } | 1097 | } |
1105 | break; | 1098 | break; |
1106 | default: | 1099 | default: |
@@ -1172,28 +1165,22 @@ prepare_ipv6_packet (const void *payload, size_t payload_length, | |||
1172 | { | 1165 | { |
1173 | struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1]; | 1166 | struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1]; |
1174 | 1167 | ||
1175 | memcpy (&pkt6[1], payload, payload_length); | ||
1176 | pkt6_udp->crc = 0; | ||
1177 | pkt6_udp->spt = htons (src_address->port); | 1168 | pkt6_udp->spt = htons (src_address->port); |
1178 | pkt6_udp->dpt = htons (dst_address->port); | 1169 | pkt6_udp->dpt = htons (dst_address->port); |
1179 | pkt6_udp->len = htons ((uint16_t) payload_length); | 1170 | pkt6_udp->len = htons ((uint16_t) payload_length); |
1180 | 1171 | pkt6_udp->crc = 0; | |
1181 | uint32_t sum = 0; | 1172 | GNUNET_TUN_calculate_udp6_checksum (pkt6, |
1182 | sum = GNUNET_CRYPTO_crc16_step (sum, | 1173 | pkt6_udp, |
1183 | &pkt6->source_address, | 1174 | payload, |
1184 | sizeof (struct in6_addr) * 2); | 1175 | payload_length); |
1185 | uint32_t tmp = htons (len); | 1176 | memcpy (&pkt6[1], payload, payload_length); |
1186 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
1187 | tmp = htonl (pkt6->next_header); | ||
1188 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
1189 | sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, len); | ||
1190 | pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1191 | } | 1177 | } |
1192 | break; | 1178 | break; |
1193 | case IPPROTO_TCP: | 1179 | case IPPROTO_TCP: |
1194 | { | 1180 | { |
1195 | struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) pkt6; | 1181 | struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) pkt6; |
1196 | 1182 | ||
1183 | /* memcpy first here as some TCP header fields are initialized this way! */ | ||
1197 | memcpy (pkt6_tcp, payload, payload_length); | 1184 | memcpy (pkt6_tcp, payload, payload_length); |
1198 | pkt6_tcp->spt = htons (src_address->port); | 1185 | pkt6_tcp->spt = htons (src_address->port); |
1199 | pkt6_tcp->dpt = htons (dst_address->port); | 1186 | pkt6_tcp->dpt = htons (dst_address->port); |
diff --git a/src/include/gnunet_tun_lib.h b/src/include/gnunet_tun_lib.h index b30b2b03a..5fddf70b2 100644 --- a/src/include/gnunet_tun_lib.h +++ b/src/include/gnunet_tun_lib.h | |||
@@ -182,10 +182,24 @@ GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, | |||
182 | const struct in6_addr *dst); | 182 | const struct in6_addr *dst); |
183 | 183 | ||
184 | /** | 184 | /** |
185 | * Calculate IPv4 TCP checksum. | ||
186 | * | ||
187 | * @param ipv4 header fully initialized | ||
188 | * @param tcp TCP header (initialized except for CRC) | ||
189 | * @param payload the TCP payload | ||
190 | * @param payload_length number of bytes of TCP payload | ||
191 | */ | ||
192 | void | ||
193 | GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, | ||
194 | struct GNUNET_TUN_TcpHeader *tcp, | ||
195 | const void *payload, | ||
196 | uint16_t payload_length); | ||
197 | |||
198 | /** | ||
185 | * Calculate IPv6 TCP checksum. | 199 | * Calculate IPv6 TCP checksum. |
186 | * | 200 | * |
187 | * @param ipv6 header fully initialized | 201 | * @param ipv6 header fully initialized |
188 | * @param tcp header (initialized except for CRC) | 202 | * @param tcp TCP header (initialized except for CRC) |
189 | * @param payload the TCP payload | 203 | * @param payload the TCP payload |
190 | * @param payload_length number of bytes of TCP payload | 204 | * @param payload_length number of bytes of TCP payload |
191 | */ | 205 | */ |
@@ -195,5 +209,34 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, | |||
195 | const void *payload, | 209 | const void *payload, |
196 | uint16_t payload_length); | 210 | uint16_t payload_length); |
197 | 211 | ||
212 | /** | ||
213 | * Calculate IPv4 UDP checksum. | ||
214 | * | ||
215 | * @param ipv4 header fully initialized | ||
216 | * @param udp UDP header (initialized except for CRC) | ||
217 | * @param payload the UDP payload | ||
218 | * @param payload_length number of bytes of UDP payload | ||
219 | */ | ||
220 | void | ||
221 | GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, | ||
222 | struct GNUNET_TUN_UdpHeader *udp, | ||
223 | const void *payload, | ||
224 | uint16_t payload_length); | ||
225 | |||
226 | |||
227 | /** | ||
228 | * Calculate IPv6 UDP checksum. | ||
229 | * | ||
230 | * @param ipv6 header fully initialized | ||
231 | * @param udp UDP header (initialized except for CRC) | ||
232 | * @param payload the UDP payload | ||
233 | * @param payload_length number of bytes of UDP payload | ||
234 | */ | ||
235 | void | ||
236 | GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, | ||
237 | struct GNUNET_TUN_UdpHeader *udp, | ||
238 | const void *payload, | ||
239 | uint16_t payload_length); | ||
240 | |||
198 | 241 | ||
199 | #endif | 242 | #endif |
diff --git a/src/tun/tun.c b/src/tun/tun.c index c30861cce..009fdd952 100644 --- a/src/tun/tun.c +++ b/src/tun/tun.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file tun/tun. | 22 | * @file tun/tun.c |
23 | * @brief standard IP calculations for TUN interaction | 23 | * @brief standard IP calculations for TUN interaction |
24 | * @author Philipp Toelke | 24 | * @author Philipp Toelke |
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
@@ -32,6 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | #define FRESH_TTL 255 | 33 | #define FRESH_TTL 255 |
34 | 34 | ||
35 | |||
35 | /** | 36 | /** |
36 | * Initialize an IPv4 header. | 37 | * Initialize an IPv4 header. |
37 | * | 38 | * |
@@ -96,6 +97,39 @@ GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, | |||
96 | 97 | ||
97 | 98 | ||
98 | /** | 99 | /** |
100 | * Calculate IPv4 TCP checksum. | ||
101 | * | ||
102 | * @param ipv4 header fully initialized | ||
103 | * @param tcp TCP header (initialized except for CRC) | ||
104 | * @param payload the TCP payload | ||
105 | * @param payload_length number of bytes of TCP payload | ||
106 | */ | ||
107 | void | ||
108 | GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, | ||
109 | struct GNUNET_TUN_TcpHeader *tcp, | ||
110 | const void *payload, | ||
111 | uint16_t payload_length) | ||
112 | { | ||
113 | uint32_t sum; | ||
114 | uint32_t tmp; | ||
115 | |||
116 | GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_TcpHeader) == | ||
117 | ntohs (ip->total_length)); | ||
118 | GNUNET_assert (IPPROTO_TCP == ip->protocol); | ||
119 | |||
120 | tcp->crc = 0; | ||
121 | sum = GNUNET_CRYPTO_crc16_step (0, | ||
122 | &ip->source_address, | ||
123 | sizeof (struct in_addr) * 2); | ||
124 | tmp = htonl ((IPPROTO_TCP << 16) | (payload_length + sizeof (struct GNUNET_TUN_TcpHeader))); | ||
125 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
126 | sum = GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader)); | ||
127 | sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); | ||
128 | tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
99 | * Calculate IPv6 TCP checksum. | 133 | * Calculate IPv6 TCP checksum. |
100 | * | 134 | * |
101 | * @param ipv6 header fully initialized | 135 | * @param ipv6 header fully initialized |
@@ -114,6 +148,7 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, | |||
114 | 148 | ||
115 | GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + sizeof (struct GNUNET_TUN_TcpHeader) == | 149 | GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + sizeof (struct GNUNET_TUN_TcpHeader) == |
116 | ntohs (ip->payload_length)); | 150 | ntohs (ip->payload_length)); |
151 | GNUNET_assert (IPPROTO_TCP == ip->next_header); | ||
117 | tcp->crc = 0; | 152 | tcp->crc = 0; |
118 | sum = GNUNET_CRYPTO_crc16_step (0, &ip->source_address, 2 * sizeof (struct in6_addr)); | 153 | sum = GNUNET_CRYPTO_crc16_step (0, &ip->source_address, 2 * sizeof (struct in6_addr)); |
119 | tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length); | 154 | tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length); |
@@ -127,5 +162,84 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, | |||
127 | } | 162 | } |
128 | 163 | ||
129 | 164 | ||
165 | /** | ||
166 | * Calculate IPv4 UDP checksum. | ||
167 | * | ||
168 | * @param ipv4 header fully initialized | ||
169 | * @param udp UDP header (initialized except for CRC) | ||
170 | * @param payload the UDP payload | ||
171 | * @param payload_length number of bytes of UDP payload | ||
172 | */ | ||
173 | void | ||
174 | GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, | ||
175 | struct GNUNET_TUN_UdpHeader *udp, | ||
176 | const void *payload, | ||
177 | uint16_t payload_length) | ||
178 | { | ||
179 | uint32_t sum; | ||
180 | uint16_t tmp; | ||
181 | |||
182 | GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_UdpHeader) == | ||
183 | ntohs (ip->total_length)); | ||
184 | GNUNET_assert (IPPROTO_UDP == ip->protocol); | ||
185 | |||
186 | udp->crc = 0; /* technically optional, but we calculate it anyway, just to be sure */ | ||
187 | sum = GNUNET_CRYPTO_crc16_step (0, | ||
188 | &ip->source_address, | ||
189 | sizeof (struct in_addr) * 2); | ||
190 | tmp = htons (IPPROTO_UDP); | ||
191 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
192 | &tmp, | ||
193 | sizeof (uint16_t)); | ||
194 | tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); | ||
195 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
196 | &tmp, | ||
197 | sizeof (uint16_t)); | ||
198 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
199 | udp, | ||
200 | sizeof (struct GNUNET_TUN_UdpHeader)); | ||
201 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
202 | payload, | ||
203 | payload_length); | ||
204 | udp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
205 | } | ||
206 | |||
207 | |||
208 | /** | ||
209 | * Calculate IPv6 UDP checksum. | ||
210 | * | ||
211 | * @param ipv6 header fully initialized | ||
212 | * @param udp UDP header (initialized except for CRC) | ||
213 | * @param payload the UDP payload | ||
214 | * @param payload_length number of bytes of UDP payload | ||
215 | */ | ||
216 | void | ||
217 | GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, | ||
218 | struct GNUNET_TUN_UdpHeader *udp, | ||
219 | const void *payload, | ||
220 | uint16_t payload_length) | ||
221 | { | ||
222 | uint32_t sum; | ||
223 | uint32_t tmp; | ||
224 | |||
225 | GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + sizeof (struct GNUNET_TUN_UdpHeader) == | ||
226 | ntohs (ip->payload_length)); | ||
227 | GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == | ||
228 | ntohs (udp->len)); | ||
229 | GNUNET_assert (IPPROTO_UDP == ip->next_header); | ||
230 | |||
231 | udp->crc = 0; | ||
232 | sum = GNUNET_CRYPTO_crc16_step (0, | ||
233 | &ip->source_address, | ||
234 | sizeof (struct in6_addr) * 2); | ||
235 | tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); /* aka udp->len */ | ||
236 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
237 | tmp = htons (ip->next_header); | ||
238 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
239 | sum = GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader)); | ||
240 | sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); | ||
241 | udp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
242 | } | ||
243 | |||
130 | 244 | ||
131 | /* end of tun.c */ | 245 | /* end of tun.c */ |
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 0d236975e..153327b9b 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -32,10 +32,6 @@ | |||
32 | * | 32 | * |
33 | * Features: | 33 | * Features: |
34 | * - add back ICMP support (especially needed for IPv6) | 34 | * - add back ICMP support (especially needed for IPv6) |
35 | * | ||
36 | * Code cleanup: | ||
37 | * - consider moving IP-header building / checksumming code into shared library | ||
38 | * with dns/exit/vpn (libgnunettun_tcpip?) | ||
39 | */ | 35 | */ |
40 | #include "platform.h" | 36 | #include "platform.h" |
41 | #include "gnunet_util_lib.h" | 37 | #include "gnunet_util_lib.h" |
@@ -1436,7 +1432,10 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1436 | else | 1432 | else |
1437 | udp->dpt = reply->destination_port; | 1433 | udp->dpt = reply->destination_port; |
1438 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | 1434 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); |
1439 | udp->crc = 0; // FIXME: optional, but we might want to calculate this one anyway | 1435 | GNUNET_TUN_calculate_udp4_checksum (ipv4, |
1436 | udp, | ||
1437 | &reply[1], | ||
1438 | mlen); | ||
1440 | memcpy (&udp[1], | 1439 | memcpy (&udp[1], |
1441 | &reply[1], | 1440 | &reply[1], |
1442 | mlen); | 1441 | mlen); |
@@ -1464,15 +1463,11 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1464 | msg->size = htons (size); | 1463 | msg->size = htons (size); |
1465 | tun->flags = htons (0); | 1464 | tun->flags = htons (0); |
1466 | tun->proto = htons (ETH_P_IPV6); | 1465 | tun->proto = htons (ETH_P_IPV6); |
1467 | ipv6->traffic_class_h = 0; | 1466 | GNUNET_TUN_initialize_ipv6_header (ipv6, |
1468 | ipv6->version = 6; | 1467 | IPPROTO_UDP, |
1469 | ipv6->traffic_class_l = 0; | 1468 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, |
1470 | ipv6->flow_label = 0; | 1469 | &ts->destination_ip.v6, |
1471 | ipv6->payload_length = htons (sizeof (struct GNUNET_TUN_UdpHeader) + sizeof (struct GNUNET_TUN_IPv6Header) + mlen); | 1470 | &ts->source_ip.v6); |
1472 | ipv6->next_header = IPPROTO_UDP; | ||
1473 | ipv6->hop_limit = 255; | ||
1474 | ipv6->source_address = ts->destination_ip.v6; | ||
1475 | ipv6->destination_address = ts->source_ip.v6; | ||
1476 | if (0 == ntohs (reply->source_port)) | 1471 | if (0 == ntohs (reply->source_port)) |
1477 | udp->spt = htons (ts->destination_port); | 1472 | udp->spt = htons (ts->destination_port); |
1478 | else | 1473 | else |
@@ -1482,24 +1477,12 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1482 | else | 1477 | else |
1483 | udp->dpt = reply->destination_port; | 1478 | udp->dpt = reply->destination_port; |
1484 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | 1479 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); |
1485 | udp->crc = 0; | 1480 | GNUNET_TUN_calculate_udp6_checksum (ipv6, |
1481 | udp, | ||
1482 | &reply[1], mlen); | ||
1486 | memcpy (&udp[1], | 1483 | memcpy (&udp[1], |
1487 | &reply[1], | 1484 | &reply[1], |
1488 | mlen); | 1485 | mlen); |
1489 | { | ||
1490 | uint32_t sum = 0; | ||
1491 | sum = | ||
1492 | GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, | ||
1493 | sizeof (struct in6_addr) * 2); | ||
1494 | uint32_t tmp = udp->len; | ||
1495 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
1496 | tmp = htons (IPPROTO_UDP); | ||
1497 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
1498 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
1499 | udp, | ||
1500 | ntohs (udp->len)); | ||
1501 | udp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1502 | } | ||
1503 | (void) GNUNET_HELPER_send (helper_handle, | 1486 | (void) GNUNET_HELPER_send (helper_handle, |
1504 | msg, | 1487 | msg, |
1505 | GNUNET_YES, | 1488 | GNUNET_YES, |
@@ -1596,22 +1579,13 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1596 | *tcp = data->tcp_header; | 1579 | *tcp = data->tcp_header; |
1597 | tcp->spt = htons (ts->destination_port); | 1580 | tcp->spt = htons (ts->destination_port); |
1598 | tcp->dpt = htons (ts->source_port); | 1581 | tcp->dpt = htons (ts->source_port); |
1599 | tcp->crc = 0; | 1582 | GNUNET_TUN_calculate_tcp4_checksum (ipv4, |
1583 | tcp, | ||
1584 | &data[1], | ||
1585 | mlen); | ||
1600 | memcpy (&tcp[1], | 1586 | memcpy (&tcp[1], |
1601 | &data[1], | 1587 | &data[1], |
1602 | mlen); | 1588 | mlen); |
1603 | { | ||
1604 | uint32_t sum = 0; | ||
1605 | uint32_t tmp; | ||
1606 | |||
1607 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
1608 | &ipv4->source_address, | ||
1609 | 2 * sizeof (struct in_addr)); | ||
1610 | tmp = htonl ((IPPROTO_TCP << 16) | (mlen + sizeof (struct GNUNET_TUN_TcpHeader))); | ||
1611 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
1612 | sum = GNUNET_CRYPTO_crc16_step (sum, tcp, mlen + sizeof (struct GNUNET_TUN_TcpHeader)); | ||
1613 | tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1614 | } | ||
1615 | (void) GNUNET_HELPER_send (helper_handle, | 1589 | (void) GNUNET_HELPER_send (helper_handle, |
1616 | msg, | 1590 | msg, |
1617 | GNUNET_YES, | 1591 | GNUNET_YES, |