1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "resolved-dns-domain.h"
26 #include "resolved-dns-packet.h"
28 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
35 a = DNS_PACKET_SIZE_START;
39 if (a < DNS_PACKET_HEADER_SIZE)
40 a = DNS_PACKET_HEADER_SIZE;
42 /* round up to next page size */
43 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
45 /* make sure we never allocate more than useful */
46 if (a > DNS_PACKET_SIZE_MAX)
47 a = DNS_PACKET_SIZE_MAX;
49 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
53 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
55 p->protocol = protocol;
63 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
70 r = dns_packet_new(&p, protocol, mtu);
74 h = DNS_PACKET_HEADER(p);
76 if (protocol == DNS_PROTOCOL_LLMNR)
77 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
87 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
91 1 /* rd (ask for recursion) */,
101 DnsPacket *dns_packet_ref(DnsPacket *p) {
106 assert(p->n_ref > 0);
111 static void dns_packet_free(DnsPacket *p) {
116 dns_question_unref(p->question);
117 dns_answer_unref(p->answer);
119 while ((s = hashmap_steal_first_key(p->names)))
121 hashmap_free(p->names);
127 DnsPacket *dns_packet_unref(DnsPacket *p) {
131 assert(p->n_ref > 0);
141 int dns_packet_validate(DnsPacket *p) {
144 if (p->size < DNS_PACKET_HEADER_SIZE)
147 if (p->size > DNS_PACKET_SIZE_MAX)
153 int dns_packet_validate_reply(DnsPacket *p) {
158 r = dns_packet_validate(p);
162 if (DNS_PACKET_QR(p) != 1)
165 if (DNS_PACKET_OPCODE(p) != 0)
168 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
169 if (p->protocol == DNS_PROTOCOL_LLMNR &&
170 DNS_PACKET_QDCOUNT(p) != 1)
176 int dns_packet_validate_query(DnsPacket *p) {
181 r = dns_packet_validate(p);
185 if (DNS_PACKET_QR(p) != 0)
188 if (DNS_PACKET_OPCODE(p) != 0)
191 if (DNS_PACKET_TC(p))
194 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
195 if (p->protocol == DNS_PROTOCOL_LLMNR &&
196 DNS_PACKET_QDCOUNT(p) != 1)
199 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
200 if (DNS_PACKET_ANCOUNT(p) > 0)
203 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
204 if (DNS_PACKET_NSCOUNT(p) > 0)
210 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
213 if (p->size + add > p->allocated) {
216 a = PAGE_ALIGN((p->size + add) * 2);
217 if (a > DNS_PACKET_SIZE_MAX)
218 a = DNS_PACKET_SIZE_MAX;
220 if (p->size + add > a)
226 d = realloc(p->_data, a);
232 p->_data = malloc(a);
236 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
237 memzero((uint8_t*) p->_data + p->size, a - p->size);
247 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
253 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
263 HASHMAP_FOREACH_KEY(s, n, p->names, i) {
265 if (PTR_TO_SIZE(n) < sz)
268 hashmap_remove(p->names, s);
275 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
281 r = dns_packet_extend(p, l, &q, start);
289 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
295 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
299 ((uint8_t*) d)[0] = v;
304 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
310 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
314 ((uint8_t*) d)[0] = (uint8_t) (v >> 8);
315 ((uint8_t*) d)[1] = (uint8_t) v;
320 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
326 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
330 ((uint8_t*) d)[0] = (uint8_t) (v >> 24);
331 ((uint8_t*) d)[1] = (uint8_t) (v >> 16);
332 ((uint8_t*) d)[2] = (uint8_t) (v >> 8);
333 ((uint8_t*) d)[3] = (uint8_t) v;
338 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
350 r = dns_packet_extend(p, 1 + l, &d, start);
354 ((uint8_t*) d)[0] = (uint8_t) l;
355 memcpy(((uint8_t*) d) + 1, s, l);
360 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
367 if (l > DNS_LABEL_MAX)
370 r = dns_packet_extend(p, 1 + l, &w, start);
374 ((uint8_t*) w)[0] = (uint8_t) l;
375 memcpy(((uint8_t*) w) + 1, d, l);
380 int dns_packet_append_name(DnsPacket *p, const char *name, size_t *start) {
387 saved_size = p->size;
390 _cleanup_free_ char *s = NULL;
391 char label[DNS_LABEL_MAX];
395 n = PTR_TO_SIZE(hashmap_get(p->names, name));
400 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
414 r = dns_label_unescape(&name, label, sizeof(label));
418 if (p->protocol == DNS_PROTOCOL_DNS)
419 k = dns_label_apply_idna(label, r, label, sizeof(label));
421 k = dns_label_undo_idna(label, r, label, sizeof(label));
429 r = dns_packet_append_label(p, label, r, &n);
433 r = hashmap_ensure_allocated(&p->names, dns_name_hash_func, dns_name_compare_func);
437 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
444 r = dns_packet_append_uint8(p, 0, NULL);
455 dns_packet_truncate(p, saved_size);
459 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
466 saved_size = p->size;
468 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), NULL);
472 r = dns_packet_append_uint16(p, k->type, NULL);
476 r = dns_packet_append_uint16(p, k->class, NULL);
486 dns_packet_truncate(p, saved_size);
490 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
491 size_t saved_size, rdlength_offset, end, rdlength;
497 saved_size = p->size;
499 r = dns_packet_append_key(p, rr->key, NULL);
503 r = dns_packet_append_uint32(p, rr->ttl, NULL);
507 /* Initially we write 0 here */
508 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
512 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
515 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
519 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
523 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
527 r = dns_packet_append_name(p, rr->srv.name, NULL);
534 r = dns_packet_append_name(p, rr->ptr.name, NULL);
538 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
542 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
545 case DNS_TYPE_SPF: /* exactly the same as TXT */
549 STRV_FOREACH(s, rr->txt.strings) {
550 r = dns_packet_append_string(p, *s, NULL);
560 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
564 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
568 r = dns_packet_append_name(p, rr->soa.mname, NULL);
572 r = dns_packet_append_name(p, rr->soa.rname, NULL);
576 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
580 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
584 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
588 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
592 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
596 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
600 r = dns_packet_append_name(p, rr->mx.exchange, NULL);
604 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
608 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
612 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
616 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
620 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
624 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
628 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
632 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
636 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
640 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
643 case DNS_TYPE_DNSKEY:
644 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
648 r = dns_packet_append_uint8(p, 3u, NULL);
652 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
656 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
659 case _DNS_TYPE_INVALID: /* unparseable */
662 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
668 /* Let's calculate the actual data size and update the field */
669 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
670 if (rdlength > 0xFFFF) {
676 p->size = rdlength_offset;
677 r = dns_packet_append_uint16(p, rdlength, NULL);
688 dns_packet_truncate(p, saved_size);
693 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
696 if (p->rindex + sz > p->size)
700 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
709 void dns_packet_rewind(DnsPacket *p, size_t idx) {
711 assert(idx <= p->size);
712 assert(idx >= DNS_PACKET_HEADER_SIZE);
717 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
724 r = dns_packet_read(p, sz, &q, start);
732 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
738 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
742 *ret = ((uint8_t*) d)[0];
746 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
752 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
756 *ret = (((uint16_t) ((uint8_t*) d)[0]) << 8) |
757 ((uint16_t) ((uint8_t*) d)[1]);
761 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
767 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
771 *ret = (((uint32_t) ((uint8_t*) d)[0]) << 24) |
772 (((uint32_t) ((uint8_t*) d)[1]) << 16) |
773 (((uint32_t) ((uint8_t*) d)[2]) << 8) |
774 ((uint32_t) ((uint8_t*) d)[3]);
779 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
788 saved_rindex = p->rindex;
790 r = dns_packet_read_uint8(p, &c, NULL);
794 r = dns_packet_read(p, c, &d, NULL);
798 if (memchr(d, 0, c)) {
809 if (!utf8_is_valid(t)) {
818 *start = saved_rindex;
823 dns_packet_rewind(p, saved_rindex);
827 int dns_packet_read_name(DnsPacket *p, char **_ret, size_t *start) {
828 size_t saved_rindex, after_rindex = 0;
829 _cleanup_free_ char *ret = NULL;
830 size_t n = 0, allocated = 0;
837 saved_rindex = p->rindex;
842 r = dns_packet_read_uint8(p, &c, NULL);
850 _cleanup_free_ char *t = NULL;
854 r = dns_packet_read(p, c, (const void**) &label, NULL);
858 r = dns_label_escape(label, c, &t);
862 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
872 memcpy(ret + n, t, r);
875 } else if ((c & 0xc0) == 0xc0) {
879 r = dns_packet_read_uint8(p, &d, NULL);
883 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
884 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
889 if (after_rindex == 0)
890 after_rindex = p->rindex;
897 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
904 if (after_rindex != 0)
905 p->rindex= after_rindex;
911 *start = saved_rindex;
916 dns_packet_rewind(p, saved_rindex);
920 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
921 _cleanup_free_ char *name = NULL;
922 uint16_t class, type;
930 saved_rindex = p->rindex;
932 r = dns_packet_read_name(p, &name, NULL);
936 r = dns_packet_read_uint16(p, &type, NULL);
940 r = dns_packet_read_uint16(p, &class, NULL);
944 key = dns_resource_key_new_consume(class, type, name);
954 *start = saved_rindex;
958 dns_packet_rewind(p, saved_rindex);
962 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
963 void **dp, size_t *lengthp,
969 r = dns_packet_read(p, length, &d, NULL);
973 d2 = memdup(d, length);
982 static bool loc_size_ok(uint8_t size) {
983 uint8_t m = size >> 4, e = size & 0xF;
985 return m <= 9 && e <= 9 && (m > 0 || e == 0);
988 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
989 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
992 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
993 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
997 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
998 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
999 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1000 size_t saved_rindex, offset;
1008 saved_rindex = p->rindex;
1010 r = dns_packet_read_key(p, &key, NULL);
1014 if (key->class == DNS_CLASS_ANY ||
1015 key->type == DNS_TYPE_ANY) {
1020 rr = dns_resource_record_new(key);
1026 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1030 r = dns_packet_read_uint16(p, &rdlength, NULL);
1034 if (p->rindex + rdlength > p->size) {
1041 switch (rr->key->type) {
1044 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1047 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1050 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1053 r = dns_packet_read_name(p, &rr->srv.name, NULL);
1058 case DNS_TYPE_CNAME:
1059 case DNS_TYPE_DNAME:
1060 r = dns_packet_read_name(p, &rr->ptr.name, NULL);
1063 case DNS_TYPE_HINFO:
1064 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1068 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1071 case DNS_TYPE_SPF: /* exactly the same as TXT */
1072 case DNS_TYPE_TXT: {
1075 while (p->rindex < offset + rdlength) {
1076 r = dns_packet_read_string(p, &s, NULL);
1080 r = strv_consume(&rr->txt.strings, s);
1090 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1094 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1098 r = dns_packet_read_name(p, &rr->soa.mname, NULL);
1102 r = dns_packet_read_name(p, &rr->soa.rname, NULL);
1106 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1110 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1114 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1118 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1122 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1126 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1130 r = dns_packet_read_name(p, &rr->mx.exchange, NULL);
1133 case DNS_TYPE_LOC: {
1137 r = dns_packet_read_uint8(p, &t, &pos);
1142 rr->loc.version = t;
1144 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1148 if (!loc_size_ok(rr->loc.size)) {
1153 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1157 if (!loc_size_ok(rr->loc.horiz_pre)) {
1162 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1166 if (!loc_size_ok(rr->loc.vert_pre)) {
1171 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1175 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1179 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1185 dns_packet_rewind(p, pos);
1186 rr->unparseable = true;
1191 case DNS_TYPE_SSHFP:
1192 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1196 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1200 r = dns_packet_read_public_key(p, rdlength - 2,
1201 &rr->sshfp.key, &rr->sshfp.key_size,
1205 case DNS_TYPE_DNSKEY: {
1209 r = dns_packet_read_uint16(p, &flags, NULL);
1213 r = dnskey_parse_flags(rr, flags);
1217 r = dns_packet_read_uint8(p, &proto, NULL);
1221 /* protocol is required to be always 3 */
1227 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1231 r = dns_packet_read_public_key(p, rdlength - 4,
1232 &rr->dnskey.key, &rr->dnskey.key_size,
1239 r = dns_packet_read(p, rdlength, &d, NULL);
1243 rr->generic.data = memdup(d, rdlength);
1244 if (!rr->generic.data) {
1249 rr->generic.size = rdlength;
1254 if (p->rindex != offset + rdlength) {
1263 *start = saved_rindex;
1267 dns_packet_rewind(p, saved_rindex);
1271 int dns_packet_extract(DnsPacket *p) {
1272 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1273 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1274 size_t saved_rindex;
1278 saved_rindex = p->rindex;
1279 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1281 n = DNS_PACKET_QDCOUNT(p);
1283 question = dns_question_new(n);
1289 for (i = 0; i < n; i++) {
1290 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1292 r = dns_packet_read_key(p, &key, NULL);
1296 r = dns_question_add(question, key);
1302 n = DNS_PACKET_RRCOUNT(p);
1304 answer = dns_answer_new(n);
1310 for (i = 0; i < n; i++) {
1311 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1313 r = dns_packet_read_rr(p, &rr, NULL);
1317 r = dns_answer_add(answer, rr);
1323 p->question = question;
1332 p->rindex = saved_rindex;
1336 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1337 [DNS_RCODE_SUCCESS] = "SUCCESS",
1338 [DNS_RCODE_FORMERR] = "FORMERR",
1339 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1340 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1341 [DNS_RCODE_NOTIMP] = "NOTIMP",
1342 [DNS_RCODE_REFUSED] = "REFUSED",
1343 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1344 [DNS_RCODE_YXRRSET] = "YRRSET",
1345 [DNS_RCODE_NXRRSET] = "NXRRSET",
1346 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1347 [DNS_RCODE_NOTZONE] = "NOTZONE",
1348 [DNS_RCODE_BADVERS] = "BADVERS",
1349 [DNS_RCODE_BADKEY] = "BADKEY",
1350 [DNS_RCODE_BADTIME] = "BADTIME",
1351 [DNS_RCODE_BADMODE] = "BADMODE",
1352 [DNS_RCODE_BADNAME] = "BADNAME",
1353 [DNS_RCODE_BADALG] = "BADALG",
1354 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1356 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1358 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1359 [DNS_PROTOCOL_DNS] = "dns",
1360 [DNS_PROTOCOL_MDNS] = "mdns",
1361 [DNS_PROTOCOL_LLMNR] = "llmnr",
1363 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1365 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1366 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1367 [DNSSEC_ALGORITHM_DH] = "DH",
1368 [DNSSEC_ALGORITHM_DSA] = "DSA",
1369 [DNSSEC_ALGORITHM_ECC] = "ECC",
1370 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1371 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1372 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1373 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1375 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);