aboutsummaryrefslogtreecommitdiff
path: root/src/util/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/tun.c')
-rw-r--r--src/util/tun.c163
1 files changed, 84 insertions, 79 deletions
diff --git a/src/util/tun.c b/src/util/tun.c
index 97fbaa83b..e3643d0c6 100644
--- a/src/util/tun.c
+++ b/src/util/tun.c
@@ -44,24 +44,27 @@
44 */ 44 */
45void 45void
46GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip, 46GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
47 uint8_t protocol, 47 uint8_t protocol,
48 uint16_t payload_length, 48 uint16_t payload_length,
49 const struct in_addr *src, 49 const struct in_addr *src,
50 const struct in_addr *dst) 50 const struct in_addr *dst)
51{ 51{
52 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_IPv4Header)); 52 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_IPv4Header));
53 GNUNET_assert (payload_length <= UINT16_MAX - sizeof (struct GNUNET_TUN_IPv4Header)); 53 GNUNET_assert (payload_length <=
54 UINT16_MAX - sizeof (struct GNUNET_TUN_IPv4Header));
54 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv4Header)); 55 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv4Header));
55 ip->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4; 56 ip->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4;
56 ip->version = 4; 57 ip->version = 4;
57 ip->total_length = htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length); 58 ip->total_length =
58 ip->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 59 htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length);
59 65536); 60 ip->identification =
61 (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 65536);
60 ip->ttl = FRESH_TTL; 62 ip->ttl = FRESH_TTL;
61 ip->protocol = protocol; 63 ip->protocol = protocol;
62 ip->source_address = *src; 64 ip->source_address = *src;
63 ip->destination_address = *dst; 65 ip->destination_address = *dst;
64 ip->checksum = GNUNET_CRYPTO_crc16_n (ip, sizeof (struct GNUNET_TUN_IPv4Header)); 66 ip->checksum =
67 GNUNET_CRYPTO_crc16_n (ip, sizeof (struct GNUNET_TUN_IPv4Header));
65} 68}
66 69
67 70
@@ -76,13 +79,14 @@ GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
76 */ 79 */
77void 80void
78GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, 81GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
79 uint8_t protocol, 82 uint8_t protocol,
80 uint16_t payload_length, 83 uint16_t payload_length,
81 const struct in6_addr *src, 84 const struct in6_addr *src,
82 const struct in6_addr *dst) 85 const struct in6_addr *dst)
83{ 86{
84 GNUNET_assert (40 == sizeof (struct GNUNET_TUN_IPv6Header)); 87 GNUNET_assert (40 == sizeof (struct GNUNET_TUN_IPv6Header));
85 GNUNET_assert (payload_length <= UINT16_MAX - sizeof (struct GNUNET_TUN_IPv6Header)); 88 GNUNET_assert (payload_length <=
89 UINT16_MAX - sizeof (struct GNUNET_TUN_IPv6Header));
86 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header)); 90 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header));
87 ip->version = 6; 91 ip->version = 6;
88 ip->next_header = protocol; 92 ip->next_header = protocol;
@@ -103,27 +107,29 @@ GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
103 */ 107 */
104void 108void
105GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, 109GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
106 struct GNUNET_TUN_TcpHeader *tcp, 110 struct GNUNET_TUN_TcpHeader *tcp,
107 const void *payload, 111 const void *payload,
108 uint16_t payload_length) 112 uint16_t payload_length)
109{ 113{
110 uint32_t sum; 114 uint32_t sum;
111 uint16_t tmp; 115 uint16_t tmp;
112 116
113 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader)); 117 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader));
114 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_TcpHeader) == 118 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) +
115 ntohs (ip->total_length)); 119 sizeof (struct GNUNET_TUN_TcpHeader) ==
120 ntohs (ip->total_length));
116 GNUNET_assert (IPPROTO_TCP == ip->protocol); 121 GNUNET_assert (IPPROTO_TCP == ip->protocol);
117 122
118 tcp->crc = 0; 123 tcp->crc = 0;
119 sum = GNUNET_CRYPTO_crc16_step (0, 124 sum = GNUNET_CRYPTO_crc16_step (0,
120 &ip->source_address, 125 &ip->source_address,
121 sizeof (struct in_addr) * 2); 126 sizeof (struct in_addr) * 2);
122 tmp = htons (IPPROTO_TCP); 127 tmp = htons (IPPROTO_TCP);
123 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 128 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
124 tmp = htons (payload_length + sizeof (struct GNUNET_TUN_TcpHeader)); 129 tmp = htons (payload_length + sizeof (struct GNUNET_TUN_TcpHeader));
125 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 130 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
126 sum = GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader)); 131 sum =
132 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader));
127 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 133 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
128 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); 134 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
129} 135}
@@ -139,25 +145,27 @@ GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
139 */ 145 */
140void 146void
141GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, 147GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
142 struct GNUNET_TUN_TcpHeader *tcp, 148 struct GNUNET_TUN_TcpHeader *tcp,
143 const void *payload, 149 const void *payload,
144 uint16_t payload_length) 150 uint16_t payload_length)
145{ 151{
146 uint32_t sum; 152 uint32_t sum;
147 uint32_t tmp; 153 uint32_t tmp;
148 154
149 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader)); 155 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader));
150 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_TcpHeader) == 156 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_TcpHeader) ==
151 ntohs (ip->payload_length)); 157 ntohs (ip->payload_length));
152 GNUNET_assert (IPPROTO_TCP == ip->next_header); 158 GNUNET_assert (IPPROTO_TCP == ip->next_header);
153 tcp->crc = 0; 159 tcp->crc = 0;
154 sum = GNUNET_CRYPTO_crc16_step (0, &ip->source_address, 2 * sizeof (struct in6_addr)); 160 sum = GNUNET_CRYPTO_crc16_step (0,
161 &ip->source_address,
162 2 * sizeof (struct in6_addr));
155 tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length); 163 tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length);
156 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 164 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
157 tmp = htonl (IPPROTO_TCP); 165 tmp = htonl (IPPROTO_TCP);
158 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 166 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
159 sum = GNUNET_CRYPTO_crc16_step (sum, tcp, 167 sum =
160 sizeof (struct GNUNET_TUN_TcpHeader)); 168 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader));
161 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 169 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
162 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); 170 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
163} 171}
@@ -173,36 +181,31 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
173 */ 181 */
174void 182void
175GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, 183GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
176 struct GNUNET_TUN_UdpHeader *udp, 184 struct GNUNET_TUN_UdpHeader *udp,
177 const void *payload, 185 const void *payload,
178 uint16_t payload_length) 186 uint16_t payload_length)
179{ 187{
180 uint32_t sum; 188 uint32_t sum;
181 uint16_t tmp; 189 uint16_t tmp;
182 190
183 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 191 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
184 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_UdpHeader) == 192 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) +
185 ntohs (ip->total_length)); 193 sizeof (struct GNUNET_TUN_UdpHeader) ==
194 ntohs (ip->total_length));
186 GNUNET_assert (IPPROTO_UDP == ip->protocol); 195 GNUNET_assert (IPPROTO_UDP == ip->protocol);
187 196
188 udp->crc = 0; /* technically optional, but we calculate it anyway, just to be sure */ 197 udp->crc =
198 0; /* technically optional, but we calculate it anyway, just to be sure */
189 sum = GNUNET_CRYPTO_crc16_step (0, 199 sum = GNUNET_CRYPTO_crc16_step (0,
190 &ip->source_address, 200 &ip->source_address,
191 sizeof (struct in_addr) * 2); 201 sizeof (struct in_addr) * 2);
192 tmp = htons (IPPROTO_UDP); 202 tmp = htons (IPPROTO_UDP);
193 sum = GNUNET_CRYPTO_crc16_step (sum, 203 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
194 &tmp,
195 sizeof (uint16_t));
196 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); 204 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length);
197 sum = GNUNET_CRYPTO_crc16_step (sum, 205 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
198 &tmp, 206 sum =
199 sizeof (uint16_t)); 207 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader));
200 sum = GNUNET_CRYPTO_crc16_step (sum, 208 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
201 udp,
202 sizeof (struct GNUNET_TUN_UdpHeader));
203 sum = GNUNET_CRYPTO_crc16_step (sum,
204 payload,
205 payload_length);
206 udp->crc = GNUNET_CRYPTO_crc16_finish (sum); 209 udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
207} 210}
208 211
@@ -217,28 +220,30 @@ GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
217 */ 220 */
218void 221void
219GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, 222GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
220 struct GNUNET_TUN_UdpHeader *udp, 223 struct GNUNET_TUN_UdpHeader *udp,
221 const void *payload, 224 const void *payload,
222 uint16_t payload_length) 225 uint16_t payload_length)
223{ 226{
224 uint32_t sum; 227 uint32_t sum;
225 uint32_t tmp; 228 uint32_t tmp;
226 229
227 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == 230 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
228 ntohs (ip->payload_length)); 231 ntohs (ip->payload_length));
229 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == 232 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
230 ntohs (udp->len)); 233 ntohs (udp->len));
231 GNUNET_assert (IPPROTO_UDP == ip->next_header); 234 GNUNET_assert (IPPROTO_UDP == ip->next_header);
232 235
233 udp->crc = 0; 236 udp->crc = 0;
234 sum = GNUNET_CRYPTO_crc16_step (0, 237 sum = GNUNET_CRYPTO_crc16_step (0,
235 &ip->source_address, 238 &ip->source_address,
236 sizeof (struct in6_addr) * 2); 239 sizeof (struct in6_addr) * 2);
237 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); /* aka udp->len */ 240 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) +
241 payload_length); /* aka udp->len */
238 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 242 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
239 tmp = htons (ip->next_header); 243 tmp = htons (ip->next_header);
240 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 244 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
241 sum = GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader)); 245 sum =
246 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader));
242 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 247 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
243 udp->crc = GNUNET_CRYPTO_crc16_finish (sum); 248 udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
244} 249}
@@ -253,16 +258,15 @@ GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
253 */ 258 */
254void 259void
255GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp, 260GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
256 const void *payload, 261 const void *payload,
257 uint16_t payload_length) 262 uint16_t payload_length)
258{ 263{
259 uint32_t sum; 264 uint32_t sum;
260 265
261 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader)); 266 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader));
262 icmp->crc = 0; 267 icmp->crc = 0;
263 sum = GNUNET_CRYPTO_crc16_step (0, 268 sum =
264 icmp, 269 GNUNET_CRYPTO_crc16_step (0, icmp, sizeof (struct GNUNET_TUN_IcmpHeader));
265 sizeof (struct GNUNET_TUN_IcmpHeader));
266 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 270 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
267 icmp->crc = GNUNET_CRYPTO_crc16_finish (sum); 271 icmp->crc = GNUNET_CRYPTO_crc16_finish (sum);
268} 272}
@@ -286,21 +290,22 @@ GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
286 290
287 switch (sa->sa_family) 291 switch (sa->sa_family)
288 { 292 {
289 case AF_INET: 293 case AF_INET: {
290 { 294 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
291 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa; 295 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
292 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb; 296 if ((include_port) && (sa4->sin_port != sb4->sin_port))
293 return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr); 297 return GNUNET_NO;
294 } 298 return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
295 case AF_INET6: 299 }
296 { 300 case AF_INET6: {
297 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa; 301 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
298 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb; 302 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
299 303
300 return (0 == memcmp(&sa6->sin6_addr, 304 if ((include_port) && (sa6->sin6_port != sb6->sin6_port))
301 &sb6->sin6_addr, 305 return GNUNET_NO;
302 sizeof (struct in6_addr))); 306 return (
303 } 307 0 == memcmp (&sa6->sin6_addr, &sb6->sin6_addr, sizeof (struct in6_addr)));
308 }
304 default: 309 default:
305 GNUNET_break (0); 310 GNUNET_break (0);
306 return GNUNET_SYSERR; 311 return GNUNET_SYSERR;