X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Finclude%2Fgnunet_tun_lib.h;h=11c43e8b74b80b6ad21461d4f5c94b31c18e2e7a;hb=6e626937fd5133188d2bd06f280a1b889219eef2;hp=33938354b3f2c74656b9903cbf3d810e42e57a02;hpb=14dc5d7546f1588caeee4af92fcad2e435008ee4;p=oweals%2Fgnunet.git diff --git a/src/include/gnunet_tun_lib.h b/src/include/gnunet_tun_lib.h index 33938354b..11c43e8b7 100644 --- a/src/include/gnunet_tun_lib.h +++ b/src/include/gnunet_tun_lib.h @@ -1,33 +1,39 @@ /* This file is part of GNUnet. - (C) 2010, 2011, 2012 Christian Grothoff + Copyright (C) 2010-2013 Christian Grothoff - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + SPDX-License-Identifier: AGPL3.0-or-later */ /** - * @file include/gnunet_tun_lib.h - * @brief standard TCP/IP network structs and IP checksum calculations for TUN interaction * @author Philipp Toelke * @author Christian Grothoff + * + * @file + * Standard TCP/IP network structs and IP checksum calculations for TUN interaction + * + * @defgroup tun TUN library + * Standard TCP/IP network structs and IP checksum calculations for TUN interaction + * @{ */ #ifndef GNUNET_TUN_LIB_H #define GNUNET_TUN_LIB_H -#include "gnunet_util_lib.h" +#include "gnunet_common.h" +#include "gnunet_crypto_lib.h" /* see http://www.iana.org/assignments/ethernet-numbers */ @@ -46,16 +52,35 @@ #endif +/** + * Maximum regex string length for use with #GNUNET_TUN_ipv4toregexsearch. + * + * 8 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-", + * one byte for 0-termination. + */ + +#define GNUNET_TUN_IPV4_REGEXLEN 16 + + +/** + * Maximum regex string length for use with #GNUNET_TUN_ipv6toregexsearch + * + * 32 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-", + * one byte for 0-termination. + */ +#define GNUNET_TUN_IPV6_REGEXLEN 40 + + GNUNET_NETWORK_STRUCT_BEGIN /** * Header from Linux TUN interface. - */ + */ struct GNUNET_TUN_Layer2PacketHeader { /** * Some flags (unused). - */ + */ uint16_t flags GNUNET_PACKED; /** @@ -70,10 +95,10 @@ struct GNUNET_TUN_Layer2PacketHeader */ struct GNUNET_TUN_IPv4Header { -#if __BYTE_ORDER == __LITTLE_ENDIAN || _BYTE_ORDER == _LITTLE_ENDIAN +#if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int header_length:4 GNUNET_PACKED; unsigned int version:4 GNUNET_PACKED; -#elif __BYTE_ORDER == __BIG_ENDIAN || _BYTE_ORDER == _BIG_ENDIAN +#elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4 GNUNET_PACKED; unsigned int header_length:4 GNUNET_PACKED; #else @@ -85,7 +110,7 @@ struct GNUNET_TUN_IPv4Header * Length of the packet, including this header. */ uint16_t total_length GNUNET_PACKED; - + /** * Unique random ID for matching up fragments. */ @@ -112,14 +137,14 @@ struct GNUNET_TUN_IPv4Header /** * Origin of the packet. - */ + */ struct in_addr source_address GNUNET_PACKED; /** * Destination of the packet. - */ + */ struct in_addr destination_address GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; /** @@ -127,12 +152,12 @@ struct GNUNET_TUN_IPv4Header */ struct GNUNET_TUN_IPv6Header { -#if __BYTE_ORDER == __LITTLE_ENDIAN || _BYTE_ORDER == _LITTLE_ENDIAN +#if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int traffic_class_h:4 GNUNET_PACKED; unsigned int version:4 GNUNET_PACKED; unsigned int traffic_class_l:4 GNUNET_PACKED; unsigned int flow_label:20 GNUNET_PACKED; -#elif __BYTE_ORDER == __BIG_ENDIAN || _BYTE_ORDER == _BIG_ENDIAN +#elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4 GNUNET_PACKED; unsigned int traffic_class:8 GNUNET_PACKED; unsigned int flow_label:20 GNUNET_PACKED; @@ -156,22 +181,41 @@ struct GNUNET_TUN_IPv6Header /** * Origin of the packet. - */ + */ struct in6_addr source_address GNUNET_PACKED; /** * Destination of the packet. - */ + */ struct in6_addr destination_address GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; +/** + * TCP flags. + */ +#define GNUNET_TUN_TCP_FLAGS_FIN 1 +#define GNUNET_TUN_TCP_FLAGS_SYN 2 +#define GNUNET_TUN_TCP_FLAGS_RST 4 +#define GNUNET_TUN_TCP_FLAGS_PSH 8 +#define GNUNET_TUN_TCP_FLAGS_ACK 16 +#define GNUNET_TUN_TCP_FLAGS_URG 32 +#define GNUNET_TUN_TCP_FLAGS_ECE 64 +#define GNUNET_TUN_TCP_FLAGS_CWR 128 + /** * TCP packet header. */ struct GNUNET_TUN_TcpHeader { + /** + * Source port (in NBO). + */ uint16_t source_port GNUNET_PACKED; + + /** + * Destination port (in NBO). + */ uint16_t destination_port GNUNET_PACKED; /** @@ -183,7 +227,7 @@ struct GNUNET_TUN_TcpHeader * Acknowledgement number. */ uint32_t ack GNUNET_PACKED; -#if __BYTE_ORDER == __LITTLE_ENDIAN || _BYTE_ORDER == _LITTLE_ENDIAN +#if __BYTE_ORDER == __LITTLE_ENDIAN /** * Reserved. Must be zero. */ @@ -192,7 +236,7 @@ struct GNUNET_TUN_TcpHeader * Number of 32-bit words in TCP header. */ unsigned int off : 4 GNUNET_PACKED; -#elif __BYTE_ORDER == __BIG_ENDIAN || _BYTE_ORDER == _BIG_ENDIAN +#elif __BYTE_ORDER == __BIG_ENDIAN /** * Number of 32-bit words in TCP header. */ @@ -203,7 +247,7 @@ struct GNUNET_TUN_TcpHeader unsigned int reserved : 4 GNUNET_PACKED; #else #error byteorder undefined -#endif +#endif /** * Flags (SYN, FIN, ACK, etc.) @@ -224,7 +268,7 @@ struct GNUNET_TUN_TcpHeader * Urgent pointer. */ uint16_t urgent_pointer GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; /** @@ -232,26 +276,413 @@ struct GNUNET_TUN_TcpHeader */ struct GNUNET_TUN_UdpHeader { + /** + * Source port (in NBO). + */ uint16_t source_port GNUNET_PACKED; + + /** + * Destination port (in NBO). + */ uint16_t destination_port GNUNET_PACKED; + + /** + * Number of bytes of payload. + */ uint16_t len GNUNET_PACKED; + + /** + * Checksum. + */ uint16_t crc GNUNET_PACKED; }; + +/** + * A few common DNS classes (ok, only one is common, but I list a + * couple more to make it clear what we're talking about here). + */ +#define GNUNET_TUN_DNS_CLASS_INTERNET 1 +#define GNUNET_TUN_DNS_CLASS_CHAOS 3 +#define GNUNET_TUN_DNS_CLASS_HESIOD 4 + +#define GNUNET_TUN_DNS_OPCODE_QUERY 0 +#define GNUNET_TUN_DNS_OPCODE_INVERSE_QUERY 1 +#define GNUNET_TUN_DNS_OPCODE_STATUS 2 + + +/** + * RFC 1035 codes. + */ +#define GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR 0 +#define GNUNET_TUN_DNS_RETURN_CODE_FORMAT_ERROR 1 +#define GNUNET_TUN_DNS_RETURN_CODE_SERVER_FAILURE 2 +#define GNUNET_TUN_DNS_RETURN_CODE_NAME_ERROR 3 +#define GNUNET_TUN_DNS_RETURN_CODE_NOT_IMPLEMENTED 4 +#define GNUNET_TUN_DNS_RETURN_CODE_REFUSED 5 + +/** + * RFC 2136 codes + */ +#define GNUNET_TUN_DNS_RETURN_CODE_YXDOMAIN 6 +#define GNUNET_TUN_DNS_RETURN_CODE_YXRRSET 7 +#define GNUNET_TUN_DNS_RETURN_CODE_NXRRSET 8 +#define GNUNET_TUN_DNS_RETURN_CODE_NOT_AUTH 9 +#define GNUNET_TUN_DNS_RETURN_CODE_NOT_ZONE 10 + + +/** + * DNS flags (largely RFC 1035 / RFC 2136). + */ +struct GNUNET_TUN_DnsFlags +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + /** + * Set to 1 if recursion is desired (client -> server) + */ + unsigned int recursion_desired : 1 GNUNET_PACKED; + + /** + * Set to 1 if message is truncated + */ + unsigned int message_truncated : 1 GNUNET_PACKED; + + /** + * Set to 1 if this is an authoritative answer + */ + unsigned int authoritative_answer : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_OPCODE_ defines. + */ + unsigned int opcode : 4 GNUNET_PACKED; + + /** + * query:0, response:1 + */ + unsigned int query_or_response : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_RETURN_CODE_ defines. + */ + unsigned int return_code : 4 GNUNET_PACKED; + + /** + * See RFC 4035. + */ + unsigned int checking_disabled : 1 GNUNET_PACKED; + + /** + * Response has been cryptographically verified, RFC 4035. + */ + unsigned int authenticated_data : 1 GNUNET_PACKED; + + /** + * Always zero. + */ + unsigned int zero : 1 GNUNET_PACKED; + + /** + * Set to 1 if recursion is available (server -> client) + */ + unsigned int recursion_available : 1 GNUNET_PACKED; +#elif __BYTE_ORDER == __BIG_ENDIAN + + /** + * query:0, response:1 + */ + unsigned int query_or_response : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_OPCODE_ defines. + */ + unsigned int opcode : 4 GNUNET_PACKED; + + /** + * Set to 1 if this is an authoritative answer + */ + unsigned int authoritative_answer : 1 GNUNET_PACKED; + + /** + * Set to 1 if message is truncated + */ + unsigned int message_truncated : 1 GNUNET_PACKED; + + /** + * Set to 1 if recursion is desired (client -> server) + */ + unsigned int recursion_desired : 1 GNUNET_PACKED; + + + /** + * Set to 1 if recursion is available (server -> client) + */ + unsigned int recursion_available : 1 GNUNET_PACKED; + + /** + * Always zero. + */ + unsigned int zero : 1 GNUNET_PACKED; + + /** + * Response has been cryptographically verified, RFC 4035. + */ + unsigned int authenticated_data : 1 GNUNET_PACKED; + + /** + * See RFC 4035. + */ + unsigned int checking_disabled : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_RETURN_CODE_ defines. + */ + unsigned int return_code : 4 GNUNET_PACKED; +#else + #error byteorder undefined +#endif + +} GNUNET_GCC_STRUCT_LAYOUT; + + + /** * DNS header. */ struct GNUNET_TUN_DnsHeader { + /** + * Unique identifier for the request/response. + */ uint16_t id GNUNET_PACKED; - uint16_t flags GNUNET_PACKED; - uint16_t qdcount GNUNET_PACKED; - uint16_t ancount GNUNET_PACKED; - uint16_t nscount GNUNET_PACKED; - uint16_t arcount GNUNET_PACKED; + + /** + * Flags. + */ + struct GNUNET_TUN_DnsFlags flags; + + /** + * Number of queries. + */ + uint16_t query_count GNUNET_PACKED; + + /** + * Number of answers. + */ + uint16_t answer_rcount GNUNET_PACKED; + + /** + * Number of authoritative answers. + */ + uint16_t authority_rcount GNUNET_PACKED; + + /** + * Number of additional records. + */ + uint16_t additional_rcount GNUNET_PACKED; +}; + + +/** + * Payload of DNS SOA record (header). + */ +struct GNUNET_TUN_DnsSoaRecord +{ + /** + * The version number of the original copy of the zone. (NBO) + */ + uint32_t serial GNUNET_PACKED; + + /** + * Time interval before the zone should be refreshed. (NBO) + */ + uint32_t refresh GNUNET_PACKED; + + /** + * Time interval that should elapse before a failed refresh should + * be retried. (NBO) + */ + uint32_t retry GNUNET_PACKED; + + /** + * Time value that specifies the upper limit on the time interval + * that can elapse before the zone is no longer authoritative. (NBO) + */ + uint32_t expire GNUNET_PACKED; + + /** + * The bit minimum TTL field that should be exported with any RR + * from this zone. (NBO) + */ + uint32_t minimum GNUNET_PACKED; +}; + + +/** + * Payload of DNS SRV record (header). + */ +struct GNUNET_TUN_DnsSrvRecord +{ + + /** + * Preference for this entry (lower value is higher preference). Clients + * will contact hosts from the lowest-priority group first and fall back + * to higher priorities if the low-priority entries are unavailable. (NBO) + */ + uint16_t prio GNUNET_PACKED; + + /** + * Relative weight for records with the same priority. Clients will use + * the hosts of the same (lowest) priority with a probability proportional + * to the weight given. (NBO) + */ + uint16_t weight GNUNET_PACKED; + + /** + * TCP or UDP port of the service. (NBO) + */ + uint16_t port GNUNET_PACKED; + + /* followed by 'target' name */ }; + +/** + * Payload of DNS CERT record. + */ +struct GNUNET_TUN_DnsCertRecord +{ + + /** + * Certificate type + */ + uint16_t cert_type; + + /** + * Certificate KeyTag + */ + uint16_t cert_tag; + + /** + * Algorithm + */ + uint8_t algorithm; + + /* Followed by the certificate */ +}; + + +/** + * Payload of DNSSEC TLSA record. + * http://datatracker.ietf.org/doc/draft-ietf-dane-protocol/ + */ +struct GNUNET_TUN_DnsTlsaRecord +{ + + /** + * Certificate usage + * 0: CA cert + * 1: Entity cert + * 2: Trust anchor + * 3: domain-issued cert + */ + uint8_t usage; + + /** + * Selector + * What part will be matched against the cert + * presented by server + * 0: Full cert (in binary) + * 1: Full cert (in DER) + */ + uint8_t selector; + + /** + * Matching type (of selected content) + * 0: exact match + * 1: SHA-256 hash + * 2: SHA-512 hash + */ + uint8_t matching_type; + + /** + * followed by certificate association data + * The "certificate association data" to be matched. + * These bytes are either raw data (that is, the full certificate or + * its SubjectPublicKeyInfo, depending on the selector) for matching + * type 0, or the hash of the raw data for matching types 1 and 2. + * The data refers to the certificate in the association, not to the + * TLS ASN.1 Certificate object. + * + * The data is represented as a string of hex chars + */ +}; + + +/** + * Payload of GNS VPN record + */ +struct GNUNET_TUN_GnsVpnRecord +{ + /** + * The peer to contact + */ + struct GNUNET_PeerIdentity peer; + + /** + * The protocol to use + */ + uint16_t proto; + + /* followed by the servicename */ +}; + + +/** + * DNS query prefix. + */ +struct GNUNET_TUN_DnsQueryLine +{ + /** + * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) + */ + uint16_t type GNUNET_PACKED; + + /** + * Desired class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO) + */ + uint16_t dns_traffic_class GNUNET_PACKED; +}; + + +/** + * General DNS record prefix. + */ +struct GNUNET_TUN_DnsRecordLine +{ + /** + * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) + */ + uint16_t type GNUNET_PACKED; + + /** + * Record class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO) + */ + uint16_t dns_traffic_class GNUNET_PACKED; + + /** + * Expiration for the record (in seconds). (NBO) + */ + uint32_t ttl GNUNET_PACKED; + + /** + * Number of bytes of data that follow. (NBO) + */ + uint16_t data_len GNUNET_PACKED; +}; + + #define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0 #define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3 #define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4 @@ -272,33 +703,37 @@ struct GNUNET_TUN_DnsHeader /** * ICMP header. */ -struct GNUNET_TUN_IcmpHeader { - uint8_t type; - uint8_t code; +struct GNUNET_TUN_IcmpHeader +{ + uint8_t type; + uint8_t code; uint16_t crc GNUNET_PACKED; - union { + union + { /** - * ICMP Echo (request/reply) + * ICMP Echo (request/reply) */ - struct { + struct + { uint16_t identifier GNUNET_PACKED; uint16_t sequence_number GNUNET_PACKED; } echo; /** - * ICMP Destination Unreachable (RFC 1191) + * ICMP Destination Unreachable (RFC 1191) */ - struct ih_pmtu { + struct ih_pmtu + { uint16_t empty GNUNET_PACKED; uint16_t next_hop_mtu GNUNET_PACKED; /* followed by original IP header + first 8 bytes of original IP datagram */ } destination_unreachable; /** - * ICMP Redirect - */ - struct in_addr redirect_gateway_address GNUNET_PACKED; + * ICMP Redirect + */ + struct in_addr redirect_gateway_address GNUNET_PACKED; /** * MTU for packets that are too big (IPv6). @@ -352,7 +787,7 @@ GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, * @param ip ipv4 header fully initialized * @param tcp TCP header (initialized except for CRC) * @param payload the TCP payload - * @param payload_length number of bytes of TCP payload + * @param payload_length number of bytes of TCP @a payload */ void GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, @@ -380,7 +815,7 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, * @param ip ipv4 header fully initialized * @param udp UDP header (initialized except for CRC) * @param payload the UDP payload - * @param payload_length number of bytes of UDP payload + * @param payload_length number of bytes of UDP @a payload */ void GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, @@ -395,7 +830,7 @@ GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, * @param ip ipv6 header fully initialized * @param udp UDP header (initialized except for CRC) * @param payload the UDP payload - * @param payload_length number of bytes of UDP payload + * @param payload_length number of bytes of @a payload */ void GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, @@ -409,7 +844,7 @@ GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, * * @param icmp IMCP header (initialized except for CRC) * @param payload the ICMP payload - * @param payload_length number of bytes of ICMP payload + * @param payload_length number of bytes of @a payload */ void GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp, @@ -417,4 +852,101 @@ GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp, uint16_t payload_length); +/** + * Create a regex in @a rxstr from the given @a ip and @a port. + * + * @param ip IPv4 representation. + * @param port destination port + * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV4_REGEXLEN + * bytes long. + */ +void +GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip, + uint16_t port, + char *rxstr); + + +/** + * Create a regex in @a rxstr from the given @a ipv6 and @a port. + * + * @param ipv6 IPv6 representation. + * @param port destination port + * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV6_REGEXLEN + * bytes long. + */ +void +GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6, + uint16_t port, + char *rxstr); + + +/** + * Convert an exit policy to a regular expression. The exit policy + * specifies a set of subnets this peer is willing to serve as an + * exit for; the resulting regular expression will match the + * IPv6 address strings as returned by #GNUNET_TUN_ipv6toregexsearch. + * + * @param policy exit policy specification + * @return regular expression, NULL on error + */ +char * +GNUNET_TUN_ipv6policy2regex (const char *policy); + + +/** + * Convert an exit policy to a regular expression. The exit policy + * specifies a set of subnets this peer is willing to serve as an + * exit for; the resulting regular expression will match the + * IPv4 address strings as returned by #GNUNET_TUN_ipv4toregexsearch. + * + * @param policy exit policy specification + * @return regular expression, NULL on error + */ +char * +GNUNET_TUN_ipv4policy2regex (const char *policy); + + +/** + * Hash the service name of a hosted service to the + * hash code that is used to identify the service on + * the network. + * + * @param service_name a string + * @param[out] hc corresponding hash + */ +void +GNUNET_TUN_service_name_to_hash (const char *service_name, + struct GNUNET_HashCode *hc); + + +/** + * Check if two sockaddrs are equal. + * + * @param sa one address + * @param sb another address + * @param include_port also check ports + * @return #GNUNET_YES if they are equal + */ +int +GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa, + const struct sockaddr *sb, + int include_port); + + +/** + * Compute the CADET port given a service descriptor + * (returned from #GNUNET_TUN_service_name_to_hash) and + * a TCP/UDP port @a ip_port. + * + * @param desc service shared secret + * @param ip_port TCP/UDP port, use 0 for ICMP + * @param[out] cadet_port CADET port to use + */ +void +GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc, + uint16_t ip_port, + struct GNUNET_HashCode *cadet_port); + #endif + +/** @} */ /* end of group */