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