Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/ldns/packet.c
39475 views
1
/*
2
* packet.c
3
*
4
* dns packet implementation
5
*
6
* a Net::DNS like library for C
7
*
8
* (c) NLnet Labs, 2004-2006
9
*
10
* See the file LICENSE for the license
11
*/
12
13
#include <ldns/config.h>
14
15
#include <ldns/ldns.h>
16
#include <ldns/internal.h>
17
18
#include <strings.h>
19
#include <limits.h>
20
21
#ifdef HAVE_SSL
22
#include <openssl/rand.h>
23
#endif
24
25
/* Access functions
26
* do this as functions to get type checking
27
*/
28
29
#define LDNS_EDNS_MASK_DO_BIT 0x8000
30
#define LDNS_EDNS_MASK_UNASSIGNED (0xFFFF & ~LDNS_EDNS_MASK_DO_BIT)
31
32
/* TODO defines for 3600 */
33
/* convert to and from numerical flag values */
34
ldns_lookup_table ldns_edns_flags[] = {
35
{ 3600, "do"},
36
{ 0, NULL}
37
};
38
39
/* read */
40
uint16_t
41
ldns_pkt_id(const ldns_pkt *packet)
42
{
43
return packet->_header->_id;
44
}
45
46
bool
47
ldns_pkt_qr(const ldns_pkt *packet)
48
{
49
return packet->_header->_qr;
50
}
51
52
bool
53
ldns_pkt_aa(const ldns_pkt *packet)
54
{
55
return packet->_header->_aa;
56
}
57
58
bool
59
ldns_pkt_tc(const ldns_pkt *packet)
60
{
61
return packet->_header->_tc;
62
}
63
64
bool
65
ldns_pkt_rd(const ldns_pkt *packet)
66
{
67
return packet->_header->_rd;
68
}
69
70
bool
71
ldns_pkt_cd(const ldns_pkt *packet)
72
{
73
return packet->_header->_cd;
74
}
75
76
bool
77
ldns_pkt_ra(const ldns_pkt *packet)
78
{
79
return packet->_header->_ra;
80
}
81
82
bool
83
ldns_pkt_ad(const ldns_pkt *packet)
84
{
85
return packet->_header->_ad;
86
}
87
88
ldns_pkt_opcode
89
ldns_pkt_get_opcode(const ldns_pkt *packet)
90
{
91
return packet->_header->_opcode;
92
}
93
94
ldns_pkt_rcode
95
ldns_pkt_get_rcode(const ldns_pkt *packet)
96
{
97
return packet->_header->_rcode;
98
}
99
100
uint16_t
101
ldns_pkt_qdcount(const ldns_pkt *packet)
102
{
103
return packet->_header->_qdcount;
104
}
105
106
uint16_t
107
ldns_pkt_ancount(const ldns_pkt *packet)
108
{
109
return packet->_header->_ancount;
110
}
111
112
uint16_t
113
ldns_pkt_nscount(const ldns_pkt *packet)
114
{
115
return packet->_header->_nscount;
116
}
117
118
uint16_t
119
ldns_pkt_arcount(const ldns_pkt *packet)
120
{
121
return packet->_header->_arcount;
122
}
123
124
ldns_rr_list *
125
ldns_pkt_question(const ldns_pkt *packet)
126
{
127
return packet->_question;
128
}
129
130
ldns_rr_list *
131
ldns_pkt_answer(const ldns_pkt *packet)
132
{
133
return packet->_answer;
134
}
135
136
ldns_rr_list *
137
ldns_pkt_authority(const ldns_pkt *packet)
138
{
139
return packet->_authority;
140
}
141
142
ldns_rr_list *
143
ldns_pkt_additional(const ldns_pkt *packet)
144
{
145
return packet->_additional;
146
}
147
148
/* return ALL section concatenated */
149
ldns_rr_list *
150
ldns_pkt_all(const ldns_pkt *packet)
151
{
152
ldns_rr_list *all, *prev_all;
153
154
all = ldns_rr_list_cat_clone(
155
ldns_pkt_question(packet),
156
ldns_pkt_answer(packet));
157
prev_all = all;
158
all = ldns_rr_list_cat_clone(all,
159
ldns_pkt_authority(packet));
160
ldns_rr_list_deep_free(prev_all);
161
prev_all = all;
162
all = ldns_rr_list_cat_clone(all,
163
ldns_pkt_additional(packet));
164
ldns_rr_list_deep_free(prev_all);
165
return all;
166
}
167
168
ldns_rr_list *
169
ldns_pkt_all_noquestion(const ldns_pkt *packet)
170
{
171
ldns_rr_list *all, *all2;
172
173
all = ldns_rr_list_cat_clone(
174
ldns_pkt_answer(packet),
175
ldns_pkt_authority(packet));
176
all2 = ldns_rr_list_cat_clone(all,
177
ldns_pkt_additional(packet));
178
179
ldns_rr_list_deep_free(all);
180
return all2;
181
}
182
183
size_t
184
ldns_pkt_size(const ldns_pkt *packet)
185
{
186
return packet->_size;
187
}
188
189
uint32_t
190
ldns_pkt_querytime(const ldns_pkt *packet)
191
{
192
return packet->_querytime;
193
}
194
195
ldns_rdf *
196
ldns_pkt_answerfrom(const ldns_pkt *packet)
197
{
198
return packet->_answerfrom;
199
}
200
201
struct timeval
202
ldns_pkt_timestamp(const ldns_pkt *packet)
203
{
204
return packet->timestamp;
205
}
206
207
uint16_t
208
ldns_pkt_edns_udp_size(const ldns_pkt *packet)
209
{
210
return packet->_edns_udp_size;
211
}
212
213
uint8_t
214
ldns_pkt_edns_extended_rcode(const ldns_pkt *packet)
215
{
216
return packet->_edns_extended_rcode;
217
}
218
219
uint8_t
220
ldns_pkt_edns_version(const ldns_pkt *packet)
221
{
222
return packet->_edns_version;
223
}
224
225
uint16_t
226
ldns_pkt_edns_z(const ldns_pkt *packet)
227
{
228
return packet->_edns_z;
229
}
230
231
bool
232
ldns_pkt_edns_do(const ldns_pkt *packet)
233
{
234
return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT);
235
}
236
237
void
238
ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
239
{
240
if (value) {
241
packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT;
242
} else {
243
packet->_edns_z = packet->_edns_z & ~LDNS_EDNS_MASK_DO_BIT;
244
}
245
}
246
247
uint16_t
248
ldns_pkt_edns_unassigned(const ldns_pkt *packet)
249
{
250
return (packet->_edns_z & LDNS_EDNS_MASK_UNASSIGNED);
251
}
252
253
void
254
ldns_pkt_set_edns_unassigned(ldns_pkt *packet, uint16_t value)
255
{
256
packet->_edns_z = (packet->_edns_z & ~LDNS_EDNS_MASK_UNASSIGNED)
257
| (value & LDNS_EDNS_MASK_UNASSIGNED);
258
}
259
260
ldns_rdf *
261
ldns_pkt_edns_data(const ldns_pkt *packet)
262
{
263
return packet->_edns_data;
264
}
265
266
/* return only those rr that share the ownername */
267
ldns_rr_list *
268
ldns_pkt_rr_list_by_name(const ldns_pkt *packet,
269
const ldns_rdf *ownername,
270
ldns_pkt_section sec)
271
{
272
ldns_rr_list *rrs;
273
ldns_rr_list *ret;
274
uint16_t i;
275
276
if (!packet) {
277
return NULL;
278
}
279
280
rrs = ldns_pkt_get_section_clone(packet, sec);
281
ret = NULL;
282
283
for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
284
if (ldns_dname_compare(ldns_rr_owner(
285
ldns_rr_list_rr(rrs, i)),
286
ownername) == 0) {
287
/* owner names match */
288
if (ret == NULL) {
289
ret = ldns_rr_list_new();
290
}
291
ldns_rr_list_push_rr(ret,
292
ldns_rr_clone(
293
ldns_rr_list_rr(rrs, i))
294
);
295
}
296
}
297
298
ldns_rr_list_deep_free(rrs);
299
300
return ret;
301
}
302
303
/* return only those rr that share a type */
304
ldns_rr_list *
305
ldns_pkt_rr_list_by_type(const ldns_pkt *packet,
306
ldns_rr_type type,
307
ldns_pkt_section sec)
308
{
309
ldns_rr_list *rrs;
310
ldns_rr_list *new;
311
uint16_t i;
312
313
if(!packet) {
314
return NULL;
315
}
316
317
rrs = ldns_pkt_get_section_clone(packet, sec);
318
new = ldns_rr_list_new();
319
320
for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
321
if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
322
/* types match */
323
ldns_rr_list_push_rr(new,
324
ldns_rr_clone(
325
ldns_rr_list_rr(rrs, i))
326
);
327
}
328
}
329
ldns_rr_list_deep_free(rrs);
330
331
if (ldns_rr_list_rr_count(new) == 0) {
332
ldns_rr_list_free(new);
333
return NULL;
334
} else {
335
return new;
336
}
337
}
338
339
/* return only those rrs that share name and type */
340
ldns_rr_list *
341
ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet,
342
const ldns_rdf *ownername,
343
ldns_rr_type type,
344
ldns_pkt_section sec)
345
{
346
ldns_rr_list *rrs;
347
ldns_rr_list *new;
348
ldns_rr_list *ret;
349
uint16_t i;
350
351
if(!packet) {
352
return NULL;
353
}
354
355
rrs = ldns_pkt_get_section_clone(packet, sec);
356
new = ldns_rr_list_new();
357
ret = NULL;
358
359
for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
360
if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
361
ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
362
ownername
363
) == 0
364
) {
365
/* types match */
366
ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
367
ret = new;
368
}
369
}
370
ldns_rr_list_deep_free(rrs);
371
if (!ret) {
372
ldns_rr_list_free(new);
373
}
374
return ret;
375
}
376
377
bool
378
ldns_pkt_rr(const ldns_pkt *pkt, ldns_pkt_section sec, const ldns_rr *rr)
379
{
380
bool result = false;
381
382
switch (sec) {
383
case LDNS_SECTION_QUESTION:
384
return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
385
case LDNS_SECTION_ANSWER:
386
return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr);
387
case LDNS_SECTION_AUTHORITY:
388
return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr);
389
case LDNS_SECTION_ADDITIONAL:
390
return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
391
case LDNS_SECTION_ANY:
392
result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
393
/* fallthrough */
394
case LDNS_SECTION_ANY_NOQUESTION:
395
result = result
396
|| ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr)
397
|| ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr)
398
|| ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
399
}
400
401
return result;
402
}
403
404
uint16_t
405
ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
406
{
407
switch(s) {
408
case LDNS_SECTION_QUESTION:
409
return ldns_pkt_qdcount(packet);
410
case LDNS_SECTION_ANSWER:
411
return ldns_pkt_ancount(packet);
412
case LDNS_SECTION_AUTHORITY:
413
return ldns_pkt_nscount(packet);
414
case LDNS_SECTION_ADDITIONAL:
415
return ldns_pkt_arcount(packet);
416
case LDNS_SECTION_ANY:
417
return ldns_pkt_qdcount(packet) +
418
ldns_pkt_ancount(packet) +
419
ldns_pkt_nscount(packet) +
420
ldns_pkt_arcount(packet);
421
case LDNS_SECTION_ANY_NOQUESTION:
422
return ldns_pkt_ancount(packet) +
423
ldns_pkt_nscount(packet) +
424
ldns_pkt_arcount(packet);
425
default:
426
return 0;
427
}
428
}
429
430
bool
431
ldns_pkt_empty(ldns_pkt *p)
432
{
433
if (!p) {
434
return true; /* NULL is empty? */
435
}
436
if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
437
return false;
438
} else {
439
return true;
440
}
441
}
442
443
444
ldns_rr_list *
445
ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s)
446
{
447
switch(s) {
448
case LDNS_SECTION_QUESTION:
449
return ldns_rr_list_clone(ldns_pkt_question(packet));
450
case LDNS_SECTION_ANSWER:
451
return ldns_rr_list_clone(ldns_pkt_answer(packet));
452
case LDNS_SECTION_AUTHORITY:
453
return ldns_rr_list_clone(ldns_pkt_authority(packet));
454
case LDNS_SECTION_ADDITIONAL:
455
return ldns_rr_list_clone(ldns_pkt_additional(packet));
456
case LDNS_SECTION_ANY:
457
/* these are already clones */
458
return ldns_pkt_all(packet);
459
case LDNS_SECTION_ANY_NOQUESTION:
460
return ldns_pkt_all_noquestion(packet);
461
default:
462
return NULL;
463
}
464
}
465
466
ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
467
return pkt->_tsig_rr;
468
}
469
470
/* write */
471
void
472
ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
473
{
474
packet->_header->_id = id;
475
}
476
477
void
478
ldns_pkt_set_random_id(ldns_pkt *packet)
479
{
480
uint16_t rid = ldns_get_random();
481
ldns_pkt_set_id(packet, rid);
482
}
483
484
485
void
486
ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
487
{
488
packet->_header->_qr = qr;
489
}
490
491
void
492
ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
493
{
494
packet->_header->_aa = aa;
495
}
496
497
void
498
ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
499
{
500
packet->_header->_tc = tc;
501
}
502
503
void
504
ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
505
{
506
packet->_header->_rd = rd;
507
}
508
509
void
510
ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
511
{
512
p->_additional = rr;
513
}
514
515
void
516
ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
517
{
518
p->_question = rr;
519
}
520
521
void
522
ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
523
{
524
p->_answer = rr;
525
}
526
527
void
528
ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
529
{
530
p->_authority = rr;
531
}
532
533
void
534
ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
535
{
536
packet->_header->_cd = cd;
537
}
538
539
void
540
ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
541
{
542
packet->_header->_ra = ra;
543
}
544
545
void
546
ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
547
{
548
packet->_header->_ad = ad;
549
}
550
551
void
552
ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
553
{
554
packet->_header->_opcode = opcode;
555
}
556
557
void
558
ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
559
{
560
packet->_header->_rcode = rcode;
561
}
562
563
void
564
ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
565
{
566
packet->_header->_qdcount = qdcount;
567
}
568
569
void
570
ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
571
{
572
packet->_header->_ancount = ancount;
573
}
574
575
void
576
ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
577
{
578
packet->_header->_nscount = nscount;
579
}
580
581
void
582
ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
583
{
584
packet->_header->_arcount = arcount;
585
}
586
587
void
588
ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time)
589
{
590
packet->_querytime = time;
591
}
592
593
void
594
ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
595
{
596
packet->_answerfrom = answerfrom;
597
}
598
599
void
600
ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
601
{
602
packet->timestamp.tv_sec = timeval.tv_sec;
603
packet->timestamp.tv_usec = timeval.tv_usec;
604
}
605
606
void
607
ldns_pkt_set_size(ldns_pkt *packet, size_t s)
608
{
609
packet->_size = s;
610
}
611
612
void
613
ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
614
{
615
packet->_edns_udp_size = s;
616
}
617
618
void
619
ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
620
{
621
packet->_edns_extended_rcode = c;
622
}
623
624
void
625
ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
626
{
627
packet->_edns_version = v;
628
}
629
630
void
631
ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
632
{
633
packet->_edns_z = z;
634
}
635
636
void
637
ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
638
{
639
packet->_edns_data = data;
640
}
641
642
void
643
ldns_pkt_set_edns_option_list(ldns_pkt *packet, ldns_edns_option_list *list)
644
{
645
if (packet->_edns_list)
646
ldns_edns_option_list_deep_free(packet->_edns_list);
647
packet->_edns_list = list;
648
}
649
650
651
void
652
ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
653
{
654
switch(s) {
655
case LDNS_SECTION_QUESTION:
656
ldns_pkt_set_qdcount(packet, count);
657
break;
658
case LDNS_SECTION_ANSWER:
659
ldns_pkt_set_ancount(packet, count);
660
break;
661
case LDNS_SECTION_AUTHORITY:
662
ldns_pkt_set_nscount(packet, count);
663
break;
664
case LDNS_SECTION_ADDITIONAL:
665
ldns_pkt_set_arcount(packet, count);
666
break;
667
case LDNS_SECTION_ANY:
668
case LDNS_SECTION_ANY_NOQUESTION:
669
break;
670
}
671
}
672
673
void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
674
{
675
pkt->_tsig_rr = rr;
676
}
677
678
bool
679
ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
680
{
681
switch(section) {
682
case LDNS_SECTION_QUESTION:
683
if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
684
return false;
685
}
686
ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
687
break;
688
case LDNS_SECTION_ANSWER:
689
if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
690
return false;
691
}
692
ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
693
break;
694
case LDNS_SECTION_AUTHORITY:
695
if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
696
return false;
697
}
698
ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
699
break;
700
case LDNS_SECTION_ADDITIONAL:
701
if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
702
return false;
703
}
704
ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
705
break;
706
case LDNS_SECTION_ANY:
707
case LDNS_SECTION_ANY_NOQUESTION:
708
/* shouldn't this error? */
709
break;
710
}
711
return true;
712
}
713
714
bool
715
ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
716
{
717
718
/* check to see if its there */
719
if (ldns_pkt_rr(pkt, sec, rr)) {
720
/* already there */
721
return false;
722
}
723
return ldns_pkt_push_rr(pkt, sec, rr);
724
}
725
726
bool
727
ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
728
{
729
size_t i;
730
for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
731
if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
732
return false;
733
}
734
}
735
return true;
736
}
737
738
bool
739
ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
740
{
741
size_t i;
742
for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
743
if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
744
return false;
745
}
746
}
747
return true;
748
}
749
750
bool
751
ldns_pkt_edns(const ldns_pkt *pkt)
752
{
753
return (ldns_pkt_edns_udp_size(pkt) > 0 ||
754
ldns_pkt_edns_extended_rcode(pkt) > 0 ||
755
ldns_pkt_edns_data(pkt) ||
756
ldns_pkt_edns_do(pkt) ||
757
pkt->_edns_list ||
758
pkt->_edns_present
759
);
760
}
761
762
ldns_edns_option_list*
763
pkt_edns_data2edns_option_list(const ldns_rdf *edns_data)
764
{
765
size_t pos = 0;
766
ldns_edns_option_list* edns_list;
767
size_t max;
768
const uint8_t* wire;
769
770
if (!edns_data)
771
return NULL;
772
773
max = ldns_rdf_size(edns_data);
774
wire = ldns_rdf_data(edns_data);
775
if (!max)
776
return NULL;
777
778
if (!(edns_list = ldns_edns_option_list_new()))
779
return NULL;
780
781
while (pos < max) {
782
ldns_edns_option* edns;
783
uint8_t *data;
784
785
if (pos + 4 > max) { /* make sure the header is */
786
ldns_edns_option_list_deep_free(edns_list);
787
return NULL;
788
}
789
ldns_edns_option_code code = ldns_read_uint16(&wire[pos]);
790
size_t size = ldns_read_uint16(&wire[pos+2]);
791
pos += 4;
792
793
if (pos + size > max) { /* make sure the size fits the data */
794
ldns_edns_option_list_deep_free(edns_list);
795
return NULL;
796
}
797
data = LDNS_XMALLOC(uint8_t, size);
798
799
if (!data) {
800
ldns_edns_option_list_deep_free(edns_list);
801
return NULL;
802
}
803
memcpy(data, &wire[pos], size);
804
pos += size;
805
806
edns = ldns_edns_new(code, size, data);
807
808
if (!edns) {
809
ldns_edns_option_list_deep_free(edns_list);
810
return NULL;
811
}
812
if (!ldns_edns_option_list_push(edns_list, edns)) {
813
ldns_edns_option_list_deep_free(edns_list);
814
return NULL;
815
}
816
}
817
return edns_list;
818
819
}
820
821
ldns_edns_option_list*
822
ldns_pkt_edns_get_option_list(ldns_pkt *packet)
823
{
824
/* return the list if it already exists */
825
if (packet->_edns_list != NULL)
826
return packet->_edns_list;
827
828
/* if the list doesn't exists, we create it by parsing the
829
* packet->_edns_data
830
*/
831
if (!ldns_pkt_edns_data(packet))
832
return NULL;
833
834
return ( packet->_edns_list
835
= pkt_edns_data2edns_option_list(ldns_pkt_edns_data(packet)));
836
}
837
838
839
/* Create/destroy/convert functions
840
*/
841
ldns_pkt *
842
ldns_pkt_new(void)
843
{
844
ldns_pkt *packet;
845
packet = LDNS_MALLOC(ldns_pkt);
846
if (!packet) {
847
return NULL;
848
}
849
850
packet->_header = LDNS_MALLOC(ldns_hdr);
851
if (!packet->_header) {
852
LDNS_FREE(packet);
853
return NULL;
854
}
855
856
packet->_question = ldns_rr_list_new();
857
packet->_answer = ldns_rr_list_new();
858
packet->_authority = ldns_rr_list_new();
859
packet->_additional = ldns_rr_list_new();
860
861
/* default everything to false */
862
ldns_pkt_set_qr(packet, false);
863
ldns_pkt_set_aa(packet, false);
864
ldns_pkt_set_tc(packet, false);
865
ldns_pkt_set_rd(packet, false);
866
ldns_pkt_set_ra(packet, false);
867
ldns_pkt_set_ad(packet, false);
868
ldns_pkt_set_cd(packet, false);
869
870
ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
871
ldns_pkt_set_rcode(packet, 0);
872
ldns_pkt_set_id(packet, 0);
873
ldns_pkt_set_size(packet, 0);
874
ldns_pkt_set_querytime(packet, 0);
875
memset(&packet->timestamp, 0, sizeof(packet->timestamp));
876
ldns_pkt_set_answerfrom(packet, NULL);
877
ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
878
ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
879
ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
880
ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
881
882
ldns_pkt_set_edns_udp_size(packet, 0);
883
ldns_pkt_set_edns_extended_rcode(packet, 0);
884
ldns_pkt_set_edns_version(packet, 0);
885
ldns_pkt_set_edns_z(packet, 0);
886
ldns_pkt_set_edns_data(packet, NULL);
887
packet->_edns_list = NULL;
888
packet->_edns_present = false;
889
890
ldns_pkt_set_tsig(packet, NULL);
891
892
return packet;
893
}
894
895
void
896
ldns_pkt_free(ldns_pkt *packet)
897
{
898
if (packet) {
899
LDNS_FREE(packet->_header);
900
ldns_rr_list_deep_free(packet->_question);
901
ldns_rr_list_deep_free(packet->_answer);
902
ldns_rr_list_deep_free(packet->_authority);
903
ldns_rr_list_deep_free(packet->_additional);
904
ldns_rr_free(packet->_tsig_rr);
905
ldns_rdf_deep_free(packet->_edns_data);
906
ldns_edns_option_list_deep_free(packet->_edns_list);
907
ldns_rdf_deep_free(packet->_answerfrom);
908
LDNS_FREE(packet);
909
}
910
}
911
912
bool
913
ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
914
{
915
if (!packet) {
916
return false;
917
}
918
if ((flags & LDNS_QR) == LDNS_QR) {
919
ldns_pkt_set_qr(packet, true);
920
}
921
if ((flags & LDNS_AA) == LDNS_AA) {
922
ldns_pkt_set_aa(packet, true);
923
}
924
if ((flags & LDNS_RD) == LDNS_RD) {
925
ldns_pkt_set_rd(packet, true);
926
}
927
if ((flags & LDNS_TC) == LDNS_TC) {
928
ldns_pkt_set_tc(packet, true);
929
}
930
if ((flags & LDNS_CD) == LDNS_CD) {
931
ldns_pkt_set_cd(packet, true);
932
}
933
if ((flags & LDNS_RA) == LDNS_RA) {
934
ldns_pkt_set_ra(packet, true);
935
}
936
if ((flags & LDNS_AD) == LDNS_AD) {
937
ldns_pkt_set_ad(packet, true);
938
}
939
return true;
940
}
941
942
943
static ldns_rr*
944
ldns_pkt_authsoa(const ldns_rdf* rr_name, ldns_rr_class rr_class)
945
{
946
ldns_rr* soa_rr = ldns_rr_new();
947
ldns_rdf *owner_rdf;
948
ldns_rdf *mname_rdf;
949
ldns_rdf *rname_rdf;
950
ldns_rdf *serial_rdf;
951
ldns_rdf *refresh_rdf;
952
ldns_rdf *retry_rdf;
953
ldns_rdf *expire_rdf;
954
ldns_rdf *minimum_rdf;
955
956
if (!soa_rr) {
957
return NULL;
958
}
959
owner_rdf = ldns_rdf_clone(rr_name);
960
if (!owner_rdf) {
961
ldns_rr_free(soa_rr);
962
return NULL;
963
}
964
965
ldns_rr_set_owner(soa_rr, owner_rdf);
966
ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA);
967
ldns_rr_set_class(soa_rr, rr_class);
968
ldns_rr_set_question(soa_rr, false);
969
970
if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
971
ldns_rr_free(soa_rr);
972
return NULL;
973
} else {
974
ldns_rr_push_rdf(soa_rr, mname_rdf);
975
}
976
if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
977
ldns_rr_free(soa_rr);
978
return NULL;
979
} else {
980
ldns_rr_push_rdf(soa_rr, rname_rdf);
981
}
982
serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
983
if (!serial_rdf) {
984
ldns_rr_free(soa_rr);
985
return NULL;
986
} else {
987
ldns_rr_push_rdf(soa_rr, serial_rdf);
988
}
989
refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
990
if (!refresh_rdf) {
991
ldns_rr_free(soa_rr);
992
return NULL;
993
} else {
994
ldns_rr_push_rdf(soa_rr, refresh_rdf);
995
}
996
retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
997
if (!retry_rdf) {
998
ldns_rr_free(soa_rr);
999
return NULL;
1000
} else {
1001
ldns_rr_push_rdf(soa_rr, retry_rdf);
1002
}
1003
expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1004
if (!expire_rdf) {
1005
ldns_rr_free(soa_rr);
1006
return NULL;
1007
} else {
1008
ldns_rr_push_rdf(soa_rr, expire_rdf);
1009
}
1010
minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1011
if (!minimum_rdf) {
1012
ldns_rr_free(soa_rr);
1013
return NULL;
1014
} else {
1015
ldns_rr_push_rdf(soa_rr, minimum_rdf);
1016
}
1017
return soa_rr;
1018
}
1019
1020
1021
static ldns_status
1022
ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name,
1023
ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags,
1024
ldns_rr* authsoa_rr)
1025
{
1026
ldns_pkt *packet;
1027
ldns_rr *question_rr;
1028
ldns_rdf *name_rdf;
1029
1030
packet = ldns_pkt_new();
1031
if (!packet) {
1032
return LDNS_STATUS_MEM_ERR;
1033
}
1034
1035
if (!ldns_pkt_set_flags(packet, flags)) {
1036
ldns_pkt_free(packet);
1037
return LDNS_STATUS_ERR;
1038
}
1039
1040
question_rr = ldns_rr_new();
1041
if (!question_rr) {
1042
ldns_pkt_free(packet);
1043
return LDNS_STATUS_MEM_ERR;
1044
}
1045
1046
if (rr_type == 0) {
1047
rr_type = LDNS_RR_TYPE_A;
1048
}
1049
if (rr_class == 0) {
1050
rr_class = LDNS_RR_CLASS_IN;
1051
}
1052
1053
if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
1054
ldns_rr_set_owner(question_rr, name_rdf);
1055
ldns_rr_set_type(question_rr, rr_type);
1056
ldns_rr_set_class(question_rr, rr_class);
1057
ldns_rr_set_question(question_rr, true);
1058
1059
ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
1060
} else {
1061
ldns_rr_free(question_rr);
1062
ldns_pkt_free(packet);
1063
return LDNS_STATUS_ERR;
1064
}
1065
1066
if (authsoa_rr) {
1067
ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
1068
}
1069
1070
packet->_tsig_rr = NULL;
1071
ldns_pkt_set_answerfrom(packet, NULL);
1072
if (p) {
1073
*p = packet;
1074
return LDNS_STATUS_OK;
1075
} else {
1076
ldns_pkt_free(packet);
1077
return LDNS_STATUS_NULL;
1078
}
1079
}
1080
1081
ldns_status
1082
ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name,
1083
ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
1084
{
1085
return ldns_pkt_query_new_frm_str_internal(p, name, rr_type,
1086
rr_class, flags, NULL);
1087
}
1088
1089
ldns_status
1090
ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name,
1091
ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa)
1092
{
1093
ldns_rr* authsoa_rr = soa;
1094
if (!authsoa_rr) {
1095
ldns_rdf *name_rdf;
1096
if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
1097
authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class);
1098
}
1099
ldns_rdf_free(name_rdf);
1100
}
1101
return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR,
1102
rr_class, flags, authsoa_rr);
1103
}
1104
1105
static ldns_pkt *
1106
ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type,
1107
ldns_rr_class rr_class, uint16_t flags, ldns_rr* authsoa_rr)
1108
{
1109
ldns_pkt *packet;
1110
ldns_rr *question_rr;
1111
1112
packet = ldns_pkt_new();
1113
if (!packet) {
1114
return NULL;
1115
}
1116
1117
if (!ldns_pkt_set_flags(packet, flags)) {
1118
return NULL;
1119
}
1120
1121
question_rr = ldns_rr_new();
1122
if (!question_rr) {
1123
ldns_pkt_free(packet);
1124
return NULL;
1125
}
1126
1127
if (rr_type == 0) {
1128
rr_type = LDNS_RR_TYPE_A;
1129
}
1130
if (rr_class == 0) {
1131
rr_class = LDNS_RR_CLASS_IN;
1132
}
1133
1134
ldns_rr_set_owner(question_rr, rr_name);
1135
ldns_rr_set_type(question_rr, rr_type);
1136
ldns_rr_set_class(question_rr, rr_class);
1137
ldns_rr_set_question(question_rr, true);
1138
ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
1139
1140
if (authsoa_rr) {
1141
ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
1142
}
1143
1144
packet->_tsig_rr = NULL;
1145
return packet;
1146
}
1147
1148
ldns_pkt *
1149
ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type,
1150
ldns_rr_class rr_class, uint16_t flags)
1151
{
1152
return ldns_pkt_query_new_internal(rr_name, rr_type,
1153
rr_class, flags, NULL);
1154
}
1155
1156
ldns_pkt *
1157
ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class,
1158
uint16_t flags, ldns_rr* soa)
1159
{
1160
ldns_rr* authsoa_rr = soa;
1161
if (!authsoa_rr) {
1162
authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class);
1163
}
1164
return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR,
1165
rr_class, flags, authsoa_rr);
1166
}
1167
1168
ldns_pkt_type
1169
ldns_pkt_reply_type(const ldns_pkt *p)
1170
{
1171
ldns_rr_list *tmp;
1172
1173
if (!p) {
1174
return LDNS_PACKET_UNKNOWN;
1175
}
1176
1177
if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
1178
return LDNS_PACKET_NXDOMAIN;
1179
}
1180
1181
if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
1182
&& ldns_pkt_nscount(p) == 1) {
1183
1184
/* check for SOA */
1185
tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA,
1186
LDNS_SECTION_AUTHORITY);
1187
if (tmp) {
1188
ldns_rr_list_deep_free(tmp);
1189
return LDNS_PACKET_NODATA;
1190
} else {
1191
/* I have no idea ... */
1192
}
1193
}
1194
1195
if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
1196
tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
1197
LDNS_SECTION_AUTHORITY);
1198
if (tmp) {
1199
/* there are nameservers here */
1200
ldns_rr_list_deep_free(tmp);
1201
return LDNS_PACKET_REFERRAL;
1202
} else {
1203
/* I have no idea */
1204
}
1205
ldns_rr_list_deep_free(tmp);
1206
}
1207
1208
/* if we cannot determine the packet type, we say it's an
1209
* answer...
1210
*/
1211
return LDNS_PACKET_ANSWER;
1212
}
1213
1214
ldns_pkt *
1215
ldns_pkt_clone(const ldns_pkt *pkt)
1216
{
1217
ldns_pkt *new_pkt;
1218
1219
if (!pkt) {
1220
return NULL;
1221
}
1222
new_pkt = ldns_pkt_new();
1223
1224
ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
1225
ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
1226
ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
1227
ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
1228
ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
1229
ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
1230
ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
1231
ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
1232
ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
1233
ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
1234
ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
1235
ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
1236
ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
1237
ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
1238
if (ldns_pkt_answerfrom(pkt))
1239
ldns_pkt_set_answerfrom(new_pkt,
1240
ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
1241
ldns_pkt_set_timestamp(new_pkt, ldns_pkt_timestamp(pkt));
1242
ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
1243
ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
1244
ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
1245
1246
ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt));
1247
ldns_pkt_set_edns_extended_rcode(new_pkt,
1248
ldns_pkt_edns_extended_rcode(pkt));
1249
ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt));
1250
new_pkt->_edns_present = pkt->_edns_present;
1251
ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt));
1252
if(ldns_pkt_edns_data(pkt))
1253
ldns_pkt_set_edns_data(new_pkt,
1254
ldns_rdf_clone(ldns_pkt_edns_data(pkt)));
1255
ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt));
1256
if (pkt->_edns_list)
1257
ldns_pkt_set_edns_option_list(new_pkt,
1258
ldns_edns_option_list_clone(pkt->_edns_list));
1259
1260
ldns_rr_list_deep_free(new_pkt->_question);
1261
ldns_rr_list_deep_free(new_pkt->_answer);
1262
ldns_rr_list_deep_free(new_pkt->_authority);
1263
ldns_rr_list_deep_free(new_pkt->_additional);
1264
new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
1265
new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
1266
new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
1267
new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
1268
return new_pkt;
1269
}
1270
1271