BSD 4_4 release
[unix-history] / usr / src / lib / libc / net / res_mkquery.c
CommitLineData
882ceeb2 1/*-
67039e6d
KB
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
6b2f9dd0 4 *
ad787160
C
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.
6b2f9dd0 20 *
ad787160
C
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.
882ceeb2
MK
32 * -
33 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
34 *
35 * Permission to use, copy, modify, and distribute this software for any
36 * purpose with or without fee is hereby granted, provided that the above
37 * copyright notice and this permission notice appear in all copies, and that
38 * the name of Digital Equipment Corporation not be used in advertising or
39 * publicity pertaining to distribution of the document or software without
40 * specific, written prior permission.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
43 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
45 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
46 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
47 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
48 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 * SOFTWARE.
50 * -
51 * --Copyright--
b423e985 52 */
5e95d9b7 53
2ce81398 54#if defined(LIBC_SCCS) && !defined(lint)
ad787160 55static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
882ceeb2 56static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp $";
6b2f9dd0 57#endif /* LIBC_SCCS and not lint */
8ea4199d 58
7596199c 59#include <sys/param.h>
5e95d9b7 60#include <netinet/in.h>
61e99f72 61#include <arpa/nameser.h>
f94b2f50 62#include <resolv.h>
24fac7d8
KB
63#include <stdio.h>
64#include <string.h>
5e95d9b7
RC
65
66/*
67 * Form all types of queries.
68 * Returns the size of the result or -1.
69 */
882ceeb2 70res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
5e95d9b7 71 int op; /* opcode of query */
24fac7d8 72 const char *dname; /* domain name */
5e95d9b7 73 int class, type; /* class and type of query */
24fac7d8 74 const char *data; /* resource record data */
5e95d9b7 75 int datalen; /* length of data */
882ceeb2 76 const char *newrr_in; /* new rr for modify or append */
5e95d9b7
RC
77 char *buf; /* buffer to put query */
78 int buflen; /* size of buffer */
79{
80 register HEADER *hp;
81 register char *cp;
82 register int n;
882ceeb2 83 struct rrec *newrr = (struct rrec *) newrr_in;
5e95d9b7 84 char *dnptrs[10], **dpp, **lastdnptr;
5e95d9b7 85
ae94a224 86#ifdef DEBUG
5e95d9b7 87 if (_res.options & RES_DEBUG)
882ceeb2
MK
88 printf(";; res_mkquery(%d, %s, %d, %d)\n",
89 op, dname, class, type);
90#endif
5e95d9b7
RC
91 /*
92 * Initialize header fields.
93 */
43c7d2d3
JB
94 if ((buf == NULL) || (buflen < sizeof(HEADER)))
95 return(-1);
83d504bd 96 bzero(buf, sizeof(HEADER));
5e95d9b7
RC
97 hp = (HEADER *) buf;
98 hp->id = htons(++_res.id);
99 hp->opcode = op;
5e95d9b7
RC
100 hp->pr = (_res.options & RES_PRIMARY) != 0;
101 hp->rd = (_res.options & RES_RECURSE) != 0;
102 hp->rcode = NOERROR;
5e95d9b7
RC
103 cp = buf + sizeof(HEADER);
104 buflen -= sizeof(HEADER);
105 dpp = dnptrs;
106 *dpp++ = buf;
107 *dpp++ = NULL;
36534519 108 lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
5e95d9b7
RC
109 /*
110 * perform opcode specific processing
111 */
112 switch (op) {
113 case QUERY:
43c7d2d3
JB
114 if ((buflen -= QFIXEDSZ) < 0)
115 return(-1);
24fac7d8
KB
116 if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
117 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
5e95d9b7
RC
118 return (-1);
119 cp += n;
120 buflen -= n;
16dfe61e 121 __putshort(type, (u_char *)cp);
882ceeb2 122 cp += sizeof(u_int16_t);
16dfe61e 123 __putshort(class, (u_char *)cp);
882ceeb2 124 cp += sizeof(u_int16_t);
a766fb4a 125 hp->qdcount = htons(1);
5e95d9b7
RC
126 if (op == QUERY || data == NULL)
127 break;
128 /*
129 * Make an additional record for completion domain.
130 */
11e57e73 131 buflen -= RRFIXEDSZ;
24fac7d8
KB
132 if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
133 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
5e95d9b7
RC
134 return (-1);
135 cp += n;
136 buflen -= n;
16dfe61e 137 __putshort(T_NULL, (u_char *)cp);
882ceeb2 138 cp += sizeof(u_int16_t);
16dfe61e 139 __putshort(class, (u_char *)cp);
882ceeb2 140 cp += sizeof(u_int16_t);
16dfe61e 141 __putlong(0, (u_char *)cp);
882ceeb2 142 cp += sizeof(u_int32_t);
16dfe61e 143 __putshort(0, (u_char *)cp);
882ceeb2 144 cp += sizeof(u_int16_t);
a766fb4a 145 hp->arcount = htons(1);
5e95d9b7
RC
146 break;
147
148 case IQUERY:
149 /*
150 * Initialize answer section
151 */
152 if (buflen < 1 + RRFIXEDSZ + datalen)
153 return (-1);
154 *cp++ = '\0'; /* no domain name */
16dfe61e 155 __putshort(type, (u_char *)cp);
882ceeb2 156 cp += sizeof(u_int16_t);
16dfe61e 157 __putshort(class, (u_char *)cp);
882ceeb2 158 cp += sizeof(u_int16_t);
16dfe61e 159 __putlong(0, (u_char *)cp);
882ceeb2 160 cp += sizeof(u_int32_t);
16dfe61e 161 __putshort(datalen, (u_char *)cp);
882ceeb2 162 cp += sizeof(u_int16_t);
5e95d9b7
RC
163 if (datalen) {
164 bcopy(data, cp, datalen);
165 cp += datalen;
166 }
a766fb4a 167 hp->ancount = htons(1);
5e95d9b7
RC
168 break;
169
3bf25746
KD
170#ifdef ALLOW_UPDATES
171 /*
172 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
173 * (Record to be modified is followed by its replacement in msg.)
174 */
5e95d9b7 175 case UPDATEM:
3bf25746
KD
176 case UPDATEMA:
177
178 case UPDATED:
5e95d9b7 179 /*
3bf25746
KD
180 * The res code for UPDATED and UPDATEDA is the same; user
181 * calls them differently: specifies data for UPDATED; server
182 * ignores data if specified for UPDATEDA.
5e95d9b7 183 */
3bf25746 184 case UPDATEDA:
5e95d9b7
RC
185 buflen -= RRFIXEDSZ + datalen;
186 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
187 return (-1);
188 cp += n;
371d3c9b 189 __putshort(type, cp);
882ceeb2 190 cp += sizeof(u_int16_t);
371d3c9b 191 __putshort(class, cp);
882ceeb2 192 cp += sizeof(u_int16_t);
371d3c9b 193 __putlong(0, cp);
882ceeb2 194 cp += sizeof(u_int32_t);
371d3c9b 195 __putshort(datalen, cp);
882ceeb2 196 cp += sizeof(u_int16_t);
5e95d9b7
RC
197 if (datalen) {
198 bcopy(data, cp, datalen);
199 cp += datalen;
200 }
3bf25746
KD
201 if ( (op == UPDATED) || (op == UPDATEDA) ) {
202 hp->ancount = htons(0);
203 break;
204 }
205 /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
5e95d9b7 206
3bf25746
KD
207 case UPDATEA: /* Add new resource record */
208 buflen -= RRFIXEDSZ + datalen;
5e95d9b7
RC
209 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
210 return (-1);
211 cp += n;
371d3c9b 212 __putshort(newrr->r_type, cp);
882ceeb2 213 cp += sizeof(u_int16_t);
371d3c9b 214 __putshort(newrr->r_class, cp);
882ceeb2 215 cp += sizeof(u_int16_t);
371d3c9b 216 __putlong(0, cp);
882ceeb2 217 cp += sizeof(u_int32_t);
371d3c9b 218 __putshort(newrr->r_size, cp);
882ceeb2 219 cp += sizeof(u_int16_t);
5e95d9b7
RC
220 if (newrr->r_size) {
221 bcopy(newrr->r_data, cp, newrr->r_size);
222 cp += newrr->r_size;
223 }
3bf25746 224 hp->ancount = htons(0);
5e95d9b7 225 break;
3bf25746 226
882ceeb2 227#endif /* ALLOW_UPDATES */
5e95d9b7
RC
228 }
229 return (cp - buf);
230}