/[resiprocate]/main/contrib/ares/ares_mkquery.c
ViewVC logotype

Contents of /main/contrib/ares/ares_mkquery.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5295 - (show annotations) (download)
Mon Aug 22 00:30:05 2005 UTC (14 years, 3 months ago) by jason
File MIME type: text/plain
File size: 5005 byte(s)
merged 5270:HEAD from b-directory-reorg
1 /* Copyright 1998 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose. It is provided "as is"
13 * without express or implied warranty.
14 */
15
16
17 #include <sys/types.h>
18 #ifndef WIN32
19 #include <netinet/in.h>
20 #ifndef __CYGWIN__
21 # include <arpa/nameser.h>
22 #endif
23 #endif
24 #include <stdlib.h>
25 #include <string.h>
26 #include "ares.h"
27 #include "ares_dns.h"
28
29 /* Header format, from RFC 1035:
30 * 1 1 1 1 1 1
31 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
32 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
33 * | ID |
34 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
35 * |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
36 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
37 * | QDCOUNT |
38 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
39 * | ANCOUNT |
40 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
41 * | NSCOUNT |
42 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
43 * | ARCOUNT |
44 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
45 *
46 * AA, TC, RA, and RCODE are only set in responses. Brief description
47 * of the remaining fields:
48 * ID Identifier to match responses with queries
49 * QR Query (0) or response (1)
50 * Opcode For our purposes, always QUERY
51 * RD Recursion desired
52 * Z Reserved (zero)
53 * QDCOUNT Number of queries
54 * ANCOUNT Number of answers
55 * NSCOUNT Number of name server records
56 * ARCOUNT Number of additional records
57 *
58 * Question format, from RFC 1035:
59 * 1 1 1 1 1 1
60 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
61 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62 * | |
63 * / QNAME /
64 * / /
65 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
66 * | QTYPE |
67 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
68 * | QCLASS |
69 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70 *
71 * The query name is encoded as a series of labels, each represented
72 * as a one-byte length (maximum 63) followed by the text of the
73 * label. The list is terminated by a label of length zero (which can
74 * be thought of as the root domain).
75 */
76
77 int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
78 int rd, unsigned char **buf, int *buflen)
79 {
80 int len;
81 unsigned char *q;
82 const char *p;
83
84 /* Compute the length of the encoded name so we can check buflen.
85 * Start counting at 1 for the zero-length label at the end. */
86 len = 1;
87 for (p = name; *p; p++)
88 {
89 if (*p == '\\' && *(p + 1) != 0)
90 p++;
91 len++;
92 }
93 /* If there are n periods in the name, there are n + 1 labels, and
94 * thus n + 1 length fields, unless the name is empty or ends with a
95 * period. So add 1 unless name is empty or ends with a period.
96 */
97 if (*name && *(p - 1) != '.')
98 len++;
99
100 *buflen = len + HFIXEDSZ + QFIXEDSZ;
101 *buf = malloc(*buflen);
102 if (!*buf)
103 return ARES_ENOMEM;
104
105 /* Set up the header. */
106 q = *buf;
107 memset(q, 0, HFIXEDSZ);
108 DNS_HEADER_SET_QID(q, id);
109 DNS_HEADER_SET_OPCODE(q, QUERY);
110 DNS_HEADER_SET_RD(q, (rd) ? 1 : 0);
111 DNS_HEADER_SET_QDCOUNT(q, 1);
112
113 /* A name of "." is a screw case for the loop below, so adjust it. */
114 if (strcmp(name, ".") == 0)
115 name++;
116
117 /* Start writing out the name after the header. */
118 q += HFIXEDSZ;
119 while (*name)
120 {
121 if (*name == '.')
122 return ARES_EBADNAME;
123
124 /* Count the number of bytes in this label. */
125 len = 0;
126 for (p = name; *p && *p != '.'; p++)
127 {
128 if (*p == '\\' && *(p + 1) != 0)
129 p++;
130 len++;
131 }
132 if (len > MAXLABEL)
133 return ARES_EBADNAME;
134
135 /* Encode the length and copy the data. */
136 *q++ = len;
137 for (p = name; *p && *p != '.'; p++)
138 {
139 if (*p == '\\' && *(p + 1) != 0)
140 p++;
141 *q++ = *p;
142 }
143
144 /* Go to the next label and repeat, unless we hit the end. */
145 if (!*p)
146 break;
147 name = p + 1;
148 }
149
150 /* Add the zero-length label at the end. */
151 *q++ = 0;
152
153 /* Finish off the question with the type and class. */
154 DNS_QUESTION_SET_TYPE(q, type);
155 DNS_QUESTION_SET_CLASS(q, dnsclass);
156
157 return ARES_SUCCESS;
158 }

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27