-keep split
[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_h:4 GNUNET_PACKED;
136   unsigned int traffic_class_l:4 GNUNET_PACKED;
137   unsigned int flow_label:20 GNUNET_PACKED;
138 #endif
139   /**
140    * Length of the payload, excluding this header.
141    */
142   uint16_t payload_length GNUNET_PACKED;
143
144   /**
145    * For example, IPPROTO_UDP or IPPROTO_TCP.
146    */
147   uint8_t next_header;
148
149   /**
150    * How many more hops can this packet be forwarded?
151    */
152   uint8_t hop_limit;
153
154   /**
155    * Origin of the packet.
156    */ 
157   struct in6_addr source_address GNUNET_PACKED;
158
159   /**
160    * Destination of the packet.
161    */ 
162   struct in6_addr destination_address GNUNET_PACKED;
163 };
164
165
166 /**
167  * TCP packet header.
168  */
169 struct GNUNET_TUN_TcpHeader
170 {
171   uint16_t source_port GNUNET_PACKED;
172   uint16_t destination_port GNUNET_PACKED;
173
174   /**
175    * Sequence number.
176    */
177   uint32_t seq GNUNET_PACKED;
178
179   /**
180    * Acknowledgement number.
181    */
182   uint32_t ack GNUNET_PACKED;
183 #if __BYTE_ORDER == __LITTLE_ENDIAN       
184   /**
185    * Reserved.
186    */
187   unsigned int reserved : 4 GNUNET_PACKED;
188   /**
189    * Number of 32-bit words in TCP header.
190    */
191   unsigned int off : 4 GNUNET_PACKED;
192 #elif __BYTE_ORDER == __BIG_ENDIAN
193   /**
194    * Number of 32-bit words in TCP header.
195    */
196   unsigned int off : 4 GNUNET_PACKED;
197   /**
198    * Reserved.
199    */
200   unsigned int reserved : 4 GNUNET_PACKED;
201 #endif        
202   uint8_t flags;
203
204   /**
205    * Window size.
206    */
207   uint16_t window_size GNUNET_PACKED;
208
209   /**
210    * Checksum.
211    */
212   uint16_t crc GNUNET_PACKED;
213
214   /**
215    * Urgent pointer.
216    */
217   uint16_t urgent_pointer GNUNET_PACKED;
218 };
219
220
221 /**
222  * UDP packet header.
223  */
224 struct GNUNET_TUN_UdpHeader
225 {
226   uint16_t source_port GNUNET_PACKED;
227   uint16_t destination_port GNUNET_PACKED;
228   uint16_t len GNUNET_PACKED;
229   uint16_t crc GNUNET_PACKED;
230 };
231
232
233 /**
234  * DNS header.
235  */
236 struct GNUNET_TUN_DnsHeader
237 {
238   uint16_t id GNUNET_PACKED;
239   uint16_t flags GNUNET_PACKED;
240   uint16_t qdcount GNUNET_PACKED;
241   uint16_t ancount GNUNET_PACKED;
242   uint16_t nscount GNUNET_PACKED;
243   uint16_t arcount GNUNET_PACKED;
244 };
245
246 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
247 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
248 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
249 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
250 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
251 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
252 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
253 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
254
255 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
256 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
257 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
258 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
259 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
260 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
261
262
263 /**
264  * ICMP header.
265  */
266 struct GNUNET_TUN_IcmpHeader {
267   uint8_t type;         
268   uint8_t code;          
269   uint16_t crc GNUNET_PACKED;
270
271   union {
272     /**
273      * ICMP Echo (request/reply) 
274      */
275     struct {
276       uint16_t  identifier GNUNET_PACKED;
277       uint16_t  sequence_number GNUNET_PACKED;
278     } echo;
279
280     /**
281      * ICMP Destination Unreachable (RFC 1191) 
282      */
283     struct ih_pmtu {
284       uint16_t empty GNUNET_PACKED;
285       uint16_t next_hop_mtu GNUNET_PACKED;
286       /* followed by original IP header + first 8 bytes of original IP datagram */
287     } destination_unreachable;
288
289     /**
290      * ICMP Redirect 
291      */ 
292     struct in_addr redirect_gateway_address GNUNET_PACKED;      
293
294     /**
295      * MTU for packets that are too big (IPv6).
296      */
297     uint32_t packet_too_big_mtu GNUNET_PACKED;
298
299   } quench;
300
301 };
302
303
304 GNUNET_NETWORK_STRUCT_END
305
306
307 /**
308  * Initialize an IPv4 header.
309  *
310  * @param ip header to initialize
311  * @param protocol protocol to use (i.e. IPPROTO_UDP)
312  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
313  * @param src source IP address to use
314  * @param dst destination IP address to use
315  */
316 void
317 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
318                                    uint8_t protocol,
319                                    uint16_t payload_length,
320                                    const struct in_addr *src,
321                                    const struct in_addr *dst);
322
323
324 /**
325  * Initialize an IPv6 header.
326  *
327  * @param ip header to initialize
328  * @param protocol protocol to use (i.e. IPPROTO_UDP)
329  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
330  * @param src source IP address to use
331  * @param dst destination IP address to use
332  */
333 void
334 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
335                                    uint8_t protocol,
336                                    uint16_t payload_length,
337                                    const struct in6_addr *src,
338                                    const struct in6_addr *dst);
339
340 /**
341  * Calculate IPv4 TCP checksum.
342  *
343  * @param ip ipv4 header fully initialized
344  * @param tcp TCP header (initialized except for CRC)
345  * @param payload the TCP payload
346  * @param payload_length number of bytes of TCP payload
347  */
348 void
349 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
350                                     struct GNUNET_TUN_TcpHeader *tcp,
351                                     const void *payload,
352                                     uint16_t payload_length);
353
354 /**
355  * Calculate IPv6 TCP checksum.
356  *
357  * @param ip ipv6 header fully initialized
358  * @param tcp TCP header (initialized except for CRC)
359  * @param payload the TCP payload
360  * @param payload_length number of bytes of TCP payload
361  */
362 void
363 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
364                                     struct GNUNET_TUN_TcpHeader *tcp,
365                                     const void *payload,
366                                     uint16_t payload_length);
367
368 /**
369  * Calculate IPv4 UDP checksum.
370  *
371  * @param ip ipv4 header fully initialized
372  * @param udp UDP header (initialized except for CRC)
373  * @param payload the UDP payload
374  * @param payload_length number of bytes of UDP payload
375  */
376 void
377 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
378                                     struct GNUNET_TUN_UdpHeader *udp,
379                                     const void *payload,
380                                     uint16_t payload_length);
381
382
383 /**
384  * Calculate IPv6 UDP checksum.
385  *
386  * @param ip ipv6 header fully initialized
387  * @param udp UDP header (initialized except for CRC)
388  * @param payload the UDP payload
389  * @param payload_length number of bytes of UDP payload
390  */
391 void
392 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
393                                     struct GNUNET_TUN_UdpHeader *udp,
394                                     const void *payload,
395                                     uint16_t payload_length);
396
397
398 /**
399  * Calculate ICMP checksum.
400  *
401  * @param icmp IMCP header (initialized except for CRC)
402  * @param payload the ICMP payload
403  * @param payload_length number of bytes of ICMP payload
404  */
405 void
406 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
407                                     const void *payload,
408                                     uint16_t payload_length);
409
410
411 #endif