1b0bb716dab8393f781b5e8359b78c7104ca2d37
[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 /**
50  * Maximum regex string length for use with GNUNET_TUN_ipv4toregexsearch
51  */
52 #define GNUNET_TUN_IPV4_REGEXLEN 32 + 6
53
54
55 /**
56  * Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch
57  */
58 #define GNUNET_TUN_IPV6_REGEXLEN 128 + 6
59
60
61 GNUNET_NETWORK_STRUCT_BEGIN
62
63 /**
64  * Header from Linux TUN interface.
65  */ 
66 struct GNUNET_TUN_Layer2PacketHeader
67 {
68   /**
69    * Some flags (unused).
70    */ 
71   uint16_t flags GNUNET_PACKED;
72
73   /**
74    * Here we get an ETH_P_-number.
75    */
76   uint16_t proto GNUNET_PACKED;
77 };
78
79
80 /**
81  * Standard IPv4 header.
82  */
83 struct GNUNET_TUN_IPv4Header
84 {
85 #if __BYTE_ORDER == __LITTLE_ENDIAN
86   unsigned int header_length:4 GNUNET_PACKED;
87   unsigned int version:4 GNUNET_PACKED;
88 #elif __BYTE_ORDER == __BIG_ENDIAN
89   unsigned int version:4 GNUNET_PACKED;
90   unsigned int header_length:4 GNUNET_PACKED;
91 #else
92   #error byteorder undefined
93 #endif
94   uint8_t diff_serv;
95
96   /**
97    * Length of the packet, including this header.
98    */
99   uint16_t total_length GNUNET_PACKED;
100   
101   /**
102    * Unique random ID for matching up fragments.
103    */
104   uint16_t identification GNUNET_PACKED;
105
106   unsigned int flags:3 GNUNET_PACKED;
107
108   unsigned int fragmentation_offset:13 GNUNET_PACKED;
109
110   /**
111    * How many more hops can this packet be forwarded?
112    */
113   uint8_t ttl;
114
115   /**
116    * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
117    */
118   uint8_t protocol;
119
120   /**
121    * Checksum.
122    */
123   uint16_t checksum GNUNET_PACKED;
124
125   /**
126    * Origin of the packet.
127    */ 
128   struct in_addr source_address GNUNET_PACKED;
129
130   /**
131    * Destination of the packet.
132    */ 
133   struct in_addr destination_address GNUNET_PACKED;
134 } GNUNET_GCC_STRUCT_LAYOUT;
135
136
137 /**
138  * Standard IPv6 header.
139  */
140 struct GNUNET_TUN_IPv6Header
141 {
142 #if __BYTE_ORDER == __LITTLE_ENDIAN
143   unsigned int traffic_class_h:4 GNUNET_PACKED;
144   unsigned int version:4 GNUNET_PACKED;
145   unsigned int traffic_class_l:4 GNUNET_PACKED;
146   unsigned int flow_label:20 GNUNET_PACKED;
147 #elif __BYTE_ORDER == __BIG_ENDIAN
148   unsigned int version:4 GNUNET_PACKED;
149   unsigned int traffic_class:8 GNUNET_PACKED;
150   unsigned int flow_label:20 GNUNET_PACKED;
151 #else
152   #error byteorder undefined
153 #endif
154   /**
155    * Length of the payload, excluding this header.
156    */
157   uint16_t payload_length GNUNET_PACKED;
158
159   /**
160    * For example, IPPROTO_UDP or IPPROTO_TCP.
161    */
162   uint8_t next_header;
163
164   /**
165    * How many more hops can this packet be forwarded?
166    */
167   uint8_t hop_limit;
168
169   /**
170    * Origin of the packet.
171    */ 
172   struct in6_addr source_address GNUNET_PACKED;
173
174   /**
175    * Destination of the packet.
176    */ 
177   struct in6_addr destination_address GNUNET_PACKED;
178 } GNUNET_GCC_STRUCT_LAYOUT;
179
180
181 /**
182  * TCP packet header.
183  */
184 struct GNUNET_TUN_TcpHeader
185 {
186   uint16_t source_port GNUNET_PACKED;
187   uint16_t destination_port GNUNET_PACKED;
188
189   /**
190    * Sequence number.
191    */
192   uint32_t seq GNUNET_PACKED;
193
194   /**
195    * Acknowledgement number.
196    */
197   uint32_t ack GNUNET_PACKED;
198 #if __BYTE_ORDER == __LITTLE_ENDIAN
199   /**
200    * Reserved.  Must be zero.
201    */
202   unsigned int reserved : 4 GNUNET_PACKED;
203   /**
204    * Number of 32-bit words in TCP header.
205    */
206   unsigned int off : 4 GNUNET_PACKED;
207 #elif __BYTE_ORDER == __BIG_ENDIAN
208   /**
209    * Number of 32-bit words in TCP header.
210    */
211   unsigned int off : 4 GNUNET_PACKED;
212   /**
213    * Reserved.  Must be zero.
214    */
215   unsigned int reserved : 4 GNUNET_PACKED;
216 #else
217   #error byteorder undefined
218 #endif        
219
220   /**
221    * Flags (SYN, FIN, ACK, etc.)
222    */
223   uint8_t flags;
224
225   /**
226    * Window size.
227    */
228   uint16_t window_size GNUNET_PACKED;
229
230   /**
231    * Checksum.
232    */
233   uint16_t crc GNUNET_PACKED;
234
235   /**
236    * Urgent pointer.
237    */
238   uint16_t urgent_pointer GNUNET_PACKED;
239 } GNUNET_GCC_STRUCT_LAYOUT;
240
241
242 /**
243  * UDP packet header.
244  */
245 struct GNUNET_TUN_UdpHeader
246 {
247   uint16_t source_port GNUNET_PACKED;
248   uint16_t destination_port GNUNET_PACKED;
249   uint16_t len GNUNET_PACKED;
250   uint16_t crc GNUNET_PACKED;
251 };
252
253
254 /**
255  * DNS header.
256  */
257 struct GNUNET_TUN_DnsHeader
258 {
259   uint16_t id GNUNET_PACKED;
260   uint16_t flags GNUNET_PACKED;
261   uint16_t qdcount GNUNET_PACKED;
262   uint16_t ancount GNUNET_PACKED;
263   uint16_t nscount GNUNET_PACKED;
264   uint16_t arcount GNUNET_PACKED;
265 };
266
267 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
268 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
269 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
270 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
271 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
272 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
273 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
274 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
275
276 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
277 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
278 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
279 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
280 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
281 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
282
283
284 /**
285  * ICMP header.
286  */
287 struct GNUNET_TUN_IcmpHeader {
288   uint8_t type;         
289   uint8_t code;          
290   uint16_t crc GNUNET_PACKED;
291
292   union {
293     /**
294      * ICMP Echo (request/reply) 
295      */
296     struct {
297       uint16_t  identifier GNUNET_PACKED;
298       uint16_t  sequence_number GNUNET_PACKED;
299     } echo;
300
301     /**
302      * ICMP Destination Unreachable (RFC 1191) 
303      */
304     struct ih_pmtu {
305       uint16_t empty GNUNET_PACKED;
306       uint16_t next_hop_mtu GNUNET_PACKED;
307       /* followed by original IP header + first 8 bytes of original IP datagram */
308     } destination_unreachable;
309
310     /**
311      * ICMP Redirect 
312      */ 
313     struct in_addr redirect_gateway_address GNUNET_PACKED;      
314
315     /**
316      * MTU for packets that are too big (IPv6).
317      */
318     uint32_t packet_too_big_mtu GNUNET_PACKED;
319
320   } quench;
321
322 };
323
324
325 GNUNET_NETWORK_STRUCT_END
326
327
328 /**
329  * Initialize an IPv4 header.
330  *
331  * @param ip header to initialize
332  * @param protocol protocol to use (i.e. IPPROTO_UDP)
333  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
334  * @param src source IP address to use
335  * @param dst destination IP address to use
336  */
337 void
338 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
339                                    uint8_t protocol,
340                                    uint16_t payload_length,
341                                    const struct in_addr *src,
342                                    const struct in_addr *dst);
343
344
345 /**
346  * Initialize an IPv6 header.
347  *
348  * @param ip header to initialize
349  * @param protocol protocol to use (i.e. IPPROTO_UDP)
350  * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
351  * @param src source IP address to use
352  * @param dst destination IP address to use
353  */
354 void
355 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
356                                    uint8_t protocol,
357                                    uint16_t payload_length,
358                                    const struct in6_addr *src,
359                                    const struct in6_addr *dst);
360
361 /**
362  * Calculate IPv4 TCP checksum.
363  *
364  * @param ip ipv4 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_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
371                                     struct GNUNET_TUN_TcpHeader *tcp,
372                                     const void *payload,
373                                     uint16_t payload_length);
374
375 /**
376  * Calculate IPv6 TCP checksum.
377  *
378  * @param ip ipv6 header fully initialized
379  * @param tcp TCP header (initialized except for CRC)
380  * @param payload the TCP payload
381  * @param payload_length number of bytes of TCP payload
382  */
383 void
384 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
385                                     struct GNUNET_TUN_TcpHeader *tcp,
386                                     const void *payload,
387                                     uint16_t payload_length);
388
389 /**
390  * Calculate IPv4 UDP checksum.
391  *
392  * @param ip ipv4 header fully initialized
393  * @param udp UDP header (initialized except for CRC)
394  * @param payload the UDP payload
395  * @param payload_length number of bytes of UDP payload
396  */
397 void
398 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
399                                     struct GNUNET_TUN_UdpHeader *udp,
400                                     const void *payload,
401                                     uint16_t payload_length);
402
403
404 /**
405  * Calculate IPv6 UDP checksum.
406  *
407  * @param ip ipv6 header fully initialized
408  * @param udp UDP header (initialized except for CRC)
409  * @param payload the UDP payload
410  * @param payload_length number of bytes of UDP payload
411  */
412 void
413 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
414                                     struct GNUNET_TUN_UdpHeader *udp,
415                                     const void *payload,
416                                     uint16_t payload_length);
417
418
419 /**
420  * Calculate ICMP checksum.
421  *
422  * @param icmp IMCP header (initialized except for CRC)
423  * @param payload the ICMP payload
424  * @param payload_length number of bytes of ICMP payload
425  */
426 void
427 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
428                                     const void *payload,
429                                     uint16_t payload_length);
430
431
432 /**
433  * Create a regex in 'rxstr' from the given 'ip' and 'netmask'.
434  *
435  * @param ip IPv4 representation.
436  * @param netmask netmask for the ip.
437  * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV4_REGEXLEN
438  *              bytes long.
439  */
440 void
441 GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip, const char *netmask,
442                         char *rxstr);
443
444
445 /**
446  * Create a regex in 'rxstr' from the given 'ipv6' and 'prefixlen'.
447  *
448  * @param ipv6 IPv6 representation.
449  * @param prefixlen length of the ipv6 prefix.
450  * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV6_REGEXLEN
451  *              bytes long.
452  */
453 void
454 GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6,
455                         unsigned int prefixlen, char *rxstr);
456
457
458 /**
459  * Convert an exit policy to a regular expression.  The exit policy
460  * specifies a set of subnets this peer is willing to serve as an
461  * exit for; the resulting regular expression will match the
462  * IPv6 address strings as returned by 'GNUNET_TUN_ipv6toregexsearch'.
463  *
464  * @param policy exit policy specification
465  * @return regular expression, NULL on error
466  */
467 char *
468 GNUNET_TUN_ipv6policy2regex (const char *policy);
469
470
471 /**
472  * Convert an exit policy to a regular expression.  The exit policy
473  * specifies a set of subnets this peer is willing to serve as an
474  * exit for; the resulting regular expression will match the
475  * IPv4 address strings as returned by 'GNUNET_TUN_ipv4toregexsearch'.
476  *
477  * @param policy exit policy specification
478  * @return regular expression, NULL on error
479  */
480 char *
481 GNUNET_TUN_ipv4policy2regex (const char *policy);
482
483
484 #endif