add copyright notice
[unix-history] / usr / src / lib / libc / net / res_mkquery.c
CommitLineData
b423e985
RC
1/* res_mkquery.c 4.5 85/04/01 */
2
3/*
4 * Copyright (c) 1985 Regents of the University of California
5 * All Rights Reserved
6 */
5e95d9b7
RC
7
8#include <stdio.h>
9#include <sys/types.h>
10#include <netinet/in.h>
11#include <nameser.h>
12#include <resolv.h>
13
14/*
15 * Form all types of queries.
16 * Returns the size of the result or -1.
17 */
31f0ead0 18res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
5e95d9b7
RC
19 int op; /* opcode of query */
20 char *dname; /* domain name */
21 int class, type; /* class and type of query */
22 char *data; /* resource record data */
23 int datalen; /* length of data */
24 struct rrec *newrr; /* new rr for modify or append */
25 char *buf; /* buffer to put query */
26 int buflen; /* size of buffer */
27{
28 register HEADER *hp;
29 register char *cp;
30 register int n;
31 char dnbuf[MAXDNAME];
32 char *dnptrs[10], **dpp, **lastdnptr;
11e57e73 33 extern char *index();
5e95d9b7
RC
34
35 if (_res.options & RES_DEBUG)
31f0ead0 36 printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
5e95d9b7
RC
37 /*
38 * Initialize header fields.
39 */
40 hp = (HEADER *) buf;
41 hp->id = htons(++_res.id);
42 hp->opcode = op;
43 hp->qr = hp->aa = hp->tc = hp->ra = 0;
44 hp->pr = (_res.options & RES_PRIMARY) != 0;
45 hp->rd = (_res.options & RES_RECURSE) != 0;
46 hp->rcode = NOERROR;
47 hp->qdcount = 0;
48 hp->ancount = 0;
49 hp->nscount = 0;
50 hp->arcount = 0;
51 cp = buf + sizeof(HEADER);
52 buflen -= sizeof(HEADER);
53 dpp = dnptrs;
54 *dpp++ = buf;
55 *dpp++ = NULL;
36534519 56 lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
5e95d9b7 57 /*
11e57e73 58 * If the domain name contains no dots (single label), then
5e95d9b7
RC
59 * append the default domain name to the one given.
60 */
11e57e73
RC
61 if ((_res.options & RES_DEFNAMES) && dname[0] != '\0' &&
62 index(dname, '.') == NULL) {
5e95d9b7
RC
63 if (!(_res.options & RES_INIT))
64 res_init();
65 if (_res.defdname[0] != '\0')
66 dname = sprintf(dnbuf, "%s.%s", dname, _res.defdname);
67 }
68 /*
69 * perform opcode specific processing
70 */
71 switch (op) {
72 case QUERY:
73 case CQUERYM:
74 case CQUERYU:
75 buflen -= QFIXEDSZ;
76 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
77 return (-1);
78 cp += n;
79 buflen -= n;
11e57e73 80 putshort(type, cp);
5e95d9b7 81 cp += sizeof(u_short);
11e57e73 82 putshort(class, cp);
5e95d9b7
RC
83 cp += sizeof(u_short);
84 hp->qdcount = HTONS(1);
85 if (op == QUERY || data == NULL)
86 break;
87 /*
88 * Make an additional record for completion domain.
89 */
11e57e73 90 buflen -= RRFIXEDSZ;
5e95d9b7
RC
91 if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
92 return (-1);
93 cp += n;
94 buflen -= n;
11e57e73 95 putshort(T_NULL, cp);
5e95d9b7 96 cp += sizeof(u_short);
11e57e73 97 putshort(class, cp);
5e95d9b7 98 cp += sizeof(u_short);
11e57e73 99 putlong(0, cp);
5e95d9b7 100 cp += sizeof(u_long);
11e57e73 101 putshort(0, cp);
5e95d9b7
RC
102 cp += sizeof(u_short);
103 hp->arcount = HTONS(1);
104 break;
105
106 case IQUERY:
107 /*
108 * Initialize answer section
109 */
110 if (buflen < 1 + RRFIXEDSZ + datalen)
111 return (-1);
112 *cp++ = '\0'; /* no domain name */
11e57e73 113 putshort(type, cp);
5e95d9b7 114 cp += sizeof(u_short);
11e57e73 115 putshort(class, cp);
5e95d9b7 116 cp += sizeof(u_short);
11e57e73 117 putlong(0, cp);
5e95d9b7 118 cp += sizeof(u_long);
11e57e73 119 putshort(datalen, cp);
5e95d9b7
RC
120 cp += sizeof(u_short);
121 if (datalen) {
122 bcopy(data, cp, datalen);
123 cp += datalen;
124 }
125 hp->ancount = HTONS(1);
126 break;
127
128#ifdef notdef
129 case UPDATED:
130 /*
131 * Put record to be added or deleted in additional section
132 */
133 buflen -= RRFIXEDSZ + datalen;
134 if ((n = dn_comp(dname, cp, buflen, NULL, NULL)) < 0)
135 return (-1);
136 cp += n;
137 *((u_short *)cp) = htons(type);
138 cp += sizeof(u_short);
139 *((u_short *)cp) = htons(class);
140 cp += sizeof(u_short);
141 *((u_long *)cp) = 0;
142 cp += sizeof(u_long);
143 *((u_short *)cp) = htons(datalen);
144 cp += sizeof(u_short);
145 if (datalen) {
146 bcopy(data, cp, datalen);
147 cp += datalen;
148 }
149 break;
150
151 case UPDATEM:
152 /*
153 * Record to be modified followed by its replacement
154 */
155 buflen -= RRFIXEDSZ + datalen;
156 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
157 return (-1);
158 cp += n;
159 *((u_short *)cp) = htons(type);
160 cp += sizeof(u_short);
161 *((u_short *)cp) = htons(class);
162 cp += sizeof(u_short);
163 *((u_long *)cp) = 0;
164 cp += sizeof(u_long);
165 *((u_short *)cp) = htons(datalen);
166 cp += sizeof(u_short);
167 if (datalen) {
168 bcopy(data, cp, datalen);
169 cp += datalen;
170 }
171
172 case UPDATEA:
173 buflen -= RRFIXEDSZ + newrr->r_size;
174 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
175 return (-1);
176 cp += n;
177 *((u_short *)cp) = htons(newrr->r_type);
178 cp += sizeof(u_short);
179 *((u_short *)cp) = htons(newrr->r_type);
180 cp += sizeof(u_short);
181 *((u_long *)cp) = htonl(newrr->r_ttl);
182 cp += sizeof(u_long);
183 *((u_short *)cp) = htons(newrr->r_size);
184 cp += sizeof(u_short);
185 if (newrr->r_size) {
186 bcopy(newrr->r_data, cp, newrr->r_size);
187 cp += newrr->r_size;
188 }
189 break;
190#endif
191 }
192 return (cp - buf);
193}