-docu
[oweals/gnunet.git] / src / include / gnunet_tun_lib.h
1 /*
2      This file is part of GNUnet.
3      (C) 2010, 2011, 2012 Christian Grothoff
4
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.
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      General Public License for more details.
14
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.
19 */
20
21 /**
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
26  */
27 #ifndef GNUNET_TUN_LIB_H
28 #define GNUNET_TUN_LIB_H
29
30 #include "gnunet_util_lib.h"
31
32
33 /* see http://www.iana.org/assignments/ethernet-numbers */
34 #ifndef ETH_P_IPV4
35 /**
36  * Number for IPv4
37  */
38 #define ETH_P_IPV4 0x0800
39 #endif
40
41 #ifndef ETH_P_IPV6
42 /**
43  * Number for IPv6
44  */
45 #define ETH_P_IPV6 0x86DD
46 #endif
47
48
49 GNUNET_NETWORK_STRUCT_BEGIN
50
51 /**
52  * Header from Linux TUN interface.
53  */ 
54 struct GNUNET_TUN_Layer2PacketHeader
55 {
56   /**
57    * Some flags (unused).
58    */ 
59   uint16_t flags GNUNET_PACKED;
60
61   /**
62    * Here we get an ETH_P_-number.
63    */
64   uint16_t proto GNUNET_PACKED;
65 };
66
67
68 /**
69  * Standard IPv4 header.
70  */
71 struct GNUNET_TUN_IPv4Header
72 {
73 #if __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
77   unsigned int version:4 GNUNET_PACKED;
78   unsigned int header_length:4 GNUNET_PACKED;
79 #endif
80   uint8_t diff_serv;
81
82   /**
83    * Length of the packet, including this header.
84    */
85   uint16_t total_length GNUNET_PACKED;
86   
87   /**
88    * Unique random ID for matching up fragments.
89    */
90   uint16_t identification GNUNET_PACKED;
91
92   unsigned int flags:3 GNUNET_PACKED;
93
94   unsigned int fragmentation_offset:13 GNUNET_PACKED;
95
96   /**
97    * How many more hops can this packet be forwarded?
98    */
99   uint8_t ttl;
100
101   /**
102    * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
103    */
104   uint8_t protocol;
105
106   /**
107    * Checksum.
108    */
109   uint16_t checksum GNUNET_PACKED;
110
111   /**
112    * Origin of the packet.
113    */ 
114   struct in_addr source_address GNUNET_PACKED;
115
116   /**
117    * Destination of the packet.
118    */ 
119   struct in_addr destination_address GNUNET_PACKED;
120 };
121
122
123 /**
124  * Standard IPv6 header.
125  */
126 struct GNUNET_TUN_IPv6Header
127 {
128 #if __BYTE_ORDER == __LITTLE_ENDIAN 
129   unsigned int traffic_class_h:4 GNUNET_PACKED;
130   unsigned int version:4 GNUNET_PACKED;
131   unsigned int traffic_class_l:4 GNUNET_PACKED;
132   unsigned int flow_label:20 GNUNET_PACKED;
133 #elif __BYTE_ORDER == __BIG_ENDIAN
134   unsigned int version:4 GNUNET_PACKED;
135   unsigned int traffic_class:8 GNUNET_PACKED;
136   unsigned int flow_label:20 GNUNET_PACKED;
137 #endif
138   /**
139    * Length of the payload, excluding this header.
140    */
141   uint16_t payload_length GNUNET_PACKED;
142
143   /**
144    * For example, IPPROTO_UDP or IPPROTO_TCP.
145    */
146   uint8_t next_header;
147
148   /**
149    * How many more hops can this packet be forwarded?
150    */
151   uint8_t hop_limit;
152
153   /**
154    * Origin of the packet.
155    */ 
156   struct in6_addr source_address GNUNET_PACKED;
157
158   /**
159    * Destination of the packet.
160    */ 
161   struct in6_addr destination_address GNUNET_PACKED;
162 };
163
164
165 /**
166  * TCP packet header.
167  */
168 struct GNUNET_TUN_TcpHeader
169 {
170   uint16_t source_port GNUNET_PACKED;
171   uint16_t destination_port GNUNET_PACKED;
172
173   /**
174    * Sequence number.
175    */
176   uint32_t seq GNUNET_PACKED;
177
178   /**
179    * Acknowledgement number.
180    */
181   uint32_t ack GNUNET_PACKED;
182 #if __BYTE_ORDER == __LITTLE_ENDIAN       
183   /**
184    * Reserved.
185    */
186   unsigned int reserved : 4 GNUNET_PACKED;
187   /**
188    * Number of 32-bit words in TCP header.
189    */
190   unsigned int off : 4 GNUNET_PACKED;
191 #elif __BYTE_ORDER == __BIG_ENDIAN
192   /**
193    * Number of 32-bit words in TCP header.
194    */
195   unsigned int off : 4 GNUNET_PACKED;
196   /**
197    * Reserved.
198    */
199   unsigned int reserved : 4 GNUNET_PACKED;
200 #endif        
201   uint8_t flags;
202
203   /**
204    * Window size.
205    */
206   uint16_t window_size GNUNET_PACKED;
207
208   /**
209    * Checksum.
210    */
211   uint16_t crc GNUNET_PACKED;
212
213   /**
214    * Urgent pointer.
215    */
216   uint16_t urgent_pointer GNUNET_PACKED;
217 };
218
219
220 /**
221  * UDP packet header.
222  */
223 struct GNUNET_TUN_UdpHeader
224 {
225   uint16_t source_port GNUNET_PACKED;
226   uint16_t destination_port GNUNET_PACKED;
227   uint16_t len GNUNET_PACKED;
228   uint16_t crc GNUNET_PACKED;
229 };
230
231
232 /**
233  * DNS header.
234  */
235 struct GNUNET_TUN_DnsHeader
236 {
237   uint16_t id GNUNET_PACKED;
238   uint16_t flags GNUNET_PACKED;
239   uint16_t qdcount GNUNET_PACKED;
240   uint16_t ancount GNUNET_PACKED;
241   uint16_t nscount GNUNET_PACKED;
242   uint16_t arcount GNUNET_PACKED;
243 };
244
245 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
246 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
247 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
248 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
249 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
250 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
251 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
252 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
253
254 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
255 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
256 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
257 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
258 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
259 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
260
261
262 /**
263  * ICMP header.
264  */
265 struct GNUNET_TUN_IcmpHeader {
266   uint8_t type;         
267   uint8_t code;          
268   uint16_t crc GNUNET_PACKED;
269
270   union {
271     /**
272      * ICMP Echo (request/reply) 
273      */
274     struct {
275       uint16_t  identifier GNUNET_PACKED;
276       uint16_t  sequence_number GNUNET_PACKED;
277     } echo;
278
279     /**
280      * ICMP Destination Unreachable (RFC 1191) 
281      */
282     struct ih_pmtu {
283       uint16_t empty GNUNET_PACKED;
284       uint16_t next_hop_mtu GNUNET_PACKED;
285       /* followed by original IP header + first 8 bytes of original IP datagram */
286     } destination_unreachable;
287
288     /**
289      * ICMP Redirect 
290      */ 
291     struct in_addr redirect_gateway_address GNUNET_PACKED;      
292
293     /**
294      * MTU for packets that are too big (IPv6).
295      */
296     uint32_t packet_too_big_mtu GNUNET_PACKED;
297
298   } quench;
299
300 };
301
302
303 GNUNET_NETWORK_STRUCT_END
304
305
306 /**
307  * Initialize an IPv4 header.
308  *
309  * @param ip header to initialize
310  * @param protocol protocol to use (i.e. IPPROTO_UDP)
311  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
312  * @param src source IP address to use
313  * @param dst destination IP address to use
314  */
315 void
316 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
317                                    uint8_t protocol,
318                                    uint16_t payload_length,
319                                    const struct in_addr *src,
320                                    const struct in_addr *dst);
321
322
323 /**
324  * Initialize an IPv6 header.
325  *
326  * @param ip header to initialize
327  * @param protocol protocol to use (i.e. IPPROTO_UDP)
328  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
329  * @param src source IP address to use
330  * @param dst destination IP address to use
331  */
332 void
333 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
334                                    uint8_t protocol,
335                                    uint16_t payload_length,
336                                    const struct in6_addr *src,
337                                    const struct in6_addr *dst);
338
339 /**
340  * Calculate IPv4 TCP checksum.
341  *
342  * @param ip ipv4 header fully initialized
343  * @param tcp TCP header (initialized except for CRC)
344  * @param payload the TCP payload
345  * @param payload_length number of bytes of TCP payload
346  */
347 void
348 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
349                                     struct GNUNET_TUN_TcpHeader *tcp,
350                                     const void *payload,
351                                     uint16_t payload_length);
352
353 /**
354  * Calculate IPv6 TCP checksum.
355  *
356  * @param ip ipv6 header fully initialized
357  * @param tcp TCP header (initialized except for CRC)
358  * @param payload the TCP payload
359  * @param payload_length number of bytes of TCP payload
360  */
361 void
362 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
363                                     struct GNUNET_TUN_TcpHeader *tcp,
364                                     const void *payload,
365                                     uint16_t payload_length);
366
367 /**
368  * Calculate IPv4 UDP checksum.
369  *
370  * @param ip ipv4 header fully initialized
371  * @param udp UDP header (initialized except for CRC)
372  * @param payload the UDP payload
373  * @param payload_length number of bytes of UDP payload
374  */
375 void
376 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
377                                     struct GNUNET_TUN_UdpHeader *udp,
378                                     const void *payload,
379                                     uint16_t payload_length);
380
381
382 /**
383  * Calculate IPv6 UDP checksum.
384  *
385  * @param ip ipv6 header fully initialized
386  * @param udp UDP header (initialized except for CRC)
387  * @param payload the UDP payload
388  * @param payload_length number of bytes of UDP payload
389  */
390 void
391 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
392                                     struct GNUNET_TUN_UdpHeader *udp,
393                                     const void *payload,
394                                     uint16_t payload_length);
395
396
397 /**
398  * Calculate ICMP checksum.
399  *
400  * @param icmp IMCP header (initialized except for CRC)
401  * @param payload the ICMP payload
402  * @param payload_length number of bytes of ICMP payload
403  */
404 void
405 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
406                                     const void *payload,
407                                     uint16_t payload_length);
408
409
410 #endif