aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-17 20:19:03 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-17 20:19:03 +0000
commit11cbed2558f43f11a4329266ecfb46bf916c5a4a (patch)
tree632f52a2a7afc8b2c53d9be44a9417e12def8bc6
parent0e9f40d2a5470c648f26effdb155a392a4b4be1b (diff)
downloadgnunet-11cbed2558f43f11a4329266ecfb46bf916c5a4a.tar.gz
gnunet-11cbed2558f43f11a4329266ecfb46bf916c5a4a.zip
-moving remaining checksum calculations to tun library, fixing #2066
-rw-r--r--src/dns/gnunet-service-dns.c70
-rw-r--r--src/exit/gnunet-daemon-exit.c45
-rw-r--r--src/include/gnunet_tun_lib.h45
-rw-r--r--src/tun/tun.c116
-rw-r--r--src/vpn/gnunet-service-vpn.c58
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 */
192void
193GNUNET_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 */
220void
221GNUNET_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 */
235void
236GNUNET_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 */
107void
108GNUNET_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 */
173void
174GNUNET_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 */
216void
217GNUNET_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,