5bac236d97c8ca446abbc40062b1941325baeb67
[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.  Must be zero.
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.  Must be zero.
198    */
199   unsigned int reserved : 4 GNUNET_PACKED;
200 #endif        
201
202   /**
203    * Flags (SYN, FIN, ACK, etc.)
204    */
205   uint8_t flags;
206
207   /**
208    * Window size.
209    */
210   uint16_t window_size GNUNET_PACKED;
211
212   /**
213    * Checksum.
214    */
215   uint16_t crc GNUNET_PACKED;
216
217   /**
218    * Urgent pointer.
219    */
220   uint16_t urgent_pointer GNUNET_PACKED;
221 };
222
223
224 /**
225  * UDP packet header.
226  */
227 struct GNUNET_TUN_UdpHeader
228 {
229   uint16_t source_port GNUNET_PACKED;
230   uint16_t destination_port GNUNET_PACKED;
231   uint16_t len GNUNET_PACKED;
232   uint16_t crc GNUNET_PACKED;
233 };
234
235
236 /**
237  * DNS header.
238  */
239 struct GNUNET_TUN_DnsHeader
240 {
241   uint16_t id GNUNET_PACKED;
242   uint16_t flags GNUNET_PACKED;
243   uint16_t qdcount GNUNET_PACKED;
244   uint16_t ancount GNUNET_PACKED;
245   uint16_t nscount GNUNET_PACKED;
246   uint16_t arcount GNUNET_PACKED;
247 };
248
249 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
250 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
251 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
252 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
253 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
254 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
255 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
256 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
257
258 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
259 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
260 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
261 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
262 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
263 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
264
265
266 /**
267  * ICMP header.
268  */
269 struct GNUNET_TUN_IcmpHeader {
270   uint8_t type;         
271   uint8_t code;          
272   uint16_t crc GNUNET_PACKED;
273
274   union {
275     /**
276      * ICMP Echo (request/reply) 
277      */
278     struct {
279       uint16_t  identifier GNUNET_PACKED;
280       uint16_t  sequence_number GNUNET_PACKED;
281     } echo;
282
283     /**
284      * ICMP Destination Unreachable (RFC 1191) 
285      */
286     struct ih_pmtu {
287       uint16_t empty GNUNET_PACKED;
288       uint16_t next_hop_mtu GNUNET_PACKED;
289       /* followed by original IP header + first 8 bytes of original IP datagram */
290     } destination_unreachable;
291
292     /**
293      * ICMP Redirect 
294      */ 
295     struct in_addr redirect_gateway_address GNUNET_PACKED;      
296
297     /**
298      * MTU for packets that are too big (IPv6).
299      */
300     uint32_t packet_too_big_mtu GNUNET_PACKED;
301
302   } quench;
303
304 };
305
306
307 GNUNET_NETWORK_STRUCT_END
308
309
310 /**
311  * Initialize an IPv4 header.
312  *
313  * @param ip header to initialize
314  * @param protocol protocol to use (i.e. IPPROTO_UDP)
315  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
316  * @param src source IP address to use
317  * @param dst destination IP address to use
318  */
319 void
320 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
321                                    uint8_t protocol,
322                                    uint16_t payload_length,
323                                    const struct in_addr *src,
324                                    const struct in_addr *dst);
325
326
327 /**
328  * Initialize an IPv6 header.
329  *
330  * @param ip header to initialize
331  * @param protocol protocol to use (i.e. IPPROTO_UDP)
332  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
333  * @param src source IP address to use
334  * @param dst destination IP address to use
335  */
336 void
337 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
338                                    uint8_t protocol,
339                                    uint16_t payload_length,
340                                    const struct in6_addr *src,
341                                    const struct in6_addr *dst);
342
343 /**
344  * Calculate IPv4 TCP checksum.
345  *
346  * @param ip ipv4 header fully initialized
347  * @param tcp TCP header (initialized except for CRC)
348  * @param payload the TCP payload
349  * @param payload_length number of bytes of TCP payload
350  */
351 void
352 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
353                                     struct GNUNET_TUN_TcpHeader *tcp,
354                                     const void *payload,
355                                     uint16_t payload_length);
356
357 /**
358  * Calculate IPv6 TCP checksum.
359  *
360  * @param ip ipv6 header fully initialized
361  * @param tcp TCP header (initialized except for CRC)
362  * @param payload the TCP payload
363  * @param payload_length number of bytes of TCP payload
364  */
365 void
366 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
367                                     struct GNUNET_TUN_TcpHeader *tcp,
368                                     const void *payload,
369                                     uint16_t payload_length);
370
371 /**
372  * Calculate IPv4 UDP checksum.
373  *
374  * @param ip ipv4 header fully initialized
375  * @param udp UDP header (initialized except for CRC)
376  * @param payload the UDP payload
377  * @param payload_length number of bytes of UDP payload
378  */
379 void
380 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
381                                     struct GNUNET_TUN_UdpHeader *udp,
382                                     const void *payload,
383                                     uint16_t payload_length);
384
385
386 /**
387  * Calculate IPv6 UDP checksum.
388  *
389  * @param ip ipv6 header fully initialized
390  * @param udp UDP header (initialized except for CRC)
391  * @param payload the UDP payload
392  * @param payload_length number of bytes of UDP payload
393  */
394 void
395 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
396                                     struct GNUNET_TUN_UdpHeader *udp,
397                                     const void *payload,
398                                     uint16_t payload_length);
399
400
401 /**
402  * Calculate ICMP checksum.
403  *
404  * @param icmp IMCP header (initialized except for CRC)
405  * @param payload the ICMP payload
406  * @param payload_length number of bytes of ICMP payload
407  */
408 void
409 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
410                                     const void *payload,
411                                     uint16_t payload_length);
412
413
414 #endif