]> git.saurik.com Git - apple/libresolv.git/blob - res_mkquery.c
libresolv-65.tar.gz
[apple/libresolv.git] / res_mkquery.c
1 /*
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 /*
35 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
36 *
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies, and that
40 * the name of Digital Equipment Corporation not be used in advertising or
41 * publicity pertaining to distribution of the document or software without
42 * specific, written prior permission.
43 *
44 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
45 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
47 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
48 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
49 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51 * SOFTWARE.
52 */
53
54 /*
55 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
56 *
57 * Permission to use, copy, modify, and distribute this software for any
58 * purpose with or without fee is hereby granted, provided that the above
59 * copyright notice and this permission notice appear in all copies.
60 *
61 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
62 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
63 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
64 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
65 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
66 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
67 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
68 * SOFTWARE.
69 */
70
71 #if defined(LIBC_SCCS) && !defined(lint)
72 static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
73 static const char rcsid[] = "$Id: res_mkquery.c,v 1.1 2006/03/01 19:01:38 majka Exp $";
74 #endif /* LIBC_SCCS and not lint */
75
76 #ifndef __APPLE__
77 #include "port_before.h"
78 #endif
79 #include <sys/types.h>
80 #include <sys/param.h>
81 #include <netinet/in.h>
82 #include <arpa/nameser.h>
83 #include <netdb.h>
84 #include <resolv.h>
85 #include <stdio.h>
86 #include <string.h>
87 #include "res_private.h"
88 #ifndef __APPLE__
89 #include "port_after.h"
90 #endif
91
92 /* Options. Leave them on. */
93 #define DEBUG
94
95 extern const char *__res_opcodes[];
96
97 /*
98 * Form all types of queries.
99 * Returns the size of the result or -1.
100 */
101 int
102 res_nmkquery(res_state statp,
103 int op, /* opcode of query */
104 const char *dname, /* domain name */
105 int class, int type, /* class and type of query */
106 const u_char *data, /* resource record data */
107 int datalen, /* length of data */
108 const u_char *newrr_in, /* new rr for modify or append */
109 u_char *buf, /* buffer to put query */
110 int buflen) /* size of buffer */
111 {
112 register HEADER *hp;
113 register u_char *cp;
114 register int n;
115 u_char *dnptrs[20], **dpp, **lastdnptr;
116
117 #ifdef __APPLE__
118 n = 0;
119 #else
120 UNUSED(newrr_in);
121 #endif
122
123 #ifdef DEBUG
124 if (statp->options & RES_DEBUG)
125 printf(";; res_nmkquery(%s, %s, %s, %s)\n",
126 __res_opcodes[op], dname, p_class(class), p_type(type));
127 #endif
128 /*
129 * Initialize header fields.
130 */
131 if ((buf == NULL) || (buflen < NS_HFIXEDSZ))
132 return (-1);
133 memset(buf, 0, NS_HFIXEDSZ);
134 hp = (HEADER *) buf;
135 #ifdef __APPLE__
136 hp->id = res_randomid();
137 #else
138 hp->id = htons(++statp->id);
139 #endif
140 hp->opcode = op;
141 hp->rd = (statp->options & RES_RECURSE) != 0;
142 hp->rcode = ns_r_noerror;
143 cp = buf + NS_HFIXEDSZ;
144 buflen -= NS_HFIXEDSZ;
145 dpp = dnptrs;
146 *dpp++ = buf;
147 *dpp++ = NULL;
148 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
149 /*
150 * perform opcode specific processing
151 */
152 switch (op) {
153 case ns_o_query: /*FALLTHROUGH*/
154 case ns_o_update:
155 if ((buflen -= NS_QFIXEDSZ) < 0)
156 return (-1);
157 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
158 return (-1);
159 cp += n;
160 buflen -= n;
161 putshort(type, cp);
162 cp += NS_INT16SZ;
163 putshort(class, cp);
164 cp += NS_INT16SZ;
165 hp->qdcount = htons(1);
166 if (op == ns_o_query || data == NULL)
167 break;
168 /*
169 * Make an additional record for completion domain.
170 */
171 buflen -= NS_RRFIXEDSZ;
172 n = dn_comp((const char *)data, cp, buflen, dnptrs, lastdnptr);
173 if (n < 0)
174 return (-1);
175 cp += n;
176 buflen -= n;
177 putshort(ns_t_null, cp);
178 cp += NS_INT16SZ;
179 putshort(class, cp);
180 cp += NS_INT16SZ;
181 putlong(0, cp);
182 cp += NS_INT32SZ;
183 putshort(0, cp);
184 cp += NS_INT16SZ;
185 hp->arcount = htons(1);
186 break;
187
188 case ns_o_iquery:
189 /*
190 * Initialize answer section
191 */
192 if (buflen < 1 + NS_RRFIXEDSZ + datalen)
193 return (-1);
194 *cp++ = '\0'; /* no domain name */
195 putshort(type, cp);
196 cp += NS_INT16SZ;
197 putshort(class, cp);
198 cp += NS_INT16SZ;
199 putlong(0, cp);
200 cp += NS_INT32SZ;
201 putshort(datalen, cp);
202 cp += NS_INT16SZ;
203 if (datalen) {
204 memcpy(cp, data, datalen);
205 cp += datalen;
206 }
207 hp->ancount = htons(1);
208 break;
209
210 default:
211 return (-1);
212 }
213 return (cp - buf);
214 }
215
216 #ifdef RES_USE_EDNS0
217 /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
218 #ifndef T_OPT
219 #define T_OPT 41
220 #endif
221
222 int
223 res_nopt(statp, n0, buf, buflen, anslen)
224 res_state statp;
225 int n0;
226 u_char *buf; /* buffer to put query */
227 int buflen; /* size of buffer */
228 int anslen; /* answer buffer length */
229 {
230 register HEADER *hp;
231 register u_char *cp;
232 u_int16_t flags = 0;
233
234 #ifdef DEBUG
235 if ((statp->options & RES_DEBUG) != 0)
236 printf(";; res_nopt()\n");
237 #endif
238
239 hp = (HEADER *) buf;
240 cp = buf + n0;
241 buflen -= n0;
242
243 if (buflen < 1 + NS_RRFIXEDSZ)
244 return -1;
245
246 *cp++ = 0; /* "." */
247 buflen--;
248
249 putshort(T_OPT, cp); /* TYPE */
250 cp += NS_INT16SZ;
251 putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */
252 cp += NS_INT16SZ;
253 *cp++ = ns_r_noerror; /* extended RCODE */
254 *cp++ = 0; /* EDNS version */
255 if (statp->options & RES_USE_DNSSEC) {
256 #ifdef DEBUG
257 if (statp->options & RES_DEBUG)
258 printf(";; res_opt()... ENDS0 DNSSEC\n");
259 #endif
260 flags |= NS_OPT_DNSSEC_OK;
261 }
262 putshort(flags, cp);
263 cp += NS_INT16SZ;
264 putshort(0, cp); /* RDLEN */
265 cp += NS_INT16SZ;
266 hp->arcount = htons(ntohs(hp->arcount) + 1);
267 buflen -= NS_RRFIXEDSZ;
268
269 return cp - buf;
270 }
271 #endif