#pragma once
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "hashmap.h"
#include "in-addr-util.h"
#include "macro.h"
#include "sparse-endian.h"
#include "resolved-def.h"
#include "resolved-dns-answer.h"
#include "resolved-dns-question.h"
#include "resolved-dns-rr.h"
typedef enum DnsProtocol {
} DnsProtocol;
struct DnsPacketHeader {
};
/* The various DNS protocols deviate in how large a packet can grow,
but the TCP transport has a 16bit size field, hence that appears to
be the absolute maximum. */
/* RFC 1035 say 512 is the maximum, for classic unicast DNS */
/* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
struct DnsPacket {
int n_ref;
/* Parsed data */
/* Packet reception metadata */
int ifindex;
/* For support of truncated packets */
};
if (_unlikely_(!p))
return NULL;
if (p->_data)
return p->_data;
}
if (p->opt)
else
rcode = 0;
}
/* LLMNR defines some bits differently */
return
(unsigned) DNS_PACKET_ANCOUNT(p) +
(unsigned) DNS_PACKET_NSCOUNT(p) +
(unsigned) DNS_PACKET_ARCOUNT(p);
}
int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled);
int dns_packet_validate(DnsPacket *p);
int dns_packet_validate_reply(DnsPacket *p);
int dns_packet_validate_query(DnsPacket *p);
int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, bool canonical_candidate, size_t *start);
int dns_packet_append_name(DnsPacket *p, const char *name, bool allow_compression, bool canonical_candidate, size_t *start);
int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start);
int dns_packet_truncate_opt(DnsPacket *p);
int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_flush, size_t *start);
int dns_packet_skip_question(DnsPacket *p);
int dns_packet_extract(DnsPacket *p);
/* Never cache data originating from localhost, under the
* assumption, that it's coming from a locally DNS forwarder
* or server, that is caching on its own. */
}
/* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 */
enum {
DNS_RCODE_SUCCESS = 0,
};
const char* dns_rcode_to_string(int i) _const_;
int dns_rcode_from_string(const char *s) _pure_;
#define LLMNR_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03 } })
#define MDNS_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } })
static inline uint64_t SD_RESOLVED_FLAGS_MAKE(DnsProtocol protocol, int family, bool authenticated) {
uint64_t f;
/* Converts a protocol + family into a flags field as used in queries and responses */
f = authenticated ? SD_RESOLVED_AUTHENTICATED : 0;
switch (protocol) {
case DNS_PROTOCOL_DNS:
return f|SD_RESOLVED_DNS;
case DNS_PROTOCOL_LLMNR:
case DNS_PROTOCOL_MDNS:
default:
break;
}
return 0;
}