OpenDNSSEC-signer  1.4.5
buffer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
49 #include "config.h"
50 #include "shared/log.h"
51 #include "wire/buffer.h"
52 
53 #include <string.h>
54 
55 static const char* buffer_str = "buffer";
56 
58  { LDNS_RCODE_NOERROR, "NOERROR" },
59  { LDNS_RCODE_FORMERR, "FORMERR" },
60  { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
61  { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
62  { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
63  { LDNS_RCODE_REFUSED, "REFUSED" },
64  { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
65  { LDNS_RCODE_YXRRSET, "YXRRSET" },
66  { LDNS_RCODE_NXRRSET, "NXRRSET" },
67  { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
68  { LDNS_RCODE_NOTZONE, "NOTZONE" },
69  { 0, NULL }
70 };
71 
72 
78 buffer_create(allocator_type* allocator, size_t capacity)
79 {
80  buffer_type* buffer = NULL;
81  if (!allocator || !capacity) {
82  return NULL;
83  }
84  buffer = (buffer_type *) allocator_alloc(allocator, sizeof(buffer_type));
85  if (!buffer) {
86  return NULL;
87  }
88  buffer->data = (uint8_t*) calloc(capacity, sizeof(uint8_t));
89  buffer->position = 0;
90  buffer->limit = capacity;
91  buffer->capacity = capacity;
92  buffer->fixed = 0;
93  return buffer;
94 }
95 
96 
101 void
102 buffer_create_from(buffer_type* buffer, void* data, size_t size)
103 {
104  ods_log_assert(buffer);
105  buffer->data = (uint8_t*) data;
106  buffer->position = 0;
107  buffer->limit = size;
108  buffer->capacity = size;
109  buffer->fixed = 1;
110  return;
111 }
112 
113 
118 void
120 {
121  ods_log_assert(buffer);
122  buffer->position = 0;
123  buffer->limit = buffer->capacity;
124  return;
125 }
126 
127 
132 void
134 {
135  ods_log_assert(buffer);
136  buffer->limit = buffer->position;
137  buffer->position = 0;
138  return;
139 }
140 
141 
146 void
148 {
149  ods_log_assert(buffer);
150  buffer->position = 0;
151  return;
152 }
153 
154 
159 size_t
161 {
162  ods_log_assert(buffer);
163  return buffer->position;
164 }
165 
166 
171 void
172 buffer_set_position(buffer_type* buffer, size_t pos)
173 {
174  ods_log_assert(buffer);
175  ods_log_assert(pos <= buffer->limit);
176  buffer->position = pos;
177  return;
178 }
179 
180 
185 void
186 buffer_skip(buffer_type* buffer, ssize_t count)
187 {
188  ods_log_assert(buffer);
189  ods_log_assert(buffer->position + count <= buffer->limit);
190  buffer->position += count;
191  return;
192 }
193 
194 
199 static int
200 get_bit(uint8_t bits[], size_t index)
201 {
202  return bits[index / 8] & (1 << (7 - index % 8));
203 }
204 
205 
210 static void
211 set_bit(uint8_t bits[], size_t index)
212 {
213  bits[index / 8] |= (1 << (7 - index % 8));
214  return;
215 }
216 
217 
222 static int
223 label_is_pointer(const uint8_t* label)
224 {
225  ods_log_assert(label);
226  return (label[0] & 0xc0) == 0xc0;
227 }
228 
229 
234 static uint16_t
235 label_pointer_location(const uint8_t* label)
236 {
237  ods_log_assert(label);
238  ods_log_assert(label_is_pointer(label));
239  return ((uint16_t) (label[0] & ~0xc0) << 8) | (uint16_t) label[1];
240 }
241 
242 
247 static int
248 label_is_normal(const uint8_t* label)
249 {
250  ods_log_assert(label);
251  return (label[0] & 0xc0) == 0;
252 }
253 
254 /*
255  * Is root label?
256  *
257  */
258 static inline int
259 label_is_root(const uint8_t* label)
260 {
261  ods_log_assert(label);
262  return label[0] == 0;
263 }
264 
265 
266 /*
267  * Label length.
268  *
269  */
270 static uint8_t
271 label_length(const uint8_t* label)
272 {
273  ods_log_assert(label);
274  ods_log_assert(label_is_normal(label));
275  return label[0];
276 }
277 
278 
283 size_t
284 buffer_read_dname(buffer_type* buffer, uint8_t* dname, unsigned allow_pointers)
285 {
286  int done = 0;
287  uint8_t visited[(MAX_PACKET_SIZE+7)/8];
288  size_t dname_length = 0;
289  const uint8_t *label = NULL;
290  ssize_t mark = -1;
291  ods_log_assert(buffer);
292  memset(visited, 0, (buffer_limit(buffer)+7)/8);
293 
294  while (!done) {
295  if (!buffer_available(buffer, 1)) {
296  return 0;
297  }
298  if (get_bit(visited, buffer_position(buffer))) {
299  ods_log_error("[%s] dname loop!", buffer_str);
300  return 0;
301  }
302  set_bit(visited, buffer_position(buffer));
303  label = buffer_current(buffer);
304  if (label_is_pointer(label)) {
305  size_t pointer = 0;
306  if (!allow_pointers) {
307  return 0;
308  }
309  if (!buffer_available(buffer, 2)) {
310  return 0;
311  }
312  pointer = label_pointer_location(label);
313  if (pointer >= buffer_limit(buffer)) {
314  return 0;
315  }
316  buffer_skip(buffer, 2);
317  if (mark == -1) {
318  mark = buffer_position(buffer);
319  }
320  buffer_set_position(buffer, pointer);
321  } else if (label_is_normal(label)) {
322  size_t length = label_length(label) + 1;
323  done = label_is_root(label);
324  if (!buffer_available(buffer, length)) {
325  return 0;
326  }
327  if (dname_length + length >= MAXDOMAINLEN+1) {
328  return 0;
329  }
330  buffer_read(buffer, dname + dname_length, length);
331  dname_length += length;
332  } else {
333  return 0;
334  }
335  }
336  if (mark != -1) {
337  buffer_set_position(buffer, mark);
338  }
339  return dname_length;
340 }
341 
342 
347 int
349 {
350  ods_log_assert(buffer);
351  while (1) {
352  uint8_t label_size = 0;
353  if (!buffer_available(buffer, 1)) {
354  return 0;
355  }
356  label_size = buffer_read_u8(buffer);
357  if (label_size == 0) {
358  break;
359  } else if ((label_size & 0xc0) != 0) {
360  if (!buffer_available(buffer, 1)) {
361  return 0;
362  }
363  buffer_skip(buffer, 1);
364  break;
365  } else if (!buffer_available(buffer, label_size)) {
366  return 0;
367  } else {
368  buffer_skip(buffer, label_size);
369  }
370  }
371  return 1;
372 }
373 
374 
379 int
380 buffer_skip_rr(buffer_type* buffer, unsigned qrr)
381 {
382  if (!buffer_skip_dname(buffer)) {
383  return 0;
384  }
385  if (qrr) {
386  if (!buffer_available(buffer, 4)) {
387  return 0;
388  }
389  buffer_skip(buffer, 4);
390  } else {
391  uint16_t rdata_size;
392  if (!buffer_available(buffer, 10)) {
393  return 0;
394  }
395  buffer_skip(buffer, 8);
396  rdata_size = buffer_read_u16(buffer);
397  if (!buffer_available(buffer, rdata_size)) {
398  return 0;
399  }
400  buffer_skip(buffer, rdata_size);
401  }
402  return 1;
403 }
404 
405 
410 size_t
412 {
413  ods_log_assert(buffer);
414  return buffer->limit;
415 }
416 
417 
422 void
423 buffer_set_limit(buffer_type* buffer, size_t limit)
424 {
425  ods_log_assert(buffer);
426  ods_log_assert(limit <= buffer->capacity);
427  buffer->limit = limit;
428  if (buffer->position > buffer->limit) {
429  buffer->position = buffer->limit;
430  }
431  return;
432 }
433 
434 
439 size_t
441 {
442  ods_log_assert(buffer);
443  return buffer->capacity;
444 }
445 
446 
451 uint8_t*
452 buffer_at(buffer_type* buffer, size_t at)
453 {
454  ods_log_assert(buffer);
455  ods_log_assert(at <= buffer->limit);
456  return buffer->data + at;
457 }
458 
459 
464 uint8_t*
466 {
467  ods_log_assert(buffer);
468  return buffer_at(buffer, 0);
469 }
470 
471 
476 uint8_t*
478 {
479  ods_log_assert(buffer);
480  return buffer_at(buffer, buffer->limit);
481 }
482 
483 
488 uint8_t*
490 {
491  ods_log_assert(buffer);
492  return buffer_at(buffer, buffer->position);
493 }
494 
495 
500 static size_t
501 buffer_remaining_at(buffer_type* buffer, size_t at)
502 {
503  ods_log_assert(buffer);
504  ods_log_assert(at <= buffer->limit);
505  return buffer->limit - at;
506 }
507 
508 
513 size_t
515 {
516  ods_log_assert(buffer);
517  return buffer_remaining_at(buffer, buffer->position);
518 }
519 
520 
525 static int
526 buffer_available_at(buffer_type *buffer, size_t at, size_t count)
527 {
528  ods_log_assert(buffer);
529  return count <= buffer_remaining_at(buffer, at);
530 }
531 
532 
537 int
538 buffer_available(buffer_type *buffer, size_t count)
539 {
540  ods_log_assert(buffer);
541  return buffer_available_at(buffer, buffer->position, count);
542 }
543 
544 
549 static void
550 buffer_write_u8_at(buffer_type* buffer, size_t at, uint8_t data)
551 {
552  ods_log_assert(buffer);
553  ods_log_assert(buffer_available_at(buffer, at, sizeof(data)));
554  buffer->data[at] = data;
555  return;
556 }
557 
558 
563 void
564 buffer_write_u16_at(buffer_type* buffer, size_t at, uint16_t data)
565 {
566  ods_log_assert(buffer);
567  ods_log_assert(buffer_available_at(buffer, at, sizeof(data)));
568  write_uint16(buffer->data + at, data);
569  return;
570 }
571 
572 
577 static void
578 buffer_write_u32_at(buffer_type* buffer, size_t at, uint32_t data)
579 {
580  ods_log_assert(buffer);
581  ods_log_assert(buffer_available_at(buffer, at, sizeof(data)));
582  write_uint32(buffer->data + at, data);
583  return;
584 }
585 
586 
591 void
592 buffer_write(buffer_type* buffer, const void* data, size_t count)
593 {
594  ods_log_assert(buffer);
595  ods_log_assert(buffer_available(buffer, count));
596  memcpy(buffer->data + buffer->position, data, count);
597  buffer->position += count;
598  return;
599 }
600 
601 
606 void
607 buffer_write_u8(buffer_type* buffer, uint8_t data)
608 {
609  ods_log_assert(buffer);
610  buffer_write_u8_at(buffer, buffer->position, data);
611  buffer->position += sizeof(data);
612  return;
613 }
614 
615 
620 void
621 buffer_write_u16(buffer_type* buffer, uint16_t data)
622 {
623  ods_log_assert(buffer);
624  buffer_write_u16_at(buffer, buffer->position, data);
625  buffer->position += sizeof(data);
626  return;
627 }
628 
629 
634 void
635 buffer_write_u32(buffer_type* buffer, uint32_t data)
636 {
637  ods_log_assert(buffer);
638  buffer_write_u32_at(buffer, buffer->position, data);
639  buffer->position += sizeof(data);
640  return;
641 }
642 
643 
648 void
649 buffer_write_rdf(buffer_type* buffer, ldns_rdf* rdf)
650 {
651  ods_log_assert(buffer);
652  ods_log_assert(rdf);
653  buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf));
654  /* position updated by buffer_write() */
655  return;
656 }
657 
658 
663 int
664 buffer_write_rr(buffer_type* buffer, ldns_rr* rr)
665 {
666  size_t i = 0;
667  size_t tc_mark = 0;
668  size_t rdlength_pos = 0;
669  uint16_t rdlength = 0;
670  ods_log_assert(buffer);
671  ods_log_assert(rr);
672  /* set truncation mark, in case rr does not fit */
673  tc_mark = buffer_position(buffer);
674  /* owner type class ttl */
675  if (!buffer_available(buffer, ldns_rdf_size(ldns_rr_owner(rr)))) {
676  goto buffer_tc;
677  }
678  buffer_write_rdf(buffer, ldns_rr_owner(rr));
679  if (!buffer_available(buffer, sizeof(uint16_t) + sizeof(uint16_t) +
680  sizeof(uint32_t) + sizeof(rdlength))) {
681  goto buffer_tc;
682  }
683  buffer_write_u16(buffer, (uint16_t) ldns_rr_get_type(rr));
684  buffer_write_u16(buffer, (uint16_t) ldns_rr_get_class(rr));
685  buffer_write_u32(buffer, (uint32_t) ldns_rr_ttl(rr));
686  /* skip rdlength */
687  rdlength_pos = buffer_position(buffer);
688  buffer_skip(buffer, sizeof(rdlength));
689  /* write rdata */
690  for (i=0; i < ldns_rr_rd_count(rr); i++) {
691  if (!buffer_available(buffer, ldns_rdf_size(ldns_rr_rdf(rr, i)))) {
692  goto buffer_tc;
693  }
694  buffer_write_rdf(buffer, ldns_rr_rdf(rr, i));
695  }
696  /* write rdlength */
697  rdlength = buffer_position(buffer) - rdlength_pos - sizeof(rdlength);
698  buffer_write_u16_at(buffer, rdlength_pos, rdlength);
699  /* position updated by buffer_write() */
700  return 1;
701 
702 buffer_tc:
703  buffer_set_position(buffer, tc_mark);
704  return 0;
705 }
706 
707 
712 static uint8_t
713 buffer_read_u8_at(buffer_type* buffer, size_t at)
714 {
715  ods_log_assert(buffer);
716  ods_log_assert(at < buffer->capacity);
717  return buffer->data[at];
718 
719 }
720 
721 
726 static uint16_t
727 buffer_read_u16_at(buffer_type* buffer, size_t at)
728 {
729  ods_log_assert(buffer);
730  return read_uint16(buffer->data + at);
731 }
732 
733 
738 static uint32_t
739 buffer_read_u32_at(buffer_type* buffer, size_t at)
740 {
741  ods_log_assert(buffer);
742  return read_uint32(buffer->data + at);
743 }
744 
745 
750 void
751 buffer_read(buffer_type* buffer, void* data, size_t count)
752 {
753  ods_log_assert(buffer);
754  ods_log_assert(buffer_available(buffer, count));
755  memcpy(data, buffer->data + buffer->position, count);
756  buffer->position += count;
757  return;
758 }
759 
760 
765 uint8_t
767 {
768  uint16_t result = 0;
769  ods_log_assert(buffer);
770  result = buffer_read_u8_at(buffer, buffer->position);
771  buffer->position += sizeof(uint8_t);
772  return result;
773 }
774 
775 
780 uint16_t
782 {
783  uint16_t result = 0;
784  ods_log_assert(buffer);
785  result = buffer_read_u16_at(buffer, buffer->position);
786  buffer->position += sizeof(uint16_t);
787  return result;
788 }
789 
790 
795 uint32_t
797 {
798  uint32_t result = 0;
799  ods_log_assert(buffer);
800  result = buffer_read_u32_at(buffer, buffer->position);
801  buffer->position += sizeof(uint32_t);
802  return result;
803 }
804 
805 
810 uint16_t
812 {
813  ods_log_assert(buffer);
814  return buffer_read_u16_at(buffer, 0);
815 }
816 
821 static uint16_t
822 random_id(void)
823 {
824  return ldns_get_random();
825 }
826 
831 void
833 {
834  uint16_t qid = 0;
835  ods_log_assert(buffer);
836  qid = random_id();
837  buffer_write_u16_at(buffer, 0, qid);
838  return;
839 }
840 
841 
846 uint16_t
848 {
849  ods_log_assert(buffer);
850  return (uint16_t) buffer_read_u16_at(buffer, 2);
851 }
852 
853 
858 void
859 buffer_pkt_set_flags(buffer_type* buffer, uint16_t flags)
860 {
861  ods_log_assert(buffer);
862  buffer_write_u16_at(buffer, 2, flags);
863  return;
864 }
865 
866 
871 int
873 {
874  ods_log_assert(buffer);
875  return (int) QR(buffer);
876 }
877 
878 
883 void
885 {
886  ods_log_assert(buffer);
887  QR_SET(buffer);
888  return;
889 }
890 
891 
896 void
898 {
899  ods_log_assert(buffer);
900  QR_CLR(buffer);
901  return;
902 }
903 
904 
909 ldns_pkt_opcode
911 {
912  ods_log_assert(buffer);
913  return (ldns_pkt_opcode) OPCODE(buffer);
914 }
915 
916 
921 void
922 buffer_pkt_set_opcode(buffer_type* buffer, ldns_pkt_opcode opcode)
923 {
924  ods_log_assert(buffer);
925  OPCODE_SET(buffer, opcode);
926  return;
927 }
928 
929 
934 int
936 {
937  ods_log_assert(buffer);
938  return (int) AA(buffer);
939 }
940 
941 
946 void
948 {
949  ods_log_assert(buffer);
950  AA_SET(buffer);
951  return;
952 }
953 
954 
959 int
961 {
962  ods_log_assert(buffer);
963  return (int) TC(buffer);
964 }
965 
966 
971 int
973 {
974  ods_log_assert(buffer);
975  return (int) RD(buffer);
976 }
977 
978 
983 int
985 {
986  ods_log_assert(buffer);
987  return (int) RA(buffer);
988 }
989 
990 
995 int
997 {
998  ods_log_assert(buffer);
999  return (int) AD(buffer);
1000 }
1001 
1002 
1007 int
1009 {
1010  ods_log_assert(buffer);
1011  return (int) CD(buffer);
1012 }
1013 
1014 
1019 ldns_pkt_rcode
1021 {
1022  ods_log_assert(buffer);
1023  return (ldns_pkt_rcode) RCODE(buffer);
1024 }
1025 
1026 
1031 void
1032 buffer_pkt_set_rcode(buffer_type* buffer, ldns_pkt_rcode rcode)
1033 {
1034  ods_log_assert(buffer);
1035  RCODE_SET(buffer, rcode);
1036  return;
1037 }
1038 
1039 
1044 const char*
1045 buffer_rcode2str(ldns_pkt_rcode rcode)
1046 {
1047  ods_lookup_table *lt;
1048  lt = ods_lookup_by_id(ods_rcode_str, rcode);
1049  if (lt) {
1050  return lt->name;
1051  }
1052  return NULL;
1053 }
1054 
1055 
1060 uint16_t
1062 {
1063  ods_log_assert(buffer);
1064  return buffer_read_u16_at(buffer, 4);
1065 }
1066 
1067 
1072 void
1073 buffer_pkt_set_qdcount(buffer_type* buffer, uint16_t count)
1074 {
1075  ods_log_assert(buffer);
1076  buffer_write_u16_at(buffer, 4, count);
1077  return;
1078 }
1079 
1080 
1085 uint16_t
1087 {
1088  ods_log_assert(buffer);
1089  return buffer_read_u16_at(buffer, 6);
1090 }
1091 
1092 
1097 void
1098 buffer_pkt_set_ancount(buffer_type* buffer, uint16_t count)
1099 {
1100  ods_log_assert(buffer);
1101  buffer_write_u16_at(buffer, 6, count);
1102  return;
1103 }
1104 
1105 
1110 uint16_t
1112 {
1113  ods_log_assert(buffer);
1114  return buffer_read_u16_at(buffer, 8);
1115 }
1116 
1117 
1122 void
1123 buffer_pkt_set_nscount(buffer_type* buffer, uint16_t count)
1124 {
1125  ods_log_assert(buffer);
1126  buffer_write_u16_at(buffer, 8, count);
1127  return;
1128 }
1129 
1130 
1135 uint16_t
1137 {
1138  ods_log_assert(buffer);
1139  return buffer_read_u16_at(buffer, 10);
1140 }
1141 
1142 
1147 void
1148 buffer_pkt_set_arcount(buffer_type* buffer, uint16_t count)
1149 {
1150  ods_log_assert(buffer);
1151  buffer_write_u16_at(buffer, 10, count);
1152  return;
1153 }
1154 
1155 
1160 static void
1161 buffer_pkt_new(buffer_type* buffer, ldns_rdf* qname, ldns_rr_type qtype,
1162  ldns_rr_class qclass, ldns_pkt_opcode opcode)
1163 {
1164  ods_log_assert(buffer);
1165  ods_log_assert(qname);
1166  ods_log_assert(qtype);
1167  ods_log_assert(qclass);
1168  /* The header */
1169  buffer_clear(buffer);
1170  buffer_pkt_set_random_id(buffer);
1171  buffer_pkt_set_opcode(buffer, opcode);
1172  buffer_pkt_clear_qr(buffer);
1173  buffer_pkt_set_rcode(buffer, LDNS_RCODE_NOERROR);
1174  buffer_pkt_set_qdcount(buffer, 1);
1175  buffer_pkt_set_ancount(buffer, 0);
1176  buffer_pkt_set_nscount(buffer, 0);
1177  buffer_pkt_set_arcount(buffer, 0);
1179  /* The question record */
1180  buffer_write_rdf(buffer, qname);
1181  buffer_write_u16(buffer, qtype);
1182  buffer_write_u16(buffer, qclass);
1183  return;
1184 }
1185 
1186 
1191 void
1192 buffer_pkt_query(buffer_type* buffer, ldns_rdf* qname, ldns_rr_type qtype,
1193  ldns_rr_class qclass)
1194 {
1195  buffer_pkt_new(buffer, qname, qtype, qclass, LDNS_PACKET_QUERY);
1196  buffer_pkt_set_flags(buffer, 0);
1197  return;
1198 }
1199 
1200 
1205 void
1206 buffer_pkt_notify(buffer_type* buffer, ldns_rdf* qname, ldns_rr_class qclass)
1207 {
1208  buffer_pkt_new(buffer, qname, LDNS_RR_TYPE_SOA, qclass,
1209  LDNS_PACKET_NOTIFY);
1210  return;
1211 }
1212 
1213 
1218 void
1219 buffer_pkt_axfr(buffer_type* buffer, ldns_rdf* qname, ldns_rr_class qclass)
1220 {
1221  buffer_pkt_new(buffer, qname, LDNS_RR_TYPE_AXFR, qclass,
1222  LDNS_PACKET_QUERY);
1223  buffer_pkt_set_qr(buffer);
1224  return;
1225 }
1226 
1227 
1232 void
1233 buffer_pkt_print(FILE* fd, buffer_type* buffer)
1234 {
1235  ldns_status status = LDNS_STATUS_OK;
1236  ldns_pkt* pkt = NULL;
1237  ods_log_assert(fd);
1238  ods_log_assert(buffer);
1239  status = ldns_wire2pkt(&pkt, buffer_begin(buffer),
1240  buffer_remaining(buffer));
1241  if (status == LDNS_STATUS_OK) {
1242  ods_log_assert(pkt);
1243  ldns_pkt_print(fd, pkt);
1244  ldns_pkt_free(pkt);
1245  } else {
1246  fprintf(fd, ";;\n");
1247  fprintf(fd, ";; Bogus packet: %s\n", ldns_get_errorstr_by_id(status));
1248  fprintf(fd, ";;\n");
1249  fprintf(fd, ";;\n");
1250  fprintf(fd, "\n");
1251  }
1252  return;
1253 }
1254 
1255 
1260 void
1262 {
1263  if (!buffer || !allocator) {
1264  return;
1265  }
1266  free((void*)buffer->data);
1267  allocator_deallocate(allocator, (void*) buffer);
1268  return;
1269 }
1270 
1271