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
84 * Some flags (unused).
86 uint16_t flags GNUNET_PACKED;
89 * Here we get an ETH_P_-number.
91 uint16_t proto GNUNET_PACKED;
96 * Standard IPv4 header.
98 struct GNUNET_TUN_IPv4Header
100 #if __BYTE_ORDER == __LITTLE_ENDIAN
101 unsigned int header_length : 4 GNUNET_PACKED;
102 unsigned int version : 4 GNUNET_PACKED;
103 #elif __BYTE_ORDER == __BIG_ENDIAN
104 unsigned int version : 4 GNUNET_PACKED;
105 unsigned int header_length : 4 GNUNET_PACKED;
107 #error byteorder undefined
112 * Length of the packet, including this header.
114 uint16_t total_length GNUNET_PACKED;
117 * Unique random ID for matching up fragments.
119 uint16_t identification GNUNET_PACKED;
121 unsigned int flags : 3 GNUNET_PACKED;
123 unsigned int fragmentation_offset : 13 GNUNET_PACKED;
126 * How many more hops can this packet be forwarded?
131 * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
138 uint16_t checksum GNUNET_PACKED;
141 * Origin of the packet.
143 struct in_addr source_address;
146 * Destination of the packet.
148 struct in_addr destination_address;
149 } GNUNET_GCC_STRUCT_LAYOUT;
153 * Standard IPv6 header.
155 struct GNUNET_TUN_IPv6Header
157 #if __BYTE_ORDER == __LITTLE_ENDIAN
158 unsigned int traffic_class_h : 4 GNUNET_PACKED;
159 unsigned int version : 4 GNUNET_PACKED;
160 unsigned int traffic_class_l : 4 GNUNET_PACKED;
161 unsigned int flow_label : 20 GNUNET_PACKED;
162 #elif __BYTE_ORDER == __BIG_ENDIAN
163 unsigned int version : 4 GNUNET_PACKED;
164 unsigned int traffic_class : 8 GNUNET_PACKED;
165 unsigned int flow_label : 20 GNUNET_PACKED;
167 #error byteorder undefined
170 * Length of the payload, excluding this header.
172 uint16_t payload_length GNUNET_PACKED;
175 * For example, IPPROTO_UDP or IPPROTO_TCP.
180 * How many more hops can this packet be forwarded?
185 * Origin of the packet.
187 struct in6_addr source_address GNUNET_PACKED;
190 * Destination of the packet.
192 struct in6_addr destination_address GNUNET_PACKED;
193 } GNUNET_GCC_STRUCT_LAYOUT;
199 #define GNUNET_TUN_TCP_FLAGS_FIN 1
200 #define GNUNET_TUN_TCP_FLAGS_SYN 2
201 #define GNUNET_TUN_TCP_FLAGS_RST 4
202 #define GNUNET_TUN_TCP_FLAGS_PSH 8
203 #define GNUNET_TUN_TCP_FLAGS_ACK 16
204 #define GNUNET_TUN_TCP_FLAGS_URG 32
205 #define GNUNET_TUN_TCP_FLAGS_ECE 64
206 #define GNUNET_TUN_TCP_FLAGS_CWR 128
211 struct GNUNET_TUN_TcpHeader
214 * Source port (in NBO).
216 uint16_t source_port GNUNET_PACKED;
219 * Destination port (in NBO).
221 uint16_t destination_port GNUNET_PACKED;
226 uint32_t seq GNUNET_PACKED;
229 * Acknowledgement number.
231 uint32_t ack GNUNET_PACKED;
232 #if __BYTE_ORDER == __LITTLE_ENDIAN
234 * Reserved. Must be zero.
236 unsigned int reserved : 4 GNUNET_PACKED;
238 * Number of 32-bit words in TCP header.
240 unsigned int off : 4 GNUNET_PACKED;
241 #elif __BYTE_ORDER == __BIG_ENDIAN
243 * Number of 32-bit words in TCP header.
245 unsigned int off : 4 GNUNET_PACKED;
247 * Reserved. Must be zero.
249 unsigned int reserved : 4 GNUNET_PACKED;
251 #error byteorder undefined
255 * Flags (SYN, FIN, ACK, etc.)
262 uint16_t window_size GNUNET_PACKED;
267 uint16_t crc GNUNET_PACKED;
272 uint16_t urgent_pointer GNUNET_PACKED;
273 } GNUNET_GCC_STRUCT_LAYOUT;
279 struct GNUNET_TUN_UdpHeader
282 * Source port (in NBO).
284 uint16_t source_port GNUNET_PACKED;
287 * Destination port (in NBO).
289 uint16_t destination_port GNUNET_PACKED;
292 * Number of bytes of payload.
294 uint16_t len GNUNET_PACKED;
299 uint16_t crc GNUNET_PACKED;
304 * A few common DNS classes (ok, only one is common, but I list a
305 * couple more to make it clear what we're talking about here).
307 #define GNUNET_TUN_DNS_CLASS_INTERNET 1
308 #define GNUNET_TUN_DNS_CLASS_CHAOS 3
309 #define GNUNET_TUN_DNS_CLASS_HESIOD 4
311 #define GNUNET_TUN_DNS_OPCODE_QUERY 0
312 #define GNUNET_TUN_DNS_OPCODE_INVERSE_QUERY 1
313 #define GNUNET_TUN_DNS_OPCODE_STATUS 2
319 #define GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR 0
320 #define GNUNET_TUN_DNS_RETURN_CODE_FORMAT_ERROR 1
321 #define GNUNET_TUN_DNS_RETURN_CODE_SERVER_FAILURE 2
322 #define GNUNET_TUN_DNS_RETURN_CODE_NAME_ERROR 3
323 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_IMPLEMENTED 4
324 #define GNUNET_TUN_DNS_RETURN_CODE_REFUSED 5
329 #define GNUNET_TUN_DNS_RETURN_CODE_YXDOMAIN 6
330 #define GNUNET_TUN_DNS_RETURN_CODE_YXRRSET 7
331 #define GNUNET_TUN_DNS_RETURN_CODE_NXRRSET 8
332 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_AUTH 9
333 #define GNUNET_TUN_DNS_RETURN_CODE_NOT_ZONE 10
337 * DNS flags (largely RFC 1035 / RFC 2136).
339 struct GNUNET_TUN_DnsFlags
341 #if __BYTE_ORDER == __LITTLE_ENDIAN
343 * Set to 1 if recursion is desired (client -> server)
345 unsigned int recursion_desired : 1 GNUNET_PACKED;
348 * Set to 1 if message is truncated
350 unsigned int message_truncated : 1 GNUNET_PACKED;
353 * Set to 1 if this is an authoritative answer
355 unsigned int authoritative_answer : 1 GNUNET_PACKED;
358 * See GNUNET_TUN_DNS_OPCODE_ defines.
360 unsigned int opcode : 4 GNUNET_PACKED;
363 * query:0, response:1
365 unsigned int query_or_response : 1 GNUNET_PACKED;
368 * See GNUNET_TUN_DNS_RETURN_CODE_ defines.
370 unsigned int return_code : 4 GNUNET_PACKED;
375 unsigned int checking_disabled : 1 GNUNET_PACKED;
378 * Response has been cryptographically verified, RFC 4035.
380 unsigned int authenticated_data : 1 GNUNET_PACKED;
385 unsigned int zero : 1 GNUNET_PACKED;
388 * Set to 1 if recursion is available (server -> client)
390 unsigned int recursion_available : 1 GNUNET_PACKED;
391 #elif __BYTE_ORDER == __BIG_ENDIAN
394 * query:0, response:1
396 unsigned int query_or_response : 1 GNUNET_PACKED;
399 * See GNUNET_TUN_DNS_OPCODE_ defines.
401 unsigned int opcode : 4 GNUNET_PACKED;
404 * Set to 1 if this is an authoritative answer
406 unsigned int authoritative_answer : 1 GNUNET_PACKED;
409 * Set to 1 if message is truncated
411 unsigned int message_truncated : 1 GNUNET_PACKED;
414 * Set to 1 if recursion is desired (client -> server)
416 unsigned int recursion_desired : 1 GNUNET_PACKED;
420 * Set to 1 if recursion is available (server -> client)
422 unsigned int recursion_available : 1 GNUNET_PACKED;
427 unsigned int zero : 1 GNUNET_PACKED;
430 * Response has been cryptographically verified, RFC 4035.
432 unsigned int authenticated_data : 1 GNUNET_PACKED;
437 unsigned int checking_disabled : 1 GNUNET_PACKED;
440 * See GNUNET_TUN_DNS_RETURN_CODE_ defines.
442 unsigned int return_code : 4 GNUNET_PACKED;
444 #error byteorder undefined
447 } GNUNET_GCC_STRUCT_LAYOUT;
453 struct GNUNET_TUN_DnsHeader
456 * Unique identifier for the request/response.
458 uint16_t id GNUNET_PACKED;
463 struct GNUNET_TUN_DnsFlags flags;
468 uint16_t query_count GNUNET_PACKED;
473 uint16_t answer_rcount GNUNET_PACKED;
476 * Number of authoritative answers.
478 uint16_t authority_rcount GNUNET_PACKED;
481 * Number of additional records.
483 uint16_t additional_rcount GNUNET_PACKED;
488 * Payload of DNS SOA record (header).
490 struct GNUNET_TUN_DnsSoaRecord
493 * The version number of the original copy of the zone. (NBO)
495 uint32_t serial GNUNET_PACKED;
498 * Time interval before the zone should be refreshed. (NBO)
500 uint32_t refresh GNUNET_PACKED;
503 * Time interval that should elapse before a failed refresh should
506 uint32_t retry GNUNET_PACKED;
509 * Time value that specifies the upper limit on the time interval
510 * that can elapse before the zone is no longer authoritative. (NBO)
512 uint32_t expire GNUNET_PACKED;
515 * The bit minimum TTL field that should be exported with any RR
516 * from this zone. (NBO)
518 uint32_t minimum GNUNET_PACKED;
523 * Payload of DNS SRV record (header).
525 struct GNUNET_TUN_DnsSrvRecord
529 * Preference for this entry (lower value is higher preference). Clients
530 * will contact hosts from the lowest-priority group first and fall back
531 * to higher priorities if the low-priority entries are unavailable. (NBO)
533 uint16_t prio GNUNET_PACKED;
536 * Relative weight for records with the same priority. Clients will use
537 * the hosts of the same (lowest) priority with a probability proportional
538 * to the weight given. (NBO)
540 uint16_t weight GNUNET_PACKED;
543 * TCP or UDP port of the service. (NBO)
545 uint16_t port GNUNET_PACKED;
547 /* followed by 'target' name */
552 * Payload of DNS CERT record.
554 struct GNUNET_TUN_DnsCertRecord
572 /* Followed by the certificate */
577 * Payload of DNSSEC TLSA record.
578 * http://datatracker.ietf.org/doc/draft-ietf-dane-protocol/
580 struct GNUNET_TUN_DnsTlsaRecord
588 * 3: domain-issued cert
594 * What part will be matched against the cert
595 * presented by server
596 * 0: Full cert (in binary)
597 * 1: Full cert (in DER)
602 * Matching type (of selected content)
607 uint8_t matching_type;
610 * followed by certificate association data
611 * The "certificate association data" to be matched.
612 * These bytes are either raw data (that is, the full certificate or
613 * its SubjectPublicKeyInfo, depending on the selector) for matching
614 * type 0, or the hash of the raw data for matching types 1 and 2.
615 * The data refers to the certificate in the association, not to the
616 * TLS ASN.1 Certificate object.
618 * The data is represented as a string of hex chars
624 * Payload of GNS VPN record
626 struct GNUNET_TUN_GnsVpnRecord
629 * The peer to contact
631 struct GNUNET_PeerIdentity peer;
634 * The protocol to use
638 /* followed by the servicename */
645 struct GNUNET_TUN_DnsQueryLine
648 * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
650 uint16_t type GNUNET_PACKED;
653 * Desired class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO)
655 uint16_t dns_traffic_class GNUNET_PACKED;
660 * General DNS record prefix.
662 struct GNUNET_TUN_DnsRecordLine
665 * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
667 uint16_t type GNUNET_PACKED;
670 * Record class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO)
672 uint16_t dns_traffic_class GNUNET_PACKED;
675 * Expiration for the record (in seconds). (NBO)
677 uint32_t ttl GNUNET_PACKED;
680 * Number of bytes of data that follow. (NBO)
682 uint16_t data_len GNUNET_PACKED;
686 #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0
687 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3
688 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4
689 #define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5
690 #define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8
691 #define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9
692 #define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10
693 #define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11
695 #define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1
696 #define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2
697 #define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3
698 #define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4
699 #define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128
700 #define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129
706 struct GNUNET_TUN_IcmpHeader
710 uint16_t crc GNUNET_PACKED;
715 * ICMP Echo (request/reply)
719 uint16_t identifier GNUNET_PACKED;
720 uint16_t sequence_number GNUNET_PACKED;
724 * ICMP Destination Unreachable (RFC 1191)
728 uint16_t empty GNUNET_PACKED;
729 uint16_t next_hop_mtu GNUNET_PACKED;
730 /* followed by original IP header + first 8 bytes of original IP datagram
732 } destination_unreachable;
737 struct in_addr redirect_gateway_address;
740 * MTU for packets that are too big (IPv6).
742 uint32_t packet_too_big_mtu GNUNET_PACKED;
748 GNUNET_NETWORK_STRUCT_END
752 * Initialize an IPv4 header.
754 * @param ip header to initialize
755 * @param protocol protocol to use (i.e. IPPROTO_UDP)
756 * @param payload_length number of bytes of payload that follow (excluding IPv4
758 * @param src source IP address to use
759 * @param dst destination IP address to use
762 GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
764 uint16_t payload_length,
765 const struct in_addr *src,
766 const struct in_addr *dst);
770 * Initialize an IPv6 header.
772 * @param ip header to initialize
773 * @param protocol protocol to use (i.e. IPPROTO_UDP)
774 * @param payload_length number of bytes of payload that follow (excluding IPv4
776 * @param src source IP address to use
777 * @param dst destination IP address to use
780 GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
782 uint16_t payload_length,
783 const struct in6_addr *src,
784 const struct in6_addr *dst);
787 * Calculate IPv4 TCP checksum.
789 * @param ip ipv4 header fully initialized
790 * @param tcp TCP header (initialized except for CRC)
791 * @param payload the TCP payload
792 * @param payload_length number of bytes of TCP @a payload
795 GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
796 struct GNUNET_TUN_TcpHeader *tcp,
798 uint16_t payload_length);
801 * Calculate IPv6 TCP checksum.
803 * @param ip ipv6 header fully initialized
804 * @param tcp TCP header (initialized except for CRC)
805 * @param payload the TCP payload
806 * @param payload_length number of bytes of TCP payload
809 GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
810 struct GNUNET_TUN_TcpHeader *tcp,
812 uint16_t payload_length);
815 * Calculate IPv4 UDP checksum.
817 * @param ip ipv4 header fully initialized
818 * @param udp UDP header (initialized except for CRC)
819 * @param payload the UDP payload
820 * @param payload_length number of bytes of UDP @a payload
823 GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
824 struct GNUNET_TUN_UdpHeader *udp,
826 uint16_t payload_length);
830 * Calculate IPv6 UDP checksum.
832 * @param ip ipv6 header fully initialized
833 * @param udp UDP header (initialized except for CRC)
834 * @param payload the UDP payload
835 * @param payload_length number of bytes of @a payload
838 GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
839 struct GNUNET_TUN_UdpHeader *udp,
841 uint16_t payload_length);
845 * Calculate ICMP checksum.
847 * @param icmp IMCP header (initialized except for CRC)
848 * @param payload the ICMP payload
849 * @param payload_length number of bytes of @a payload
852 GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
854 uint16_t payload_length);
858 * Create a regex in @a rxstr from the given @a ip and @a port.
860 * @param ip IPv4 representation.
861 * @param port destination port
862 * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV4_REGEXLEN
866 GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip,
872 * Create a regex in @a rxstr from the given @a ipv6 and @a port.
874 * @param ipv6 IPv6 representation.
875 * @param port destination port
876 * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV6_REGEXLEN
880 GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6,
886 * Convert an exit policy to a regular expression. The exit policy
887 * specifies a set of subnets this peer is willing to serve as an
888 * exit for; the resulting regular expression will match the
889 * IPv6 address strings as returned by #GNUNET_TUN_ipv6toregexsearch.
891 * @param policy exit policy specification
892 * @return regular expression, NULL on error
895 GNUNET_TUN_ipv6policy2regex (const char *policy);
899 * Convert an exit policy to a regular expression. The exit policy
900 * specifies a set of subnets this peer is willing to serve as an
901 * exit for; the resulting regular expression will match the
902 * IPv4 address strings as returned by #GNUNET_TUN_ipv4toregexsearch.
904 * @param policy exit policy specification
905 * @return regular expression, NULL on error
908 GNUNET_TUN_ipv4policy2regex (const char *policy);
912 * Hash the service name of a hosted service to the
913 * hash code that is used to identify the service on
916 * @param service_name a string
917 * @param[out] hc corresponding hash
920 GNUNET_TUN_service_name_to_hash (const char *service_name,
921 struct GNUNET_HashCode *hc);
925 * Check if two sockaddrs are equal.
927 * @param sa one address
928 * @param sb another address
929 * @param include_port also check ports
930 * @return #GNUNET_YES if they are equal
933 GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
934 const struct sockaddr *sb,
939 * Compute the CADET port given a service descriptor
940 * (returned from #GNUNET_TUN_service_name_to_hash) and
941 * a TCP/UDP port @a ip_port.
943 * @param desc service shared secret
944 * @param ip_port TCP/UDP port, use 0 for ICMP
945 * @param[out] cadet_port CADET port to use
948 GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc,
950 struct GNUNET_HashCode *cadet_port);
954 /** @} */ /* end of group */