/src/freeradius-server/src/protocols/dns/dns.h
Line | Count | Source |
1 | | #pragma once |
2 | | /* |
3 | | * This program is free software; you can redistribute it and/or modify |
4 | | * it under the terms of the GNU General Public License as published by |
5 | | * the Free Software Foundation; either version 2 of the License, or |
6 | | * (at your option) any later version. |
7 | | * |
8 | | * This program is distributed in the hope that it will be useful, |
9 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | | * GNU General Public License for more details. |
12 | | * |
13 | | * You should have received a copy of the GNU General Public License |
14 | | * along with this program; if not, write to the Free Software |
15 | | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
16 | | */ |
17 | | |
18 | | /** |
19 | | * $Id: ccd4976e6e62129e2296fc9db32c33ed27714112 $ |
20 | | * |
21 | | * @file protocols/dns/dns.h |
22 | | * @brief Implementation of the DNS protocol. |
23 | | * |
24 | | * @copyright 2021 Network RADIUS SAS (legal@networkradius.com) |
25 | | */ |
26 | | RCSIDH(dhcp_h, "$Id: ccd4976e6e62129e2296fc9db32c33ed27714112 $") |
27 | | |
28 | | #ifdef __cplusplus |
29 | | extern "C" { |
30 | | #endif |
31 | | |
32 | | #include <freeradius-devel/util/packet.h> |
33 | | #include <freeradius-devel/util/dns.h> |
34 | | |
35 | | #define DNS_MAX_ATTRIBUTES 255 |
36 | | |
37 | | typedef struct { |
38 | | uint16_t id; |
39 | | #ifdef WORDS_BIGENDIAN |
40 | | unsigned int query : 1; |
41 | | unsigned int opcode : 4; |
42 | | unsigned int authoritative : 1; |
43 | | unsigned int truncated : 1; |
44 | | unsigned int recursion_desired : 1; |
45 | | #else |
46 | | unsigned int recursion_desired : 1; |
47 | | unsigned int truncated : 1; |
48 | | unsigned int authoritative : 1; |
49 | | unsigned int opcode : 4; |
50 | | unsigned int query : 1; |
51 | | #endif |
52 | | |
53 | | #ifdef WORDS_BIGENDIAN |
54 | | unsigned int recursion_available : 1; |
55 | | unsigned int reserved : 1; |
56 | | unsigned int authentic_data : 1; |
57 | | unsigned int checking_disabled : 1; |
58 | | unsigned int rcode : 4; |
59 | | #else |
60 | | unsigned int rcode : 4; |
61 | | unsigned int checking_disabled : 1; |
62 | | unsigned int authentic_data : 1; |
63 | | unsigned int reserved : 1; |
64 | | unsigned int recursion_available : 1; |
65 | | #endif |
66 | | |
67 | | uint16_t qdcount; |
68 | | uint16_t ancount; |
69 | | uint16_t nscount; |
70 | | uint16_t arcount; |
71 | | } CC_HINT(__packed__) fr_dns_packet_t; |
72 | | |
73 | | typedef struct { |
74 | | TALLOC_CTX *tmp_ctx; //!< for temporary things cleaned up during decoding |
75 | | uint8_t const *packet; //!< DNS labels can point anywhere in the packet :( |
76 | | size_t packet_len; |
77 | | fr_dns_labels_t *lb; |
78 | | } fr_dns_ctx_t; |
79 | | |
80 | | int fr_dns_global_init(void); |
81 | | void fr_dns_global_free(void); |
82 | | |
83 | | typedef enum { |
84 | | FR_DNS_QUERY = 0, |
85 | | FR_DNS_INVERSE_QUERY = 1, |
86 | | FR_DNS_STATUS = 2, |
87 | | FR_DNS_NOTIFY = 4, |
88 | | FR_DNS_UPDATE = 5, |
89 | | FR_DNS_STATEFUL_OPERATION = 6, |
90 | | FR_DNS_CODE_MAX = 7, |
91 | | |
92 | | FR_DNS_QUERY_RESPONSE = 16, |
93 | | FR_DNS_INVERSE_QUERY_RESPONSE = 17, |
94 | | FR_DNS_STATUS_RESPONSE = 18, |
95 | | FR_DNS_NOTIFY_RESPONSE = 20, |
96 | | FR_DNS_UPDATE_RESPONSE = 21, |
97 | | FR_DNS_STATEFUL_OPERATION_RESPONSE = 22, |
98 | | |
99 | | FR_DNS_DO_NOT_RESPOND = 256, |
100 | | } fr_dns_packet_code_t; |
101 | | |
102 | | typedef enum { |
103 | | FR_DNS_DECODE_FAIL_NONE = 0, |
104 | | FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET, |
105 | | FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET, |
106 | | FR_DNS_DECODE_FAIL_UNEXPECTED, |
107 | | FR_DNS_DECODE_FAIL_NO_QUESTIONS, |
108 | | FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION, |
109 | | FR_DNS_DECODE_FAIL_NS_IN_QUESTION, |
110 | | FR_DNS_DECODE_FAIL_INVALID_RR_LABEL, |
111 | | FR_DNS_DECODE_FAIL_MISSING_RR_HEADER, |
112 | | FR_DNS_DECODE_FAIL_MISSING_RR_LEN, |
113 | | FR_DNS_DECODE_FAIL_ZERO_RR_LEN, |
114 | | FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET, |
115 | | FR_DNS_DECODE_FAIL_TOO_MANY_RRS, |
116 | | FR_DNS_DECODE_FAIL_TOO_FEW_RRS, |
117 | | FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL, |
118 | | FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET, |
119 | | FR_DNS_DECODE_FAIL_POINTER_TO_HEADER, |
120 | | FR_DNS_DECODE_FAIL_POINTER_LOOPS, |
121 | | FR_DNS_DECODE_FAIL_INVALID_POINTER, |
122 | | FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET, |
123 | | FR_DNS_DECODE_FAIL_LABEL_TOO_LONG, |
124 | | FR_DNS_DECODE_FAIL_MISSING_QD_HEADER, |
125 | | FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER, |
126 | | FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR, |
127 | | FR_DNS_DECODE_FAIL_MAX |
128 | | } fr_dns_decode_fail_t; |
129 | | |
130 | | #define FR_DNS_PACKET_CODE_VALID(_code) (((_code) < FR_DNS_CODE_MAX) || (((_code & 0x10) != 0) && ((_code & ~0x10) < FR_DNS_CODE_MAX))) |
131 | | |
132 | 12.1k | #define DNS_HDR_LEN (12) |
133 | | |
134 | | typedef struct { |
135 | | bool dns_label; |
136 | | bool dns_label_uncompressed; |
137 | | } fr_dns_attr_flags_t; |
138 | | |
139 | | static inline fr_dns_attr_flags_t const *fr_dns_attr_flags(fr_dict_attr_t const *da) |
140 | 34.0k | { |
141 | 34.0k | return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); |
142 | 34.0k | } Line | Count | Source | 140 | 152 | { | 141 | 152 | return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); | 142 | 152 | } |
decode.c:fr_dns_attr_flags Line | Count | Source | 140 | 33.8k | { | 141 | 33.8k | return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); | 142 | 33.8k | } |
Unexecuted instantiation: encode.c:fr_dns_attr_flags |
143 | | |
144 | | static inline bool fr_dns_flag_dns_label_any(fr_dict_attr_t const *da) |
145 | 152 | { |
146 | 152 | fr_dns_attr_flags_t const *flags = fr_dns_attr_flags(da); |
147 | | |
148 | 152 | return flags->dns_label || flags->dns_label_uncompressed; |
149 | 152 | } base.c:fr_dns_flag_dns_label_any Line | Count | Source | 145 | 152 | { | 146 | 152 | fr_dns_attr_flags_t const *flags = fr_dns_attr_flags(da); | 147 | | | 148 | 152 | return flags->dns_label || flags->dns_label_uncompressed; | 149 | 152 | } |
Unexecuted instantiation: decode.c:fr_dns_flag_dns_label_any Unexecuted instantiation: encode.c:fr_dns_flag_dns_label_any |
150 | | |
151 | 34.5k | #define fr_dns_flag_dns_label(_da) (fr_dns_attr_flags(_da)->dns_label) |
152 | | #define fr_dns_flag_dns_label_uncompressed(_da) (fr_dns_attr_flags(_da)->dns_label_uncompressed) |
153 | | |
154 | | extern fr_table_num_ordered_t fr_dns_reason_fail_table[]; |
155 | | extern char const *fr_dns_packet_names[FR_DNS_CODE_MAX]; |
156 | | extern size_t fr_dns_reason_fail_table_len; |
157 | | |
158 | | bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query, fr_dns_decode_fail_t *reason); |
159 | | |
160 | | fr_dns_labels_t *fr_dns_labels_get(uint8_t const *packet, size_t packet_len, bool init_mark); |
161 | | |
162 | | ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, |
163 | | uint8_t const *packet, size_t packet_len, fr_dns_ctx_t *packet_ctx); |
164 | | |
165 | | ssize_t fr_dns_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_dns_ctx_t *encode_ctx); |
166 | | |
167 | | #ifdef __cplusplus |
168 | | } |
169 | | #endif |