]>
Commit | Line | Data |
---|---|---|
74b2466e LP |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | #pragma once | |
4 | ||
5 | /*** | |
6 | This file is part of systemd. | |
7 | ||
8 | Copyright 2014 Lennart Poettering | |
9 | ||
10 | systemd is free software; you can redistribute it and/or modify it | |
11 | under the terms of the GNU Lesser General Public License as published by | |
12 | the Free Software Foundation; either version 2.1 of the License, or | |
13 | (at your option) any later version. | |
14 | ||
15 | systemd is distributed in the hope that it will be useful, but | |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | Lesser General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU Lesser General Public License | |
21 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
22 | ***/ | |
23 | ||
24 | typedef struct DnsPacketHeader DnsPacketHeader; | |
25 | typedef struct DnsPacket DnsPacket; | |
26 | ||
27 | #include <inttypes.h> | |
28 | ||
29 | #include "macro.h" | |
30 | #include "sparse-endian.h" | |
31 | #include "hashmap.h" | |
32 | #include "resolved-dns-rr.h" | |
33 | ||
34 | struct DnsPacketHeader { | |
35 | uint16_t id; | |
36 | be16_t flags; | |
37 | be16_t qdcount; | |
38 | be16_t ancount; | |
39 | be16_t nscount; | |
40 | be16_t arcount; | |
41 | }; | |
42 | ||
43 | #define DNS_PACKET_HEADER_SIZE sizeof(DnsPacketHeader) | |
44 | #define DNS_PACKET_SIZE_START 512 | |
45 | ||
46 | struct DnsPacket { | |
47 | int n_ref; | |
48 | size_t size, allocated, rindex; | |
49 | Hashmap *names; /* For name compression */ | |
50 | void *data; | |
51 | int ifindex; | |
52 | }; | |
53 | ||
54 | static inline uint8_t* DNS_PACKET_DATA(DnsPacket *p) { | |
55 | if (_unlikely_(!p)) | |
56 | return NULL; | |
57 | ||
58 | if (p->data) | |
59 | return p->data; | |
60 | ||
61 | return ((uint8_t*) p) + ALIGN(sizeof(DnsPacket)); | |
62 | } | |
63 | ||
64 | #define DNS_PACKET_HEADER(p) ((DnsPacketHeader*) DNS_PACKET_DATA(p)) | |
3cb10d3a LP |
65 | #define DNS_PACKET_ID(p) DNS_PACKET_HEADER(p)->id |
66 | #define DNS_PACKET_QR(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 15) & 1) | |
67 | #define DNS_PACKET_OPCODE(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 11) & 15) | |
68 | #define DNS_PACKET_RCODE(p) (be16toh(DNS_PACKET_HEADER(p)->flags) & 15) | |
69 | #define DNS_PACKET_QDCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->qdcount) | |
70 | #define DNS_PACKET_ANCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->ancount) | |
71 | #define DNS_PACKET_NSCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->nscount) | |
72 | #define DNS_PACKET_ARCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->arcount) | |
73 | ||
74 | #define DNS_PACKET_MAKE_FLAGS(qr, opcode, aa, tc, rd, ra, ad, cd, rcode) \ | |
75 | (((uint16_t) !!qr << 15) | \ | |
76 | ((uint16_t) (opcode & 15) << 11) | \ | |
77 | ((uint16_t) !!aa << 10) | \ | |
78 | ((uint16_t) !!tc << 9) | \ | |
79 | ((uint16_t) !!rd << 8) | \ | |
80 | ((uint16_t) !!ra << 7) | \ | |
81 | ((uint16_t) !!ad << 5) | \ | |
82 | ((uint16_t) !!cd << 4) | \ | |
83 | ((uint16_t) (rcode & 15))) | |
84 | ||
74b2466e LP |
85 | |
86 | int dns_packet_new(DnsPacket **p, size_t mtu); | |
87 | int dns_packet_new_query(DnsPacket **p, size_t mtu); | |
88 | ||
89 | DnsPacket *dns_packet_ref(DnsPacket *p); | |
90 | DnsPacket *dns_packet_unref(DnsPacket *p); | |
91 | ||
92 | DEFINE_TRIVIAL_CLEANUP_FUNC(DnsPacket*, dns_packet_unref); | |
93 | ||
94 | int dns_packet_validate(DnsPacket *p); | |
95 | int dns_packet_validate_reply(DnsPacket *p); | |
96 | ||
97 | int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start); | |
98 | int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start); | |
99 | int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start); | |
100 | int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, size_t *start); | |
101 | int dns_packet_append_name(DnsPacket *p, const char *name, size_t *start); | |
102 | int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start); | |
103 | ||
104 | int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start); | |
105 | int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start); | |
106 | int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start); | |
107 | int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start); | |
108 | int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start); | |
109 | int dns_packet_read_name(DnsPacket *p, char **ret, size_t *start); | |
110 | int dns_packet_read_key(DnsPacket *p, DnsResourceKey *ret, size_t *start); | |
111 | int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start); | |
112 | ||
113 | int dns_packet_skip_question(DnsPacket *p); | |
114 | ||
74b2466e LP |
115 | enum { |
116 | DNS_RCODE_SUCCESS = 0, | |
117 | DNS_RCODE_FORMERR = 1, | |
118 | DNS_RCODE_SERVFAIL = 2, | |
119 | DNS_RCODE_NXDOMAIN = 3, | |
120 | DNS_RCODE_NOTIMP = 4, | |
121 | DNS_RCODE_REFUSED = 5, | |
122 | DNS_RCODE_YXDOMAIN = 6, | |
123 | DNS_RCODE_YXRRSET = 7, | |
124 | DNS_RCODE_NXRRSET = 8, | |
125 | DNS_RCODE_NOTAUTH = 9, | |
126 | DNS_RCODE_NOTZONE = 10, | |
127 | DNS_RCODE_BADVERS = 16, | |
128 | DNS_RCODE_BADSIG = 16, /* duplicate value! */ | |
129 | DNS_RCODE_BADKEY = 17, | |
130 | DNS_RCODE_BADTIME = 18, | |
131 | DNS_RCODE_BADMODE = 19, | |
132 | DNS_RCODE_BADNAME = 20, | |
133 | DNS_RCODE_BADALG = 21, | |
134 | DNS_RCODE_BADTRUNC = 22, | |
135 | _DNS_RCODE_MAX_DEFINED | |
136 | }; | |
137 | ||
138 | const char* dns_rcode_to_string(int i) _const_; | |
139 | int dns_rcode_from_string(const char *s) _pure_; |