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
49 GNUNET_NETWORK_STRUCT_BEGIN
52 * Header from Linux TUN interface.
54 struct GNUNET_TUN_Layer2PacketHeader
57 * Some flags (unused).
59 uint16_t flags GNUNET_PACKED;
62 * Here we get an ETH_P_-number.
64 uint16_t proto GNUNET_PACKED;
69 * Standard IPv4 header.
71 struct GNUNET_TUN_IPv4Header
73 #if __BYTE_ORDER == __LITTLE_ENDIAN || _BYTE_ORDER == _LITTLE_ENDIAN
74 unsigned int header_length:4 GNUNET_PACKED;
75 unsigned int version:4 GNUNET_PACKED;
76 #elif __BYTE_ORDER == __BIG_ENDIAN || _BYTE_ORDER == _BIG_ENDIAN
77 unsigned int version:4 GNUNET_PACKED;
78 unsigned int header_length:4 GNUNET_PACKED;
80 #error byteorder undefined
85 * Length of the packet, including this header.
87 uint16_t total_length GNUNET_PACKED;
90 * Unique random ID for matching up fragments.
92 uint16_t identification GNUNET_PACKED;
94 unsigned int flags:3 GNUNET_PACKED;
96 unsigned int fragmentation_offset:13 GNUNET_PACKED;
99 * How many more hops can this packet be forwarded?
104 * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
111 uint16_t checksum GNUNET_PACKED;
114 * Origin of the packet.
116 struct in_addr source_address GNUNET_PACKED;
119 * Destination of the packet.
121 struct in_addr destination_address GNUNET_PACKED;
126 * Standard IPv6 header.
128 struct GNUNET_TUN_IPv6Header
130 #if __BYTE_ORDER == __LITTLE_ENDIAN || _BYTE_ORDER == _LITTLE_ENDIAN
131 unsigned int traffic_class_h:4 GNUNET_PACKED;
132 unsigned int version:4 GNUNET_PACKED;
133 unsigned int traffic_class_l:4 GNUNET_PACKED;
134 unsigned int flow_label:20 GNUNET_PACKED;
135 #elif __BYTE_ORDER == __BIG_ENDIAN || _BYTE_ORDER == _BIG_ENDIAN
136 unsigned int version:4 GNUNET_PACKED;
137 unsigned int traffic_class:8 GNUNET_PACKED;
138 unsigned int flow_label:20 GNUNET_PACKED;
140 #error byteorder undefined
143 * Length of the payload, excluding this header.
145 uint16_t payload_length GNUNET_PACKED;
148 * For example, IPPROTO_UDP or IPPROTO_TCP.
153 * How many more hops can this packet be forwarded?
158 * Origin of the packet.
160 struct in6_addr source_address GNUNET_PACKED;
163 * Destination of the packet.
165 struct in6_addr destination_address GNUNET_PACKED;
172 struct GNUNET_TUN_TcpHeader
174 uint16_t source_port GNUNET_PACKED;
175 uint16_t destination_port GNUNET_PACKED;
180 uint32_t seq GNUNET_PACKED;
183 * Acknowledgement number.
185 uint32_t ack GNUNET_PACKED;
186 #if __BYTE_ORDER == __LITTLE_ENDIAN || _BYTE_ORDER == _LITTLE_ENDIAN
188 * Reserved. Must be zero.
190 unsigned int reserved : 4 GNUNET_PACKED;
192 * Number of 32-bit words in TCP header.
194 unsigned int off : 4 GNUNET_PACKED;
195 #elif __BYTE_ORDER == __BIG_ENDIAN || _BYTE_ORDER == _BIG_ENDIAN
197 * Number of 32-bit words in TCP header.
199 unsigned int off : 4 GNUNET_PACKED;
201 * Reserved. Must be zero.
203 unsigned int reserved : 4 GNUNET_PACKED;
205 #error byteorder undefined
209 * Flags (SYN, FIN, ACK, etc.)
216 uint16_t window_size GNUNET_PACKED;
221 uint16_t crc GNUNET_PACKED;
226 uint16_t urgent_pointer GNUNET_PACKED;
233 struct GNUNET_TUN_UdpHeader
235 uint16_t source_port GNUNET_PACKED;
236 uint16_t destination_port GNUNET_PACKED;
237 uint16_t len GNUNET_PACKED;
238 uint16_t crc GNUNET_PACKED;
245 struct GNUNET_TUN_DnsHeader
247 uint16_t id GNUNET_PACKED;
248 uint16_t flags GNUNET_PACKED;
249 uint16_t qdcount GNUNET_PACKED;
250 uint16_t ancount GNUNET_PACKED;
251 uint16_t nscount GNUNET_PACKED;
252 uint16_t arcount GNUNET_PACKED;
255 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
256 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
257 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
258 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
259 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
260 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
261 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
262 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
264 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
265 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
266 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
267 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
268 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
269 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
275 struct GNUNET_TUN_IcmpHeader {
278 uint16_t crc GNUNET_PACKED;
282 * ICMP Echo (request/reply)
285 uint16_t identifier GNUNET_PACKED;
286 uint16_t sequence_number GNUNET_PACKED;
290 * ICMP Destination Unreachable (RFC 1191)
293 uint16_t empty GNUNET_PACKED;
294 uint16_t next_hop_mtu GNUNET_PACKED;
295 /* followed by original IP header + first 8 bytes of original IP datagram */
296 } destination_unreachable;
301 struct in_addr redirect_gateway_address GNUNET_PACKED;
304 * MTU for packets that are too big (IPv6).
306 uint32_t packet_too_big_mtu GNUNET_PACKED;
313 GNUNET_NETWORK_STRUCT_END
317 * Initialize an IPv4 header.
319 * @param ip header to initialize
320 * @param protocol protocol to use (i.e. IPPROTO_UDP)
321 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
322 * @param src source IP address to use
323 * @param dst destination IP address to use
326 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
328 uint16_t payload_length,
329 const struct in_addr *src,
330 const struct in_addr *dst);
334 * Initialize an IPv6 header.
336 * @param ip header to initialize
337 * @param protocol protocol to use (i.e. IPPROTO_UDP)
338 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
339 * @param src source IP address to use
340 * @param dst destination IP address to use
343 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
345 uint16_t payload_length,
346 const struct in6_addr *src,
347 const struct in6_addr *dst);
350 * Calculate IPv4 TCP checksum.
352 * @param ip ipv4 header fully initialized
353 * @param tcp TCP header (initialized except for CRC)
354 * @param payload the TCP payload
355 * @param payload_length number of bytes of TCP payload
358 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
359 struct GNUNET_TUN_TcpHeader *tcp,
361 uint16_t payload_length);
364 * Calculate IPv6 TCP checksum.
366 * @param ip ipv6 header fully initialized
367 * @param tcp TCP header (initialized except for CRC)
368 * @param payload the TCP payload
369 * @param payload_length number of bytes of TCP payload
372 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
373 struct GNUNET_TUN_TcpHeader *tcp,
375 uint16_t payload_length);
378 * Calculate IPv4 UDP checksum.
380 * @param ip ipv4 header fully initialized
381 * @param udp UDP header (initialized except for CRC)
382 * @param payload the UDP payload
383 * @param payload_length number of bytes of UDP payload
386 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
387 struct GNUNET_TUN_UdpHeader *udp,
389 uint16_t payload_length);
393 * Calculate IPv6 UDP checksum.
395 * @param ip ipv6 header fully initialized
396 * @param udp UDP header (initialized except for CRC)
397 * @param payload the UDP payload
398 * @param payload_length number of bytes of UDP payload
401 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
402 struct GNUNET_TUN_UdpHeader *udp,
404 uint16_t payload_length);
408 * Calculate ICMP checksum.
410 * @param icmp IMCP header (initialized except for CRC)
411 * @param payload the ICMP payload
412 * @param payload_length number of bytes of ICMP payload
415 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
417 uint16_t payload_length);