/*
* Copyright (c) 1985 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef lint
-static char sccsid[] = "@(#)res_mkquery.c 5.6 (Berkeley) %G%";
-#endif not lint
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_mkquery.c 6.9 (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
-#include <arpa/resolv.h>
-
-extern char *sprintf();
+#include <resolv.h>
/*
* Form all types of queries.
/*
* Initialize header fields.
*/
+ bzero(buf, sizeof(HEADER));
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
hp->opcode = op;
- hp->qr = hp->aa = hp->tc = hp->ra = 0;
hp->pr = (_res.options & RES_PRIMARY) != 0;
hp->rd = (_res.options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
- hp->qdcount = 0;
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
cp = buf + sizeof(HEADER);
buflen -= sizeof(HEADER);
dpp = dnptrs;
*dpp++ = buf;
*dpp++ = NULL;
lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
- /*
- * If the domain name contains no dots (single label), then
- * append the default domain name to the one given.
- */
- if ((_res.options & RES_DEFNAMES) && dname != 0 && dname[0] != '\0' &&
- index(dname, '.') == NULL) {
- if (!(_res.options & RES_INIT))
- if (res_init() == -1)
- return(-1);
- if (_res.defdname[0] != '\0')
- dname = sprintf(dnbuf, "%s.%s", dname, _res.defdname);
- }
/*
* perform opcode specific processing
*/
switch (op) {
case QUERY:
- case CQUERYM:
- case CQUERYU:
buflen -= QFIXEDSZ;
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
hp->ancount = htons(1);
break;
-#ifdef notdef
- case UPDATED:
- /*
- * Put record to be added or deleted in additional section
- */
- buflen -= RRFIXEDSZ + datalen;
- if ((n = dn_comp(dname, cp, buflen, NULL, NULL)) < 0)
- return (-1);
- cp += n;
- *((u_short *)cp) = htons(type);
- cp += sizeof(u_short);
- *((u_short *)cp) = htons(class);
- cp += sizeof(u_short);
- *((u_long *)cp) = 0;
- cp += sizeof(u_long);
- *((u_short *)cp) = htons(datalen);
- cp += sizeof(u_short);
- if (datalen) {
- bcopy(data, cp, datalen);
- cp += datalen;
- }
- break;
-
+#ifdef ALLOW_UPDATES
+ /*
+ * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
+ * (Record to be modified is followed by its replacement in msg.)
+ */
case UPDATEM:
+ case UPDATEMA:
+
+ case UPDATED:
/*
- * Record to be modified followed by its replacement
+ * The res code for UPDATED and UPDATEDA is the same; user
+ * calls them differently: specifies data for UPDATED; server
+ * ignores data if specified for UPDATEDA.
*/
+ case UPDATEDA:
buflen -= RRFIXEDSZ + datalen;
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
- *((u_short *)cp) = htons(type);
- cp += sizeof(u_short);
- *((u_short *)cp) = htons(class);
- cp += sizeof(u_short);
- *((u_long *)cp) = 0;
+ putshort(type, cp);
+ cp += sizeof(u_short);
+ putshort(class, cp);
+ cp += sizeof(u_short);
+ putlong(0, cp);
cp += sizeof(u_long);
- *((u_short *)cp) = htons(datalen);
- cp += sizeof(u_short);
+ putshort(datalen, cp);
+ cp += sizeof(u_short);
if (datalen) {
bcopy(data, cp, datalen);
cp += datalen;
}
+ if ( (op == UPDATED) || (op == UPDATEDA) ) {
+ hp->ancount = htons(0);
+ break;
+ }
+ /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
- case UPDATEA:
- buflen -= RRFIXEDSZ + newrr->r_size;
+ case UPDATEA: /* Add new resource record */
+ buflen -= RRFIXEDSZ + datalen;
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
- *((u_short *)cp) = htons(newrr->r_type);
- cp += sizeof(u_short);
- *((u_short *)cp) = htons(newrr->r_type);
- cp += sizeof(u_short);
- *((u_long *)cp) = htonl(newrr->r_ttl);
+ putshort(newrr->r_type, cp);
+ cp += sizeof(u_short);
+ putshort(newrr->r_class, cp);
+ cp += sizeof(u_short);
+ putlong(0, cp);
cp += sizeof(u_long);
- *((u_short *)cp) = htons(newrr->r_size);
- cp += sizeof(u_short);
+ putshort(newrr->r_size, cp);
+ cp += sizeof(u_short);
if (newrr->r_size) {
bcopy(newrr->r_data, cp, newrr->r_size);
cp += newrr->r_size;
}
+ hp->ancount = htons(0);
break;
-#endif
+
+#endif ALLOW_UPDATES
}
return (cp - buf);
}