2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file include/gnunet_tun_lib.h
23 * @brief standard TCP/IP network structs and IP checksum calculations for TUN interaction
24 * @author Philipp Toelke
25 * @author Christian Grothoff
27 #ifndef GNUNET_TUN_LIB_H
28 #define GNUNET_TUN_LIB_H
30 #include "gnunet_util_lib.h"
33 /* see http://www.iana.org/assignments/ethernet-numbers */
38 #define ETH_P_IPV4 0x0800
45 #define ETH_P_IPV6 0x86DD
50 * Maximum regex string length for use with GNUNET_TUN_ipv4toregexsearch
52 #define GNUNET_TUN_IPV4_REGEXLEN 32 + 6
56 * Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch
58 #define GNUNET_TUN_IPV6_REGEXLEN 128 + 6
61 GNUNET_NETWORK_STRUCT_BEGIN
64 * Header from Linux TUN interface.
66 struct GNUNET_TUN_Layer2PacketHeader
69 * Some flags (unused).
71 uint16_t flags GNUNET_PACKED;
74 * Here we get an ETH_P_-number.
76 uint16_t proto GNUNET_PACKED;
81 * Standard IPv4 header.
83 struct GNUNET_TUN_IPv4Header
85 #if __BYTE_ORDER == __LITTLE_ENDIAN
86 unsigned int header_length:4 GNUNET_PACKED;
87 unsigned int version:4 GNUNET_PACKED;
88 #elif __BYTE_ORDER == __BIG_ENDIAN
89 unsigned int version:4 GNUNET_PACKED;
90 unsigned int header_length:4 GNUNET_PACKED;
92 #error byteorder undefined
97 * Length of the packet, including this header.
99 uint16_t total_length GNUNET_PACKED;
102 * Unique random ID for matching up fragments.
104 uint16_t identification GNUNET_PACKED;
106 unsigned int flags:3 GNUNET_PACKED;
108 unsigned int fragmentation_offset:13 GNUNET_PACKED;
111 * How many more hops can this packet be forwarded?
116 * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
123 uint16_t checksum GNUNET_PACKED;
126 * Origin of the packet.
128 struct in_addr source_address GNUNET_PACKED;
131 * Destination of the packet.
133 struct in_addr destination_address GNUNET_PACKED;
134 } GNUNET_GCC_STRUCT_LAYOUT;
138 * Standard IPv6 header.
140 struct GNUNET_TUN_IPv6Header
142 #if __BYTE_ORDER == __LITTLE_ENDIAN
143 unsigned int traffic_class_h:4 GNUNET_PACKED;
144 unsigned int version:4 GNUNET_PACKED;
145 unsigned int traffic_class_l:4 GNUNET_PACKED;
146 unsigned int flow_label:20 GNUNET_PACKED;
147 #elif __BYTE_ORDER == __BIG_ENDIAN
148 unsigned int version:4 GNUNET_PACKED;
149 unsigned int traffic_class:8 GNUNET_PACKED;
150 unsigned int flow_label:20 GNUNET_PACKED;
152 #error byteorder undefined
155 * Length of the payload, excluding this header.
157 uint16_t payload_length GNUNET_PACKED;
160 * For example, IPPROTO_UDP or IPPROTO_TCP.
165 * How many more hops can this packet be forwarded?
170 * Origin of the packet.
172 struct in6_addr source_address GNUNET_PACKED;
175 * Destination of the packet.
177 struct in6_addr destination_address GNUNET_PACKED;
178 } GNUNET_GCC_STRUCT_LAYOUT;
184 struct GNUNET_TUN_TcpHeader
186 uint16_t source_port GNUNET_PACKED;
187 uint16_t destination_port GNUNET_PACKED;
192 uint32_t seq GNUNET_PACKED;
195 * Acknowledgement number.
197 uint32_t ack GNUNET_PACKED;
198 #if __BYTE_ORDER == __LITTLE_ENDIAN
200 * Reserved. Must be zero.
202 unsigned int reserved : 4 GNUNET_PACKED;
204 * Number of 32-bit words in TCP header.
206 unsigned int off : 4 GNUNET_PACKED;
207 #elif __BYTE_ORDER == __BIG_ENDIAN
209 * Number of 32-bit words in TCP header.
211 unsigned int off : 4 GNUNET_PACKED;
213 * Reserved. Must be zero.
215 unsigned int reserved : 4 GNUNET_PACKED;
217 #error byteorder undefined
221 * Flags (SYN, FIN, ACK, etc.)
228 uint16_t window_size GNUNET_PACKED;
233 uint16_t crc GNUNET_PACKED;
238 uint16_t urgent_pointer GNUNET_PACKED;
239 } GNUNET_GCC_STRUCT_LAYOUT;
245 struct GNUNET_TUN_UdpHeader
247 uint16_t source_port GNUNET_PACKED;
248 uint16_t destination_port GNUNET_PACKED;
249 uint16_t len GNUNET_PACKED;
250 uint16_t crc GNUNET_PACKED;
257 struct GNUNET_TUN_DnsHeader
259 uint16_t id GNUNET_PACKED;
260 uint16_t flags GNUNET_PACKED;
261 uint16_t qdcount GNUNET_PACKED;
262 uint16_t ancount GNUNET_PACKED;
263 uint16_t nscount GNUNET_PACKED;
264 uint16_t arcount GNUNET_PACKED;
267 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
268 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
269 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
270 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
271 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
272 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
273 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
274 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
276 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
277 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
278 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
279 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
280 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
281 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
287 struct GNUNET_TUN_IcmpHeader {
290 uint16_t crc GNUNET_PACKED;
294 * ICMP Echo (request/reply)
297 uint16_t identifier GNUNET_PACKED;
298 uint16_t sequence_number GNUNET_PACKED;
302 * ICMP Destination Unreachable (RFC 1191)
305 uint16_t empty GNUNET_PACKED;
306 uint16_t next_hop_mtu GNUNET_PACKED;
307 /* followed by original IP header + first 8 bytes of original IP datagram */
308 } destination_unreachable;
313 struct in_addr redirect_gateway_address GNUNET_PACKED;
316 * MTU for packets that are too big (IPv6).
318 uint32_t packet_too_big_mtu GNUNET_PACKED;
325 GNUNET_NETWORK_STRUCT_END
329 * Initialize an IPv4 header.
331 * @param ip header to initialize
332 * @param protocol protocol to use (i.e. IPPROTO_UDP)
333 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
334 * @param src source IP address to use
335 * @param dst destination IP address to use
338 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
340 uint16_t payload_length,
341 const struct in_addr *src,
342 const struct in_addr *dst);
346 * Initialize an IPv6 header.
348 * @param ip header to initialize
349 * @param protocol protocol to use (i.e. IPPROTO_UDP)
350 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
351 * @param src source IP address to use
352 * @param dst destination IP address to use
355 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
357 uint16_t payload_length,
358 const struct in6_addr *src,
359 const struct in6_addr *dst);
362 * Calculate IPv4 TCP checksum.
364 * @param ip ipv4 header fully initialized
365 * @param tcp TCP header (initialized except for CRC)
366 * @param payload the TCP payload
367 * @param payload_length number of bytes of TCP payload
370 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
371 struct GNUNET_TUN_TcpHeader *tcp,
373 uint16_t payload_length);
376 * Calculate IPv6 TCP checksum.
378 * @param ip ipv6 header fully initialized
379 * @param tcp TCP header (initialized except for CRC)
380 * @param payload the TCP payload
381 * @param payload_length number of bytes of TCP payload
384 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
385 struct GNUNET_TUN_TcpHeader *tcp,
387 uint16_t payload_length);
390 * Calculate IPv4 UDP checksum.
392 * @param ip ipv4 header fully initialized
393 * @param udp UDP header (initialized except for CRC)
394 * @param payload the UDP payload
395 * @param payload_length number of bytes of UDP payload
398 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
399 struct GNUNET_TUN_UdpHeader *udp,
401 uint16_t payload_length);
405 * Calculate IPv6 UDP checksum.
407 * @param ip ipv6 header fully initialized
408 * @param udp UDP header (initialized except for CRC)
409 * @param payload the UDP payload
410 * @param payload_length number of bytes of UDP payload
413 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
414 struct GNUNET_TUN_UdpHeader *udp,
416 uint16_t payload_length);
420 * Calculate ICMP checksum.
422 * @param icmp IMCP header (initialized except for CRC)
423 * @param payload the ICMP payload
424 * @param payload_length number of bytes of ICMP payload
427 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
429 uint16_t payload_length);
433 * Create a regex in 'rxstr' from the given 'ip' and 'netmask'.
435 * @param ip IPv4 representation.
436 * @param netmask netmask for the ip.
437 * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV4_REGEXLEN
441 GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip, const char *netmask,
446 * Create a regex in 'rxstr' from the given 'ipv6' and 'prefixlen'.
448 * @param ipv6 IPv6 representation.
449 * @param prefixlen length of the ipv6 prefix.
450 * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV6_REGEXLEN
454 GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6,
455 unsigned int prefixlen, char *rxstr);
459 * Convert an exit policy to a regular expression. The exit policy
460 * specifies a set of subnets this peer is willing to serve as an
461 * exit for; the resulting regular expression will match the
462 * IPv6 address strings as returned by 'GNUNET_TUN_ipv6toregexsearch'.
464 * @param policy exit policy specification
465 * @return regular expression, NULL on error
468 GNUNET_TUN_ipv6policy2regex (const char *policy);
472 * Convert an exit policy to a regular expression. The exit policy
473 * specifies a set of subnets this peer is willing to serve as an
474 * exit for; the resulting regular expression will match the
475 * IPv4 address strings as returned by 'GNUNET_TUN_ipv4toregexsearch'.
477 * @param policy exit policy specification
478 * @return regular expression, NULL on error
481 GNUNET_TUN_ipv4policy2regex (const char *policy);