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.c264
1 files changed, 133 insertions, 131 deletions
diff --git a/src/util/tun.c b/src/util/tun.c
index e3643d0c6..f3b97b860 100644
--- a/src/util/tun.c
+++ b/src/util/tun.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file tun/tun.c 22 * @file tun/tun.c
@@ -43,28 +43,28 @@
43 * @param dst destination IP address to use 43 * @param dst destination IP address to use
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 <= 53 GNUNET_assert(payload_length <=
54 UINT16_MAX - sizeof (struct GNUNET_TUN_IPv4Header)); 54 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv4Header));
55 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv4Header)); 55 memset(ip, 0, sizeof(struct GNUNET_TUN_IPv4Header));
56 ip->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4; 56 ip->header_length = sizeof(struct GNUNET_TUN_IPv4Header) / 4;
57 ip->version = 4; 57 ip->version = 4;
58 ip->total_length = 58 ip->total_length =
59 htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length); 59 htons(sizeof(struct GNUNET_TUN_IPv4Header) + payload_length);
60 ip->identification = 60 ip->identification =
61 (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 65536); 61 (uint16_t)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 65536);
62 ip->ttl = FRESH_TTL; 62 ip->ttl = FRESH_TTL;
63 ip->protocol = protocol; 63 ip->protocol = protocol;
64 ip->source_address = *src; 64 ip->source_address = *src;
65 ip->destination_address = *dst; 65 ip->destination_address = *dst;
66 ip->checksum = 66 ip->checksum =
67 GNUNET_CRYPTO_crc16_n (ip, sizeof (struct GNUNET_TUN_IPv4Header)); 67 GNUNET_CRYPTO_crc16_n(ip, sizeof(struct GNUNET_TUN_IPv4Header));
68} 68}
69 69
70 70
@@ -78,19 +78,19 @@ GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
78 * @param dst destination IP address to use 78 * @param dst destination IP address to use
79 */ 79 */
80void 80void
81GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, 81GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip,
82 uint8_t protocol, 82 uint8_t protocol,
83 uint16_t payload_length, 83 uint16_t payload_length,
84 const struct in6_addr *src, 84 const struct in6_addr *src,
85 const struct in6_addr *dst) 85 const struct in6_addr *dst)
86{ 86{
87 GNUNET_assert (40 == sizeof (struct GNUNET_TUN_IPv6Header)); 87 GNUNET_assert(40 == sizeof(struct GNUNET_TUN_IPv6Header));
88 GNUNET_assert (payload_length <= 88 GNUNET_assert(payload_length <=
89 UINT16_MAX - sizeof (struct GNUNET_TUN_IPv6Header)); 89 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv6Header));
90 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header)); 90 memset(ip, 0, sizeof(struct GNUNET_TUN_IPv6Header));
91 ip->version = 6; 91 ip->version = 6;
92 ip->next_header = protocol; 92 ip->next_header = protocol;
93 ip->payload_length = htons ((uint16_t) payload_length); 93 ip->payload_length = htons((uint16_t)payload_length);
94 ip->hop_limit = FRESH_TTL; 94 ip->hop_limit = FRESH_TTL;
95 ip->destination_address = *dst; 95 ip->destination_address = *dst;
96 ip->source_address = *src; 96 ip->source_address = *src;
@@ -106,32 +106,32 @@ GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
106 * @param payload_length number of bytes of TCP payload 106 * @param payload_length number of bytes of TCP payload
107 */ 107 */
108void 108void
109GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, 109GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip,
110 struct GNUNET_TUN_TcpHeader *tcp, 110 struct GNUNET_TUN_TcpHeader *tcp,
111 const void *payload, 111 const void *payload,
112 uint16_t payload_length) 112 uint16_t payload_length)
113{ 113{
114 uint32_t sum; 114 uint32_t sum;
115 uint16_t tmp; 115 uint16_t tmp;
116 116
117 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader)); 117 GNUNET_assert(20 == sizeof(struct GNUNET_TUN_TcpHeader));
118 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + 118 GNUNET_assert(payload_length + sizeof(struct GNUNET_TUN_IPv4Header) +
119 sizeof (struct GNUNET_TUN_TcpHeader) == 119 sizeof(struct GNUNET_TUN_TcpHeader) ==
120 ntohs (ip->total_length)); 120 ntohs(ip->total_length));
121 GNUNET_assert (IPPROTO_TCP == ip->protocol); 121 GNUNET_assert(IPPROTO_TCP == ip->protocol);
122 122
123 tcp->crc = 0; 123 tcp->crc = 0;
124 sum = GNUNET_CRYPTO_crc16_step (0, 124 sum = GNUNET_CRYPTO_crc16_step(0,
125 &ip->source_address, 125 &ip->source_address,
126 sizeof (struct in_addr) * 2); 126 sizeof(struct in_addr) * 2);
127 tmp = htons (IPPROTO_TCP); 127 tmp = htons(IPPROTO_TCP);
128 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 128 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint16_t));
129 tmp = htons (payload_length + sizeof (struct GNUNET_TUN_TcpHeader)); 129 tmp = htons(payload_length + sizeof(struct GNUNET_TUN_TcpHeader));
130 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 130 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint16_t));
131 sum = 131 sum =
132 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader)); 132 GNUNET_CRYPTO_crc16_step(sum, tcp, sizeof(struct GNUNET_TUN_TcpHeader));
133 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 133 sum = GNUNET_CRYPTO_crc16_step(sum, payload, payload_length);
134 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); 134 tcp->crc = GNUNET_CRYPTO_crc16_finish(sum);
135} 135}
136 136
137 137
@@ -144,30 +144,30 @@ GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
144 * @param payload_length number of bytes of TCP payload 144 * @param payload_length number of bytes of TCP payload
145 */ 145 */
146void 146void
147GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, 147GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip,
148 struct GNUNET_TUN_TcpHeader *tcp, 148 struct GNUNET_TUN_TcpHeader *tcp,
149 const void *payload, 149 const void *payload,
150 uint16_t payload_length) 150 uint16_t payload_length)
151{ 151{
152 uint32_t sum; 152 uint32_t sum;
153 uint32_t tmp; 153 uint32_t tmp;
154 154
155 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader)); 155 GNUNET_assert(20 == sizeof(struct GNUNET_TUN_TcpHeader));
156 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_TcpHeader) == 156 GNUNET_assert(payload_length + sizeof(struct GNUNET_TUN_TcpHeader) ==
157 ntohs (ip->payload_length)); 157 ntohs(ip->payload_length));
158 GNUNET_assert (IPPROTO_TCP == ip->next_header); 158 GNUNET_assert(IPPROTO_TCP == ip->next_header);
159 tcp->crc = 0; 159 tcp->crc = 0;
160 sum = GNUNET_CRYPTO_crc16_step (0, 160 sum = GNUNET_CRYPTO_crc16_step(0,
161 &ip->source_address, 161 &ip->source_address,
162 2 * sizeof (struct in6_addr)); 162 2 * sizeof(struct in6_addr));
163 tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length); 163 tmp = htonl(sizeof(struct GNUNET_TUN_TcpHeader) + payload_length);
164 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 164 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint32_t));
165 tmp = htonl (IPPROTO_TCP); 165 tmp = htonl(IPPROTO_TCP);
166 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 166 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint32_t));
167 sum = 167 sum =
168 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader)); 168 GNUNET_CRYPTO_crc16_step(sum, tcp, sizeof(struct GNUNET_TUN_TcpHeader));
169 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 169 sum = GNUNET_CRYPTO_crc16_step(sum, payload, payload_length);
170 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); 170 tcp->crc = GNUNET_CRYPTO_crc16_finish(sum);
171} 171}
172 172
173 173
@@ -180,33 +180,33 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
180 * @param payload_length number of bytes of UDP payload 180 * @param payload_length number of bytes of UDP payload
181 */ 181 */
182void 182void
183GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, 183GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip,
184 struct GNUNET_TUN_UdpHeader *udp, 184 struct GNUNET_TUN_UdpHeader *udp,
185 const void *payload, 185 const void *payload,
186 uint16_t payload_length) 186 uint16_t payload_length)
187{ 187{
188 uint32_t sum; 188 uint32_t sum;
189 uint16_t tmp; 189 uint16_t tmp;
190 190
191 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 191 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
192 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + 192 GNUNET_assert(payload_length + sizeof(struct GNUNET_TUN_IPv4Header) +
193 sizeof (struct GNUNET_TUN_UdpHeader) == 193 sizeof(struct GNUNET_TUN_UdpHeader) ==
194 ntohs (ip->total_length)); 194 ntohs(ip->total_length));
195 GNUNET_assert (IPPROTO_UDP == ip->protocol); 195 GNUNET_assert(IPPROTO_UDP == ip->protocol);
196 196
197 udp->crc = 197 udp->crc =
198 0; /* technically optional, but we calculate it anyway, just to be sure */ 198 0; /* technically optional, but we calculate it anyway, just to be sure */
199 sum = GNUNET_CRYPTO_crc16_step (0, 199 sum = GNUNET_CRYPTO_crc16_step(0,
200 &ip->source_address, 200 &ip->source_address,
201 sizeof (struct in_addr) * 2); 201 sizeof(struct in_addr) * 2);
202 tmp = htons (IPPROTO_UDP); 202 tmp = htons(IPPROTO_UDP);
203 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 203 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint16_t));
204 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); 204 tmp = htons(sizeof(struct GNUNET_TUN_UdpHeader) + payload_length);
205 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 205 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint16_t));
206 sum = 206 sum =
207 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader)); 207 GNUNET_CRYPTO_crc16_step(sum, udp, sizeof(struct GNUNET_TUN_UdpHeader));
208 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 208 sum = GNUNET_CRYPTO_crc16_step(sum, payload, payload_length);
209 udp->crc = GNUNET_CRYPTO_crc16_finish (sum); 209 udp->crc = GNUNET_CRYPTO_crc16_finish(sum);
210} 210}
211 211
212 212
@@ -219,33 +219,33 @@ GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
219 * @param payload_length number of bytes of UDP payload 219 * @param payload_length number of bytes of UDP payload
220 */ 220 */
221void 221void
222GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, 222GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip,
223 struct GNUNET_TUN_UdpHeader *udp, 223 struct GNUNET_TUN_UdpHeader *udp,
224 const void *payload, 224 const void *payload,
225 uint16_t payload_length) 225 uint16_t payload_length)
226{ 226{
227 uint32_t sum; 227 uint32_t sum;
228 uint32_t tmp; 228 uint32_t tmp;
229 229
230 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == 230 GNUNET_assert(payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
231 ntohs (ip->payload_length)); 231 ntohs(ip->payload_length));
232 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == 232 GNUNET_assert(payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
233 ntohs (udp->len)); 233 ntohs(udp->len));
234 GNUNET_assert (IPPROTO_UDP == ip->next_header); 234 GNUNET_assert(IPPROTO_UDP == ip->next_header);
235 235
236 udp->crc = 0; 236 udp->crc = 0;
237 sum = GNUNET_CRYPTO_crc16_step (0, 237 sum = GNUNET_CRYPTO_crc16_step(0,
238 &ip->source_address, 238 &ip->source_address,
239 sizeof (struct in6_addr) * 2); 239 sizeof(struct in6_addr) * 2);
240 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + 240 tmp = htons(sizeof(struct GNUNET_TUN_UdpHeader) +
241 payload_length); /* aka udp->len */ 241 payload_length); /* aka udp->len */
242 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 242 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint32_t));
243 tmp = htons (ip->next_header); 243 tmp = htons(ip->next_header);
244 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 244 sum = GNUNET_CRYPTO_crc16_step(sum, &tmp, sizeof(uint32_t));
245 sum = 245 sum =
246 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader)); 246 GNUNET_CRYPTO_crc16_step(sum, udp, sizeof(struct GNUNET_TUN_UdpHeader));
247 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 247 sum = GNUNET_CRYPTO_crc16_step(sum, payload, payload_length);
248 udp->crc = GNUNET_CRYPTO_crc16_finish (sum); 248 udp->crc = GNUNET_CRYPTO_crc16_finish(sum);
249} 249}
250 250
251 251
@@ -257,18 +257,18 @@ GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
257 * @param payload_length number of bytes of ICMP payload 257 * @param payload_length number of bytes of ICMP payload
258 */ 258 */
259void 259void
260GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp, 260GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp,
261 const void *payload, 261 const void *payload,
262 uint16_t payload_length) 262 uint16_t payload_length)
263{ 263{
264 uint32_t sum; 264 uint32_t sum;
265 265
266 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader)); 266 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_IcmpHeader));
267 icmp->crc = 0; 267 icmp->crc = 0;
268 sum = 268 sum =
269 GNUNET_CRYPTO_crc16_step (0, icmp, sizeof (struct GNUNET_TUN_IcmpHeader)); 269 GNUNET_CRYPTO_crc16_step(0, icmp, sizeof(struct GNUNET_TUN_IcmpHeader));
270 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 270 sum = GNUNET_CRYPTO_crc16_step(sum, payload, payload_length);
271 icmp->crc = GNUNET_CRYPTO_crc16_finish (sum); 271 icmp->crc = GNUNET_CRYPTO_crc16_finish(sum);
272} 272}
273 273
274 274
@@ -281,35 +281,37 @@ GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
281 * @return #GNUNET_YES if they are equal 281 * @return #GNUNET_YES if they are equal
282 */ 282 */
283int 283int
284GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa, 284GNUNET_TUN_sockaddr_cmp(const struct sockaddr *sa,
285 const struct sockaddr *sb, 285 const struct sockaddr *sb,
286 int include_port) 286 int include_port)
287{ 287{
288 if (sa->sa_family != sb->sa_family) 288 if (sa->sa_family != sb->sa_family)
289 return GNUNET_NO; 289 return GNUNET_NO;
290 290
291 switch (sa->sa_family) 291 switch (sa->sa_family)
292 { 292 {
293 case AF_INET: { 293 case AF_INET: {
294 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa; 294 const struct sockaddr_in *sa4 = (const struct sockaddr_in *)sa;
295 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb; 295 const struct sockaddr_in *sb4 = (const struct sockaddr_in *)sb;
296 if ((include_port) && (sa4->sin_port != sb4->sin_port)) 296 if ((include_port) && (sa4->sin_port != sb4->sin_port))
297 return GNUNET_NO; 297 return GNUNET_NO;
298 return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr); 298 return(sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
299 } 299 }
300 case AF_INET6: { 300
301 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa; 301 case AF_INET6: {
302 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb; 302 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *)sa;
303 303 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *)sb;
304 if ((include_port) && (sa6->sin6_port != sb6->sin6_port)) 304
305 return GNUNET_NO; 305 if ((include_port) && (sa6->sin6_port != sb6->sin6_port))
306 return ( 306 return GNUNET_NO;
307 0 == memcmp (&sa6->sin6_addr, &sb6->sin6_addr, sizeof (struct in6_addr))); 307 return(
308 } 308 0 == memcmp(&sa6->sin6_addr, &sb6->sin6_addr, sizeof(struct in6_addr)));
309 default: 309 }
310 GNUNET_break (0); 310
311 return GNUNET_SYSERR; 311 default:
312 } 312 GNUNET_break(0);
313 return GNUNET_SYSERR;
314 }
313} 315}
314 316
315 317