Annotation of src/lib/libc/resolv/res_mkquery.c, Revision 1.13.10.1
1.13.10.1! martin 1: /* $NetBSD: res_mkquery.c,v 1.13 2012/03/13 21:13:43 christos Exp $ */
1.11 christos 2:
3: /*
4: * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
5: * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003 Internet Software Consortium.
6: *
7: * Permission to use, copy, modify, and/or distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17: * PERFORMANCE OF THIS SOFTWARE.
18: */
1.1 christos 19:
20: /*
21: * Copyright (c) 1985, 1993
22: * The Regents of the University of California. All rights reserved.
1.11 christos 23: *
1.1 christos 24: * Redistribution and use in source and binary forms, with or without
25: * modification, are permitted provided that the following conditions
26: * are met:
27: * 1. Redistributions of source code must retain the above copyright
28: * notice, this list of conditions and the following disclaimer.
29: * 2. Redistributions in binary form must reproduce the above copyright
30: * notice, this list of conditions and the following disclaimer in the
31: * documentation and/or other materials provided with the distribution.
32: * 3. All advertising materials mentioning features or use of this software
33: * must display the following acknowledgement:
34: * This product includes software developed by the University of
35: * California, Berkeley and its contributors.
36: * 4. Neither the name of the University nor the names of its contributors
37: * may be used to endorse or promote products derived from this software
38: * without specific prior written permission.
1.11 christos 39: *
1.1 christos 40: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
41: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50: * SUCH DAMAGE.
51: */
52:
53: /*
54: * Portions Copyright (c) 1993 by Digital Equipment Corporation.
1.11 christos 55: *
1.1 christos 56: * Permission to use, copy, modify, and distribute this software for any
57: * purpose with or without fee is hereby granted, provided that the above
58: * copyright notice and this permission notice appear in all copies, and that
59: * the name of Digital Equipment Corporation not be used in advertising or
60: * publicity pertaining to distribution of the document or software without
61: * specific, written prior permission.
1.11 christos 62: *
1.1 christos 63: * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
64: * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
65: * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
66: * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
67: * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
68: * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
69: * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70: * SOFTWARE.
71: */
72:
1.3 christos 73: #include <sys/cdefs.h>
1.1 christos 74: #if defined(LIBC_SCCS) && !defined(lint)
1.3 christos 75: #ifdef notdef
1.1 christos 76: static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
1.11 christos 77: static const char rcsid[] = "Id: res_mkquery.c,v 1.10 2008/12/11 09:59:00 marka Exp";
1.3 christos 78: #else
1.13.10.1! martin 79: __RCSID("$NetBSD: res_mkquery.c,v 1.13 2012/03/13 21:13:43 christos Exp $");
1.3 christos 80: #endif
1.1 christos 81: #endif /* LIBC_SCCS and not lint */
82:
83: #include "port_before.h"
1.4 christos 84:
85: #include "namespace.h"
1.1 christos 86: #include <sys/types.h>
87: #include <sys/param.h>
88: #include <netinet/in.h>
89: #include <arpa/nameser.h>
1.13 christos 90: #include <assert.h>
1.1 christos 91: #include <netdb.h>
92: #include <resolv.h>
93: #include <stdio.h>
94: #include <string.h>
95: #include "port_after.h"
96:
1.5 christos 97: #if 0
1.4 christos 98: #ifdef __weak_alias
99: __weak_alias(res_nmkquery,_res_nmkquery)
100: __weak_alias(res_nopt,_res_nopt)
101: #endif
1.5 christos 102: #endif
1.4 christos 103:
1.1 christos 104: /* Options. Leave them on. */
1.10 christos 105: #ifndef DEBUG
1.1 christos 106: #define DEBUG
1.10 christos 107: #endif
1.1 christos 108:
109: extern const char *_res_opcodes[];
110:
1.7 christos 111: /*%
1.1 christos 112: * Form all types of queries.
113: * Returns the size of the result or -1.
114: */
115: int
116: res_nmkquery(res_state statp,
1.7 christos 117: int op, /*!< opcode of query */
118: const char *dname, /*!< domain name */
119: int class, int type, /*!< class and type of query */
120: const u_char *data, /*!< resource record data */
121: int datalen, /*!< length of data */
122: const u_char *newrr_in, /*!< new rr for modify or append */
123: u_char *buf, /*!< buffer to put query */
124: int buflen) /*!< size of buffer */
1.1 christos 125: {
126: register HEADER *hp;
127: register u_char *cp, *ep;
128: register int n;
129: u_char *dnptrs[20], **dpp, **lastdnptr;
130:
131: UNUSED(newrr_in);
132:
133: #ifdef DEBUG
134: if (statp->options & RES_DEBUG)
135: printf(";; res_nmkquery(%s, %s, %s, %s)\n",
136: _res_opcodes[op], dname, p_class(class), p_type(type));
137: #endif
138: /*
139: * Initialize header fields.
140: */
141: if ((buf == NULL) || (buflen < HFIXEDSZ))
142: return (-1);
143: memset(buf, 0, HFIXEDSZ);
1.2 christos 144: hp = (HEADER *)(void *)buf;
1.11 christos 145: statp->id = res_nrandomid(statp);
146: hp->id = htons(statp->id);
1.1 christos 147: hp->opcode = op;
148: hp->rd = (statp->options & RES_RECURSE) != 0U;
149: hp->rcode = NOERROR;
150: cp = buf + HFIXEDSZ;
151: ep = buf + buflen;
152: dpp = dnptrs;
153: *dpp++ = buf;
154: *dpp++ = NULL;
155: lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
156: /*
157: * perform opcode specific processing
158: */
159: switch (op) {
160: case QUERY: /*FALLTHROUGH*/
161: case NS_NOTIFY_OP:
162: if (ep - cp < QFIXEDSZ)
163: return (-1);
1.13 christos 164: if ((n = dn_comp(dname, cp, (int)(ep - cp - QFIXEDSZ), dnptrs,
1.1 christos 165: lastdnptr)) < 0)
166: return (-1);
167: cp += n;
168: ns_put16(type, cp);
169: cp += INT16SZ;
170: ns_put16(class, cp);
171: cp += INT16SZ;
172: hp->qdcount = htons(1);
173: if (op == QUERY || data == NULL)
174: break;
175: /*
176: * Make an additional record for completion domain.
177: */
178: if ((ep - cp) < RRFIXEDSZ)
179: return (-1);
1.13 christos 180: n = dn_comp((const char *)data, cp, (int)(ep - cp - RRFIXEDSZ),
1.1 christos 181: dnptrs, lastdnptr);
182: if (n < 0)
183: return (-1);
184: cp += n;
185: ns_put16(T_NULL, cp);
186: cp += INT16SZ;
187: ns_put16(class, cp);
188: cp += INT16SZ;
189: ns_put32(0, cp);
190: cp += INT32SZ;
191: ns_put16(0, cp);
192: cp += INT16SZ;
193: hp->arcount = htons(1);
194: break;
195:
196: case IQUERY:
197: /*
198: * Initialize answer section
199: */
200: if (ep - cp < 1 + RRFIXEDSZ + datalen)
201: return (-1);
1.7 christos 202: *cp++ = '\0'; /*%< no domain name */
1.1 christos 203: ns_put16(type, cp);
204: cp += INT16SZ;
205: ns_put16(class, cp);
206: cp += INT16SZ;
207: ns_put32(0, cp);
208: cp += INT32SZ;
209: ns_put16(datalen, cp);
210: cp += INT16SZ;
211: if (datalen) {
1.2 christos 212: memcpy(cp, data, (size_t)datalen);
1.1 christos 213: cp += datalen;
214: }
215: hp->ancount = htons(1);
216: break;
217:
218: default:
219: return (-1);
220: }
1.13 christos 221: _DIAGASSERT(__type_fit(int, cp - buf));
222: return (int)(cp - buf);
1.1 christos 223: }
224:
225: #ifdef RES_USE_EDNS0
226: /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
227:
228: int
229: res_nopt(res_state statp,
1.7 christos 230: int n0, /*%< current offset in buffer */
231: u_char *buf, /*%< buffer to put query */
232: int buflen, /*%< size of buffer */
233: int anslen) /*%< UDP answer buffer size */
1.1 christos 234: {
235: register HEADER *hp;
236: register u_char *cp, *ep;
237: u_int16_t flags = 0;
238:
239: #ifdef DEBUG
240: if ((statp->options & RES_DEBUG) != 0U)
241: printf(";; res_nopt()\n");
242: #endif
243:
1.2 christos 244: hp = (HEADER *)(void *)buf;
1.1 christos 245: cp = buf + n0;
246: ep = buf + buflen;
247:
248: if ((ep - cp) < 1 + RRFIXEDSZ)
249: return (-1);
250:
1.11 christos 251: *cp++ = 0; /*%< "." */
252: ns_put16(ns_t_opt, cp); /*%< TYPE */
1.1 christos 253: cp += INT16SZ;
1.13.10.1! martin 254: if (anslen > 0xffff)
! 255: anslen = 0xffff;
! 256: ns_put16(anslen, cp); /*%< CLASS = UDP payload size */
1.1 christos 257: cp += INT16SZ;
1.11 christos 258: *cp++ = NOERROR; /*%< extended RCODE */
259: *cp++ = 0; /*%< EDNS version */
1.9 christos 260:
1.1 christos 261: if (statp->options & RES_USE_DNSSEC) {
262: #ifdef DEBUG
263: if (statp->options & RES_DEBUG)
264: printf(";; res_opt()... ENDS0 DNSSEC\n");
265: #endif
266: flags |= NS_OPT_DNSSEC_OK;
267: }
268: ns_put16(flags, cp);
269: cp += INT16SZ;
1.9 christos 270:
1.11 christos 271: ns_put16(0U, cp); /*%< RDLEN */
1.1 christos 272: cp += INT16SZ;
1.9 christos 273:
1.1 christos 274: hp->arcount = htons(ntohs(hp->arcount) + 1);
275:
1.13 christos 276: _DIAGASSERT(__type_fit(int, cp - buf));
277: return (int)(cp - buf);
1.1 christos 278: }
1.9 christos 279:
280: /*
281: * Construct variable data (RDATA) block for OPT psuedo-RR, append it
282: * to the buffer, then update the RDLEN field (previously set to zero by
283: * res_nopt()) with the new RDATA length.
284: */
285: int
286: res_nopt_rdata(res_state statp,
287: int n0, /*%< current offset in buffer */
288: u_char *buf, /*%< buffer to put query */
289: int buflen, /*%< size of buffer */
290: u_char *rdata, /*%< ptr to start of opt rdata */
291: u_short code, /*%< OPTION-CODE */
292: u_short len, /*%< OPTION-LENGTH */
293: u_char *data) /*%< OPTION_DATA */
294: {
295: register u_char *cp, *ep;
296:
297: #ifdef DEBUG
298: if ((statp->options & RES_DEBUG) != 0U)
299: printf(";; res_nopt_rdata()\n");
300: #endif
301:
302: cp = buf + n0;
303: ep = buf + buflen;
304:
305: if ((ep - cp) < (4 + len))
306: return (-1);
307:
308: if (rdata < (buf + 2) || rdata >= ep)
309: return (-1);
310:
311: ns_put16(code, cp);
312: cp += INT16SZ;
313:
314: ns_put16(len, cp);
315: cp += INT16SZ;
316:
1.12 christos 317: memcpy(cp, data, (size_t)len);
1.9 christos 318: cp += len;
319:
1.13 christos 320: _DIAGASSERT(__type_fit(u_short, cp - rdata));
321: len = (u_short)(cp - rdata);
1.9 christos 322: ns_put16(len, rdata - 2); /* Update RDLEN field */
323:
1.13 christos 324: _DIAGASSERT(__type_fit(int, cp - buf));
325: return (int)(cp - buf);
1.9 christos 326: }
1.1 christos 327: #endif
1.7 christos 328:
329: /*! \file */
CVSweb <webmaster@jp.NetBSD.org>