GNUnet 0.22.2
tun.c
Go to the documentation of this file.
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
28#include "platform.h"
29#include "gnunet_util_lib.h"
30
34#define FRESH_TTL 64
35
36
37void
39 struct GNUNET_HashCode *hc)
40{
42 strlen (service_name),
43 hc);
44}
45
46
56void
58 uint16_t ip_port,
60{
61 uint16_t be_port = htons (ip_port);
62
63 *cadet_port = *desc;
65 &be_port,
66 sizeof(uint16_t));
67}
68
69
79void
81 uint8_t protocol,
82 uint16_t payload_length,
83 const struct in_addr *src,
84 const struct in_addr *dst)
85{
86 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_IPv4Header));
87 GNUNET_assert (payload_length <=
88 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv4Header));
89 memset (ip, 0, sizeof(struct GNUNET_TUN_IPv4Header));
90 ip->header_length = sizeof(struct GNUNET_TUN_IPv4Header) / 4;
91 ip->version = 4;
92 ip->total_length =
93 htons (sizeof(struct GNUNET_TUN_IPv4Header) + payload_length);
94 ip->identification =
96 ip->ttl = FRESH_TTL;
97 ip->protocol = protocol;
98 ip->source_address = *src;
99 ip->destination_address = *dst;
100 ip->checksum =
101 GNUNET_CRYPTO_crc16_n (ip, sizeof(struct GNUNET_TUN_IPv4Header));
102}
103
104
114void
116 uint8_t protocol,
117 uint16_t payload_length,
118 const struct in6_addr *src,
119 const struct in6_addr *dst)
120{
121 GNUNET_assert (40 == sizeof(struct GNUNET_TUN_IPv6Header));
122 GNUNET_assert (payload_length <=
123 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv6Header));
124 memset (ip, 0, sizeof(struct GNUNET_TUN_IPv6Header));
125 ip->version = 6;
126 ip->next_header = protocol;
127 ip->payload_length = htons ((uint16_t) payload_length);
128 ip->hop_limit = FRESH_TTL;
129 ip->destination_address = *dst;
130 ip->source_address = *src;
131}
132
133
134void
137 const void *payload,
138 uint16_t payload_length)
139{
140 uint32_t sum;
141 uint16_t tmp;
142
143 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_TcpHeader));
144 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_IPv4Header)
145 + sizeof(struct GNUNET_TUN_TcpHeader) ==
146 ntohs (ip->total_length));
147 GNUNET_assert (IPPROTO_TCP == ip->protocol);
148
149 tcp->crc = 0;
151 &ip->source_address,
152 sizeof(struct in_addr) * 2);
153 tmp = htons (IPPROTO_TCP);
154 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
155 tmp = htons (payload_length + sizeof(struct GNUNET_TUN_TcpHeader));
156 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
157 sum =
159 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
161}
162
163
164void
167 const void *payload,
168 uint16_t payload_length)
169{
170 uint32_t sum;
171 uint32_t tmp;
172
173 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_TcpHeader));
174 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_TcpHeader) ==
175 ntohs (ip->payload_length));
176 GNUNET_assert (IPPROTO_TCP == ip->next_header);
177 tcp->crc = 0;
179 &ip->source_address,
180 2 * sizeof(struct in6_addr));
181 tmp = htonl (sizeof(struct GNUNET_TUN_TcpHeader) + payload_length);
182 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
183 tmp = htonl (IPPROTO_TCP);
184 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
185 sum =
187 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
189}
190
191
192void
195 const void *payload,
196 uint16_t payload_length)
197{
198 uint32_t sum;
199 uint16_t tmp;
200
201 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
202 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_IPv4Header)
203 + sizeof(struct GNUNET_TUN_UdpHeader) ==
204 ntohs (ip->total_length));
205 GNUNET_assert (IPPROTO_UDP == ip->protocol);
206
207 udp->crc =
208 0; /* technically optional, but we calculate it anyway, just to be sure */
210 &ip->source_address,
211 sizeof(struct in_addr) * 2);
212 tmp = htons (IPPROTO_UDP);
213 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
214 tmp = htons (sizeof(struct GNUNET_TUN_UdpHeader) + payload_length);
215 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
216 sum =
218 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
220}
221
222
223void
226 const void *payload,
227 uint16_t payload_length)
228{
229 uint32_t sum;
230 uint32_t tmp;
231
232 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
233 ntohs (ip->payload_length));
234 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
235 ntohs (udp->len));
236 GNUNET_assert (IPPROTO_UDP == ip->next_header);
237
238 udp->crc = 0;
240 &ip->source_address,
241 sizeof(struct in6_addr) * 2);
242 tmp = htons (sizeof(struct GNUNET_TUN_UdpHeader)
243 + payload_length); /* aka udp->len */
244 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
245 tmp = htons (ip->next_header);
246 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
247 sum =
249 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
251}
252
253
254void
256 const void *payload,
257 uint16_t payload_length)
258{
259 uint32_t sum;
260
261 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_IcmpHeader));
262 icmp->crc = 0;
263 sum =
264 GNUNET_CRYPTO_crc16_step (0, icmp, sizeof(struct GNUNET_TUN_IcmpHeader));
265 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
267}
268
269
278int
279GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
280 const struct sockaddr *sb,
281 int include_port)
282{
283 if (sa->sa_family != sb->sa_family)
284 return GNUNET_NO;
285
286 switch (sa->sa_family)
287 {
288 case AF_INET: {
289 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
290 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
291 if ((include_port) && (sa4->sin_port != sb4->sin_port))
292 return GNUNET_NO;
293 return(sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
294 }
295
296 case AF_INET6: {
297 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
298 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
299
300 if ((include_port) && (sa6->sin6_port != sb6->sin6_port))
301 return GNUNET_NO;
302 return(
303 0 == memcmp (&sa6->sin6_addr, &sb6->sin6_addr, sizeof(struct
304 in6_addr)));
305 }
306
307 default:
308 GNUNET_break (0);
309 return GNUNET_SYSERR;
310 }
311}
312
313
314/* end of tun.c */
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:50
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:75
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:70
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
uint16_t GNUNET_CRYPTO_crc16_n(const void *buf, size_t len)
Calculate the checksum of a buffer in one step.
Definition: crypto_crc.c:133
uint16_t GNUNET_CRYPTO_crc16_finish(uint32_t sum)
Convert results from GNUNET_CRYPTO_crc16_step to final crc16.
Definition: crypto_crc.c:123
uint32_t GNUNET_CRYPTO_crc16_step(uint32_t sum, const void *buf, size_t len)
Perform an incremental step in a CRC16 (for TCP/IP) calculation.
Definition: crypto_crc.c:110
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:115
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
Definition: tun.c:193
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:80
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:255
void GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and...
Definition: tun.c:57
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition: tun.c:165
void GNUNET_TUN_service_name_to_hash(const char *service_name, struct GNUNET_HashCode *hc)
Hash the service name of a hosted service to the hash code that is used to identify the service on th...
Definition: tun.c:38
int GNUNET_TUN_sockaddr_cmp(const struct sockaddr *sa, const struct sockaddr *sb, int include_port)
Check if two sockaddrs are equal.
Definition: tun.c:279
void GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv4 TCP checksum.
Definition: tun.c:135
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
Definition: tun.c:224
A 512-bit hashcode.
Standard IPv4 header.
uint16_t total_length
Length of the packet, including this header.
uint8_t ttl
How many more hops can this packet be forwarded?
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
uint16_t checksum
Checksum.
uint16_t identification
Unique random ID for matching up fragments.
struct in_addr source_address
Origin of the packet.
struct in_addr destination_address
Destination of the packet.
unsigned int header_length
Standard IPv6 header.
struct in6_addr source_address
Origin of the packet.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
uint8_t hop_limit
How many more hops can this packet be forwarded?
struct in6_addr destination_address
Destination of the packet.
uint16_t payload_length
Length of the payload, excluding this header.
TCP packet header.
UDP packet header.
#define FRESH_TTL
IP TTL we use for packets that we assemble (8 bit unsigned integer)
Definition: tun.c:34