2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
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.
10 * Low level DNS protocol routines
14 * UDP replies with TC set should be retried via TCP
18 #include "dns/rfc1035.h"
19 #include "dns/rfc2671.h"
35 #include <netinet/in.h>
38 #include <arpa/inet.h>
44 #define RFC1035_MAXLABELSZ 63
45 #define rfc1035_unpack_error 15
48 #define RFC1035_UNPACK_DEBUG fprintf(stderr, "unpack error at %s:%d\n", __FILE__,__LINE__)
50 #define RFC1035_UNPACK_DEBUG (void)0
56 * Packs a rfc1035_header structure into a buffer.
57 * Returns number of octets packed (should always be 12)
60 rfc1035HeaderPack(char *buf
, size_t sz
, rfc1035_message
* hdr
)
67 memcpy(buf
+ off
, &s
, sizeof(s
));
71 t
|= (hdr
->opcode
<< 11);
78 memcpy(buf
+ off
, &s
, sizeof(s
));
80 s
= htons(hdr
->qdcount
);
81 memcpy(buf
+ off
, &s
, sizeof(s
));
83 s
= htons(hdr
->ancount
);
84 memcpy(buf
+ off
, &s
, sizeof(s
));
86 s
= htons(hdr
->nscount
);
87 memcpy(buf
+ off
, &s
, sizeof(s
));
89 s
= htons(hdr
->arcount
);
90 memcpy(buf
+ off
, &s
, sizeof(s
));
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.
105 rfc1035LabelPack(char *buf
, size_t sz
, const char *label
)
108 size_t len
= label
? strlen(label
) : 0;
110 assert(!strchr(label
, '.'));
111 if (len
> RFC1035_MAXLABELSZ
)
112 len
= RFC1035_MAXLABELSZ
;
113 assert(sz
>= len
+ 1);
114 *(buf
+ off
) = (char) len
;
116 memcpy(buf
+ off
, label
, len
);
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.
130 rfc1035NamePack(char *buf
, size_t sz
, const char *name
)
132 unsigned int off
= 0;
133 char *copy
= xstrdup(name
);
136 * NOTE: use of strtok here makes names like foo....com valid.
138 for (t
= strtok(copy
, "."); t
; t
= strtok(NULL
, "."))
139 off
+= rfc1035LabelPack(buf
+ off
, sz
- off
, t
);
141 off
+= rfc1035LabelPack(buf
+ off
, sz
- off
, NULL
);
147 * rfc1035QuestionPack()
149 * Packs a QUESTION section of a message.
150 * Returns number of octets packed.
153 rfc1035QuestionPack(char *buf
,
156 const unsigned short type
,
157 const unsigned short _class
)
159 unsigned int off
= 0;
161 off
+= rfc1035NamePack(buf
+ off
, sz
- off
, name
);
163 memcpy(buf
+ off
, &s
, sizeof(s
));
166 memcpy(buf
+ off
, &s
, sizeof(s
));
173 * rfc1035HeaderUnpack()
175 * Unpacks a RFC1035 message header buffer into the header fields
176 * of the rfc1035_message structure.
178 * Updates the buffer offset, which is the same as number of
179 * octects unpacked since the header starts at offset 0.
181 * Returns 0 (success) or 1 (error)
184 rfc1035HeaderUnpack(const char *buf
, size_t sz
, unsigned int *off
, rfc1035_message
* h
)
190 * The header is 12 octets. This is a bogus message if the size
195 memcpy(&s
, buf
+ (*off
), sizeof(s
));
198 memcpy(&s
, buf
+ (*off
), sizeof(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;
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
211 * NO! RFCs say ignore inbound reserved, they may be used in future.
212 * NEW messages need to be set 0, thats all.
215 memcpy(&s
, buf
+ (*off
), sizeof(s
));
217 h
->qdcount
= ntohs(s
);
218 memcpy(&s
, buf
+ (*off
), sizeof(s
));
220 h
->ancount
= ntohs(s
);
221 memcpy(&s
, buf
+ (*off
), sizeof(s
));
223 h
->nscount
= ntohs(s
);
224 memcpy(&s
, buf
+ (*off
), sizeof(s
));
226 h
->arcount
= ntohs(s
);
227 assert((*off
) == 12);
232 * rfc1035NameUnpack()
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
240 * Supports the RFC1035 message compression through recursion.
242 * Updates the new buffer offset.
244 * Returns 0 (success) or 1 (error)
247 rfc1035NameUnpack(const char *buf
, size_t sz
, unsigned int *off
, unsigned short *rdlength
, char *name
, size_t ns
, int rdepth
)
255 RFC1035_UNPACK_DEBUG
;
260 /* blasted compression */
263 if (rdepth
> 64) { /* infinite pointer loop */
264 RFC1035_UNPACK_DEBUG
;
267 memcpy(&s
, buf
+ (*off
), sizeof(s
));
272 RFC1035_UNPACK_DEBUG
;
276 /* Make sure the pointer is inside this message */
278 RFC1035_UNPACK_DEBUG
;
281 return rfc1035NameUnpack(buf
, sz
, &ptr
, rdlength
, name
+ no
, ns
- no
, rdepth
+ 1);
282 } else if (c
> RFC1035_MAXLABELSZ
) {
284 * "(The 10 and 01 combinations are reserved for future use.)"
286 RFC1035_UNPACK_DEBUG
;
293 if (len
> (ns
- no
- 1)) { /* label won't fit */
294 RFC1035_UNPACK_DEBUG
;
297 if ((*off
) + len
>= sz
) { /* message is too short */
298 RFC1035_UNPACK_DEBUG
;
301 memcpy(name
+ no
, buf
+ (*off
), len
);
304 *(name
+ (no
++)) = '.';
306 *rdlength
+= len
+ 1;
308 } while (c
> 0 && no
< ns
);
310 *(name
+ no
- 1) = '\0';
313 /* make sure we didn't allow someone to overflow the name buffer */
321 * Packs a RFC1035 Resource Record into a message buffer from 'RR'.
322 * The caller must allocate and free RR->rdata and RR->name!
324 * Updates the new message buffer.
326 * Returns the number of bytes added to the buffer or 0 for error.
329 rfc1035RRPack(char *buf
, const size_t sz
, const rfc1035_rr
* RR
)
335 off
= rfc1035NamePack(buf
, sz
, RR
->name
);
338 * Make sure the remaining message has enough octets for the
339 * rest of the RR fields.
341 if ((off
+ sizeof(s
)*3 + sizeof(i
) + RR
->rdlength
) > sz
) {
345 memcpy(buf
+ off
, &s
, sizeof(s
));
347 s
= htons(RR
->_class
);
348 memcpy(buf
+ off
, &s
, sizeof(s
));
351 memcpy(buf
+ off
, &i
, sizeof(i
));
353 s
= htons(RR
->rdlength
);
354 memcpy(buf
+ off
, &s
, sizeof(s
));
356 memcpy(buf
+ off
, &(RR
->rdata
), RR
->rdlength
);
365 * Unpacks a RFC1035 Resource Record into 'RR' from a message buffer.
366 * The caller must free RR->rdata!
368 * Updates the new message buffer offset.
370 * Returns 0 (success) or 1 (error)
373 rfc1035RRUnpack(const char *buf
, size_t sz
, unsigned int *off
, rfc1035_rr
* RR
)
377 unsigned short rdlength
;
378 unsigned int rdata_off
;
379 if (rfc1035NameUnpack(buf
, sz
, off
, NULL
, RR
->name
, RFC1035_MAXHOSTNAMESZ
, 0)) {
380 RFC1035_UNPACK_DEBUG
;
381 memset(RR
, '\0', sizeof(*RR
));
385 * Make sure the remaining message has enough octets for the
386 * rest of the RR fields.
388 if ((*off
) + 10 > sz
) {
389 RFC1035_UNPACK_DEBUG
;
390 memset(RR
, '\0', sizeof(*RR
));
393 memcpy(&s
, buf
+ (*off
), sizeof(s
));
396 memcpy(&s
, buf
+ (*off
), sizeof(s
));
398 RR
->_class
= ntohs(s
);
399 memcpy(&i
, buf
+ (*off
), sizeof(i
));
402 memcpy(&s
, buf
+ (*off
), sizeof(s
));
405 if ((*off
) + rdlength
> sz
) {
407 * We got a truncated packet. 'dnscache' truncates UDP
408 * replies at 512 octets, as per RFC 1035.
410 RFC1035_UNPACK_DEBUG
;
411 memset(RR
, '\0', sizeof(*RR
));
414 RR
->rdlength
= rdlength
;
417 case RFC1035_TYPE_CNAME
:
419 case RFC1035_TYPE_PTR
:
420 RR
->rdata
= (char*)xmalloc(RFC1035_MAXHOSTNAMESZ
);
422 RR
->rdlength
= 0; /* Filled in by rfc1035NameUnpack */
423 if (rfc1035NameUnpack(buf
, sz
, &rdata_off
, &RR
->rdlength
, RR
->rdata
, RFC1035_MAXHOSTNAMESZ
, 0)) {
424 RFC1035_UNPACK_DEBUG
;
427 if (rdata_off
> ((*off
) + rdlength
)) {
429 * This probably doesn't happen for valid packets, but
430 * I want to make sure that NameUnpack doesn't go beyond
433 RFC1035_UNPACK_DEBUG
;
435 memset(RR
, '\0', sizeof(*RR
));
441 RR
->rdata
= (char*)xmalloc(rdlength
);
442 memcpy(RR
->rdata
, buf
+ (*off
), rdlength
);
446 assert((*off
) <= sz
);
451 rfc1035ErrorMessage(int n
)
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.";
479 case rfc1035_unpack_error
:
480 return "The DNS reply message is corrupt or could "
481 "not be safely parsed.";
484 return "Unknown Error";
490 rfc1035RRDestroy(rfc1035_rr
** rr
, int n
)
498 xfree((*rr
)[n
].rdata
);
505 * rfc1035QueryUnpack()
507 * Unpacks a RFC1035 Query Record into 'query' from a message buffer.
509 * Updates the new message buffer offset.
511 * Returns 0 (success) or 1 (error)
514 rfc1035QueryUnpack(const char *buf
, size_t sz
, unsigned int *off
, rfc1035_query
* query
)
517 if (rfc1035NameUnpack(buf
, sz
, off
, NULL
, query
->name
, RFC1035_MAXHOSTNAMESZ
, 0)) {
518 RFC1035_UNPACK_DEBUG
;
519 memset(query
, '\0', sizeof(*query
));
523 RFC1035_UNPACK_DEBUG
;
524 memset(query
, '\0', sizeof(*query
));
527 memcpy(&s
, buf
+ *off
, 2);
529 query
->qtype
= ntohs(s
);
530 memcpy(&s
, buf
+ *off
, 2);
532 query
->qclass
= ntohs(s
);
537 rfc1035MessageDestroy(rfc1035_message
** msg
)
542 xfree((*msg
)->query
);
544 rfc1035RRDestroy(&(*msg
)->answer
, (*msg
)->ancount
);
550 * rfc1035QueryCompare()
552 * Compares two rfc1035_query entries
554 * Returns 0 (equal) or !=0 (different)
557 rfc1035QueryCompare(const rfc1035_query
* a
, const rfc1035_query
* b
)
560 if (a
->qtype
!= b
->qtype
)
562 if (a
->qclass
!= b
->qclass
)
564 la
= strlen(a
->name
);
565 lb
= strlen(b
->name
);
567 /* Trim root label(s) */
568 while (la
> 0 && a
->name
[la
- 1] == '.')
570 while (lb
> 0 && b
->name
[lb
- 1] == '.')
576 return strncasecmp(a
->name
, b
->name
, la
);
580 * rfc1035MessageUnpack()
582 * Takes the contents of a DNS reply and fills in an array
583 * of resource record structures. The records array is allocated
584 * here, and should be freed by calling rfc1035RRDestroy().
586 * Returns number of records unpacked, zero if DNS reply indicates
587 * zero answers, or an error number < 0.
591 rfc1035MessageUnpack(const char *buf
,
593 rfc1035_message
** answer
)
595 unsigned int off
= 0;
598 rfc1035_message
*msg
= NULL
;
599 rfc1035_rr
*recs
= NULL
;
600 rfc1035_query
*querys
= NULL
;
601 msg
= (rfc1035_message
*)xcalloc(1, sizeof(*msg
));
602 if (rfc1035HeaderUnpack(buf
+ off
, sz
- off
, &off
, msg
)) {
603 RFC1035_UNPACK_DEBUG
;
605 return -rfc1035_unpack_error
;
607 i
= (unsigned int) msg
->qdcount
;
609 /* This can not be an answer to our queries.. */
610 RFC1035_UNPACK_DEBUG
;
612 return -rfc1035_unpack_error
;
614 querys
= msg
->query
= (rfc1035_query
*)xcalloc(i
, sizeof(*querys
));
615 for (j
= 0; j
< i
; j
++) {
616 if (rfc1035QueryUnpack(buf
, sz
, &off
, &querys
[j
])) {
617 RFC1035_UNPACK_DEBUG
;
618 rfc1035MessageDestroy(&msg
);
619 return -rfc1035_unpack_error
;
624 RFC1035_UNPACK_DEBUG
;
627 if (msg
->ancount
== 0)
629 i
= (unsigned int) msg
->ancount
;
630 recs
= msg
->answer
= (rfc1035_rr
*)xcalloc(i
, sizeof(*recs
));
631 for (j
= 0; j
< i
; j
++) {
632 if (off
>= sz
) { /* corrupt packet */
633 RFC1035_UNPACK_DEBUG
;
636 if (rfc1035RRUnpack(buf
, sz
, &off
, &recs
[j
])) { /* corrupt RR */
637 RFC1035_UNPACK_DEBUG
;
644 * we expected to unpack some answers (ancount != 0), but
645 * didn't actually get any.
647 rfc1035MessageDestroy(&msg
);
649 return -rfc1035_unpack_error
;
655 * rfc1035BuildAQuery()
657 * Builds a message buffer with a QUESTION to lookup A records
658 * for a hostname. Caller must allocate 'buf' which should
659 * probably be at least 512 octets. The 'szp' initially
660 * specifies the size of the buffer, on return it contains
661 * the size of the message (i.e. how much to write).
662 * Returns the size of the query
665 rfc1035BuildAQuery(const char *hostname
, char *buf
, size_t sz
, unsigned short qid
, rfc1035_query
* query
, ssize_t edns_sz
)
667 static rfc1035_message h
;
669 memset(&h
, '\0', sizeof(h
));
673 h
.opcode
= 0; /* QUERY */
674 h
.qdcount
= (unsigned int) 1;
675 h
.arcount
= (edns_sz
> 0 ? 1 : 0);
676 offset
+= rfc1035HeaderPack(buf
+ offset
, sz
- offset
, &h
);
677 offset
+= rfc1035QuestionPack(buf
+ offset
,
683 offset
+= rfc2671RROptPack(buf
+ offset
, sz
- offset
, edns_sz
);
685 query
->qtype
= RFC1035_TYPE_A
;
686 query
->qclass
= RFC1035_CLASS_IN
;
687 xstrncpy(query
->name
, hostname
, sizeof(query
->name
));
689 assert(offset
<= sz
);
694 * rfc1035BuildPTRQuery()
696 * Builds a message buffer with a QUESTION to lookup PTR records
697 * for an address. Caller must allocate 'buf' which should
698 * probably be at least 512 octets. The 'szp' initially
699 * specifies the size of the buffer, on return it contains
700 * the size of the message (i.e. how much to write).
701 * Returns the size of the query
704 rfc1035BuildPTRQuery(const struct in_addr addr
, char *buf
, size_t sz
, unsigned short qid
, rfc1035_query
* query
, ssize_t edns_sz
)
706 static rfc1035_message h
;
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.",
720 h
.opcode
= 0; /* QUERY */
721 h
.qdcount
= (unsigned int) 1;
722 h
.arcount
= (edns_sz
> 0 ? 1 : 0);
723 offset
+= rfc1035HeaderPack(buf
+ offset
, sz
- offset
, &h
);
724 offset
+= rfc1035QuestionPack(buf
+ offset
,
730 offset
+= rfc2671RROptPack(buf
+ offset
, sz
- offset
, edns_sz
);
732 query
->qtype
= RFC1035_TYPE_PTR
;
733 query
->qclass
= RFC1035_CLASS_IN
;
734 xstrncpy(query
->name
, rev
, sizeof(query
->name
));
736 assert(offset
<= sz
);
741 * We're going to retry a former query, but we
742 * just need a new ID for it. Lucky for us ID
743 * is the first field in the message buffer.
746 rfc1035SetQueryID(char *buf
, unsigned short qid
)
748 unsigned short s
= htons(qid
);
749 memcpy(buf
, &s
, sizeof(s
));
753 #include <sys/socket.h>
755 main(int argc
, char *argv
[])
757 char input
[SQUID_DNS_BUFSZ
];
758 char buf
[SQUID_DNS_BUFSZ
];
759 char rbuf
[SQUID_DNS_BUFSZ
];
760 size_t sz
= SQUID_DNS_BUFSZ
;
764 struct sockaddr_in S
;
766 fprintf(stderr
, "usage: %s ip port\n", argv
[0]);
769 setbuf(stdout
, NULL
);
770 setbuf(stderr
, NULL
);
771 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
776 memset(&S
, '\0', sizeof(S
));
777 S
.sin_family
= AF_INET
;
778 S
.sin_port
= htons(atoi(argv
[2]));
779 S
.sin_addr
.s_addr
= inet_addr(argv
[1]);
780 while (fgets(input
, RFC1035_DEFAULT_PACKET_SZ
, stdin
)) {
782 strtok(input
, "\r\n");
783 memset(buf
, '\0', RFC1035_DEFAULT_PACKET_SZ
);
784 sz
= RFC1035_DEFAULT_PACKET_SZ
;
785 if (inet_pton(AF_INET
, input
, &junk
)) {
786 sid
= rfc1035BuildPTRQuery(junk
, buf
, &sz
);
788 sid
= rfc1035BuildAQuery(input
, buf
, &sz
);
790 sendto(s
, buf
, sz
, 0, (struct sockaddr
*) &S
, sizeof(S
));
798 rl
= select(s
+ 1, &R
, NULL
, NULL
, &to
);
804 memset(rbuf
, '\0', RFC1035_DEFAULT_PACKET_SZ
);
805 rl
= recv(s
, rbuf
, RFC1035_DEFAULT_PACKET_SZ
, 0);
807 unsigned short rid
= 0;
810 rfc1035_rr
*answers
= NULL
;
811 n
= rfc1035AnswersUnpack(rbuf
,
816 printf("ERROR %d\n", -n
);
817 } else if (rid
!= sid
) {
818 printf("ERROR, ID mismatch (%#hx, %#hx)\n", sid
, rid
);
820 printf("%d answers\n", n
);
821 for (i
= 0; i
< n
; i
++) {
822 if (answers
[i
].type
== RFC1035_TYPE_A
) {
824 char ipa_str
[sizeof(a
)];
825 memcpy(&a
, answers
[i
].rdata
, 4);
826 printf("A\t%d\t%s\n", answers
[i
].ttl
, inet_ntop(AF_INET
,&a
,tmp
,sizeof(a
)));
827 } else if (answers
[i
].type
== RFC1035_TYPE_PTR
) {
829 strncpy(ptr
, answers
[i
].rdata
, answers
[i
].rdlength
);
830 printf("PTR\t%d\t%s\n", answers
[i
].ttl
, ptr
);
832 fprintf(stderr
, "can't print answer type %d\n",
833 (int) answers
[i
].type
);