Coverage Report

Created: 2026-05-11 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: ca83b3b34a2820892bacf25f49188a296447dbd2 $
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(protocols_dns_h, "$Id: ca83b3b34a2820892bacf25f49188a296447dbd2 $")
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_UNKNOWN_OPCODE,
105
  FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET,
106
  FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET,
107
  FR_DNS_DECODE_FAIL_UNEXPECTED,
108
  FR_DNS_DECODE_FAIL_NO_QUESTIONS,
109
  FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION,
110
  FR_DNS_DECODE_FAIL_NS_IN_QUESTION,
111
  FR_DNS_DECODE_FAIL_INVALID_RR_LABEL,
112
  FR_DNS_DECODE_FAIL_MISSING_RR_HEADER,
113
  FR_DNS_DECODE_FAIL_MISSING_RR_LEN,
114
  FR_DNS_DECODE_FAIL_ZERO_RR_LEN,
115
  FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET,
116
  FR_DNS_DECODE_FAIL_TOO_MANY_RRS,
117
  FR_DNS_DECODE_FAIL_TOO_FEW_RRS,
118
  FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL,
119
  FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET,
120
  FR_DNS_DECODE_FAIL_POINTER_TO_HEADER,
121
  FR_DNS_DECODE_FAIL_POINTER_LOOPS,
122
  FR_DNS_DECODE_FAIL_INVALID_POINTER,
123
  FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET,
124
  FR_DNS_DECODE_FAIL_LABEL_TOO_LONG,
125
  FR_DNS_DECODE_FAIL_MISSING_QD_HEADER,
126
  FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER,
127
  FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR,
128
  FR_DNS_DECODE_FAIL_TRUNCATED,
129
  FR_DNS_DECODE_FAIL_MAX
130
} fr_dns_decode_fail_t;
131
132
#define FR_DNS_PACKET_CODE_VALID(_code) (((_code) < FR_DNS_CODE_MAX) || (((_code & 0x10) != 0) && ((_code & ~0x10) < FR_DNS_CODE_MAX)))
133
134
12.0k
#define DNS_HDR_LEN (12)
135
136
typedef struct {
137
  bool      dns_label;
138
  bool      dns_label_uncompressed;
139
} fr_dns_attr_flags_t;
140
141
static inline fr_dns_attr_flags_t const *fr_dns_attr_flags(fr_dict_attr_t const *da)
142
41.2k
{
143
41.2k
  return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC);
144
41.2k
}
base.c:fr_dns_attr_flags
Line
Count
Source
142
162
{
143
162
  return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC);
144
162
}
decode.c:fr_dns_attr_flags
Line
Count
Source
142
41.1k
{
143
41.1k
  return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC);
144
41.1k
}
Unexecuted instantiation: encode.c:fr_dns_attr_flags
145
146
static inline bool fr_dns_flag_dns_label_any(fr_dict_attr_t const *da)
147
162
{
148
162
  fr_dns_attr_flags_t const *flags = fr_dns_attr_flags(da);
149
150
162
  return flags->dns_label || flags->dns_label_uncompressed;
151
162
}
base.c:fr_dns_flag_dns_label_any
Line
Count
Source
147
162
{
148
162
  fr_dns_attr_flags_t const *flags = fr_dns_attr_flags(da);
149
150
162
  return flags->dns_label || flags->dns_label_uncompressed;
151
162
}
Unexecuted instantiation: decode.c:fr_dns_flag_dns_label_any
Unexecuted instantiation: encode.c:fr_dns_flag_dns_label_any
152
153
42.1k
#define fr_dns_flag_dns_label(_da)      (fr_dns_attr_flags(_da)->dns_label)
154
#define fr_dns_flag_dns_label_uncompressed(_da)   (fr_dns_attr_flags(_da)->dns_label_uncompressed)
155
156
extern fr_table_num_ordered_t fr_dns_reason_fail_table[];
157
extern char const *fr_dns_packet_names[FR_DNS_CODE_MAX];
158
extern size_t fr_dns_reason_fail_table_len;
159
160
bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query, fr_dns_decode_fail_t *reason);
161
162
fr_dns_labels_t *fr_dns_labels_get(uint8_t const *packet, size_t packet_len, bool init_mark);
163
164
ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
165
          uint8_t const *packet, size_t packet_len, fr_dns_ctx_t *packet_ctx);
166
167
ssize_t fr_dns_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_dns_ctx_t *encode_ctx);
168
169
#ifdef __cplusplus
170
}
171
#endif