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