rfc1035.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /*
10  * Low level DNS protocol routines
11  *
12  * KNOWN BUGS:
13  *
14  * UDP replies with TC set should be retried via TCP
15  */
16 
17 #include "squid.h"
18 #include "dns/rfc1035.h"
19 #include "dns/rfc2671.h"
20 #include "util.h"
21 
22 #include <cassert>
23 #include <cstring>
24 #if HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #if HAVE_MEMORY_H
28 #include <memory.h>
29 #endif
30 #if HAVE_NETINET_IN_H
31 #include <netinet/in.h>
32 #endif
33 #if HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
36 #if HAVE_STRINGS_H
37 #include <strings.h>
38 #endif
39 
40 #define RFC1035_MAXLABELSZ 63
41 #define rfc1035_unpack_error 15
42 
43 #if 0
44 #define RFC1035_UNPACK_DEBUG fprintf(stderr, "unpack error at %s:%d\n", __FILE__,__LINE__)
45 #else
46 #define RFC1035_UNPACK_DEBUG (void)0
47 #endif
48 
49 /*
50  * rfc1035HeaderPack()
51  *
52  * Packs a rfc1035_header structure into a buffer.
53  * Returns number of octets packed (should always be 12)
54  */
55 int
56 rfc1035HeaderPack(char *buf, size_t sz, rfc1035_message * hdr)
57 {
58  int off = 0;
59  unsigned short s;
60  unsigned short t;
61  assert(sz >= 12);
62  s = htons(hdr->id);
63  memcpy(buf + off, &s, sizeof(s));
64  off += sizeof(s);
65  t = 0;
66  t |= hdr->qr << 15;
67  t |= (hdr->opcode << 11);
68  t |= (hdr->aa << 10);
69  t |= (hdr->tc << 9);
70  t |= (hdr->rd << 8);
71  t |= (hdr->ra << 7);
72  t |= hdr->rcode;
73  s = htons(t);
74  memcpy(buf + off, &s, sizeof(s));
75  off += sizeof(s);
76  s = htons(hdr->qdcount);
77  memcpy(buf + off, &s, sizeof(s));
78  off += sizeof(s);
79  s = htons(hdr->ancount);
80  memcpy(buf + off, &s, sizeof(s));
81  off += sizeof(s);
82  s = htons(hdr->nscount);
83  memcpy(buf + off, &s, sizeof(s));
84  off += sizeof(s);
85  s = htons(hdr->arcount);
86  memcpy(buf + off, &s, sizeof(s));
87  off += sizeof(s);
88  assert(off == 12);
89  return off;
90 }
91 
92 /*
93  * rfc1035LabelPack()
94  *
95  * Packs a label into a buffer. The format of
96  * a label is one octet specifying the number of character
97  * bytes to follow. Labels must be smaller than 64 octets.
98  * Returns number of octets packed.
99  */
100 static int
101 rfc1035LabelPack(char *buf, size_t sz, const char *label)
102 {
103  assert(label);
104  assert(!strchr(label, '.'));
105 
106  int off = 0;
107  auto len = strlen(label);
108  if (len > RFC1035_MAXLABELSZ)
109  len = RFC1035_MAXLABELSZ;
110  assert(sz >= len + 1);
111  *(buf + off) = (char) len;
112  off++;
113  memcpy(buf + off, label, len);
114  off += len;
115  return off;
116 }
117 
118 /*
119  * rfc1035NamePack()
120  *
121  * Packs a name into a buffer. Names are packed as a
122  * sequence of labels, terminated with NULL label.
123  * Note message compression is not supported here.
124  * Returns number of octets packed.
125  */
126 static int
127 rfc1035NamePack(char *buf, size_t sz, const char *name)
128 {
129  unsigned int off = 0;
130  char *copy = xstrdup(name);
131  char *t;
132  /*
133  * NOTE: use of strtok here makes names like foo....com valid.
134  */
135  for (t = strtok(copy, "."); t; t = strtok(nullptr, "."))
136  off += rfc1035LabelPack(buf + off, sz - off, t);
137  xfree(copy);
138 
139  // add a terminating root (i.e. zero length) label
140  assert(off < sz);
141  buf[off] = 0;
142  ++off;
143 
144  return off;
145 }
146 
147 /*
148  * rfc1035QuestionPack()
149  *
150  * Packs a QUESTION section of a message.
151  * Returns number of octets packed.
152  */
153 int
155  const size_t sz,
156  const char *name,
157  const unsigned short type,
158  const unsigned short _class)
159 {
160  unsigned int off = 0;
161  unsigned short s;
162  off += rfc1035NamePack(buf + off, sz - off, name);
163  s = htons(type);
164  memcpy(buf + off, &s, sizeof(s));
165  off += sizeof(s);
166  s = htons(_class);
167  memcpy(buf + off, &s, sizeof(s));
168  off += sizeof(s);
169  assert(off <= sz);
170  return off;
171 }
172 
173 /*
174  * rfc1035HeaderUnpack()
175  *
176  * Unpacks a RFC1035 message header buffer into the header fields
177  * of the rfc1035_message structure.
178  *
179  * Updates the buffer offset, which is the same as number of
180  * octects unpacked since the header starts at offset 0.
181  *
182  * Returns 0 (success) or 1 (error)
183  */
184 int
185 rfc1035HeaderUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_message * h)
186 {
187  unsigned short s;
188  unsigned short t;
189  assert(*off == 0);
190  /*
191  * The header is 12 octets. This is a bogus message if the size
192  * is less than that.
193  */
194  if (sz < 12)
195  return 1;
196  memcpy(&s, buf + (*off), sizeof(s));
197  (*off) += sizeof(s);
198  h->id = ntohs(s);
199  memcpy(&s, buf + (*off), sizeof(s));
200  (*off) += sizeof(s);
201  t = ntohs(s);
202  h->qr = (t >> 15) & 0x01;
203  h->opcode = (t >> 11) & 0x0F;
204  h->aa = (t >> 10) & 0x01;
205  h->tc = (t >> 9) & 0x01;
206  h->rd = (t >> 8) & 0x01;
207  h->ra = (t >> 7) & 0x01;
208  /*
209  * We might want to check that the reserved 'Z' bits (6-4) are
210  * all zero as per RFC 1035. If not the message should be
211  * rejected.
212  * NO! RFCs say ignore inbound reserved, they may be used in future.
213  * NEW messages need to be set 0, that's all.
214  */
215  h->rcode = t & 0x0F;
216  memcpy(&s, buf + (*off), sizeof(s));
217  (*off) += sizeof(s);
218  h->qdcount = ntohs(s);
219  memcpy(&s, buf + (*off), sizeof(s));
220  (*off) += sizeof(s);
221  h->ancount = ntohs(s);
222  memcpy(&s, buf + (*off), sizeof(s));
223  (*off) += sizeof(s);
224  h->nscount = ntohs(s);
225  memcpy(&s, buf + (*off), sizeof(s));
226  (*off) += sizeof(s);
227  h->arcount = ntohs(s);
228  assert((*off) == 12);
229  return 0;
230 }
231 
232 /*
233  * rfc1035NameUnpack()
234  *
235  * Unpacks a Name in a message buffer into a char*.
236  * Note 'buf' points to the beginning of the whole message,
237  * 'off' points to the spot where the Name begins, and 'sz'
238  * is the size of the whole message. 'name' must be allocated
239  * by the caller.
240  *
241  * Supports the RFC1035 message compression through recursion.
242  *
243  * Updates the new buffer offset.
244  *
245  * Returns 0 (success) or 1 (error)
246  */
247 static int
248 rfc1035NameUnpack(const char *buf, size_t sz, unsigned int *off, unsigned short *rdlength, char *name, size_t ns, int rdepth)
249 {
250  unsigned int no = 0;
251  unsigned char c;
252  size_t len;
253  assert(ns > 0);
254  do {
255  if ((*off) >= sz) {
257  return 1;
258  }
259  c = *(buf + (*off));
260  if (c > 191) {
261  /* blasted compression */
262  unsigned short s;
263  unsigned int ptr;
264  if (rdepth > 64) { /* infinite pointer loop */
266  return 1;
267  }
268  /* before copying compression offset value, ensure it is inside the buffer */
269  if ((*off) + sizeof(s) > sz) {
271  return 1;
272  }
273  memcpy(&s, buf + (*off), sizeof(s));
274  s = ntohs(s);
275  (*off) += sizeof(s);
276  ptr = s & 0x3FFF;
277  /* Make sure the pointer is inside this message */
278  if (ptr >= sz) {
280  return 1;
281  }
282  return rfc1035NameUnpack(buf, sz, &ptr, rdlength, name + no, ns - no, rdepth + 1);
283  } else if (c > RFC1035_MAXLABELSZ) {
284  /*
285  * "(The 10 and 01 combinations are reserved for future use.)"
286  */
288  return 1;
289  } else {
290  (*off)++;
291  len = (size_t) c;
292  if (len == 0)
293  break;
294  if (len > (ns - no - 1)) { /* label won't fit */
296  return 1;
297  }
298  if ((*off) + len >= sz) { /* message is too short */
300  return 1;
301  }
302  memcpy(name + no, buf + (*off), len);
303  (*off) += len;
304  no += len;
305  *(name + (no++)) = '.';
306  if (rdlength)
307  *rdlength += len + 1;
308  }
309  } while (c > 0 && no < ns);
310  if (no)
311  *(name + no - 1) = '\0';
312  else
313  *name = '\0';
314  /* make sure we didn't allow someone to overflow the name buffer */
315  assert(no <= ns);
316  return 0;
317 }
318 
319 /*
320  * rfc1035RRPack()
321  *
322  * Packs a RFC1035 Resource Record into a message buffer from 'RR'.
323  * The caller must allocate and free RR->rdata and RR->name!
324  *
325  * Updates the new message buffer.
326  *
327  * Returns the number of bytes added to the buffer or 0 for error.
328  */
329 int
330 rfc1035RRPack(char *buf, const size_t sz, const rfc1035_rr * RR)
331 {
332  unsigned int off;
333  uint16_t s;
334  uint32_t i;
335 
336  off = rfc1035NamePack(buf, sz, RR->name);
337 
338  /*
339  * Make sure the remaining message has enough octets for the
340  * rest of the RR fields.
341  */
342  if ((off + sizeof(s)*3 + sizeof(i) + RR->rdlength) > sz) {
343  return 0;
344  }
345  s = htons(RR->type);
346  memcpy(buf + off, &s, sizeof(s));
347  off += sizeof(s);
348  s = htons(RR->_class);
349  memcpy(buf + off, &s, sizeof(s));
350  off += sizeof(s);
351  i = htonl(RR->ttl);
352  memcpy(buf + off, &i, sizeof(i));
353  off += sizeof(i);
354  s = htons(RR->rdlength);
355  memcpy(buf + off, &s, sizeof(s));
356  off += sizeof(s);
357  memcpy(buf + off, &(RR->rdata), RR->rdlength);
358  off += RR->rdlength;
359  assert(off <= sz);
360  return off;
361 }
362 
363 /*
364  * rfc1035RRUnpack()
365  *
366  * Unpacks a RFC1035 Resource Record into 'RR' from a message buffer.
367  * The caller must free RR->rdata!
368  *
369  * Updates the new message buffer offset.
370  *
371  * Returns 0 (success) or 1 (error)
372  */
373 static int
374 rfc1035RRUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_rr * RR)
375 {
376  unsigned short s;
377  unsigned int i;
378  unsigned short rdlength;
379  unsigned int rdata_off;
380  if (rfc1035NameUnpack(buf, sz, off, nullptr, RR->name, RFC1035_MAXHOSTNAMESZ, 0)) {
382  memset(RR, '\0', sizeof(*RR));
383  return 1;
384  }
385  /*
386  * Make sure the remaining message has enough octets for the
387  * rest of the RR fields.
388  */
389  if ((*off) + 10 > sz) {
391  memset(RR, '\0', sizeof(*RR));
392  return 1;
393  }
394  memcpy(&s, buf + (*off), sizeof(s));
395  (*off) += sizeof(s);
396  RR->type = ntohs(s);
397  memcpy(&s, buf + (*off), sizeof(s));
398  (*off) += sizeof(s);
399  RR->_class = ntohs(s);
400  memcpy(&i, buf + (*off), sizeof(i));
401  (*off) += sizeof(i);
402  RR->ttl = ntohl(i);
403  memcpy(&s, buf + (*off), sizeof(s));
404  (*off) += sizeof(s);
405  rdlength = ntohs(s);
406  if ((*off) + rdlength > sz) {
407  /*
408  * We got a truncated packet. 'dnscache' truncates UDP
409  * replies at 512 octets, as per RFC 1035.
410  */
412  memset(RR, '\0', sizeof(*RR));
413  return 1;
414  }
415  RR->rdlength = rdlength;
416  switch (RR->type) {
417  case RFC1035_TYPE_PTR:
418  RR->rdata = (char*)xmalloc(RFC1035_MAXHOSTNAMESZ);
419  rdata_off = *off;
420  RR->rdlength = 0; /* Filled in by rfc1035NameUnpack */
421  if (rfc1035NameUnpack(buf, sz, &rdata_off, &RR->rdlength, RR->rdata, RFC1035_MAXHOSTNAMESZ, 0)) {
423  return 1;
424  }
425  if (rdata_off > ((*off) + rdlength)) {
426  /*
427  * This probably doesn't happen for valid packets, but
428  * I want to make sure that NameUnpack doesn't go beyond
429  * the RDATA area.
430  */
432  xfree(RR->rdata);
433  memset(RR, '\0', sizeof(*RR));
434  return 1;
435  }
436  break;
437  case RFC1035_TYPE_A:
438  default:
439  RR->rdata = (char*)xmalloc(rdlength);
440  memcpy(RR->rdata, buf + (*off), rdlength);
441  break;
442  }
443  (*off) += rdlength;
444  assert((*off) <= sz);
445  return 0;
446 }
447 
448 const char *
450 {
451  if (n < 0)
452  n = -n;
453  switch (n) {
454  case 0:
455  return "No error condition";
456  break;
457  case 1:
458  return "Format Error: The name server was "
459  "unable to interpret the query.";
460  break;
461  case 2:
462  return "Server Failure: The name server was "
463  "unable to process this query.";
464  break;
465  case 3:
466  return "Name Error: The domain name does "
467  "not exist.";
468  break;
469  case 4:
470  return "Not Implemented: The name server does "
471  "not support the requested kind of query.";
472  break;
473  case 5:
474  return "Refused: The name server refuses to "
475  "perform the specified operation.";
476  break;
478  return "The DNS reply message is corrupt or could "
479  "not be safely parsed.";
480  break;
481  default:
482  return "Unknown Error";
483  break;
484  }
485 }
486 
487 void
489 {
490  if (*rr == nullptr) {
491  return;
492  }
493 
494  while (n-- > 0) {
495  if ((*rr)[n].rdata)
496  xfree((*rr)[n].rdata);
497  }
498  xfree(*rr);
499  *rr = nullptr;
500 }
501 
502 /*
503  * rfc1035QueryUnpack()
504  *
505  * Unpacks a RFC1035 Query Record into 'query' from a message buffer.
506  *
507  * Updates the new message buffer offset.
508  *
509  * Returns 0 (success) or 1 (error)
510  */
511 static int
512 rfc1035QueryUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_query * query)
513 {
514  unsigned short s;
515  if (rfc1035NameUnpack(buf, sz, off, nullptr, query->name, RFC1035_MAXHOSTNAMESZ, 0)) {
517  memset(query, '\0', sizeof(*query));
518  return 1;
519  }
520  if (*off + 4 > sz) {
522  memset(query, '\0', sizeof(*query));
523  return 1;
524  }
525  memcpy(&s, buf + *off, 2);
526  *off += 2;
527  query->qtype = ntohs(s);
528  memcpy(&s, buf + *off, 2);
529  *off += 2;
530  query->qclass = ntohs(s);
531  return 0;
532 }
533 
534 void
536 {
537  if (!*msg)
538  return;
539  if ((*msg)->query)
540  xfree((*msg)->query);
541  if ((*msg)->answer)
542  rfc1035RRDestroy(&(*msg)->answer, (*msg)->ancount);
543  xfree(*msg);
544  *msg = nullptr;
545 }
546 
547 /*
548  * rfc1035QueryCompare()
549  *
550  * Compares two rfc1035_query entries
551  *
552  * Returns 0 (equal) or !=0 (different)
553  */
554 int
556 {
557  size_t la, lb;
558  if (a->qtype != b->qtype)
559  return 1;
560  if (a->qclass != b->qclass)
561  return 1;
562  la = strlen(a->name);
563  lb = strlen(b->name);
564  if (la != lb) {
565  /* Trim root label(s) */
566  while (la > 0 && a->name[la - 1] == '.')
567  la--;
568  while (lb > 0 && b->name[lb - 1] == '.')
569  lb--;
570  }
571  if (la != lb)
572  return 1;
573 
574  return strncasecmp(a->name, b->name, la);
575 }
576 
577 /*
578  * rfc1035MessageUnpack()
579  *
580  * Takes the contents of a DNS reply and fills in an array
581  * of resource record structures. The records array is allocated
582  * here, and should be freed by calling rfc1035RRDestroy().
583  *
584  * Returns number of records unpacked, zero if DNS reply indicates
585  * zero answers, or an error number < 0.
586  */
587 
588 int
589 rfc1035MessageUnpack(const char *buf,
590  size_t sz,
591  rfc1035_message ** answer)
592 {
593  unsigned int off = 0;
594  unsigned int i, j;
595  unsigned int nr = 0;
596  rfc1035_message *msg = nullptr;
597  rfc1035_rr *recs = nullptr;
598  rfc1035_query *querys = nullptr;
599  msg = (rfc1035_message*)xcalloc(1, sizeof(*msg));
600  if (rfc1035HeaderUnpack(buf + off, sz - off, &off, msg)) {
602  xfree(msg);
603  return -rfc1035_unpack_error;
604  }
605  i = (unsigned int) msg->qdcount;
606  if (i != 1) {
607  /* This can not be an answer to our queries.. */
609  xfree(msg);
610  return -rfc1035_unpack_error;
611  }
612  querys = msg->query = (rfc1035_query*)xcalloc(i, sizeof(*querys));
613  for (j = 0; j < i; j++) {
614  if (rfc1035QueryUnpack(buf, sz, &off, &querys[j])) {
616  rfc1035MessageDestroy(&msg);
617  return -rfc1035_unpack_error;
618  }
619  }
620  *answer = msg;
621  if (msg->rcode) {
623  return -msg->rcode;
624  }
625  if (msg->ancount == 0)
626  return 0;
627  i = (unsigned int) msg->ancount;
628  recs = msg->answer = (rfc1035_rr*)xcalloc(i, sizeof(*recs));
629  for (j = 0; j < i; j++) {
630  if (off >= sz) { /* corrupt packet */
632  break;
633  }
634  if (rfc1035RRUnpack(buf, sz, &off, &recs[j])) { /* corrupt RR */
636  break;
637  }
638  nr++;
639  }
640  if (nr == 0) {
641  /*
642  * we expected to unpack some answers (ancount != 0), but
643  * didn't actually get any.
644  */
645  rfc1035MessageDestroy(&msg);
646  *answer = nullptr;
647  return -rfc1035_unpack_error;
648  }
649  return nr;
650 }
651 
652 /*
653  * rfc1035BuildAQuery()
654  *
655  * Builds a message buffer with a QUESTION to lookup A records
656  * for a hostname. Caller must allocate 'buf' which should
657  * probably be at least 512 octets. The 'szp' initially
658  * specifies the size of the buffer, on return it contains
659  * the size of the message (i.e. how much to write).
660  * Returns the size of the query
661  */
662 ssize_t
663 rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, ssize_t edns_sz)
664 {
665  static rfc1035_message h;
666  size_t offset = 0;
667  memset(&h, '\0', sizeof(h));
668  h.id = qid;
669  h.qr = 0;
670  h.rd = 1;
671  h.opcode = 0; /* QUERY */
672  h.qdcount = (unsigned int) 1;
673  h.arcount = (edns_sz > 0 ? 1 : 0);
674  offset += rfc1035HeaderPack(buf + offset, sz - offset, &h);
675  offset += rfc1035QuestionPack(buf + offset,
676  sz - offset,
677  hostname,
680  if (edns_sz > 0)
681  offset += rfc2671RROptPack(buf + offset, sz - offset, edns_sz);
682  if (query) {
683  query->qtype = RFC1035_TYPE_A;
684  query->qclass = RFC1035_CLASS_IN;
685  xstrncpy(query->name, hostname, sizeof(query->name));
686  }
687  assert(offset <= sz);
688  return offset;
689 }
690 
691 /*
692  * rfc1035BuildPTRQuery()
693  *
694  * Builds a message buffer with a QUESTION to lookup PTR records
695  * for an address. Caller must allocate 'buf' which should
696  * probably be at least 512 octets. The 'szp' initially
697  * specifies the size of the buffer, on return it contains
698  * the size of the message (i.e. how much to write).
699  * Returns the size of the query
700  */
701 ssize_t
702 rfc1035BuildPTRQuery(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, ssize_t edns_sz)
703 {
704  static rfc1035_message h;
705  size_t offset = 0;
706  static char rev[32];
707  unsigned int i;
708  memset(&h, '\0', sizeof(h));
709  i = (unsigned int) ntohl(addr.s_addr);
710  snprintf(rev, 32, "%u.%u.%u.%u.in-addr.arpa.",
711  i & 255,
712  (i >> 8) & 255,
713  (i >> 16) & 255,
714  (i >> 24) & 255);
715  h.id = qid;
716  h.qr = 0;
717  h.rd = 1;
718  h.opcode = 0; /* QUERY */
719  h.qdcount = (unsigned int) 1;
720  h.arcount = (edns_sz > 0 ? 1 : 0);
721  offset += rfc1035HeaderPack(buf + offset, sz - offset, &h);
722  offset += rfc1035QuestionPack(buf + offset,
723  sz - offset,
724  rev,
727  if (edns_sz > 0)
728  offset += rfc2671RROptPack(buf + offset, sz - offset, edns_sz);
729  if (query) {
730  query->qtype = RFC1035_TYPE_PTR;
731  query->qclass = RFC1035_CLASS_IN;
732  xstrncpy(query->name, rev, sizeof(query->name));
733  }
734  assert(offset <= sz);
735  return offset;
736 }
737 
738 /*
739  * We're going to retry a former query, but we
740  * just need a new ID for it. Lucky for us ID
741  * is the first field in the message buffer.
742  */
743 void
744 rfc1035SetQueryID(char *buf, unsigned short qid)
745 {
746  unsigned short s = htons(qid);
747  memcpy(buf, &s, sizeof(s));
748 }
749 
rfc1035_query * query
Definition: rfc1035.h:68
void * xcalloc(size_t n, size_t sz)
Definition: xalloc.cc:71
#define xmalloc
unsigned short type
Definition: rfc1035.h:40
unsigned short rdlength
Definition: rfc1035.h:43
int rfc1035RRPack(char *buf, const size_t sz, const rfc1035_rr *RR)
Definition: rfc1035.cc:330
static int rfc1035RRUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_rr *RR)
Definition: rfc1035.cc:374
rfc1035_rr * answer
Definition: rfc1035.h:69
unsigned int opcode
Definition: rfc1035.h:58
#define xstrdup
int rfc2671RROptPack(char *buf, size_t sz, ssize_t edns_sz)
Definition: rfc2671.cc:14
int rfc1035HeaderPack(char *buf, size_t sz, rfc1035_message *hdr)
Definition: rfc1035.cc:56
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37
unsigned int tc
Definition: rfc1035.h:60
#define rfc1035_unpack_error
Definition: rfc1035.cc:41
unsigned short qdcount
Definition: rfc1035.h:64
int const char size_t
Definition: stub_liblog.cc:83
int rfc1035QueryCompare(const rfc1035_query *a, const rfc1035_query *b)
Definition: rfc1035.cc:555
void rfc1035RRDestroy(rfc1035_rr **rr, int n)
Definition: rfc1035.cc:488
unsigned int ra
Definition: rfc1035.h:62
#define RFC1035_TYPE_A
Definition: rfc1035.h:93
#define RFC1035_MAXHOSTNAMESZ
Definition: rfc1035.h:32
#define RFC1035_TYPE_PTR
Definition: rfc1035.h:95
char * rdata
Definition: rfc1035.h:44
unsigned short _class
Definition: rfc1035.h:41
static int rfc1035QueryUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_query *query)
Definition: rfc1035.cc:512
#define assert(EX)
Definition: assert.h:17
void rfc1035SetQueryID(char *buf, unsigned short qid)
Definition: rfc1035.cc:744
ssize_t rfc1035BuildPTRQuery(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
Definition: rfc1035.cc:702
unsigned short qtype
Definition: rfc1035.h:50
int rfc1035MessageUnpack(const char *buf, size_t sz, rfc1035_message **answer)
Definition: rfc1035.cc:589
#define xfree
unsigned short id
Definition: rfc1035.h:56
unsigned int ttl
Definition: rfc1035.h:42
char name[RFC1035_MAXHOSTNAMESZ]
Definition: rfc1035.h:49
const char * rfc1035ErrorMessage(int n)
Definition: rfc1035.cc:449
static int rfc1035LabelPack(char *buf, size_t sz, const char *label)
Definition: rfc1035.cc:101
unsigned short qclass
Definition: rfc1035.h:51
unsigned int rcode
Definition: rfc1035.h:63
unsigned short nscount
Definition: rfc1035.h:66
unsigned short ancount
Definition: rfc1035.h:65
static int rfc1035NamePack(char *buf, size_t sz, const char *name)
Definition: rfc1035.cc:127
unsigned int aa
Definition: rfc1035.h:59
unsigned int rd
Definition: rfc1035.h:61
int rfc1035QuestionPack(char *buf, const size_t sz, const char *name, const unsigned short type, const unsigned short _class)
Definition: rfc1035.cc:154
ssize_t rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
Definition: rfc1035.cc:663
#define RFC1035_UNPACK_DEBUG
Definition: rfc1035.cc:46
#define RFC1035_MAXLABELSZ
Definition: rfc1035.cc:40
static int rfc1035NameUnpack(const char *buf, size_t sz, unsigned int *off, unsigned short *rdlength, char *name, size_t ns, int rdepth)
Definition: rfc1035.cc:248
unsigned short arcount
Definition: rfc1035.h:67
char name[RFC1035_MAXHOSTNAMESZ]
Definition: rfc1035.h:39
#define RFC1035_CLASS_IN
Definition: rfc1035.h:96
int rfc1035HeaderUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_message *h)
Definition: rfc1035.cc:185
unsigned int qr
Definition: rfc1035.h:57
int unsigned int
Definition: stub_fd.cc:19
void rfc1035MessageDestroy(rfc1035_message **msg)
Definition: rfc1035.cc:535

 

Introduction

Documentation

Support

Miscellaneous