2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 Christian Grothoff
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @author Philipp Toelke
23 * @author Christian Grothoff
26 * Standard TCP/IP network structs and IP checksum calculations for TUN
29 * @defgroup tun TUN library
30 * Standard TCP/IP network structs and IP checksum calculations for TUN
34 #ifndef GNUNET_TUN_LIB_H
35 #define GNUNET_TUN_LIB_H
37 #include "gnunet_common.h"
38 #include "gnunet_crypto_lib.h"
41 /* see http://www.iana.org/assignments/ethernet-numbers */
46 #define ETH_P_IPV4 0x0800
53 #define ETH_P_IPV6 0x86DD
58 * Maximum regex string length for use with #GNUNET_TUN_ipv4toregexsearch.
60 * 8 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-",
61 * one byte for 0-termination.
64 #define GNUNET_TUN_IPV4_REGEXLEN 16
68 * Maximum regex string length for use with #GNUNET_TUN_ipv6toregexsearch
70 * 32 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-",
71 * one byte for 0-termination.
73 #define GNUNET_TUN_IPV6_REGEXLEN 40
76 GNUNET_NETWORK_STRUCT_BEGIN
79 * Header from Linux TUN interface.
81 struct GNUNET_TUN_Layer2PacketHeader {
83 * Some flags (unused).
85 uint16_t flags GNUNET_PACKED;
88 * Here we get an ETH_P_-number.
90 uint16_t proto GNUNET_PACKED;
95 * Standard IPv4 header.
97 struct GNUNET_TUN_IPv4Header {
98 #if __BYTE_ORDER == __LITTLE_ENDIAN
99 unsigned int header_length : 4 GNUNET_PACKED;
100 unsigned int version : 4 GNUNET_PACKED;
101 #elif __BYTE_ORDER == __BIG_ENDIAN
102 unsigned int version : 4 GNUNET_PACKED;
103 unsigned int header_length : 4 GNUNET_PACKED;
105 #error byteorder undefined
110 * Length of the packet, including this header.
112 uint16_t total_length GNUNET_PACKED;
115 * Unique random ID for matching up fragments.
117 uint16_t identification GNUNET_PACKED;
119 unsigned int flags : 3 GNUNET_PACKED;
121 unsigned int fragmentation_offset : 13 GNUNET_PACKED;
124 * How many more hops can this packet be forwarded?
129 * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
136 uint16_t checksum GNUNET_PACKED;
139 * Origin of the packet.
141 struct in_addr source_address;
144 * Destination of the packet.
146 struct in_addr destination_address;
147 } GNUNET_GCC_STRUCT_LAYOUT;
151 * Standard IPv6 header.
153 struct GNUNET_TUN_IPv6Header {
154 #if __BYTE_ORDER == __LITTLE_ENDIAN
155 unsigned int traffic_class_h : 4 GNUNET_PACKED;
156 unsigned int version : 4 GNUNET_PACKED;
157 unsigned int traffic_class_l : 4 GNUNET_PACKED;
158 unsigned int flow_label : 20 GNUNET_PACKED;
159 #elif __BYTE_ORDER == __BIG_ENDIAN
160 unsigned int version : 4 GNUNET_PACKED;
161 unsigned int traffic_class : 8 GNUNET_PACKED;
162 unsigned int flow_label : 20 GNUNET_PACKED;
164 #error byteorder undefined
167 * Length of the payload, excluding this header.
169 uint16_t payload_length GNUNET_PACKED;
172 * For example, IPPROTO_UDP or IPPROTO_TCP.
177 * How many more hops can this packet be forwarded?
182 * Origin of the packet.
184 struct in6_addr source_address GNUNET_PACKED;
187 * Destination of the packet.
189 struct in6_addr destination_address GNUNET_PACKED;
190 } GNUNET_GCC_STRUCT_LAYOUT;
196 #define GNUNET_TUN_TCP_FLAGS_FIN 1
197 #define GNUNET_TUN_TCP_FLAGS_SYN 2
198 #define GNUNET_TUN_TCP_FLAGS_RST 4
199 #define GNUNET_TUN_TCP_FLAGS_PSH 8
200 #define GNUNET_TUN_TCP_FLAGS_ACK 16
201 #define GNUNET_TUN_TCP_FLAGS_URG 32
202 #define GNUNET_TUN_TCP_FLAGS_ECE 64
203 #define GNUNET_TUN_TCP_FLAGS_CWR 128
208 struct GNUNET_TUN_TcpHeader {
210 * Source port (in NBO).
212 uint16_t source_port GNUNET_PACKED;
215 * Destination port (in NBO).
217 uint16_t destination_port GNUNET_PACKED;
222 uint32_t seq GNUNET_PACKED;
225 * Acknowledgement number.
227 uint32_t ack GNUNET_PACKED;
228 #if __BYTE_ORDER == __LITTLE_ENDIAN
230 * Reserved. Must be zero.
232 unsigned int reserved : 4 GNUNET_PACKED;
234 * Number of 32-bit words in TCP header.
236 unsigned int off : 4 GNUNET_PACKED;
237 #elif __BYTE_ORDER == __BIG_ENDIAN
239 * Number of 32-bit words in TCP header.
241 unsigned int off : 4 GNUNET_PACKED;
243 * Reserved. Must be zero.
245 unsigned int reserved : 4 GNUNET_PACKED;
247 #error byteorder undefined
251 * Flags (SYN, FIN, ACK, etc.)
258 uint16_t window_size GNUNET_PACKED;
263 uint16_t crc GNUNET_PACKED;
268 uint16_t urgent_pointer GNUNET_PACKED;
269 } GNUNET_GCC_STRUCT_LAYOUT;
275 struct GNUNET_TUN_UdpHeader {
277 * Source port (in NBO).
279 uint16_t source_port GNUNET_PACKED;
282 * Destination port (in NBO).
284 uint16_t destination_port GNUNET_PACKED;
287 * Number of bytes of payload.
289 uint16_t len GNUNET_PACKED;
294 uint16_t crc GNUNET_PACKED;
299 * A few common DNS classes (ok, only one is common, but I list a
300 * couple more to make it clear what we're talking about here).
302 #define GNUNET_TUN_DNS_CLASS_INTERNET 1
303 #define GNUNET_TUN_DNS_CLASS_CHAOS 3
304 #define GNUNET_TUN_DNS_CLASS_HESIOD 4
306 #define GNUNET_TUN_DNS_OPCODE_QUERY 0
307 #define GNUNET_TUN_DNS_OPCODE_INVERSE_QUERY 1
308 #define GNUNET_TUN_DNS_OPCODE_STATUS 2
314 #define GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR 0
315 #define GNUNET_TUN_DNS_RETURN_CODE_FORMAT_ERROR 1
316 #define GNUNET_TUN_DNS_RETURN_CODE_SERVER_FAILURE 2
317 #define GNUNET_TUN_DNS_RETURN_CODE_NAME_ERROR 3
318 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_IMPLEMENTED 4
319 #define GNUNET_TUN_DNS_RETURN_CODE_REFUSED 5
324 #define GNUNET_TUN_DNS_RETURN_CODE_YXDOMAIN 6
325 #define GNUNET_TUN_DNS_RETURN_CODE_YXRRSET 7
326 #define GNUNET_TUN_DNS_RETURN_CODE_NXRRSET 8
327 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_AUTH 9
328 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_ZONE 10
332 * DNS flags (largely RFC 1035 / RFC 2136).
334 struct GNUNET_TUN_DnsFlags {
335 #if __BYTE_ORDER == __LITTLE_ENDIAN
337 * Set to 1 if recursion is desired (client -> server)
339 unsigned int recursion_desired : 1 GNUNET_PACKED;
342 * Set to 1 if message is truncated
344 unsigned int message_truncated : 1 GNUNET_PACKED;
347 * Set to 1 if this is an authoritative answer
349 unsigned int authoritative_answer : 1 GNUNET_PACKED;
352 * See GNUNET_TUN_DNS_OPCODE_ defines.
354 unsigned int opcode : 4 GNUNET_PACKED;
357 * query:0, response:1
359 unsigned int query_or_response : 1 GNUNET_PACKED;
362 * See GNUNET_TUN_DNS_RETURN_CODE_ defines.
364 unsigned int return_code : 4 GNUNET_PACKED;
369 unsigned int checking_disabled : 1 GNUNET_PACKED;
372 * Response has been cryptographically verified, RFC 4035.
374 unsigned int authenticated_data : 1 GNUNET_PACKED;
379 unsigned int zero : 1 GNUNET_PACKED;
382 * Set to 1 if recursion is available (server -> client)
384 unsigned int recursion_available : 1 GNUNET_PACKED;
385 #elif __BYTE_ORDER == __BIG_ENDIAN
387 * query:0, response:1
389 unsigned int query_or_response : 1 GNUNET_PACKED;
392 * See GNUNET_TUN_DNS_OPCODE_ defines.
394 unsigned int opcode : 4 GNUNET_PACKED;
397 * Set to 1 if this is an authoritative answer
399 unsigned int authoritative_answer : 1 GNUNET_PACKED;
402 * Set to 1 if message is truncated
404 unsigned int message_truncated : 1 GNUNET_PACKED;
407 * Set to 1 if recursion is desired (client -> server)
409 unsigned int recursion_desired : 1 GNUNET_PACKED;
413 * Set to 1 if recursion is available (server -> client)
415 unsigned int recursion_available : 1 GNUNET_PACKED;
420 unsigned int zero : 1 GNUNET_PACKED;
423 * Response has been cryptographically verified, RFC 4035.
425 unsigned int authenticated_data : 1 GNUNET_PACKED;
430 unsigned int checking_disabled : 1 GNUNET_PACKED;
433 * See GNUNET_TUN_DNS_RETURN_CODE_ defines.
435 unsigned int return_code : 4 GNUNET_PACKED;
437 #error byteorder undefined
439 } GNUNET_GCC_STRUCT_LAYOUT;
445 struct GNUNET_TUN_DnsHeader {
447 * Unique identifier for the request/response.
449 uint16_t id GNUNET_PACKED;
454 struct GNUNET_TUN_DnsFlags flags;
459 uint16_t query_count GNUNET_PACKED;
464 uint16_t answer_rcount GNUNET_PACKED;
467 * Number of authoritative answers.
469 uint16_t authority_rcount GNUNET_PACKED;
472 * Number of additional records.
474 uint16_t additional_rcount GNUNET_PACKED;
479 * Payload of DNS SOA record (header).
481 struct GNUNET_TUN_DnsSoaRecord {
483 * The version number of the original copy of the zone. (NBO)
485 uint32_t serial GNUNET_PACKED;
488 * Time interval before the zone should be refreshed. (NBO)
490 uint32_t refresh GNUNET_PACKED;
493 * Time interval that should elapse before a failed refresh should
496 uint32_t retry GNUNET_PACKED;
499 * Time value that specifies the upper limit on the time interval
500 * that can elapse before the zone is no longer authoritative. (NBO)
502 uint32_t expire GNUNET_PACKED;
505 * The bit minimum TTL field that should be exported with any RR
506 * from this zone. (NBO)
508 uint32_t minimum GNUNET_PACKED;
513 * Payload of DNS SRV record (header).
515 struct GNUNET_TUN_DnsSrvRecord {
517 * Preference for this entry (lower value is higher preference). Clients
518 * will contact hosts from the lowest-priority group first and fall back
519 * to higher priorities if the low-priority entries are unavailable. (NBO)
521 uint16_t prio GNUNET_PACKED;
524 * Relative weight for records with the same priority. Clients will use
525 * the hosts of the same (lowest) priority with a probability proportional
526 * to the weight given. (NBO)
528 uint16_t weight GNUNET_PACKED;
531 * TCP or UDP port of the service. (NBO)
533 uint16_t port GNUNET_PACKED;
535 /* followed by 'target' name */
540 * Payload of DNS CERT record.
542 struct GNUNET_TUN_DnsCertRecord {
558 /* Followed by the certificate */
563 * Payload of DNSSEC TLSA record.
564 * http://datatracker.ietf.org/doc/draft-ietf-dane-protocol/
566 struct GNUNET_TUN_DnsTlsaRecord {
572 * 3: domain-issued cert
578 * What part will be matched against the cert
579 * presented by server
580 * 0: Full cert (in binary)
581 * 1: Full cert (in DER)
586 * Matching type (of selected content)
591 uint8_t matching_type;
594 * followed by certificate association data
595 * The "certificate association data" to be matched.
596 * These bytes are either raw data (that is, the full certificate or
597 * its SubjectPublicKeyInfo, depending on the selector) for matching
598 * type 0, or the hash of the raw data for matching types 1 and 2.
599 * The data refers to the certificate in the association, not to the
600 * TLS ASN.1 Certificate object.
602 * The data is represented as a string of hex chars
608 * Payload of GNS VPN record
610 struct GNUNET_TUN_GnsVpnRecord {
612 * The peer to contact
614 struct GNUNET_PeerIdentity peer;
617 * The protocol to use
621 /* followed by the servicename */
628 struct GNUNET_TUN_DnsQueryLine {
630 * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
632 uint16_t type GNUNET_PACKED;
635 * Desired class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO)
637 uint16_t dns_traffic_class GNUNET_PACKED;
642 * General DNS record prefix.
644 struct GNUNET_TUN_DnsRecordLine {
646 * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
648 uint16_t type GNUNET_PACKED;
651 * Record class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO)
653 uint16_t dns_traffic_class GNUNET_PACKED;
656 * Expiration for the record (in seconds). (NBO)
658 uint32_t ttl GNUNET_PACKED;
661 * Number of bytes of data that follow. (NBO)
663 uint16_t data_len GNUNET_PACKED;
667 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
668 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
669 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
670 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
671 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
672 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
673 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
674 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
676 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
677 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
678 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
679 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
680 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
681 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
687 struct GNUNET_TUN_IcmpHeader {
690 uint16_t crc GNUNET_PACKED;
694 * ICMP Echo (request/reply)
697 uint16_t identifier GNUNET_PACKED;
698 uint16_t sequence_number GNUNET_PACKED;
702 * ICMP Destination Unreachable (RFC 1191)
705 uint16_t empty GNUNET_PACKED;
706 uint16_t next_hop_mtu GNUNET_PACKED;
707 /* followed by original IP header + first 8 bytes of original IP datagram
709 } destination_unreachable;
714 struct in_addr redirect_gateway_address;
717 * MTU for packets that are too big (IPv6).
719 uint32_t packet_too_big_mtu GNUNET_PACKED;
724 GNUNET_NETWORK_STRUCT_END
728 * Initialize an IPv4 header.
730 * @param ip header to initialize
731 * @param protocol protocol to use (i.e. IPPROTO_UDP)
732 * @param payload_length number of bytes of payload that follow (excluding IPv4
734 * @param src source IP address to use
735 * @param dst destination IP address to use
738 GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip,
740 uint16_t payload_length,
741 const struct in_addr *src,
742 const struct in_addr *dst);
746 * Initialize an IPv6 header.
748 * @param ip header to initialize
749 * @param protocol protocol to use (i.e. IPPROTO_UDP)
750 * @param payload_length number of bytes of payload that follow (excluding IPv4
752 * @param src source IP address to use
753 * @param dst destination IP address to use
756 GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip,
758 uint16_t payload_length,
759 const struct in6_addr *src,
760 const struct in6_addr *dst);
763 * Calculate IPv4 TCP checksum.
765 * @param ip ipv4 header fully initialized
766 * @param tcp TCP header (initialized except for CRC)
767 * @param payload the TCP payload
768 * @param payload_length number of bytes of TCP @a payload
771 GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip,
772 struct GNUNET_TUN_TcpHeader *tcp,
774 uint16_t payload_length);
777 * Calculate IPv6 TCP checksum.
779 * @param ip ipv6 header fully initialized
780 * @param tcp TCP header (initialized except for CRC)
781 * @param payload the TCP payload
782 * @param payload_length number of bytes of TCP payload
785 GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip,
786 struct GNUNET_TUN_TcpHeader *tcp,
788 uint16_t payload_length);
791 * Calculate IPv4 UDP checksum.
793 * @param ip ipv4 header fully initialized
794 * @param udp UDP header (initialized except for CRC)
795 * @param payload the UDP payload
796 * @param payload_length number of bytes of UDP @a payload
799 GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip,
800 struct GNUNET_TUN_UdpHeader *udp,
802 uint16_t payload_length);
806 * Calculate IPv6 UDP checksum.
808 * @param ip ipv6 header fully initialized
809 * @param udp UDP header (initialized except for CRC)
810 * @param payload the UDP payload
811 * @param payload_length number of bytes of @a payload
814 GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip,
815 struct GNUNET_TUN_UdpHeader *udp,
817 uint16_t payload_length);
821 * Calculate ICMP checksum.
823 * @param icmp IMCP header (initialized except for CRC)
824 * @param payload the ICMP payload
825 * @param payload_length number of bytes of @a payload
828 GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp,
830 uint16_t payload_length);
834 * Create a regex in @a rxstr from the given @a ip and @a port.
836 * @param ip IPv4 representation.
837 * @param port destination port
838 * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV4_REGEXLEN
842 GNUNET_TUN_ipv4toregexsearch(const struct in_addr *ip,
848 * Create a regex in @a rxstr from the given @a ipv6 and @a port.
850 * @param ipv6 IPv6 representation.
851 * @param port destination port
852 * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV6_REGEXLEN
856 GNUNET_TUN_ipv6toregexsearch(const struct in6_addr *ipv6,
862 * Convert an exit policy to a regular expression. The exit policy
863 * specifies a set of subnets this peer is willing to serve as an
864 * exit for; the resulting regular expression will match the
865 * IPv6 address strings as returned by #GNUNET_TUN_ipv6toregexsearch.
867 * @param policy exit policy specification
868 * @return regular expression, NULL on error
871 GNUNET_TUN_ipv6policy2regex(const char *policy);
875 * Convert an exit policy to a regular expression. The exit policy
876 * specifies a set of subnets this peer is willing to serve as an
877 * exit for; the resulting regular expression will match the
878 * IPv4 address strings as returned by #GNUNET_TUN_ipv4toregexsearch.
880 * @param policy exit policy specification
881 * @return regular expression, NULL on error
884 GNUNET_TUN_ipv4policy2regex(const char *policy);
888 * Hash the service name of a hosted service to the
889 * hash code that is used to identify the service on
892 * @param service_name a string
893 * @param[out] hc corresponding hash
896 GNUNET_TUN_service_name_to_hash(const char *service_name,
897 struct GNUNET_HashCode *hc);
901 * Check if two sockaddrs are equal.
903 * @param sa one address
904 * @param sb another address
905 * @param include_port also check ports
906 * @return #GNUNET_YES if they are equal
909 GNUNET_TUN_sockaddr_cmp(const struct sockaddr *sa,
910 const struct sockaddr *sb,
915 * Compute the CADET port given a service descriptor
916 * (returned from #GNUNET_TUN_service_name_to_hash) and
917 * a TCP/UDP port @a ip_port.
919 * @param desc service shared secret
920 * @param ip_port TCP/UDP port, use 0 for ICMP
921 * @param[out] cadet_port CADET port to use
924 GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc,
926 struct GNUNET_HashCode *cadet_port);
930 /** @} */ /* end of group */