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 /src/tun | |
parent | 0e9f40d2a5470c648f26effdb155a392a4b4be1b (diff) | |
download | gnunet-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.c | 116 |
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 | */ | ||
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 */ |