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.c319
1 files changed, 0 insertions, 319 deletions
diff --git a/src/util/tun.c b/src/util/tun.c
deleted file mode 100644
index d2b675c71..000000000
--- a/src/util/tun.c
+++ /dev/null
@@ -1,319 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 Christian Grothoff
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file tun/tun.c
23 * @brief standard IP calculations for TUN interaction
24 * @author Philipp Toelke
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29
30/**
31 * IP TTL we use for packets that we assemble (8 bit unsigned integer)
32 */
33#define FRESH_TTL 64
34
35
36/**
37 * Initialize an IPv4 header.
38 *
39 * @param ip header to initialize
40 * @param protocol protocol to use (e.g. IPPROTO_UDP)
41 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
42 * @param src source IP address to use
43 * @param dst destination IP address to use
44 */
45void
46GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
47 uint8_t protocol,
48 uint16_t payload_length,
49 const struct in_addr *src,
50 const struct in_addr *dst)
51{
52 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_IPv4Header));
53 GNUNET_assert (payload_length <=
54 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv4Header));
55 memset (ip, 0, sizeof(struct GNUNET_TUN_IPv4Header));
56 ip->header_length = sizeof(struct GNUNET_TUN_IPv4Header) / 4;
57 ip->version = 4;
58 ip->total_length =
59 htons (sizeof(struct GNUNET_TUN_IPv4Header) + payload_length);
60 ip->identification =
61 (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 65536);
62 ip->ttl = FRESH_TTL;
63 ip->protocol = protocol;
64 ip->source_address = *src;
65 ip->destination_address = *dst;
66 ip->checksum =
67 GNUNET_CRYPTO_crc16_n (ip, sizeof(struct GNUNET_TUN_IPv4Header));
68}
69
70
71/**
72 * Initialize an IPv6 header.
73 *
74 * @param ip header to initialize
75 * @param protocol protocol to use (e.g. IPPROTO_UDP), technically "next_header" for IPv6
76 * @param payload_length number of bytes of payload that follow (excluding IPv6 header)
77 * @param src source IP address to use
78 * @param dst destination IP address to use
79 */
80void
81GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
82 uint8_t protocol,
83 uint16_t payload_length,
84 const struct in6_addr *src,
85 const struct in6_addr *dst)
86{
87 GNUNET_assert (40 == sizeof(struct GNUNET_TUN_IPv6Header));
88 GNUNET_assert (payload_length <=
89 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv6Header));
90 memset (ip, 0, sizeof(struct GNUNET_TUN_IPv6Header));
91 ip->version = 6;
92 ip->next_header = protocol;
93 ip->payload_length = htons ((uint16_t) payload_length);
94 ip->hop_limit = FRESH_TTL;
95 ip->destination_address = *dst;
96 ip->source_address = *src;
97}
98
99
100/**
101 * Calculate IPv4 TCP checksum.
102 *
103 * @param ip ipv4 header fully initialized
104 * @param tcp TCP header (initialized except for CRC)
105 * @param payload the TCP payload
106 * @param payload_length number of bytes of TCP payload
107 */
108void
109GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
110 struct GNUNET_TUN_TcpHeader *tcp,
111 const void *payload,
112 uint16_t payload_length)
113{
114 uint32_t sum;
115 uint16_t tmp;
116
117 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_TcpHeader));
118 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_IPv4Header)
119 + sizeof(struct GNUNET_TUN_TcpHeader) ==
120 ntohs (ip->total_length));
121 GNUNET_assert (IPPROTO_TCP == ip->protocol);
122
123 tcp->crc = 0;
124 sum = GNUNET_CRYPTO_crc16_step (0,
125 &ip->source_address,
126 sizeof(struct in_addr) * 2);
127 tmp = htons (IPPROTO_TCP);
128 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
129 tmp = htons (payload_length + sizeof(struct GNUNET_TUN_TcpHeader));
130 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
131 sum =
132 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof(struct GNUNET_TUN_TcpHeader));
133 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
134 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
135}
136
137
138/**
139 * Calculate IPv6 TCP checksum.
140 *
141 * @param ip ipv6 header fully initialized
142 * @param tcp header (initialized except for CRC)
143 * @param payload the TCP payload
144 * @param payload_length number of bytes of TCP payload
145 */
146void
147GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
148 struct GNUNET_TUN_TcpHeader *tcp,
149 const void *payload,
150 uint16_t payload_length)
151{
152 uint32_t sum;
153 uint32_t tmp;
154
155 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_TcpHeader));
156 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_TcpHeader) ==
157 ntohs (ip->payload_length));
158 GNUNET_assert (IPPROTO_TCP == ip->next_header);
159 tcp->crc = 0;
160 sum = GNUNET_CRYPTO_crc16_step (0,
161 &ip->source_address,
162 2 * sizeof(struct in6_addr));
163 tmp = htonl (sizeof(struct GNUNET_TUN_TcpHeader) + payload_length);
164 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
165 tmp = htonl (IPPROTO_TCP);
166 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
167 sum =
168 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof(struct GNUNET_TUN_TcpHeader));
169 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
170 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
171}
172
173
174/**
175 * Calculate IPv4 UDP checksum.
176 *
177 * @param ip ipv4 header fully initialized
178 * @param udp UDP header (initialized except for CRC)
179 * @param payload the UDP payload
180 * @param payload_length number of bytes of UDP payload
181 */
182void
183GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
184 struct GNUNET_TUN_UdpHeader *udp,
185 const void *payload,
186 uint16_t payload_length)
187{
188 uint32_t sum;
189 uint16_t tmp;
190
191 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
192 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_IPv4Header)
193 + sizeof(struct GNUNET_TUN_UdpHeader) ==
194 ntohs (ip->total_length));
195 GNUNET_assert (IPPROTO_UDP == ip->protocol);
196
197 udp->crc =
198 0; /* technically optional, but we calculate it anyway, just to be sure */
199 sum = GNUNET_CRYPTO_crc16_step (0,
200 &ip->source_address,
201 sizeof(struct in_addr) * 2);
202 tmp = htons (IPPROTO_UDP);
203 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
204 tmp = htons (sizeof(struct GNUNET_TUN_UdpHeader) + payload_length);
205 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
206 sum =
207 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof(struct GNUNET_TUN_UdpHeader));
208 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
209 udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
210}
211
212
213/**
214 * Calculate IPv6 UDP checksum.
215 *
216 * @param ip ipv6 header fully initialized
217 * @param udp UDP header (initialized except for CRC)
218 * @param payload the UDP payload
219 * @param payload_length number of bytes of UDP payload
220 */
221void
222GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
223 struct GNUNET_TUN_UdpHeader *udp,
224 const void *payload,
225 uint16_t payload_length)
226{
227 uint32_t sum;
228 uint32_t tmp;
229
230 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
231 ntohs (ip->payload_length));
232 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
233 ntohs (udp->len));
234 GNUNET_assert (IPPROTO_UDP == ip->next_header);
235
236 udp->crc = 0;
237 sum = GNUNET_CRYPTO_crc16_step (0,
238 &ip->source_address,
239 sizeof(struct in6_addr) * 2);
240 tmp = htons (sizeof(struct GNUNET_TUN_UdpHeader)
241 + payload_length); /* aka udp->len */
242 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
243 tmp = htons (ip->next_header);
244 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
245 sum =
246 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof(struct GNUNET_TUN_UdpHeader));
247 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
248 udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
249}
250
251
252/**
253 * Calculate ICMP checksum.
254 *
255 * @param icmp IMCP header (initialized except for CRC)
256 * @param payload the ICMP payload
257 * @param payload_length number of bytes of ICMP payload
258 */
259void
260GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
261 const void *payload,
262 uint16_t payload_length)
263{
264 uint32_t sum;
265
266 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_IcmpHeader));
267 icmp->crc = 0;
268 sum =
269 GNUNET_CRYPTO_crc16_step (0, icmp, sizeof(struct GNUNET_TUN_IcmpHeader));
270 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
271 icmp->crc = GNUNET_CRYPTO_crc16_finish (sum);
272}
273
274
275/**
276 * Check if two sockaddrs are equal.
277 *
278 * @param sa one address
279 * @param sb another address
280 * @param include_port also check ports
281 * @return #GNUNET_YES if they are equal
282 */
283int
284GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
285 const struct sockaddr *sb,
286 int include_port)
287{
288 if (sa->sa_family != sb->sa_family)
289 return GNUNET_NO;
290
291 switch (sa->sa_family)
292 {
293 case AF_INET: {
294 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
295 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
296 if ((include_port) && (sa4->sin_port != sb4->sin_port))
297 return GNUNET_NO;
298 return(sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
299 }
300
301 case AF_INET6: {
302 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
303 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
304
305 if ((include_port) && (sa6->sin6_port != sb6->sin6_port))
306 return GNUNET_NO;
307 return(
308 0 == memcmp (&sa6->sin6_addr, &sb6->sin6_addr, sizeof(struct
309 in6_addr)));
310 }
311
312 default:
313 GNUNET_break (0);
314 return GNUNET_SYSERR;
315 }
316}
317
318
319/* end of tun.c */