1 /*
2  * Copyright (c) 1985, 1993
3  *    The Regents of the University of California.  All rights reserved.
4  *
5  * Portions copyright (c) 1999, 2000
6  * Intel Corporation.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *
23  *    This product includes software developed by the University of
24  *    California, Berkeley, Intel Corporation, and its contributors.
25  *
26  * 4. Neither the name of University, Intel Corporation, or their respective
27  *    contributors may be used to endorse or promote products derived from
28  *    this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND
31  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
32  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,
34  * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  *
42  */
43 
44 /*
45  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
46  *
47  * Permission to use, copy, modify, and distribute this software for any
48  * purpose with or without fee is hereby granted, provided that the above
49  * copyright notice and this permission notice appear in all copies, and that
50  * the name of Digital Equipment Corporation not be used in advertising or
51  * publicity pertaining to distribution of the document or software without
52  * specific, written prior permission.
53  *
54  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
55  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
56  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
57  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
58  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
59  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
60  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
61  * SOFTWARE.
62  */
63 
64 /*
65  * Portions Copyright (c) 1996 by Internet Software Consortium.
66  *
67  * Permission to use, copy, modify, and distribute this software for any
68  * purpose with or without fee is hereby granted, provided that the above
69  * copyright notice and this permission notice appear in all copies.
70  *
71  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
72  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
73  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
74  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
75  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
76  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
77  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
78  * SOFTWARE.
79  */
80 
81 #if defined(LIBC_SCCS) && !defined(lint)
82 static char sccsid[] = "@(#)res_mkquery.c   8.1 (Berkeley) 6/4/93";
83 static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
84 static char rcsid[] = "$Id: res_mkquery.c,v 1.1.1.1 2003/11/19 01:51:37 kyu3 Exp $";
85 #endif /* LIBC_SCCS and not lint */
86 
87 #include <sys/types.h>
88 #include <sys/param.h>
89 #include <netinet/in.h>
90 #include <arpa/nameser.h>
91 #include <netdb.h>
92 #include <resolv.h>
93 #include <stdio.h>
94 #include <string.h>
95 
96 #include "res_config.h"
97 
98 /*
99  * Form all types of queries.
100  * Returns the size of the result or -1.
101  */
102 int
res_mkquery(int op,const char * dname,int class,int type,const u_char * data,int datalen,const u_char * newrr_in,u_char * buf,int buflen)103 res_mkquery(
104     int op,         /* opcode of query */
105     const char *dname,  /* domain name */
106     int class,          /* class of query */
107     int type,           /* type of query */
108     const u_char *data, /* resource record data */
109     int datalen,        /* length of data */
110     const u_char *newrr_in, /* new rr for modify or append */
111     u_char *buf,        /* buffer to put query */
112     int buflen     /* size of buffer */
113     )
114 {
115     register HEADER *hp;
116     register u_char *cp;
117     register int n;
118     u_char *dnptrs[20], **dpp, **lastdnptr;
119 
120     if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
121         h_errno = NETDB_INTERNAL;
122         return (-1);
123     }
124 #ifdef DEBUG
125     if (_res.options & RES_DEBUG)
126         printf(";; res_mkquery(%d, %s, %d, %d)\n",
127                op, dname, class, type);
128 #endif
129     /*
130      * Initialize header fields.
131      */
132     if ((buf == NULL) || (buflen < HFIXEDSZ))
133         return (-1);
134     memset(buf, 0, HFIXEDSZ);
135     hp = (HEADER *) buf;
136     hp->id = htons(++_res.id);
137     hp->opcode = op;
138     hp->rd = (_res.options & RES_RECURSE) != 0;
139     hp->rcode = NOERROR;
140     cp = buf + HFIXEDSZ;
141     buflen -= HFIXEDSZ;
142     dpp = dnptrs;
143     *dpp++ = buf;
144     *dpp++ = NULL;
145     lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
146     /*
147      * perform opcode specific processing
148      */
149     switch (op) {
150     case QUERY: /*FALLTHROUGH*/
151     case NS_NOTIFY_OP:
152         if ((buflen -= QFIXEDSZ) < 0)
153             return (-1);
154         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
155             return (-1);
156         cp += n;
157         buflen -= n;
158         __putshort((u_int16_t)type, cp);
159         cp += INT16SZ;
160         __putshort((u_int16_t)class, cp);
161         cp += INT16SZ;
162         hp->qdcount = htons(1);
163         if (op == QUERY || data == NULL)
164             break;
165         /*
166          * Make an additional record for completion domain.
167          */
168         buflen -= RRFIXEDSZ;
169         n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
170         if (n < 0)
171             return (-1);
172         cp += n;
173         buflen -= n;
174         __putshort(T_NULL, cp);
175         cp += INT16SZ;
176         __putshort((u_int16_t)class, cp);
177         cp += INT16SZ;
178         __putlong(0, cp);
179         cp += INT32SZ;
180         __putshort(0, cp);
181         cp += INT16SZ;
182         hp->arcount = htons(1);
183         break;
184 
185     case IQUERY:
186         /*
187          * Initialize answer section
188          */
189         if (buflen < 1 + RRFIXEDSZ + datalen)
190             return (-1);
191         *cp++ = '\0';   /* no domain name */
192         __putshort((u_int16_t)type, cp);
193         cp += INT16SZ;
194         __putshort((u_int16_t)class, cp);
195         cp += INT16SZ;
196         __putlong(0, cp);
197         cp += INT32SZ;
198         __putshort((u_int16_t)datalen, cp);
199         cp += INT16SZ;
200         if (datalen) {
201             memcpy(cp, data, datalen);
202             cp += datalen;
203         }
204         hp->ancount = htons(1);
205         break;
206 
207     default:
208         return (-1);
209     }
210     return ((int)(cp - buf));
211 }
212