1*61023Skarels /*- 221387Sdist * Copyright (c) 1985 Regents of the University of California. 333679Sbostic * All rights reserved. 433679Sbostic * 542627Sbostic * %sccs.include.redist.c% 6*61023Skarels * - 7*61023Skarels * Portions Copyright (c) 1993 by Digital Equipment Corporation. 8*61023Skarels * 9*61023Skarels * Permission to use, copy, modify, and distribute this software for any 10*61023Skarels * purpose with or without fee is hereby granted, provided that the above 11*61023Skarels * copyright notice and this permission notice appear in all copies, and that 12*61023Skarels * the name of Digital Equipment Corporation not be used in advertising or 13*61023Skarels * publicity pertaining to distribution of the document or software without 14*61023Skarels * specific, written prior permission. 15*61023Skarels * 16*61023Skarels * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 17*61023Skarels * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 18*61023Skarels * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 19*61023Skarels * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 20*61023Skarels * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 21*61023Skarels * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 22*61023Skarels * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 23*61023Skarels * SOFTWARE. 24*61023Skarels * - 25*61023Skarels * --Copyright-- 2618548Sralph */ 2718548Sralph 2826634Sdonn #if defined(LIBC_SCCS) && !defined(lint) 29*61023Skarels static char sccsid[] = "@(#)res_mkquery.c 6.17 (Berkeley) 06/02/93"; 30*61023Skarels 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 */ 44*61023Skarels 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 */ 50*61023Skarels 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; 57*61023Skarels struct rrec *newrr = (struct rrec *) newrr_in; 5818143Sralph char *dnptrs[10], **dpp, **lastdnptr; 5918143Sralph 6024734Sbloom #ifdef DEBUG 6118143Sralph if (_res.options & RES_DEBUG) 62*61023Skarels printf(";; res_mkquery(%d, %s, %d, %d)\n", 63*61023Skarels op, dname, class, type); 64*61023Skarels #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); 96*61023Skarels cp += sizeof(u_int16_t); 9747045Sbostic __putshort(class, (u_char *)cp); 98*61023Skarels 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); 112*61023Skarels cp += sizeof(u_int16_t); 11347045Sbostic __putshort(class, (u_char *)cp); 114*61023Skarels cp += sizeof(u_int16_t); 11547045Sbostic __putlong(0, (u_char *)cp); 116*61023Skarels cp += sizeof(u_int32_t); 11747045Sbostic __putshort(0, (u_char *)cp); 118*61023Skarels 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); 130*61023Skarels cp += sizeof(u_int16_t); 13147045Sbostic __putshort(class, (u_char *)cp); 132*61023Skarels cp += sizeof(u_int16_t); 13347045Sbostic __putlong(0, (u_char *)cp); 134*61023Skarels cp += sizeof(u_int32_t); 13547045Sbostic __putshort(datalen, (u_char *)cp); 136*61023Skarels 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); 164*61023Skarels cp += sizeof(u_int16_t); 16546496Sbostic __putshort(class, cp); 166*61023Skarels cp += sizeof(u_int16_t); 16746496Sbostic __putlong(0, cp); 168*61023Skarels cp += sizeof(u_int32_t); 16946496Sbostic __putshort(datalen, cp); 170*61023Skarels 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); 187*61023Skarels cp += sizeof(u_int16_t); 18846496Sbostic __putshort(newrr->r_class, cp); 189*61023Skarels cp += sizeof(u_int16_t); 19046496Sbostic __putlong(0, cp); 191*61023Skarels cp += sizeof(u_int32_t); 19246496Sbostic __putshort(newrr->r_size, cp); 193*61023Skarels 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 201*61023Skarels #endif /* ALLOW_UPDATES */ 20218143Sralph } 20318143Sralph return (cp - buf); 20418143Sralph } 205