2 This file is part of GNUnet.
3 (C) 2010-2013 Christian Grothoff
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.
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.
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.
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
27 #ifndef GNUNET_TUN_LIB_H
28 #define GNUNET_TUN_LIB_H
30 #include "gnunet_util_lib.h"
33 /* see http://www.iana.org/assignments/ethernet-numbers */
38 #define ETH_P_IPV4 0x0800
45 #define ETH_P_IPV6 0x86DD
50 * Maximum regex string length for use with GNUNET_TUN_ipv4toregexsearch
52 #define GNUNET_TUN_IPV4_REGEXLEN 32 + 6
56 * Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch
58 #define GNUNET_TUN_IPV6_REGEXLEN 128 + 6
61 GNUNET_NETWORK_STRUCT_BEGIN
64 * Header from Linux TUN interface.
66 struct GNUNET_TUN_Layer2PacketHeader
69 * Some flags (unused).
71 uint16_t flags GNUNET_PACKED;
74 * Here we get an ETH_P_-number.
76 uint16_t proto GNUNET_PACKED;
81 * Standard IPv4 header.
83 struct GNUNET_TUN_IPv4Header
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;
92 #error byteorder undefined
97 * Length of the packet, including this header.
99 uint16_t total_length GNUNET_PACKED;
102 * Unique random ID for matching up fragments.
104 uint16_t identification GNUNET_PACKED;
106 unsigned int flags:3 GNUNET_PACKED;
108 unsigned int fragmentation_offset:13 GNUNET_PACKED;
111 * How many more hops can this packet be forwarded?
116 * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
123 uint16_t checksum GNUNET_PACKED;
126 * Origin of the packet.
128 struct in_addr source_address GNUNET_PACKED;
131 * Destination of the packet.
133 struct in_addr destination_address GNUNET_PACKED;
134 } GNUNET_GCC_STRUCT_LAYOUT;
138 * Standard IPv6 header.
140 struct GNUNET_TUN_IPv6Header
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;
152 #error byteorder undefined
155 * Length of the payload, excluding this header.
157 uint16_t payload_length GNUNET_PACKED;
160 * For example, IPPROTO_UDP or IPPROTO_TCP.
165 * How many more hops can this packet be forwarded?
170 * Origin of the packet.
172 struct in6_addr source_address GNUNET_PACKED;
175 * Destination of the packet.
177 struct in6_addr destination_address GNUNET_PACKED;
178 } GNUNET_GCC_STRUCT_LAYOUT;
184 struct GNUNET_TUN_TcpHeader
187 * Source port (in NBO).
189 uint16_t source_port GNUNET_PACKED;
192 * Destination port (in NBO).
194 uint16_t destination_port GNUNET_PACKED;
199 uint32_t seq GNUNET_PACKED;
202 * Acknowledgement number.
204 uint32_t ack GNUNET_PACKED;
205 #if __BYTE_ORDER == __LITTLE_ENDIAN
207 * Reserved. Must be zero.
209 unsigned int reserved : 4 GNUNET_PACKED;
211 * Number of 32-bit words in TCP header.
213 unsigned int off : 4 GNUNET_PACKED;
214 #elif __BYTE_ORDER == __BIG_ENDIAN
216 * Number of 32-bit words in TCP header.
218 unsigned int off : 4 GNUNET_PACKED;
220 * Reserved. Must be zero.
222 unsigned int reserved : 4 GNUNET_PACKED;
224 #error byteorder undefined
228 * Flags (SYN, FIN, ACK, etc.)
235 uint16_t window_size GNUNET_PACKED;
240 uint16_t crc GNUNET_PACKED;
245 uint16_t urgent_pointer GNUNET_PACKED;
246 } GNUNET_GCC_STRUCT_LAYOUT;
252 struct GNUNET_TUN_UdpHeader
255 * Source port (in NBO).
257 uint16_t source_port GNUNET_PACKED;
260 * Destination port (in NBO).
262 uint16_t destination_port GNUNET_PACKED;
265 * Number of bytes of payload.
267 uint16_t len GNUNET_PACKED;
272 uint16_t crc GNUNET_PACKED;
278 * A few common DNS classes (ok, only one is common, but I list a
279 * couple more to make it clear what we're talking about here).
281 #define GNUNET_TUN_DNS_CLASS_INTERNET 1
282 #define GNUNET_TUN_DNS_CLASS_CHAOS 3
283 #define GNUNET_TUN_DNS_CLASS_HESIOD 4
285 #define GNUNET_TUN_DNS_OPCODE_QUERY 0
286 #define GNUNET_TUN_DNS_OPCODE_INVERSE_QUERY 1
287 #define GNUNET_TUN_DNS_OPCODE_STATUS 2
293 #define GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR 0
294 #define GNUNET_TUN_DNS_RETURN_CODE_FORMAT_ERROR 1
295 #define GNUNET_TUN_DNS_RETURN_CODE_SERVER_FAILURE 2
296 #define GNUNET_TUN_DNS_RETURN_CODE_NAME_ERROR 3
297 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_IMPLEMENTED 4
298 #define GNUNET_TUN_DNS_RETURN_CODE_REFUSED 5
303 #define GNUNET_TUN_DNS_RETURN_CODE_YXDOMAIN 6
304 #define GNUNET_TUN_DNS_RETURN_CODE_YXRRSET 7
305 #define GNUNET_TUN_DNS_RETURN_CODE_NXRRSET 8
306 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_AUTH 9
307 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_ZONE 10
311 * DNS flags (largely RFC 1035 / RFC 2136).
313 struct GNUNET_TUN_DnsFlags
315 #if __BYTE_ORDER == __LITTLE_ENDIAN
317 * Set to 1 if recursion is desired (client -> server)
319 unsigned int recursion_desired : 1 GNUNET_PACKED;
322 * Set to 1 if message is truncated
324 unsigned int message_truncated : 1 GNUNET_PACKED;
327 * Set to 1 if this is an authoritative answer
329 unsigned int authoritative_answer : 1 GNUNET_PACKED;
332 * See GNUNET_TUN_DNS_OPCODE_ defines.
334 unsigned int opcode : 4 GNUNET_PACKED;
337 * query:0, response:1
339 unsigned int query_or_response : 1 GNUNET_PACKED;
342 * See GNUNET_TUN_DNS_RETURN_CODE_ defines.
344 unsigned int return_code : 4 GNUNET_PACKED;
349 unsigned int checking_disabled : 1 GNUNET_PACKED;
352 * Response has been cryptographically verified, RFC 4035.
354 unsigned int authenticated_data : 1 GNUNET_PACKED;
359 unsigned int zero : 1 GNUNET_PACKED;
362 * Set to 1 if recursion is available (server -> client)
364 unsigned int recursion_available : 1 GNUNET_PACKED;
365 #elif __BYTE_ORDER == __BIG_ENDIAN
368 * query:0, response:1
370 unsigned int query_or_response : 1 GNUNET_PACKED;
373 * See GNUNET_TUN_DNS_OPCODE_ defines.
375 unsigned int opcode : 4 GNUNET_PACKED;
378 * Set to 1 if this is an authoritative answer
380 unsigned int authoritative_answer : 1 GNUNET_PACKED;
383 * Set to 1 if message is truncated
385 unsigned int message_truncated : 1 GNUNET_PACKED;
388 * Set to 1 if recursion is desired (client -> server)
390 unsigned int recursion_desired : 1 GNUNET_PACKED;
394 * Set to 1 if recursion is available (server -> client)
396 unsigned int recursion_available : 1 GNUNET_PACKED;
401 unsigned int zero : 1 GNUNET_PACKED;
404 * Response has been cryptographically verified, RFC 4035.
406 unsigned int authenticated_data : 1 GNUNET_PACKED;
411 unsigned int checking_disabled : 1 GNUNET_PACKED;
414 * See GNUNET_TUN_DNS_RETURN_CODE_ defines.
416 unsigned int return_code : 4 GNUNET_PACKED;
418 #error byteorder undefined
421 } GNUNET_GCC_STRUCT_LAYOUT;
428 struct GNUNET_TUN_DnsHeader
431 * Unique identifier for the request/response.
433 uint16_t id GNUNET_PACKED;
438 struct GNUNET_TUN_DnsFlags flags;
443 uint16_t query_count GNUNET_PACKED;
448 uint16_t answer_rcount GNUNET_PACKED;
451 * Number of authoritative answers.
453 uint16_t authority_rcount GNUNET_PACKED;
456 * Number of additional records.
458 uint16_t additional_rcount GNUNET_PACKED;
463 * Payload of DNS SOA record (header).
465 struct GNUNET_TUN_DnsSoaRecord
468 * The version number of the original copy of the zone. (NBO)
470 uint32_t serial GNUNET_PACKED;
473 * Time interval before the zone should be refreshed. (NBO)
475 uint32_t refresh GNUNET_PACKED;
478 * Time interval that should elapse before a failed refresh should
481 uint32_t retry GNUNET_PACKED;
484 * Time value that specifies the upper limit on the time interval
485 * that can elapse before the zone is no longer authoritative. (NBO)
487 uint32_t expire GNUNET_PACKED;
490 * The bit minimum TTL field that should be exported with any RR
491 * from this zone. (NBO)
493 uint32_t minimum GNUNET_PACKED;
498 * Payload of DNS SRV record (header).
500 struct GNUNET_TUN_DnsSrvRecord
504 * Preference for this entry (lower value is higher preference). Clients
505 * will contact hosts from the lowest-priority group first and fall back
506 * to higher priorities if the low-priority entries are unavailable. (NBO)
508 uint16_t prio GNUNET_PACKED;
511 * Relative weight for records with the same priority. Clients will use
512 * the hosts of the same (lowest) priority with a probability proportional
513 * to the weight given. (NBO)
515 uint16_t weight GNUNET_PACKED;
518 * TCP or UDP port of the service. (NBO)
520 uint16_t port GNUNET_PACKED;
522 /* followed by 'target' name */
527 * Payload of DNSSEC TLSA record.
528 * http://datatracker.ietf.org/doc/draft-ietf-dane-protocol/
530 struct GNUNET_TUN_DnsTlsaRecord
538 * 3: domain-issued cert
544 * What part will be matched against the cert
545 * presented by server
546 * 0: Full cert (in binary)
547 * 1: Full cert (in DER)
552 * Matching type (of selected content)
557 uint8_t matching_type;
560 * followed by certificate association data
561 * The "certificate association data" to be matched.
562 * These bytes are either raw data (that is, the full certificate or
563 * its SubjectPublicKeyInfo, depending on the selector) for matching
564 * type 0, or the hash of the raw data for matching types 1 and 2.
565 * The data refers to the certificate in the association, not to the
566 * TLS ASN.1 Certificate object.
568 * The data is represented as a string of hex chars
574 * Payload of GNS VPN record
576 struct GNUNET_TUN_GnsVpnRecord
579 * The peer to contact
581 struct GNUNET_PeerIdentity peer;
584 * The protocol to use
588 /* followed by the servicename */
594 struct GNUNET_TUN_DnsQueryLine
597 * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
599 uint16_t type GNUNET_PACKED;
602 * Desired class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO)
604 uint16_t class GNUNET_PACKED;
609 * General DNS record prefix.
611 struct GNUNET_TUN_DnsRecordLine
614 * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
616 uint16_t type GNUNET_PACKED;
619 * Record class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO)
621 uint16_t class GNUNET_PACKED;
624 * Expiration for the record (in seconds). (NBO)
626 uint32_t ttl GNUNET_PACKED;
629 * Number of bytes of data that follow. (NBO)
631 uint16_t data_len GNUNET_PACKED;
635 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
636 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
637 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
638 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
639 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
640 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
641 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
642 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
644 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
645 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
646 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
647 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
648 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
649 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
655 struct GNUNET_TUN_IcmpHeader {
658 uint16_t crc GNUNET_PACKED;
662 * ICMP Echo (request/reply)
665 uint16_t identifier GNUNET_PACKED;
666 uint16_t sequence_number GNUNET_PACKED;
670 * ICMP Destination Unreachable (RFC 1191)
673 uint16_t empty GNUNET_PACKED;
674 uint16_t next_hop_mtu GNUNET_PACKED;
675 /* followed by original IP header + first 8 bytes of original IP datagram */
676 } destination_unreachable;
681 struct in_addr redirect_gateway_address GNUNET_PACKED;
684 * MTU for packets that are too big (IPv6).
686 uint32_t packet_too_big_mtu GNUNET_PACKED;
693 GNUNET_NETWORK_STRUCT_END
697 * Initialize an IPv4 header.
699 * @param ip header to initialize
700 * @param protocol protocol to use (i.e. IPPROTO_UDP)
701 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
702 * @param src source IP address to use
703 * @param dst destination IP address to use
706 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
708 uint16_t payload_length,
709 const struct in_addr *src,
710 const struct in_addr *dst);
714 * Initialize an IPv6 header.
716 * @param ip header to initialize
717 * @param protocol protocol to use (i.e. IPPROTO_UDP)
718 * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
719 * @param src source IP address to use
720 * @param dst destination IP address to use
723 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
725 uint16_t payload_length,
726 const struct in6_addr *src,
727 const struct in6_addr *dst);
730 * Calculate IPv4 TCP checksum.
732 * @param ip ipv4 header fully initialized
733 * @param tcp TCP header (initialized except for CRC)
734 * @param payload the TCP payload
735 * @param payload_length number of bytes of TCP @a payload
738 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
739 struct GNUNET_TUN_TcpHeader *tcp,
741 uint16_t payload_length);
744 * Calculate IPv6 TCP checksum.
746 * @param ip ipv6 header fully initialized
747 * @param tcp TCP header (initialized except for CRC)
748 * @param payload the TCP payload
749 * @param payload_length number of bytes of TCP payload
752 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
753 struct GNUNET_TUN_TcpHeader *tcp,
755 uint16_t payload_length);
758 * Calculate IPv4 UDP checksum.
760 * @param ip ipv4 header fully initialized
761 * @param udp UDP header (initialized except for CRC)
762 * @param payload the UDP payload
763 * @param payload_length number of bytes of UDP @a payload
766 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
767 struct GNUNET_TUN_UdpHeader *udp,
769 uint16_t payload_length);
773 * Calculate IPv6 UDP checksum.
775 * @param ip ipv6 header fully initialized
776 * @param udp UDP header (initialized except for CRC)
777 * @param payload the UDP payload
778 * @param payload_length number of bytes of UDP payload
781 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
782 struct GNUNET_TUN_UdpHeader *udp,
784 uint16_t payload_length);
788 * Calculate ICMP checksum.
790 * @param icmp IMCP header (initialized except for CRC)
791 * @param payload the ICMP payload
792 * @param payload_length number of bytes of ICMP payload
795 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
797 uint16_t payload_length);
801 * Create a regex in @a rxstr from the given @a ip and @a netmask.
803 * @param ip IPv4 representation.
804 * @param netmask netmask for the ip.
805 * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV4_REGEXLEN
809 GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip, const char *netmask,
814 * Create a regex in @a rxstr from the given @a ipv6 and @a prefixlen.
816 * @param ipv6 IPv6 representation.
817 * @param prefixlen length of the ipv6 prefix.
818 * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV6_REGEXLEN
822 GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6,
823 unsigned int prefixlen, char *rxstr);
827 * Convert an exit policy to a regular expression. The exit policy
828 * specifies a set of subnets this peer is willing to serve as an
829 * exit for; the resulting regular expression will match the
830 * IPv6 address strings as returned by #GNUNET_TUN_ipv6toregexsearch.
832 * @param policy exit policy specification
833 * @return regular expression, NULL on error
836 GNUNET_TUN_ipv6policy2regex (const char *policy);
840 * Convert an exit policy to a regular expression. The exit policy
841 * specifies a set of subnets this peer is willing to serve as an
842 * exit for; the resulting regular expression will match the
843 * IPv4 address strings as returned by #GNUNET_TUN_ipv4toregexsearch.
845 * @param policy exit policy specification
846 * @return regular expression, NULL on error
849 GNUNET_TUN_ipv4policy2regex (const char *policy);