Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/ldns/rr_functions.c
39536 views
1
/*
2
* rr_function.c
3
*
4
* function that operate on specific rr types
5
*
6
* (c) NLnet Labs, 2004-2006
7
* See the file LICENSE for the license
8
*/
9
10
/*
11
* These come strait from perldoc Net::DNS::RR::xxx
12
* first the read variant, then the write. This is
13
* not complete.
14
*/
15
16
#include <ldns/config.h>
17
18
#include <ldns/ldns.h>
19
20
#include <limits.h>
21
#include <strings.h>
22
23
/**
24
* return a specific rdf
25
* \param[in] type type of RR
26
* \param[in] rr the rr itself
27
* \param[in] pos at which position to get it
28
* \return the rdf sought
29
*/
30
static ldns_rdf *
31
ldns_rr_function(ldns_rr_type type, const ldns_rr *rr, size_t pos)
32
{
33
if (!rr || ldns_rr_get_type(rr) != type) {
34
return NULL;
35
}
36
return ldns_rr_rdf(rr, pos);
37
}
38
39
/**
40
* set a specific rdf
41
* \param[in] type type of RR
42
* \param[in] rr the rr itself
43
* \param[in] rdf the rdf to set
44
* \param[in] pos at which position to set it
45
* \return true or false
46
*/
47
static bool
48
ldns_rr_set_function(ldns_rr_type type, ldns_rr *rr, ldns_rdf *rdf, size_t pos)
49
{
50
ldns_rdf *pop;
51
if (!rr || ldns_rr_get_type(rr) != type) {
52
return false;
53
}
54
pop = ldns_rr_set_rdf(rr, rdf, pos);
55
ldns_rdf_deep_free(pop);
56
return true;
57
}
58
59
/* A/AAAA records */
60
ldns_rdf *
61
ldns_rr_a_address(const ldns_rr *r)
62
{
63
/* 2 types to check, cannot use the macro */
64
if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
65
ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
66
return NULL;
67
}
68
return ldns_rr_rdf(r, 0);
69
}
70
71
bool
72
ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f)
73
{
74
/* 2 types to check, cannot use the macro... */
75
ldns_rdf *pop;
76
if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
77
ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
78
return false;
79
}
80
pop = ldns_rr_set_rdf(r, f, 0);
81
if (pop) {
82
LDNS_FREE(pop);
83
return true;
84
} else {
85
return false;
86
}
87
}
88
89
/* NS record */
90
ldns_rdf *
91
ldns_rr_ns_nsdname(const ldns_rr *r)
92
{
93
return ldns_rr_function(LDNS_RR_TYPE_NS, r, 0);
94
}
95
96
/* MX record */
97
ldns_rdf *
98
ldns_rr_mx_preference(const ldns_rr *r)
99
{
100
return ldns_rr_function(LDNS_RR_TYPE_MX, r, 0);
101
}
102
103
ldns_rdf *
104
ldns_rr_mx_exchange(const ldns_rr *r)
105
{
106
return ldns_rr_function(LDNS_RR_TYPE_MX, r, 1);
107
}
108
109
/* RRSIG record */
110
ldns_rdf *
111
ldns_rr_rrsig_typecovered(const ldns_rr *r)
112
{
113
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 0);
114
}
115
116
bool
117
ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f)
118
{
119
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 0);
120
}
121
122
ldns_rdf *
123
ldns_rr_rrsig_algorithm(const ldns_rr *r)
124
{
125
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 1);
126
}
127
128
bool
129
ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f)
130
{
131
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 1);
132
}
133
134
ldns_rdf *
135
ldns_rr_rrsig_labels(const ldns_rr *r)
136
{
137
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 2);
138
}
139
140
bool
141
ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f)
142
{
143
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 2);
144
}
145
146
ldns_rdf *
147
ldns_rr_rrsig_origttl(const ldns_rr *r)
148
{
149
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 3);
150
}
151
152
bool
153
ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f)
154
{
155
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 3);
156
}
157
158
ldns_rdf *
159
ldns_rr_rrsig_expiration(const ldns_rr *r)
160
{
161
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 4);
162
}
163
164
bool
165
ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f)
166
{
167
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 4);
168
}
169
170
ldns_rdf *
171
ldns_rr_rrsig_inception(const ldns_rr *r)
172
{
173
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 5);
174
}
175
176
bool
177
ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f)
178
{
179
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 5);
180
}
181
182
ldns_rdf *
183
ldns_rr_rrsig_keytag(const ldns_rr *r)
184
{
185
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 6);
186
}
187
188
bool
189
ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f)
190
{
191
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 6);
192
}
193
194
ldns_rdf *
195
ldns_rr_rrsig_signame(const ldns_rr *r)
196
{
197
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 7);
198
}
199
200
bool
201
ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f)
202
{
203
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 7);
204
}
205
206
ldns_rdf *
207
ldns_rr_rrsig_sig(const ldns_rr *r)
208
{
209
return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 8);
210
}
211
212
bool
213
ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f)
214
{
215
return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 8);
216
}
217
218
/* DNSKEY record */
219
ldns_rdf *
220
ldns_rr_dnskey_flags(const ldns_rr *r)
221
{
222
return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 0);
223
}
224
225
bool
226
ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f)
227
{
228
return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 0);
229
}
230
231
ldns_rdf *
232
ldns_rr_dnskey_protocol(const ldns_rr *r)
233
{
234
return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 1);
235
}
236
237
bool
238
ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f)
239
{
240
return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 1);
241
}
242
243
ldns_rdf *
244
ldns_rr_dnskey_algorithm(const ldns_rr *r)
245
{
246
return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 2);
247
}
248
249
bool
250
ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f)
251
{
252
return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 2);
253
}
254
255
ldns_rdf *
256
ldns_rr_dnskey_key(const ldns_rr *r)
257
{
258
return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 3);
259
}
260
261
bool
262
ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f)
263
{
264
return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 3);
265
}
266
267
size_t
268
ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
269
const size_t len,
270
const ldns_algorithm alg)
271
{
272
#ifdef USE_DSA
273
/* for DSA keys */
274
uint8_t t;
275
#endif /* USE_DSA */
276
277
/* for RSA keys */
278
uint16_t exp;
279
uint16_t int16;
280
281
switch ((ldns_signing_algorithm)alg) {
282
#ifdef USE_DSA
283
case LDNS_SIGN_DSA:
284
case LDNS_SIGN_DSA_NSEC3:
285
if (len > 0) {
286
t = keydata[0];
287
return (64 + t*8)*8;
288
} else {
289
return 0;
290
}
291
break;
292
#endif /* USE_DSA */
293
case LDNS_SIGN_RSAMD5:
294
case LDNS_SIGN_RSASHA1:
295
case LDNS_SIGN_RSASHA1_NSEC3:
296
#ifdef USE_SHA2
297
case LDNS_SIGN_RSASHA256:
298
case LDNS_SIGN_RSASHA512:
299
#endif
300
if (len > 0) {
301
if (keydata[0] == 0) {
302
/* big exponent */
303
if (len > 3) {
304
memmove(&int16, keydata + 1, 2);
305
exp = ntohs(int16);
306
return (len - exp - 3)*8;
307
} else {
308
return 0;
309
}
310
} else {
311
exp = keydata[0];
312
return (len-exp-1)*8;
313
}
314
} else {
315
return 0;
316
}
317
break;
318
#ifdef USE_GOST
319
case LDNS_SIGN_ECC_GOST:
320
return 512;
321
#endif
322
#ifdef USE_ECDSA
323
case LDNS_SIGN_ECDSAP256SHA256:
324
return 256;
325
case LDNS_SIGN_ECDSAP384SHA384:
326
return 384;
327
#endif
328
#ifdef USE_ED25519
329
case LDNS_SIGN_ED25519:
330
return 256;
331
#endif
332
#ifdef USE_ED448
333
case LDNS_SIGN_ED448:
334
return 456;
335
#endif
336
case LDNS_SIGN_HMACMD5:
337
return len;
338
default:
339
return 0;
340
}
341
}
342
343
size_t
344
ldns_rr_dnskey_key_size(const ldns_rr *key)
345
{
346
if (!key || !ldns_rr_dnskey_key(key)
347
|| !ldns_rr_dnskey_algorithm(key)) {
348
return 0;
349
}
350
return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)),
351
ldns_rdf_size(ldns_rr_dnskey_key(key)),
352
ldns_rdf2native_int8(ldns_rr_dnskey_algorithm(key))
353
);
354
}
355
356
uint32_t ldns_soa_serial_identity(uint32_t ATTR_UNUSED(unused), void *data)
357
{
358
return (uint32_t) (intptr_t) data;
359
}
360
361
uint32_t ldns_soa_serial_increment(uint32_t s, void *ATTR_UNUSED(unused))
362
{
363
return ldns_soa_serial_increment_by(s, (void *)1);
364
}
365
366
uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data)
367
{
368
return s + (intptr_t) data;
369
}
370
371
uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data)
372
{
373
struct tm tm;
374
char s_str[11];
375
int32_t new_s;
376
time_t t = data ? (time_t) (intptr_t) data : ldns_time(NULL);
377
378
(void) strftime(s_str, 11, "%Y%m%d00", localtime_r(&t, &tm));
379
new_s = (int32_t) atoi(s_str);
380
return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
381
}
382
383
uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
384
{
385
int32_t new_s = data ? (int32_t) (intptr_t) data
386
: (int32_t) ldns_time(NULL);
387
return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
388
}
389
390
void
391
ldns_rr_soa_increment(ldns_rr *soa)
392
{
393
ldns_rr_soa_increment_func_data(soa, ldns_soa_serial_increment, NULL);
394
}
395
396
void
397
ldns_rr_soa_increment_func(ldns_rr *soa, ldns_soa_serial_increment_func_t f)
398
{
399
ldns_rr_soa_increment_func_data(soa, f, NULL);
400
}
401
402
void
403
ldns_rr_soa_increment_func_data(ldns_rr *soa,
404
ldns_soa_serial_increment_func_t f, void *data)
405
{
406
ldns_rdf *prev_soa_serial_rdf;
407
if ( !soa || !f || ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA
408
|| !ldns_rr_rdf(soa, 2)) {
409
return;
410
}
411
prev_soa_serial_rdf = ldns_rr_set_rdf(
412
soa
413
, ldns_native2rdf_int32(
414
LDNS_RDF_TYPE_INT32
415
, (*f)( ldns_rdf2native_int32(
416
ldns_rr_rdf(soa, 2))
417
, data
418
)
419
)
420
, 2
421
);
422
LDNS_FREE(prev_soa_serial_rdf);
423
}
424
425
void
426
ldns_rr_soa_increment_func_int(ldns_rr *soa,
427
ldns_soa_serial_increment_func_t f, int data)
428
{
429
ldns_rr_soa_increment_func_data(soa, f, (void *) (intptr_t) data);
430
}
431
432
433