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