31#include <netinet/in.h>
40#define RFC1035_MAXLABELSZ 63
41#define rfc1035_unpack_error 15
44#define RFC1035_UNPACK_DEBUG fprintf(stderr, "unpack error at %s:%d\n", __FILE__,__LINE__)
46#define RFC1035_UNPACK_DEBUG (void)0
63 memcpy(buf +
off, &s,
sizeof(s));
74 memcpy(buf +
off, &s,
sizeof(s));
77 memcpy(buf +
off, &s,
sizeof(s));
80 memcpy(buf +
off, &s,
sizeof(s));
83 memcpy(buf +
off, &s,
sizeof(s));
86 memcpy(buf +
off, &s,
sizeof(s));
104 assert(!strchr(label,
'.'));
107 auto len = strlen(label);
111 *(buf +
off) = (
char) len;
113 memcpy(buf +
off, label, len);
129 unsigned int off = 0;
135 for (t = strtok(copy,
"."); t; t = strtok(
nullptr,
"."))
157 const unsigned short type,
158 const unsigned short _class)
160 unsigned int off = 0;
164 memcpy(buf +
off, &s,
sizeof(s));
167 memcpy(buf +
off, &s,
sizeof(s));
196 memcpy(&s, buf + (*
off),
sizeof(s));
199 memcpy(&s, buf + (*
off),
sizeof(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;
216 memcpy(&s, buf + (*
off),
sizeof(s));
219 memcpy(&s, buf + (*
off),
sizeof(s));
222 memcpy(&s, buf + (*
off),
sizeof(s));
225 memcpy(&s, buf + (*
off),
sizeof(s));
248rfc1035NameUnpack(
const char *buf,
size_t sz,
unsigned int *
off,
unsigned short *rdlength,
char *name,
size_t ns,
int rdepth)
269 if ((*
off) +
sizeof(s) > sz) {
273 memcpy(&s, buf + (*
off),
sizeof(s));
294 if (len > (
ns - no - 1)) {
298 if ((*
off) + len >= sz) {
302 memcpy(name + no, buf + (*
off), len);
305 *(name + (no++)) =
'.';
307 *rdlength += len + 1;
309 }
while (c > 0 && no <
ns);
311 *(name + no - 1) =
'\0';
342 if ((
off +
sizeof(s)*3 +
sizeof(i) + RR->
rdlength) > sz) {
346 memcpy(buf +
off, &s,
sizeof(s));
349 memcpy(buf +
off, &s,
sizeof(s));
352 memcpy(buf +
off, &i,
sizeof(i));
355 memcpy(buf +
off, &s,
sizeof(s));
378 unsigned short rdlength;
379 unsigned int rdata_off;
382 memset(RR,
'\0',
sizeof(*RR));
389 if ((*
off) + 10 > sz) {
391 memset(RR,
'\0',
sizeof(*RR));
394 memcpy(&s, buf + (*
off),
sizeof(s));
397 memcpy(&s, buf + (*
off),
sizeof(s));
400 memcpy(&i, buf + (*
off),
sizeof(i));
403 memcpy(&s, buf + (*
off),
sizeof(s));
406 if ((*
off) + rdlength > sz) {
412 memset(RR,
'\0',
sizeof(*RR));
424 memset(RR,
'\0',
sizeof(*RR));
427 if (rdata_off > ((*
off) + rdlength)) {
435 memset(RR,
'\0',
sizeof(*RR));
442 memcpy(RR->
rdata, buf + (*
off), rdlength);
457 return "No error condition";
460 return "Format Error: The name server was "
461 "unable to interpret the query.";
464 return "Server Failure: The name server was "
465 "unable to process this query.";
468 return "Name Error: The domain name does "
472 return "Not Implemented: The name server does "
473 "not support the requested kind of query.";
476 return "Refused: The name server refuses to "
477 "perform the specified operation.";
480 return "The DNS reply message is corrupt or could "
481 "not be safely parsed.";
484 return "Unknown Error";
492 if (*rr ==
nullptr) {
498 xfree((*rr)[n].rdata);
519 memset(query,
'\0',
sizeof(*query));
524 memset(query,
'\0',
sizeof(*query));
527 memcpy(&s, buf + *
off,
sizeof(s));
529 query->
qtype = ntohs(s);
530 memcpy(&s, buf + *
off,
sizeof(s));
542 xfree((*msg)->query);
564 la = strlen(a->
name);
565 lb = strlen(b->
name);
568 while (la > 0 && a->
name[la - 1] ==
'.')
570 while (lb > 0 && b->
name[lb - 1] ==
'.')
576 return strncasecmp(a->
name, b->
name, la);
595 unsigned int off = 0;
615 for (j = 0; j < i; j++) {
631 for (j = 0; j < i; j++) {
669 memset(&h,
'\0',
sizeof(h));
675 h.
arcount = (edns_sz > 0 ? 1 : 0);
710 memset(&h,
'\0',
sizeof(h));
711 i = (
unsigned int) ntohl(addr.s_addr);
712 snprintf(rev, 32,
"%u.%u.%u.%u.in-addr.arpa.",
722 h.
arcount = (edns_sz > 0 ? 1 : 0);
748 unsigned short s = htons(qid);
749 memcpy(buf, &s,
sizeof(s));
char name[RFC1035_MAXHOSTNAMESZ]
static int rfc1035LabelPack(char *buf, size_t sz, const char *label)
static int rfc1035NamePack(char *buf, size_t sz, const char *name)
void rfc1035SetQueryID(char *buf, unsigned short qid)
void rfc1035RRDestroy(rfc1035_rr **rr, int n)
int rfc1035HeaderUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_message *h)
static int rfc1035RRUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_rr *RR)
int rfc1035MessageUnpack(const char *buf, size_t sz, rfc1035_message **answer)
#define RFC1035_MAXLABELSZ
ssize_t rfc1035BuildPTRQuery(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
static int rfc1035NameUnpack(const char *buf, size_t sz, unsigned int *off, unsigned short *rdlength, char *name, size_t ns, int rdepth)
int rfc1035QueryCompare(const rfc1035_query *a, const rfc1035_query *b)
const char * rfc1035ErrorMessage(int n)
static int rfc1035QueryUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_query *query)
void rfc1035MessageDestroy(rfc1035_message **msg)
ssize_t rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
#define rfc1035_unpack_error
int rfc1035QuestionPack(char *buf, const size_t sz, const char *name, const unsigned short type, const unsigned short _class)
int rfc1035HeaderPack(char *buf, size_t sz, rfc1035_message *hdr)
#define RFC1035_UNPACK_DEBUG
int rfc1035RRPack(char *buf, const size_t sz, const rfc1035_rr *RR)
#define RFC1035_MAXHOSTNAMESZ
int rfc2671RROptPack(char *buf, size_t sz, ssize_t edns_sz)
char name[RFC1035_MAXHOSTNAMESZ]
void * xcalloc(size_t n, size_t sz)
char * xstrncpy(char *dst, const char *src, size_t n)