GNUnet  0.19.4
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 
46 void
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 =
68  GNUNET_CRYPTO_crc16_n (ip, sizeof(struct GNUNET_TUN_IPv4Header));
69 }
70 
71 
81 void
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;
93  ip->next_header = protocol;
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 
101 void
103  struct GNUNET_TUN_TcpHeader *tcp,
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 
131 void
133  struct GNUNET_TUN_TcpHeader *tcp,
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 
159 void
161  struct GNUNET_TUN_UdpHeader *udp,
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 
190 void
192  struct GNUNET_TUN_UdpHeader *udp,
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 
221 void
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 
245 int
246 GNUNET_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