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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors