aboutsummaryrefslogtreecommitdiff
path: root/src/tun
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 /src/tun
parent0e9f40d2a5470c648f26effdb155a392a4b4be1b (diff)
downloadgnunet-11cbed2558f43f11a4329266ecfb46bf916c5a4a.tar.gz
gnunet-11cbed2558f43f11a4329266ecfb46bf916c5a4a.zip
-moving remaining checksum calculations to tun library, fixing #2066
Diffstat (limited to 'src/tun')
-rw-r--r--src/tun/tun.c116
1 files changed, 115 insertions, 1 deletions
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 */