xref: /csrg-svn/lib/libc/net/res_mkquery.c (revision 61151)
161023Skarels /*-
2*61151Sbostic  * Copyright (c) 1985, 1993
3*61151Sbostic  *	The Regents of the University of California.  All rights reserved.
433679Sbostic  *
542627Sbostic  * %sccs.include.redist.c%
661023Skarels  * -
761023Skarels  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
861023Skarels  *
961023Skarels  * Permission to use, copy, modify, and distribute this software for any
1061023Skarels  * purpose with or without fee is hereby granted, provided that the above
1161023Skarels  * copyright notice and this permission notice appear in all copies, and that
1261023Skarels  * the name of Digital Equipment Corporation not be used in advertising or
1361023Skarels  * publicity pertaining to distribution of the document or software without
1461023Skarels  * specific, written prior permission.
1561023Skarels  *
1661023Skarels  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
1761023Skarels  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
1861023Skarels  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
1961023Skarels  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
2061023Skarels  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
2161023Skarels  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
2261023Skarels  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2361023Skarels  * SOFTWARE.
2461023Skarels  * -
2561023Skarels  * --Copyright--
2618548Sralph  */
2718548Sralph 
2826634Sdonn #if defined(LIBC_SCCS) && !defined(lint)
29*61151Sbostic static char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 06/04/93";
3061023Skarels static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp $";
3133679Sbostic #endif /* LIBC_SCCS and not lint */
3221387Sdist 
3345845Swilliam #include <sys/param.h>
3418143Sralph #include <netinet/in.h>
3524082Skjd #include <arpa/nameser.h>
3626895Skjd #include <resolv.h>
3746604Sbostic #include <stdio.h>
3846604Sbostic #include <string.h>
3918143Sralph 
4018143Sralph /*
4118143Sralph  * Form all types of queries.
4218143Sralph  * Returns the size of the result or -1.
4318143Sralph  */
res_mkquery(op,dname,class,type,data,datalen,newrr_in,buf,buflen)4461023Skarels res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
4518143Sralph 	int op;			/* opcode of query */
4646604Sbostic 	const char *dname;		/* domain name */
4718143Sralph 	int class, type;	/* class and type of query */
4846604Sbostic 	const char *data;		/* resource record data */
4918143Sralph 	int datalen;		/* length of data */
5061023Skarels 	const char *newrr_in;	/* new rr for modify or append */
5118143Sralph 	char *buf;		/* buffer to put query */
5218143Sralph 	int buflen;		/* size of buffer */
5318143Sralph {
5418143Sralph 	register HEADER *hp;
5518143Sralph 	register char *cp;
5618143Sralph 	register int n;
5761023Skarels 	struct rrec *newrr = (struct rrec *) newrr_in;
5818143Sralph 	char *dnptrs[10], **dpp, **lastdnptr;
5918143Sralph 
6024734Sbloom #ifdef DEBUG
6118143Sralph 	if (_res.options & RES_DEBUG)
6261023Skarels 		printf(";; res_mkquery(%d, %s, %d, %d)\n",
6361023Skarels 		       op, dname, class, type);
6461023Skarels #endif
6518143Sralph 	/*
6618143Sralph 	 * Initialize header fields.
6718143Sralph 	 */
6839789Sbloom 	if ((buf == NULL) || (buflen < sizeof(HEADER)))
6939789Sbloom 		return(-1);
7036322Skarels 	bzero(buf, sizeof(HEADER));
7118143Sralph 	hp = (HEADER *) buf;
7218143Sralph 	hp->id = htons(++_res.id);
7318143Sralph 	hp->opcode = op;
7418143Sralph 	hp->pr = (_res.options & RES_PRIMARY) != 0;
7518143Sralph 	hp->rd = (_res.options & RES_RECURSE) != 0;
7618143Sralph 	hp->rcode = NOERROR;
7718143Sralph 	cp = buf + sizeof(HEADER);
7818143Sralph 	buflen -= sizeof(HEADER);
7918143Sralph 	dpp = dnptrs;
8018143Sralph 	*dpp++ = buf;
8118143Sralph 	*dpp++ = NULL;
8218341Sralph 	lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
8318143Sralph 	/*
8418143Sralph 	 * perform opcode specific processing
8518143Sralph 	 */
8618143Sralph 	switch (op) {
8718143Sralph 	case QUERY:
8839789Sbloom 		if ((buflen -= QFIXEDSZ) < 0)
8939789Sbloom 			return(-1);
9046604Sbostic 		if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
9146604Sbostic 		    (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
9218143Sralph 			return (-1);
9318143Sralph 		cp += n;
9418143Sralph 		buflen -= n;
9547045Sbostic 		__putshort(type, (u_char *)cp);
9661023Skarels 		cp += sizeof(u_int16_t);
9747045Sbostic 		__putshort(class, (u_char *)cp);
9861023Skarels 		cp += sizeof(u_int16_t);
9923872Skjd 		hp->qdcount = htons(1);
10018143Sralph 		if (op == QUERY || data == NULL)
10118143Sralph 			break;
10218143Sralph 		/*
10318143Sralph 		 * Make an additional record for completion domain.
10418143Sralph 		 */
10518528Sralph 		buflen -= RRFIXEDSZ;
10646604Sbostic 		if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
10746604Sbostic 		    (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
10818143Sralph 			return (-1);
10918143Sralph 		cp += n;
11018143Sralph 		buflen -= n;
11147045Sbostic 		__putshort(T_NULL, (u_char *)cp);
11261023Skarels 		cp += sizeof(u_int16_t);
11347045Sbostic 		__putshort(class, (u_char *)cp);
11461023Skarels 		cp += sizeof(u_int16_t);
11547045Sbostic 		__putlong(0, (u_char *)cp);
11661023Skarels 		cp += sizeof(u_int32_t);
11747045Sbostic 		__putshort(0, (u_char *)cp);
11861023Skarels 		cp += sizeof(u_int16_t);
11923872Skjd 		hp->arcount = htons(1);
12018143Sralph 		break;
12118143Sralph 
12218143Sralph 	case IQUERY:
12318143Sralph 		/*
12418143Sralph 		 * Initialize answer section
12518143Sralph 		 */
12618143Sralph 		if (buflen < 1 + RRFIXEDSZ + datalen)
12718143Sralph 			return (-1);
12818143Sralph 		*cp++ = '\0';	/* no domain name */
12947045Sbostic 		__putshort(type, (u_char *)cp);
13061023Skarels 		cp += sizeof(u_int16_t);
13147045Sbostic 		__putshort(class, (u_char *)cp);
13261023Skarels 		cp += sizeof(u_int16_t);
13347045Sbostic 		__putlong(0, (u_char *)cp);
13461023Skarels 		cp += sizeof(u_int32_t);
13547045Sbostic 		__putshort(datalen, (u_char *)cp);
13661023Skarels 		cp += sizeof(u_int16_t);
13718143Sralph 		if (datalen) {
13818143Sralph 			bcopy(data, cp, datalen);
13918143Sralph 			cp += datalen;
14018143Sralph 		}
14123872Skjd 		hp->ancount = htons(1);
14218143Sralph 		break;
14318143Sralph 
14429989Skjd #ifdef ALLOW_UPDATES
14529989Skjd 	/*
14629989Skjd 	 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
14729989Skjd 	 * (Record to be modified is followed by its replacement in msg.)
14829989Skjd 	 */
14929989Skjd 	case UPDATEM:
15029989Skjd 	case UPDATEMA:
15129989Skjd 
15218143Sralph 	case UPDATED:
15318143Sralph 		/*
15429989Skjd 		 * The res code for UPDATED and UPDATEDA is the same; user
15529989Skjd 		 * calls them differently: specifies data for UPDATED; server
15629989Skjd 		 * ignores data if specified for UPDATEDA.
15718143Sralph 		 */
15829989Skjd 	case UPDATEDA:
15918143Sralph 		buflen -= RRFIXEDSZ + datalen;
16029989Skjd 		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
16118143Sralph 			return (-1);
16218143Sralph 		cp += n;
16346496Sbostic 		__putshort(type, cp);
16461023Skarels                 cp += sizeof(u_int16_t);
16546496Sbostic                 __putshort(class, cp);
16661023Skarels                 cp += sizeof(u_int16_t);
16746496Sbostic 		__putlong(0, cp);
16861023Skarels 		cp += sizeof(u_int32_t);
16946496Sbostic 		__putshort(datalen, cp);
17061023Skarels                 cp += sizeof(u_int16_t);
17118143Sralph 		if (datalen) {
17218143Sralph 			bcopy(data, cp, datalen);
17318143Sralph 			cp += datalen;
17418143Sralph 		}
17529989Skjd 		if ( (op == UPDATED) || (op == UPDATEDA) ) {
17629989Skjd 			hp->ancount = htons(0);
17729989Skjd 			break;
17829989Skjd 		}
17929989Skjd 		/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
18018143Sralph 
18129989Skjd 	case UPDATEA:	/* Add new resource record */
18218143Sralph 		buflen -= RRFIXEDSZ + datalen;
18318143Sralph 		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
18418143Sralph 			return (-1);
18518143Sralph 		cp += n;
18646496Sbostic 		__putshort(newrr->r_type, cp);
18761023Skarels                 cp += sizeof(u_int16_t);
18846496Sbostic                 __putshort(newrr->r_class, cp);
18961023Skarels                 cp += sizeof(u_int16_t);
19046496Sbostic 		__putlong(0, cp);
19161023Skarels 		cp += sizeof(u_int32_t);
19246496Sbostic 		__putshort(newrr->r_size, cp);
19361023Skarels                 cp += sizeof(u_int16_t);
19418143Sralph 		if (newrr->r_size) {
19518143Sralph 			bcopy(newrr->r_data, cp, newrr->r_size);
19618143Sralph 			cp += newrr->r_size;
19718143Sralph 		}
19829989Skjd 		hp->ancount = htons(0);
19918143Sralph 		break;
20029989Skjd 
20161023Skarels #endif /* ALLOW_UPDATES */
20218143Sralph 	}
20318143Sralph 	return (cp - buf);
20418143Sralph }
205