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