GNUnet 0.21.1
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
46void
48 uint8_t protocol,
49 uint16_t payload_length,
50 const struct in_addr *src,
51 const struct in_addr *dst)
52{
53 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_IPv4Header));
54 GNUNET_assert (payload_length <=
55 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv4Header));
56 memset (ip, 0, sizeof(struct GNUNET_TUN_IPv4Header));
57 ip->header_length = sizeof(struct GNUNET_TUN_IPv4Header) / 4;
58 ip->version = 4;
59 ip->total_length =
60 htons (sizeof(struct GNUNET_TUN_IPv4Header) + payload_length);
61 ip->identification =
63 ip->ttl = FRESH_TTL;
64 ip->protocol = protocol;
65 ip->source_address = *src;
66 ip->destination_address = *dst;
67 ip->checksum =
69}
70
71
81void
83 uint8_t protocol,
84 uint16_t payload_length,
85 const struct in6_addr *src,
86 const struct in6_addr *dst)
87{
88 GNUNET_assert (40 == sizeof(struct GNUNET_TUN_IPv6Header));
89 GNUNET_assert (payload_length <=
90 UINT16_MAX - sizeof(struct GNUNET_TUN_IPv6Header));
91 memset (ip, 0, sizeof(struct GNUNET_TUN_IPv6Header));
92 ip->version = 6;
94 ip->payload_length = htons ((uint16_t) payload_length);
95 ip->hop_limit = FRESH_TTL;
96 ip->destination_address = *dst;
97 ip->source_address = *src;
98}
99
100
101void
104 const void *payload,
105 uint16_t payload_length)
106{
107 uint32_t sum;
108 uint16_t tmp;
109
110 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_TcpHeader));
111 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_IPv4Header)
112 + sizeof(struct GNUNET_TUN_TcpHeader) ==
113 ntohs (ip->total_length));
114 GNUNET_assert (IPPROTO_TCP == ip->protocol);
115
116 tcp->crc = 0;
118 &ip->source_address,
119 sizeof(struct in_addr) * 2);
120 tmp = htons (IPPROTO_TCP);
121 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
122 tmp = htons (payload_length + sizeof(struct GNUNET_TUN_TcpHeader));
123 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
124 sum =
126 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
128}
129
130
131void
134 const void *payload,
135 uint16_t payload_length)
136{
137 uint32_t sum;
138 uint32_t tmp;
139
140 GNUNET_assert (20 == sizeof(struct GNUNET_TUN_TcpHeader));
141 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_TcpHeader) ==
142 ntohs (ip->payload_length));
143 GNUNET_assert (IPPROTO_TCP == ip->next_header);
144 tcp->crc = 0;
146 &ip->source_address,
147 2 * sizeof(struct in6_addr));
148 tmp = htonl (sizeof(struct GNUNET_TUN_TcpHeader) + payload_length);
149 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
150 tmp = htonl (IPPROTO_TCP);
151 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
152 sum =
154 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
156}
157
158
159void
162 const void *payload,
163 uint16_t payload_length)
164{
165 uint32_t sum;
166 uint16_t tmp;
167
168 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
169 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_IPv4Header)
170 + sizeof(struct GNUNET_TUN_UdpHeader) ==
171 ntohs (ip->total_length));
172 GNUNET_assert (IPPROTO_UDP == ip->protocol);
173
174 udp->crc =
175 0; /* technically optional, but we calculate it anyway, just to be sure */
177 &ip->source_address,
178 sizeof(struct in_addr) * 2);
179 tmp = htons (IPPROTO_UDP);
180 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
181 tmp = htons (sizeof(struct GNUNET_TUN_UdpHeader) + payload_length);
182 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint16_t));
183 sum =
185 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
187}
188
189
190void
193 const void *payload,
194 uint16_t payload_length)
195{
196 uint32_t sum;
197 uint32_t tmp;
198
199 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
200 ntohs (ip->payload_length));
201 GNUNET_assert (payload_length + sizeof(struct GNUNET_TUN_UdpHeader) ==
202 ntohs (udp->len));
203 GNUNET_assert (IPPROTO_UDP == ip->next_header);
204
205 udp->crc = 0;
207 &ip->source_address,
208 sizeof(struct in6_addr) * 2);
209 tmp = htons (sizeof(struct GNUNET_TUN_UdpHeader)
210 + payload_length); /* aka udp->len */
211 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
212 tmp = htons (ip->next_header);
213 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof(uint32_t));
214 sum =
216 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
218}
219
220
221void
223 const void *payload,
224 uint16_t payload_length)
225{
226 uint32_t sum;
227
228 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_IcmpHeader));
229 icmp->crc = 0;
230 sum =
231 GNUNET_CRYPTO_crc16_step (0, icmp, sizeof(struct GNUNET_TUN_IcmpHeader));
232 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
234}
235
236
245int
246GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
247 const struct sockaddr *sb,
248 int include_port)
249{
250 if (sa->sa_family != sb->sa_family)
251 return GNUNET_NO;
252
253 switch (sa->sa_family)
254 {
255 case AF_INET: {
256 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
257 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
258 if ((include_port) && (sa4->sin_port != sb4->sin_port))
259 return GNUNET_NO;
260 return(sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
261 }
262
263 case AF_INET6: {
264 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
265 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
266
267 if ((include_port) && (sa6->sin6_port != sb6->sin6_port))
268 return GNUNET_NO;
269 return(
270 0 == memcmp (&sa6->sin6_addr, &sb6->sin6_addr, sizeof(struct
271 in6_addr)));
272 }
273
274 default:
275 GNUNET_break (0);
276 return GNUNET_SYSERR;
277 }
278}
279
280
281/* end of tun.c */
static unsigned long long payload
How much data are we currently storing in the database?
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).
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
@ 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:82
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:160
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:47
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:222
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:132
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:246
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:102
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:191
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