Coverage Report

Created: 2026-01-10 06:14

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: 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
}
base.c:fr_dns_attr_flags
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