res_mkupdate.c revision 1.2.8.2 1 1.2.8.2 msaitoh /* $NetBSD: res_mkupdate.c,v 1.2.8.2 2013/06/13 04:20:30 msaitoh Exp $ */
2 1.2.8.2 msaitoh
3 1.2.8.2 msaitoh /*
4 1.2.8.2 msaitoh * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 1.2.8.2 msaitoh * Copyright (c) 1996-1999 by Internet Software Consortium.
6 1.2.8.2 msaitoh *
7 1.2.8.2 msaitoh * Permission to use, copy, modify, and distribute this software for any
8 1.2.8.2 msaitoh * purpose with or without fee is hereby granted, provided that the above
9 1.2.8.2 msaitoh * copyright notice and this permission notice appear in all copies.
10 1.2.8.2 msaitoh *
11 1.2.8.2 msaitoh * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 1.2.8.2 msaitoh * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 1.2.8.2 msaitoh * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 1.2.8.2 msaitoh * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 1.2.8.2 msaitoh * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 1.2.8.2 msaitoh * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 1.2.8.2 msaitoh * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 1.2.8.2 msaitoh */
19 1.2.8.2 msaitoh
20 1.2.8.2 msaitoh /*! \file
21 1.2.8.2 msaitoh * \brief
22 1.2.8.2 msaitoh * Based on the Dynamic DNS reference implementation by Viraj Bais
23 1.2.8.2 msaitoh * <viraj_bais (at) ccm.fm.intel.com>
24 1.2.8.2 msaitoh */
25 1.2.8.2 msaitoh #include <sys/cdefs.h>
26 1.2.8.2 msaitoh #if 0
27 1.2.8.2 msaitoh static const char rcsid[] = "Id: res_mkupdate.c,v 1.10 2008/12/11 09:59:00 marka Exp ";
28 1.2.8.2 msaitoh #else
29 1.2.8.2 msaitoh __RCSID("$NetBSD: res_mkupdate.c,v 1.2.8.2 2013/06/13 04:20:30 msaitoh Exp $");
30 1.2.8.2 msaitoh #endif
31 1.2.8.2 msaitoh
32 1.2.8.2 msaitoh #include "port_before.h"
33 1.2.8.2 msaitoh
34 1.2.8.2 msaitoh #include <sys/types.h>
35 1.2.8.2 msaitoh #include <sys/param.h>
36 1.2.8.2 msaitoh
37 1.2.8.2 msaitoh #include <netinet/in.h>
38 1.2.8.2 msaitoh #include <arpa/nameser.h>
39 1.2.8.2 msaitoh #include <arpa/inet.h>
40 1.2.8.2 msaitoh
41 1.2.8.2 msaitoh #include <errno.h>
42 1.2.8.2 msaitoh #include <limits.h>
43 1.2.8.2 msaitoh #include <netdb.h>
44 1.2.8.2 msaitoh #include <resolv.h>
45 1.2.8.2 msaitoh #include <res_update.h>
46 1.2.8.2 msaitoh #include <stdio.h>
47 1.2.8.2 msaitoh #include <stdlib.h>
48 1.2.8.2 msaitoh #include <string.h>
49 1.2.8.2 msaitoh #include <unistd.h>
50 1.2.8.2 msaitoh #include <ctype.h>
51 1.2.8.2 msaitoh
52 1.2.8.2 msaitoh #include "port_after.h"
53 1.2.8.2 msaitoh
54 1.2.8.2 msaitoh /* Options. Leave them on. */
55 1.2.8.2 msaitoh #define MAXPORT 1024
56 1.2.8.2 msaitoh
57 1.2.8.2 msaitoh static int getnum_str(u_char **, u_char *);
58 1.2.8.2 msaitoh static int gethexnum_str(u_char **, u_char *);
59 1.2.8.2 msaitoh static int getword_str(char *, size_t, u_char **, u_char *);
60 1.2.8.2 msaitoh static int getstr_str(char *, size_t, u_char **, u_char *);
61 1.2.8.2 msaitoh
62 1.2.8.2 msaitoh #define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2);
63 1.2.8.2 msaitoh
64 1.2.8.2 msaitoh /* Forward. */
65 1.2.8.2 msaitoh
66 1.2.8.2 msaitoh int res_protocolnumber(const char *);
67 1.2.8.2 msaitoh int res_servicenumber(const char *);
68 1.2.8.2 msaitoh
69 1.2.8.2 msaitoh /*%
70 1.2.8.2 msaitoh * Form update packets.
71 1.2.8.2 msaitoh * Returns the size of the resulting packet if no error
72 1.2.8.2 msaitoh *
73 1.2.8.2 msaitoh * On error,
74 1.2.8.2 msaitoh * returns
75 1.2.8.2 msaitoh *\li -1 if error in reading a word/number in rdata
76 1.2.8.2 msaitoh * portion for update packets
77 1.2.8.2 msaitoh *\li -2 if length of buffer passed is insufficient
78 1.2.8.2 msaitoh *\li -3 if zone section is not the first section in
79 1.2.8.2 msaitoh * the linked list, or section order has a problem
80 1.2.8.2 msaitoh *\li -4 on a number overflow
81 1.2.8.2 msaitoh *\li -5 unknown operation or no records
82 1.2.8.2 msaitoh */
83 1.2.8.2 msaitoh int
84 1.2.8.2 msaitoh res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
85 1.2.8.2 msaitoh ns_updrec *rrecp_start = rrecp_in;
86 1.2.8.2 msaitoh HEADER *hp;
87 1.2.8.2 msaitoh u_char *cp, *sp2, *startp, *endp;
88 1.2.8.2 msaitoh int n, i, soanum, multiline;
89 1.2.8.2 msaitoh ns_updrec *rrecp;
90 1.2.8.2 msaitoh struct in_addr ina;
91 1.2.8.2 msaitoh struct in6_addr in6a;
92 1.2.8.2 msaitoh char buf2[MAXDNAME];
93 1.2.8.2 msaitoh u_char buf3[MAXDNAME];
94 1.2.8.2 msaitoh int section, numrrs = 0, counts[ns_s_max];
95 1.2.8.2 msaitoh u_int16_t rtype, rclass;
96 1.2.8.2 msaitoh u_int32_t n1, rttl;
97 1.2.8.2 msaitoh u_char *dnptrs[20], **dpp, **lastdnptr;
98 1.2.8.2 msaitoh int siglen, keylen, certlen;
99 1.2.8.2 msaitoh
100 1.2.8.2 msaitoh /*
101 1.2.8.2 msaitoh * Initialize header fields.
102 1.2.8.2 msaitoh */
103 1.2.8.2 msaitoh if ((buf == NULL) || (buflen < HFIXEDSZ))
104 1.2.8.2 msaitoh return (-1);
105 1.2.8.2 msaitoh memset(buf, 0, HFIXEDSZ);
106 1.2.8.2 msaitoh hp = (void *)buf;
107 1.2.8.2 msaitoh statp->id = res_nrandomid(statp);
108 1.2.8.2 msaitoh hp->id = htons(statp->id);
109 1.2.8.2 msaitoh hp->opcode = ns_o_update;
110 1.2.8.2 msaitoh hp->rcode = NOERROR;
111 1.2.8.2 msaitoh cp = buf + HFIXEDSZ;
112 1.2.8.2 msaitoh buflen -= HFIXEDSZ;
113 1.2.8.2 msaitoh dpp = dnptrs;
114 1.2.8.2 msaitoh *dpp++ = buf;
115 1.2.8.2 msaitoh *dpp++ = NULL;
116 1.2.8.2 msaitoh lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
117 1.2.8.2 msaitoh
118 1.2.8.2 msaitoh if (rrecp_start == NULL)
119 1.2.8.2 msaitoh return (-5);
120 1.2.8.2 msaitoh else if (rrecp_start->r_section != S_ZONE)
121 1.2.8.2 msaitoh return (-3);
122 1.2.8.2 msaitoh
123 1.2.8.2 msaitoh memset(counts, 0, sizeof counts);
124 1.2.8.2 msaitoh for (rrecp = rrecp_start; rrecp; rrecp = TAILQ_NEXT(rrecp, r_glink)) {
125 1.2.8.2 msaitoh numrrs++;
126 1.2.8.2 msaitoh section = rrecp->r_section;
127 1.2.8.2 msaitoh if (section < 0 || section >= ns_s_max)
128 1.2.8.2 msaitoh return (-1);
129 1.2.8.2 msaitoh counts[section]++;
130 1.2.8.2 msaitoh for (i = section + 1; i < ns_s_max; i++)
131 1.2.8.2 msaitoh if (counts[i])
132 1.2.8.2 msaitoh return (-3);
133 1.2.8.2 msaitoh rtype = rrecp->r_type;
134 1.2.8.2 msaitoh rclass = rrecp->r_class;
135 1.2.8.2 msaitoh rttl = rrecp->r_ttl;
136 1.2.8.2 msaitoh /* overload class and type */
137 1.2.8.2 msaitoh if (section == S_PREREQ) {
138 1.2.8.2 msaitoh rttl = 0;
139 1.2.8.2 msaitoh switch (rrecp->r_opcode) {
140 1.2.8.2 msaitoh case YXDOMAIN:
141 1.2.8.2 msaitoh rclass = C_ANY;
142 1.2.8.2 msaitoh rtype = T_ANY;
143 1.2.8.2 msaitoh rrecp->r_size = 0;
144 1.2.8.2 msaitoh break;
145 1.2.8.2 msaitoh case NXDOMAIN:
146 1.2.8.2 msaitoh rclass = C_NONE;
147 1.2.8.2 msaitoh rtype = T_ANY;
148 1.2.8.2 msaitoh rrecp->r_size = 0;
149 1.2.8.2 msaitoh break;
150 1.2.8.2 msaitoh case NXRRSET:
151 1.2.8.2 msaitoh rclass = C_NONE;
152 1.2.8.2 msaitoh rrecp->r_size = 0;
153 1.2.8.2 msaitoh break;
154 1.2.8.2 msaitoh case YXRRSET:
155 1.2.8.2 msaitoh if (rrecp->r_size == 0)
156 1.2.8.2 msaitoh rclass = C_ANY;
157 1.2.8.2 msaitoh break;
158 1.2.8.2 msaitoh default:
159 1.2.8.2 msaitoh fprintf(stderr,
160 1.2.8.2 msaitoh "res_mkupdate: incorrect opcode: %d\n",
161 1.2.8.2 msaitoh rrecp->r_opcode);
162 1.2.8.2 msaitoh fflush(stderr);
163 1.2.8.2 msaitoh return (-1);
164 1.2.8.2 msaitoh }
165 1.2.8.2 msaitoh } else if (section == S_UPDATE) {
166 1.2.8.2 msaitoh switch (rrecp->r_opcode) {
167 1.2.8.2 msaitoh case DELETE:
168 1.2.8.2 msaitoh rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
169 1.2.8.2 msaitoh break;
170 1.2.8.2 msaitoh case ADD:
171 1.2.8.2 msaitoh break;
172 1.2.8.2 msaitoh default:
173 1.2.8.2 msaitoh fprintf(stderr,
174 1.2.8.2 msaitoh "res_mkupdate: incorrect opcode: %d\n",
175 1.2.8.2 msaitoh rrecp->r_opcode);
176 1.2.8.2 msaitoh fflush(stderr);
177 1.2.8.2 msaitoh return (-1);
178 1.2.8.2 msaitoh }
179 1.2.8.2 msaitoh }
180 1.2.8.2 msaitoh
181 1.2.8.2 msaitoh /*
182 1.2.8.2 msaitoh * XXX appending default domain to owner name is omitted,
183 1.2.8.2 msaitoh * fqdn must be provided
184 1.2.8.2 msaitoh */
185 1.2.8.2 msaitoh if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
186 1.2.8.2 msaitoh lastdnptr)) < 0)
187 1.2.8.2 msaitoh return (-1);
188 1.2.8.2 msaitoh cp += n;
189 1.2.8.2 msaitoh ShrinkBuffer(n + 2*INT16SZ);
190 1.2.8.2 msaitoh PUTSHORT(rtype, cp);
191 1.2.8.2 msaitoh PUTSHORT(rclass, cp);
192 1.2.8.2 msaitoh if (section == S_ZONE) {
193 1.2.8.2 msaitoh if (numrrs != 1 || rrecp->r_type != T_SOA)
194 1.2.8.2 msaitoh return (-3);
195 1.2.8.2 msaitoh continue;
196 1.2.8.2 msaitoh }
197 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ + INT16SZ);
198 1.2.8.2 msaitoh PUTLONG(rttl, cp);
199 1.2.8.2 msaitoh sp2 = cp; /*%< save pointer to length byte */
200 1.2.8.2 msaitoh cp += INT16SZ;
201 1.2.8.2 msaitoh if (rrecp->r_size == 0) {
202 1.2.8.2 msaitoh if (section == S_UPDATE && rclass != C_ANY)
203 1.2.8.2 msaitoh return (-1);
204 1.2.8.2 msaitoh else {
205 1.2.8.2 msaitoh PUTSHORT(0, sp2);
206 1.2.8.2 msaitoh continue;
207 1.2.8.2 msaitoh }
208 1.2.8.2 msaitoh }
209 1.2.8.2 msaitoh startp = rrecp->r_data;
210 1.2.8.2 msaitoh endp = startp + rrecp->r_size - 1;
211 1.2.8.2 msaitoh /* XXX this should be done centrally. */
212 1.2.8.2 msaitoh switch (rrecp->r_type) {
213 1.2.8.2 msaitoh case T_A:
214 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
215 1.2.8.2 msaitoh return (-1);
216 1.2.8.2 msaitoh if (!inet_aton(buf2, &ina))
217 1.2.8.2 msaitoh return (-1);
218 1.2.8.2 msaitoh n1 = ntohl(ina.s_addr);
219 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ);
220 1.2.8.2 msaitoh PUTLONG(n1, cp);
221 1.2.8.2 msaitoh break;
222 1.2.8.2 msaitoh case T_CNAME:
223 1.2.8.2 msaitoh case T_MB:
224 1.2.8.2 msaitoh case T_MG:
225 1.2.8.2 msaitoh case T_MR:
226 1.2.8.2 msaitoh case T_NS:
227 1.2.8.2 msaitoh case T_PTR:
228 1.2.8.2 msaitoh case ns_t_dname:
229 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
230 1.2.8.2 msaitoh return (-1);
231 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
232 1.2.8.2 msaitoh if (n < 0)
233 1.2.8.2 msaitoh return (-1);
234 1.2.8.2 msaitoh cp += n;
235 1.2.8.2 msaitoh ShrinkBuffer(n);
236 1.2.8.2 msaitoh break;
237 1.2.8.2 msaitoh case T_MINFO:
238 1.2.8.2 msaitoh case T_SOA:
239 1.2.8.2 msaitoh case T_RP:
240 1.2.8.2 msaitoh for (i = 0; i < 2; i++) {
241 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp,
242 1.2.8.2 msaitoh endp))
243 1.2.8.2 msaitoh return (-1);
244 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen,
245 1.2.8.2 msaitoh dnptrs, lastdnptr);
246 1.2.8.2 msaitoh if (n < 0)
247 1.2.8.2 msaitoh return (-1);
248 1.2.8.2 msaitoh cp += n;
249 1.2.8.2 msaitoh ShrinkBuffer(n);
250 1.2.8.2 msaitoh }
251 1.2.8.2 msaitoh if (rrecp->r_type == T_SOA) {
252 1.2.8.2 msaitoh ShrinkBuffer(5 * INT32SZ);
253 1.2.8.2 msaitoh while (isspace(*startp) || !*startp)
254 1.2.8.2 msaitoh startp++;
255 1.2.8.2 msaitoh if (*startp == '(') {
256 1.2.8.2 msaitoh multiline = 1;
257 1.2.8.2 msaitoh startp++;
258 1.2.8.2 msaitoh } else
259 1.2.8.2 msaitoh multiline = 0;
260 1.2.8.2 msaitoh /* serial, refresh, retry, expire, minimum */
261 1.2.8.2 msaitoh for (i = 0; i < 5; i++) {
262 1.2.8.2 msaitoh soanum = getnum_str(&startp, endp);
263 1.2.8.2 msaitoh if (soanum < 0)
264 1.2.8.2 msaitoh return (-1);
265 1.2.8.2 msaitoh PUTLONG(soanum, cp);
266 1.2.8.2 msaitoh }
267 1.2.8.2 msaitoh if (multiline) {
268 1.2.8.2 msaitoh while (isspace(*startp) || !*startp)
269 1.2.8.2 msaitoh startp++;
270 1.2.8.2 msaitoh if (*startp != ')')
271 1.2.8.2 msaitoh return (-1);
272 1.2.8.2 msaitoh }
273 1.2.8.2 msaitoh }
274 1.2.8.2 msaitoh break;
275 1.2.8.2 msaitoh case T_MX:
276 1.2.8.2 msaitoh case T_AFSDB:
277 1.2.8.2 msaitoh case T_RT:
278 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
279 1.2.8.2 msaitoh if (n < 0)
280 1.2.8.2 msaitoh return (-1);
281 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
282 1.2.8.2 msaitoh PUTSHORT(n, cp);
283 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
284 1.2.8.2 msaitoh return (-1);
285 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
286 1.2.8.2 msaitoh if (n < 0)
287 1.2.8.2 msaitoh return (-1);
288 1.2.8.2 msaitoh cp += n;
289 1.2.8.2 msaitoh ShrinkBuffer(n);
290 1.2.8.2 msaitoh break;
291 1.2.8.2 msaitoh case T_SRV:
292 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
293 1.2.8.2 msaitoh if (n < 0)
294 1.2.8.2 msaitoh return (-1);
295 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
296 1.2.8.2 msaitoh PUTSHORT(n, cp);
297 1.2.8.2 msaitoh
298 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
299 1.2.8.2 msaitoh if (n < 0)
300 1.2.8.2 msaitoh return (-1);
301 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
302 1.2.8.2 msaitoh PUTSHORT(n, cp);
303 1.2.8.2 msaitoh
304 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
305 1.2.8.2 msaitoh if (n < 0)
306 1.2.8.2 msaitoh return (-1);
307 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
308 1.2.8.2 msaitoh PUTSHORT(n, cp);
309 1.2.8.2 msaitoh
310 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
311 1.2.8.2 msaitoh return (-1);
312 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, NULL, NULL);
313 1.2.8.2 msaitoh if (n < 0)
314 1.2.8.2 msaitoh return (-1);
315 1.2.8.2 msaitoh cp += n;
316 1.2.8.2 msaitoh ShrinkBuffer(n);
317 1.2.8.2 msaitoh break;
318 1.2.8.2 msaitoh case T_PX:
319 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
320 1.2.8.2 msaitoh if (n < 0)
321 1.2.8.2 msaitoh return (-1);
322 1.2.8.2 msaitoh PUTSHORT(n, cp);
323 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
324 1.2.8.2 msaitoh for (i = 0; i < 2; i++) {
325 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp,
326 1.2.8.2 msaitoh endp))
327 1.2.8.2 msaitoh return (-1);
328 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, dnptrs,
329 1.2.8.2 msaitoh lastdnptr);
330 1.2.8.2 msaitoh if (n < 0)
331 1.2.8.2 msaitoh return (-1);
332 1.2.8.2 msaitoh cp += n;
333 1.2.8.2 msaitoh ShrinkBuffer(n);
334 1.2.8.2 msaitoh }
335 1.2.8.2 msaitoh break;
336 1.2.8.2 msaitoh case T_WKS: {
337 1.2.8.2 msaitoh char bm[MAXPORT/8];
338 1.2.8.2 msaitoh unsigned int maxbm = 0;
339 1.2.8.2 msaitoh
340 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
341 1.2.8.2 msaitoh return (-1);
342 1.2.8.2 msaitoh if (!inet_aton(buf2, &ina))
343 1.2.8.2 msaitoh return (-1);
344 1.2.8.2 msaitoh n1 = ntohl(ina.s_addr);
345 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ);
346 1.2.8.2 msaitoh PUTLONG(n1, cp);
347 1.2.8.2 msaitoh
348 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
349 1.2.8.2 msaitoh return (-1);
350 1.2.8.2 msaitoh if ((i = res_protocolnumber(buf2)) < 0)
351 1.2.8.2 msaitoh return (-1);
352 1.2.8.2 msaitoh ShrinkBuffer(1);
353 1.2.8.2 msaitoh *cp++ = i & 0xff;
354 1.2.8.2 msaitoh
355 1.2.8.2 msaitoh for (i = 0; i < MAXPORT/8 ; i++)
356 1.2.8.2 msaitoh bm[i] = 0;
357 1.2.8.2 msaitoh
358 1.2.8.2 msaitoh while (getword_str(buf2, sizeof buf2, &startp, endp)) {
359 1.2.8.2 msaitoh if ((n = res_servicenumber(buf2)) <= 0)
360 1.2.8.2 msaitoh return (-1);
361 1.2.8.2 msaitoh
362 1.2.8.2 msaitoh if (n < MAXPORT) {
363 1.2.8.2 msaitoh bm[n/8] |= (0x80>>(n%8));
364 1.2.8.2 msaitoh if ((unsigned)n > maxbm)
365 1.2.8.2 msaitoh maxbm = n;
366 1.2.8.2 msaitoh } else
367 1.2.8.2 msaitoh return (-1);
368 1.2.8.2 msaitoh }
369 1.2.8.2 msaitoh maxbm = maxbm/8 + 1;
370 1.2.8.2 msaitoh ShrinkBuffer(maxbm);
371 1.2.8.2 msaitoh memcpy(cp, bm, maxbm);
372 1.2.8.2 msaitoh cp += maxbm;
373 1.2.8.2 msaitoh break;
374 1.2.8.2 msaitoh }
375 1.2.8.2 msaitoh case T_HINFO:
376 1.2.8.2 msaitoh for (i = 0; i < 2; i++) {
377 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2,
378 1.2.8.2 msaitoh &startp, endp)) < 0)
379 1.2.8.2 msaitoh return (-1);
380 1.2.8.2 msaitoh if (n > 255)
381 1.2.8.2 msaitoh return (-1);
382 1.2.8.2 msaitoh ShrinkBuffer(n+1);
383 1.2.8.2 msaitoh *cp++ = n;
384 1.2.8.2 msaitoh memcpy(cp, buf2, n);
385 1.2.8.2 msaitoh cp += n;
386 1.2.8.2 msaitoh }
387 1.2.8.2 msaitoh break;
388 1.2.8.2 msaitoh case T_TXT:
389 1.2.8.2 msaitoh for (;;) {
390 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2,
391 1.2.8.2 msaitoh &startp, endp)) < 0) {
392 1.2.8.2 msaitoh if (cp != (sp2 + INT16SZ))
393 1.2.8.2 msaitoh break;
394 1.2.8.2 msaitoh return (-1);
395 1.2.8.2 msaitoh }
396 1.2.8.2 msaitoh if (n > 255)
397 1.2.8.2 msaitoh return (-1);
398 1.2.8.2 msaitoh ShrinkBuffer(n+1);
399 1.2.8.2 msaitoh *cp++ = n;
400 1.2.8.2 msaitoh memcpy(cp, buf2, n);
401 1.2.8.2 msaitoh cp += n;
402 1.2.8.2 msaitoh }
403 1.2.8.2 msaitoh break;
404 1.2.8.2 msaitoh case T_X25:
405 1.2.8.2 msaitoh /* RFC1183 */
406 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2, &startp,
407 1.2.8.2 msaitoh endp)) < 0)
408 1.2.8.2 msaitoh return (-1);
409 1.2.8.2 msaitoh if (n > 255)
410 1.2.8.2 msaitoh return (-1);
411 1.2.8.2 msaitoh ShrinkBuffer(n+1);
412 1.2.8.2 msaitoh *cp++ = n;
413 1.2.8.2 msaitoh memcpy(cp, buf2, n);
414 1.2.8.2 msaitoh cp += n;
415 1.2.8.2 msaitoh break;
416 1.2.8.2 msaitoh case T_ISDN:
417 1.2.8.2 msaitoh /* RFC1183 */
418 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2, &startp,
419 1.2.8.2 msaitoh endp)) < 0)
420 1.2.8.2 msaitoh return (-1);
421 1.2.8.2 msaitoh if ((n > 255) || (n == 0))
422 1.2.8.2 msaitoh return (-1);
423 1.2.8.2 msaitoh ShrinkBuffer(n+1);
424 1.2.8.2 msaitoh *cp++ = n;
425 1.2.8.2 msaitoh memcpy(cp, buf2, n);
426 1.2.8.2 msaitoh cp += n;
427 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2, &startp,
428 1.2.8.2 msaitoh endp)) < 0)
429 1.2.8.2 msaitoh n = 0;
430 1.2.8.2 msaitoh if (n > 255)
431 1.2.8.2 msaitoh return (-1);
432 1.2.8.2 msaitoh ShrinkBuffer(n+1);
433 1.2.8.2 msaitoh *cp++ = n;
434 1.2.8.2 msaitoh memcpy(cp, buf2, n);
435 1.2.8.2 msaitoh cp += n;
436 1.2.8.2 msaitoh break;
437 1.2.8.2 msaitoh case T_NSAP:
438 1.2.8.2 msaitoh if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2,
439 1.2.8.2 msaitoh (int)sizeof(buf2))) != 0) {
440 1.2.8.2 msaitoh ShrinkBuffer(n);
441 1.2.8.2 msaitoh memcpy(cp, buf2, n);
442 1.2.8.2 msaitoh cp += n;
443 1.2.8.2 msaitoh } else {
444 1.2.8.2 msaitoh return (-1);
445 1.2.8.2 msaitoh }
446 1.2.8.2 msaitoh break;
447 1.2.8.2 msaitoh case T_LOC:
448 1.2.8.2 msaitoh if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) {
449 1.2.8.2 msaitoh ShrinkBuffer(n);
450 1.2.8.2 msaitoh memcpy(cp, buf2, n);
451 1.2.8.2 msaitoh cp += n;
452 1.2.8.2 msaitoh } else
453 1.2.8.2 msaitoh return (-1);
454 1.2.8.2 msaitoh break;
455 1.2.8.2 msaitoh case ns_t_sig:
456 1.2.8.2 msaitoh {
457 1.2.8.2 msaitoh int sig_type, success, dateerror;
458 1.2.8.2 msaitoh u_int32_t exptime, timesigned;
459 1.2.8.2 msaitoh
460 1.2.8.2 msaitoh /* type */
461 1.2.8.2 msaitoh if ((n = getword_str(buf2, sizeof buf2,
462 1.2.8.2 msaitoh &startp, endp)) < 0)
463 1.2.8.2 msaitoh return (-1);
464 1.2.8.2 msaitoh sig_type = sym_ston(__p_type_syms, buf2, &success);
465 1.2.8.2 msaitoh if (!success || sig_type == ns_t_any)
466 1.2.8.2 msaitoh return (-1);
467 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
468 1.2.8.2 msaitoh PUTSHORT(sig_type, cp);
469 1.2.8.2 msaitoh /* alg */
470 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
471 1.2.8.2 msaitoh if (n < 0)
472 1.2.8.2 msaitoh return (-1);
473 1.2.8.2 msaitoh ShrinkBuffer(1);
474 1.2.8.2 msaitoh *cp++ = n;
475 1.2.8.2 msaitoh /* labels */
476 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
477 1.2.8.2 msaitoh if (n <= 0 || n > 255)
478 1.2.8.2 msaitoh return (-1);
479 1.2.8.2 msaitoh ShrinkBuffer(1);
480 1.2.8.2 msaitoh *cp++ = n;
481 1.2.8.2 msaitoh /* ottl & expire */
482 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
483 1.2.8.2 msaitoh return (-1);
484 1.2.8.2 msaitoh exptime = ns_datetosecs(buf2, &dateerror);
485 1.2.8.2 msaitoh if (!dateerror) {
486 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ);
487 1.2.8.2 msaitoh PUTLONG(rttl, cp);
488 1.2.8.2 msaitoh }
489 1.2.8.2 msaitoh else {
490 1.2.8.2 msaitoh char *ulendp;
491 1.2.8.2 msaitoh u_int32_t ottl;
492 1.2.8.2 msaitoh unsigned long ul;
493 1.2.8.2 msaitoh
494 1.2.8.2 msaitoh errno = 0;
495 1.2.8.2 msaitoh ul = strtoul(buf2, &ulendp, 10);
496 1.2.8.2 msaitoh if (ul > 0xffffffffU)
497 1.2.8.2 msaitoh errno = ERANGE;
498 1.2.8.2 msaitoh ottl = (u_int32_t)ul;
499 1.2.8.2 msaitoh if (errno != 0 ||
500 1.2.8.2 msaitoh (ulendp != NULL && *ulendp != '\0'))
501 1.2.8.2 msaitoh return (-1);
502 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ);
503 1.2.8.2 msaitoh PUTLONG(ottl, cp);
504 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp,
505 1.2.8.2 msaitoh endp))
506 1.2.8.2 msaitoh return (-1);
507 1.2.8.2 msaitoh exptime = ns_datetosecs(buf2, &dateerror);
508 1.2.8.2 msaitoh if (dateerror)
509 1.2.8.2 msaitoh return (-1);
510 1.2.8.2 msaitoh }
511 1.2.8.2 msaitoh /* expire */
512 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ);
513 1.2.8.2 msaitoh PUTLONG(exptime, cp);
514 1.2.8.2 msaitoh /* timesigned */
515 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
516 1.2.8.2 msaitoh return (-1);
517 1.2.8.2 msaitoh timesigned = ns_datetosecs(buf2, &dateerror);
518 1.2.8.2 msaitoh if (!dateerror) {
519 1.2.8.2 msaitoh ShrinkBuffer(INT32SZ);
520 1.2.8.2 msaitoh PUTLONG(timesigned, cp);
521 1.2.8.2 msaitoh }
522 1.2.8.2 msaitoh else
523 1.2.8.2 msaitoh return (-1);
524 1.2.8.2 msaitoh /* footprint */
525 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
526 1.2.8.2 msaitoh if (n < 0)
527 1.2.8.2 msaitoh return (-1);
528 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
529 1.2.8.2 msaitoh PUTSHORT(n, cp);
530 1.2.8.2 msaitoh /* signer name */
531 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
532 1.2.8.2 msaitoh return (-1);
533 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
534 1.2.8.2 msaitoh if (n < 0)
535 1.2.8.2 msaitoh return (-1);
536 1.2.8.2 msaitoh cp += n;
537 1.2.8.2 msaitoh ShrinkBuffer(n);
538 1.2.8.2 msaitoh /* sig */
539 1.2.8.2 msaitoh if ((n = getword_str(buf2, sizeof buf2,
540 1.2.8.2 msaitoh &startp, endp)) < 0)
541 1.2.8.2 msaitoh return (-1);
542 1.2.8.2 msaitoh siglen = b64_pton(buf2, buf3, sizeof(buf3));
543 1.2.8.2 msaitoh if (siglen < 0)
544 1.2.8.2 msaitoh return (-1);
545 1.2.8.2 msaitoh ShrinkBuffer(siglen);
546 1.2.8.2 msaitoh memcpy(cp, buf3, siglen);
547 1.2.8.2 msaitoh cp += siglen;
548 1.2.8.2 msaitoh break;
549 1.2.8.2 msaitoh }
550 1.2.8.2 msaitoh case ns_t_key:
551 1.2.8.2 msaitoh /* flags */
552 1.2.8.2 msaitoh n = gethexnum_str(&startp, endp);
553 1.2.8.2 msaitoh if (n < 0)
554 1.2.8.2 msaitoh return (-1);
555 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
556 1.2.8.2 msaitoh PUTSHORT(n, cp);
557 1.2.8.2 msaitoh /* proto */
558 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
559 1.2.8.2 msaitoh if (n < 0)
560 1.2.8.2 msaitoh return (-1);
561 1.2.8.2 msaitoh ShrinkBuffer(1);
562 1.2.8.2 msaitoh *cp++ = n;
563 1.2.8.2 msaitoh /* alg */
564 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
565 1.2.8.2 msaitoh if (n < 0)
566 1.2.8.2 msaitoh return (-1);
567 1.2.8.2 msaitoh ShrinkBuffer(1);
568 1.2.8.2 msaitoh *cp++ = n;
569 1.2.8.2 msaitoh /* key */
570 1.2.8.2 msaitoh if ((n = getword_str(buf2, sizeof buf2,
571 1.2.8.2 msaitoh &startp, endp)) < 0)
572 1.2.8.2 msaitoh return (-1);
573 1.2.8.2 msaitoh keylen = b64_pton(buf2, buf3, sizeof(buf3));
574 1.2.8.2 msaitoh if (keylen < 0)
575 1.2.8.2 msaitoh return (-1);
576 1.2.8.2 msaitoh ShrinkBuffer(keylen);
577 1.2.8.2 msaitoh memcpy(cp, buf3, keylen);
578 1.2.8.2 msaitoh cp += keylen;
579 1.2.8.2 msaitoh break;
580 1.2.8.2 msaitoh case ns_t_nxt:
581 1.2.8.2 msaitoh {
582 1.2.8.2 msaitoh int success, nxt_type;
583 1.2.8.2 msaitoh u_char data[32];
584 1.2.8.2 msaitoh int maxtype;
585 1.2.8.2 msaitoh
586 1.2.8.2 msaitoh /* next name */
587 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
588 1.2.8.2 msaitoh return (-1);
589 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, NULL, NULL);
590 1.2.8.2 msaitoh if (n < 0)
591 1.2.8.2 msaitoh return (-1);
592 1.2.8.2 msaitoh cp += n;
593 1.2.8.2 msaitoh ShrinkBuffer(n);
594 1.2.8.2 msaitoh maxtype = 0;
595 1.2.8.2 msaitoh memset(data, 0, sizeof data);
596 1.2.8.2 msaitoh for (;;) {
597 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp,
598 1.2.8.2 msaitoh endp))
599 1.2.8.2 msaitoh break;
600 1.2.8.2 msaitoh nxt_type = sym_ston(__p_type_syms, buf2,
601 1.2.8.2 msaitoh &success);
602 1.2.8.2 msaitoh if (!success || !ns_t_rr_p(nxt_type))
603 1.2.8.2 msaitoh return (-1);
604 1.2.8.2 msaitoh NS_NXT_BIT_SET(nxt_type, data);
605 1.2.8.2 msaitoh if (nxt_type > maxtype)
606 1.2.8.2 msaitoh maxtype = nxt_type;
607 1.2.8.2 msaitoh }
608 1.2.8.2 msaitoh n = maxtype/NS_NXT_BITS+1;
609 1.2.8.2 msaitoh ShrinkBuffer(n);
610 1.2.8.2 msaitoh memcpy(cp, data, n);
611 1.2.8.2 msaitoh cp += n;
612 1.2.8.2 msaitoh break;
613 1.2.8.2 msaitoh }
614 1.2.8.2 msaitoh case ns_t_cert:
615 1.2.8.2 msaitoh /* type */
616 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
617 1.2.8.2 msaitoh if (n < 0)
618 1.2.8.2 msaitoh return (-1);
619 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
620 1.2.8.2 msaitoh PUTSHORT(n, cp);
621 1.2.8.2 msaitoh /* key tag */
622 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
623 1.2.8.2 msaitoh if (n < 0)
624 1.2.8.2 msaitoh return (-1);
625 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
626 1.2.8.2 msaitoh PUTSHORT(n, cp);
627 1.2.8.2 msaitoh /* alg */
628 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
629 1.2.8.2 msaitoh if (n < 0)
630 1.2.8.2 msaitoh return (-1);
631 1.2.8.2 msaitoh ShrinkBuffer(1);
632 1.2.8.2 msaitoh *cp++ = n;
633 1.2.8.2 msaitoh /* cert */
634 1.2.8.2 msaitoh if ((n = getword_str(buf2, sizeof buf2,
635 1.2.8.2 msaitoh &startp, endp)) < 0)
636 1.2.8.2 msaitoh return (-1);
637 1.2.8.2 msaitoh certlen = b64_pton(buf2, buf3, sizeof(buf3));
638 1.2.8.2 msaitoh if (certlen < 0)
639 1.2.8.2 msaitoh return (-1);
640 1.2.8.2 msaitoh ShrinkBuffer(certlen);
641 1.2.8.2 msaitoh memcpy(cp, buf3, certlen);
642 1.2.8.2 msaitoh cp += certlen;
643 1.2.8.2 msaitoh break;
644 1.2.8.2 msaitoh case ns_t_aaaa:
645 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
646 1.2.8.2 msaitoh return (-1);
647 1.2.8.2 msaitoh if (inet_pton(AF_INET6, buf2, &in6a) <= 0)
648 1.2.8.2 msaitoh return (-1);
649 1.2.8.2 msaitoh ShrinkBuffer(NS_IN6ADDRSZ);
650 1.2.8.2 msaitoh memcpy(cp, &in6a, NS_IN6ADDRSZ);
651 1.2.8.2 msaitoh cp += NS_IN6ADDRSZ;
652 1.2.8.2 msaitoh break;
653 1.2.8.2 msaitoh case ns_t_naptr:
654 1.2.8.2 msaitoh /* Order Preference Flags Service Replacement Regexp */
655 1.2.8.2 msaitoh /* Order */
656 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
657 1.2.8.2 msaitoh if (n < 0 || n > 65535)
658 1.2.8.2 msaitoh return (-1);
659 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
660 1.2.8.2 msaitoh PUTSHORT(n, cp);
661 1.2.8.2 msaitoh /* Preference */
662 1.2.8.2 msaitoh n = getnum_str(&startp, endp);
663 1.2.8.2 msaitoh if (n < 0 || n > 65535)
664 1.2.8.2 msaitoh return (-1);
665 1.2.8.2 msaitoh ShrinkBuffer(INT16SZ);
666 1.2.8.2 msaitoh PUTSHORT(n, cp);
667 1.2.8.2 msaitoh /* Flags */
668 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2,
669 1.2.8.2 msaitoh &startp, endp)) < 0) {
670 1.2.8.2 msaitoh return (-1);
671 1.2.8.2 msaitoh }
672 1.2.8.2 msaitoh if (n > 255)
673 1.2.8.2 msaitoh return (-1);
674 1.2.8.2 msaitoh ShrinkBuffer(n+1);
675 1.2.8.2 msaitoh *cp++ = n;
676 1.2.8.2 msaitoh memcpy(cp, buf2, n);
677 1.2.8.2 msaitoh cp += n;
678 1.2.8.2 msaitoh /* Service Classes */
679 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2,
680 1.2.8.2 msaitoh &startp, endp)) < 0) {
681 1.2.8.2 msaitoh return (-1);
682 1.2.8.2 msaitoh }
683 1.2.8.2 msaitoh if (n > 255)
684 1.2.8.2 msaitoh return (-1);
685 1.2.8.2 msaitoh ShrinkBuffer(n+1);
686 1.2.8.2 msaitoh *cp++ = n;
687 1.2.8.2 msaitoh memcpy(cp, buf2, n);
688 1.2.8.2 msaitoh cp += n;
689 1.2.8.2 msaitoh /* Pattern */
690 1.2.8.2 msaitoh if ((n = getstr_str(buf2, sizeof buf2,
691 1.2.8.2 msaitoh &startp, endp)) < 0) {
692 1.2.8.2 msaitoh return (-1);
693 1.2.8.2 msaitoh }
694 1.2.8.2 msaitoh if (n > 255)
695 1.2.8.2 msaitoh return (-1);
696 1.2.8.2 msaitoh ShrinkBuffer(n+1);
697 1.2.8.2 msaitoh *cp++ = n;
698 1.2.8.2 msaitoh memcpy(cp, buf2, n);
699 1.2.8.2 msaitoh cp += n;
700 1.2.8.2 msaitoh /* Replacement */
701 1.2.8.2 msaitoh if (!getword_str(buf2, sizeof buf2, &startp, endp))
702 1.2.8.2 msaitoh return (-1);
703 1.2.8.2 msaitoh n = dn_comp(buf2, cp, buflen, NULL, NULL);
704 1.2.8.2 msaitoh if (n < 0)
705 1.2.8.2 msaitoh return (-1);
706 1.2.8.2 msaitoh cp += n;
707 1.2.8.2 msaitoh ShrinkBuffer(n);
708 1.2.8.2 msaitoh break;
709 1.2.8.2 msaitoh default:
710 1.2.8.2 msaitoh return (-1);
711 1.2.8.2 msaitoh } /*switch*/
712 1.2.8.2 msaitoh n = (u_int16_t)((cp - sp2) - INT16SZ);
713 1.2.8.2 msaitoh PUTSHORT(n, sp2);
714 1.2.8.2 msaitoh } /*for*/
715 1.2.8.2 msaitoh
716 1.2.8.2 msaitoh hp->qdcount = htons(counts[0]);
717 1.2.8.2 msaitoh hp->ancount = htons(counts[1]);
718 1.2.8.2 msaitoh hp->nscount = htons(counts[2]);
719 1.2.8.2 msaitoh hp->arcount = htons(counts[3]);
720 1.2.8.2 msaitoh return (int)(cp - buf);
721 1.2.8.2 msaitoh }
722 1.2.8.2 msaitoh
723 1.2.8.2 msaitoh /*%
724 1.2.8.2 msaitoh * Get a whitespace delimited word from a string (not file)
725 1.2.8.2 msaitoh * into buf. modify the start pointer to point after the
726 1.2.8.2 msaitoh * word in the string.
727 1.2.8.2 msaitoh */
728 1.2.8.2 msaitoh static int
729 1.2.8.2 msaitoh getword_str(char *buf, size_t size, u_char **startpp, u_char *endp) {
730 1.2.8.2 msaitoh char *cp;
731 1.2.8.2 msaitoh int c;
732 1.2.8.2 msaitoh
733 1.2.8.2 msaitoh for (cp = buf; *startpp <= endp; ) {
734 1.2.8.2 msaitoh c = **startpp;
735 1.2.8.2 msaitoh if (isspace(c) || c == '\0') {
736 1.2.8.2 msaitoh if (cp != buf) /*%< trailing whitespace */
737 1.2.8.2 msaitoh break;
738 1.2.8.2 msaitoh else { /*%< leading whitespace */
739 1.2.8.2 msaitoh (*startpp)++;
740 1.2.8.2 msaitoh continue;
741 1.2.8.2 msaitoh }
742 1.2.8.2 msaitoh }
743 1.2.8.2 msaitoh (*startpp)++;
744 1.2.8.2 msaitoh if (cp >= buf+size-1)
745 1.2.8.2 msaitoh break;
746 1.2.8.2 msaitoh *cp++ = (u_char)c;
747 1.2.8.2 msaitoh }
748 1.2.8.2 msaitoh *cp = '\0';
749 1.2.8.2 msaitoh return (cp != buf);
750 1.2.8.2 msaitoh }
751 1.2.8.2 msaitoh
752 1.2.8.2 msaitoh /*%
753 1.2.8.2 msaitoh * get a white spae delimited string from memory. Process quoted strings
754 1.2.8.2 msaitoh * and \\DDD escapes. Return length or -1 on error. Returned string may
755 1.2.8.2 msaitoh * contain nulls.
756 1.2.8.2 msaitoh */
757 1.2.8.2 msaitoh static char digits[] = "0123456789";
758 1.2.8.2 msaitoh static int
759 1.2.8.2 msaitoh getstr_str(char *buf, size_t size, u_char **startpp, u_char *endp) {
760 1.2.8.2 msaitoh char *cp;
761 1.2.8.2 msaitoh int c, c1 = 0;
762 1.2.8.2 msaitoh int inquote = 0;
763 1.2.8.2 msaitoh int seen_quote = 0;
764 1.2.8.2 msaitoh int escape = 0;
765 1.2.8.2 msaitoh int dig = 0;
766 1.2.8.2 msaitoh
767 1.2.8.2 msaitoh for (cp = buf; *startpp <= endp; ) {
768 1.2.8.2 msaitoh if ((c = **startpp) == '\0')
769 1.2.8.2 msaitoh break;
770 1.2.8.2 msaitoh /* leading white space */
771 1.2.8.2 msaitoh if ((cp == buf) && !seen_quote && isspace(c)) {
772 1.2.8.2 msaitoh (*startpp)++;
773 1.2.8.2 msaitoh continue;
774 1.2.8.2 msaitoh }
775 1.2.8.2 msaitoh
776 1.2.8.2 msaitoh switch (c) {
777 1.2.8.2 msaitoh case '\\':
778 1.2.8.2 msaitoh if (!escape) {
779 1.2.8.2 msaitoh escape = 1;
780 1.2.8.2 msaitoh dig = 0;
781 1.2.8.2 msaitoh c1 = 0;
782 1.2.8.2 msaitoh (*startpp)++;
783 1.2.8.2 msaitoh continue;
784 1.2.8.2 msaitoh }
785 1.2.8.2 msaitoh goto do_escape;
786 1.2.8.2 msaitoh case '"':
787 1.2.8.2 msaitoh if (!escape) {
788 1.2.8.2 msaitoh inquote = !inquote;
789 1.2.8.2 msaitoh seen_quote = 1;
790 1.2.8.2 msaitoh (*startpp)++;
791 1.2.8.2 msaitoh continue;
792 1.2.8.2 msaitoh }
793 1.2.8.2 msaitoh /*FALLTHROUGH*/
794 1.2.8.2 msaitoh default:
795 1.2.8.2 msaitoh do_escape:
796 1.2.8.2 msaitoh if (escape) {
797 1.2.8.2 msaitoh switch (c) {
798 1.2.8.2 msaitoh case '0':
799 1.2.8.2 msaitoh case '1':
800 1.2.8.2 msaitoh case '2':
801 1.2.8.2 msaitoh case '3':
802 1.2.8.2 msaitoh case '4':
803 1.2.8.2 msaitoh case '5':
804 1.2.8.2 msaitoh case '6':
805 1.2.8.2 msaitoh case '7':
806 1.2.8.2 msaitoh case '8':
807 1.2.8.2 msaitoh case '9':
808 1.2.8.2 msaitoh c1 = c1 * 10 +
809 1.2.8.2 msaitoh (int)(strchr(digits, c) - digits);
810 1.2.8.2 msaitoh
811 1.2.8.2 msaitoh if (++dig == 3) {
812 1.2.8.2 msaitoh c = c1 &0xff;
813 1.2.8.2 msaitoh break;
814 1.2.8.2 msaitoh }
815 1.2.8.2 msaitoh (*startpp)++;
816 1.2.8.2 msaitoh continue;
817 1.2.8.2 msaitoh }
818 1.2.8.2 msaitoh escape = 0;
819 1.2.8.2 msaitoh } else if (!inquote && isspace(c))
820 1.2.8.2 msaitoh goto done;
821 1.2.8.2 msaitoh if (cp >= buf+size-1)
822 1.2.8.2 msaitoh goto done;
823 1.2.8.2 msaitoh *cp++ = (u_char)c;
824 1.2.8.2 msaitoh (*startpp)++;
825 1.2.8.2 msaitoh }
826 1.2.8.2 msaitoh }
827 1.2.8.2 msaitoh done:
828 1.2.8.2 msaitoh *cp = '\0';
829 1.2.8.2 msaitoh return ((cp == buf)? (seen_quote? 0: -1): (int)(cp - buf));
830 1.2.8.2 msaitoh }
831 1.2.8.2 msaitoh
832 1.2.8.2 msaitoh /*%
833 1.2.8.2 msaitoh * Get a whitespace delimited base 16 number from a string (not file) into buf
834 1.2.8.2 msaitoh * update the start pointer to point after the number in the string.
835 1.2.8.2 msaitoh */
836 1.2.8.2 msaitoh static int
837 1.2.8.2 msaitoh gethexnum_str(u_char **startpp, u_char *endp) {
838 1.2.8.2 msaitoh int c, n;
839 1.2.8.2 msaitoh int seendigit = 0;
840 1.2.8.2 msaitoh int m = 0;
841 1.2.8.2 msaitoh
842 1.2.8.2 msaitoh if (*startpp + 2 >= endp || strncasecmp((char *)*startpp, "0x", 2) != 0)
843 1.2.8.2 msaitoh return getnum_str(startpp, endp);
844 1.2.8.2 msaitoh (*startpp)+=2;
845 1.2.8.2 msaitoh for (n = 0; *startpp <= endp; ) {
846 1.2.8.2 msaitoh c = **startpp;
847 1.2.8.2 msaitoh if (isspace(c) || c == '\0') {
848 1.2.8.2 msaitoh if (seendigit) /*%< trailing whitespace */
849 1.2.8.2 msaitoh break;
850 1.2.8.2 msaitoh else { /*%< leading whitespace */
851 1.2.8.2 msaitoh (*startpp)++;
852 1.2.8.2 msaitoh continue;
853 1.2.8.2 msaitoh }
854 1.2.8.2 msaitoh }
855 1.2.8.2 msaitoh if (c == ';') {
856 1.2.8.2 msaitoh while ((*startpp <= endp) &&
857 1.2.8.2 msaitoh ((c = **startpp) != '\n'))
858 1.2.8.2 msaitoh (*startpp)++;
859 1.2.8.2 msaitoh if (seendigit)
860 1.2.8.2 msaitoh break;
861 1.2.8.2 msaitoh continue;
862 1.2.8.2 msaitoh }
863 1.2.8.2 msaitoh if (!isxdigit(c)) {
864 1.2.8.2 msaitoh if (c == ')' && seendigit) {
865 1.2.8.2 msaitoh (*startpp)--;
866 1.2.8.2 msaitoh break;
867 1.2.8.2 msaitoh }
868 1.2.8.2 msaitoh return (-1);
869 1.2.8.2 msaitoh }
870 1.2.8.2 msaitoh (*startpp)++;
871 1.2.8.2 msaitoh if (isdigit(c))
872 1.2.8.2 msaitoh n = n * 16 + (c - '0');
873 1.2.8.2 msaitoh else
874 1.2.8.2 msaitoh n = n * 16 + (tolower(c) - 'a' + 10);
875 1.2.8.2 msaitoh seendigit = 1;
876 1.2.8.2 msaitoh }
877 1.2.8.2 msaitoh return (n + m);
878 1.2.8.2 msaitoh }
879 1.2.8.2 msaitoh
880 1.2.8.2 msaitoh /*%
881 1.2.8.2 msaitoh * Get a whitespace delimited base 10 number from a string (not file) into buf
882 1.2.8.2 msaitoh * update the start pointer to point after the number in the string.
883 1.2.8.2 msaitoh */
884 1.2.8.2 msaitoh static int
885 1.2.8.2 msaitoh getnum_str(u_char **startpp, u_char *endp) {
886 1.2.8.2 msaitoh int c, n;
887 1.2.8.2 msaitoh int seendigit = 0;
888 1.2.8.2 msaitoh int m = 0;
889 1.2.8.2 msaitoh
890 1.2.8.2 msaitoh for (n = 0; *startpp <= endp; ) {
891 1.2.8.2 msaitoh c = **startpp;
892 1.2.8.2 msaitoh if (isspace(c) || c == '\0') {
893 1.2.8.2 msaitoh if (seendigit) /*%< trailing whitespace */
894 1.2.8.2 msaitoh break;
895 1.2.8.2 msaitoh else { /*%< leading whitespace */
896 1.2.8.2 msaitoh (*startpp)++;
897 1.2.8.2 msaitoh continue;
898 1.2.8.2 msaitoh }
899 1.2.8.2 msaitoh }
900 1.2.8.2 msaitoh if (c == ';') {
901 1.2.8.2 msaitoh while ((*startpp <= endp) &&
902 1.2.8.2 msaitoh ((c = **startpp) != '\n'))
903 1.2.8.2 msaitoh (*startpp)++;
904 1.2.8.2 msaitoh if (seendigit)
905 1.2.8.2 msaitoh break;
906 1.2.8.2 msaitoh continue;
907 1.2.8.2 msaitoh }
908 1.2.8.2 msaitoh if (!isdigit(c)) {
909 1.2.8.2 msaitoh if (c == ')' && seendigit) {
910 1.2.8.2 msaitoh (*startpp)--;
911 1.2.8.2 msaitoh break;
912 1.2.8.2 msaitoh }
913 1.2.8.2 msaitoh return (-1);
914 1.2.8.2 msaitoh }
915 1.2.8.2 msaitoh (*startpp)++;
916 1.2.8.2 msaitoh n = n * 10 + (c - '0');
917 1.2.8.2 msaitoh seendigit = 1;
918 1.2.8.2 msaitoh }
919 1.2.8.2 msaitoh return (n + m);
920 1.2.8.2 msaitoh }
921 1.2.8.2 msaitoh
922 1.2.8.2 msaitoh /*%
923 1.2.8.2 msaitoh * Allocate a resource record buffer & save rr info.
924 1.2.8.2 msaitoh */
925 1.2.8.2 msaitoh ns_updrec *
926 1.2.8.2 msaitoh res_mkupdrec(int section, const char *dname,
927 1.2.8.2 msaitoh u_int class, u_int type, u_long ttl) {
928 1.2.8.2 msaitoh ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));
929 1.2.8.2 msaitoh
930 1.2.8.2 msaitoh if (!rrecp || !(rrecp->r_dname = strdup(dname))) {
931 1.2.8.2 msaitoh if (rrecp)
932 1.2.8.2 msaitoh free(rrecp);
933 1.2.8.2 msaitoh return (NULL);
934 1.2.8.2 msaitoh }
935 1.2.8.2 msaitoh rrecp->r_class = (ns_class)class;
936 1.2.8.2 msaitoh rrecp->r_type = (ns_type)type;
937 1.2.8.2 msaitoh rrecp->r_ttl = (u_int)ttl;
938 1.2.8.2 msaitoh rrecp->r_section = (ns_sect)section;
939 1.2.8.2 msaitoh return (rrecp);
940 1.2.8.2 msaitoh }
941 1.2.8.2 msaitoh
942 1.2.8.2 msaitoh /*%
943 1.2.8.2 msaitoh * Free a resource record buffer created by res_mkupdrec.
944 1.2.8.2 msaitoh */
945 1.2.8.2 msaitoh void
946 1.2.8.2 msaitoh res_freeupdrec(ns_updrec *rrecp) {
947 1.2.8.2 msaitoh /* Note: freeing r_dp is the caller's responsibility. */
948 1.2.8.2 msaitoh if (rrecp->r_dname != NULL)
949 1.2.8.2 msaitoh free(rrecp->r_dname);
950 1.2.8.2 msaitoh free(rrecp);
951 1.2.8.2 msaitoh }
952 1.2.8.2 msaitoh
953 1.2.8.2 msaitoh struct valuelist {
954 1.2.8.2 msaitoh struct valuelist * next;
955 1.2.8.2 msaitoh struct valuelist * prev;
956 1.2.8.2 msaitoh char * name;
957 1.2.8.2 msaitoh char * proto;
958 1.2.8.2 msaitoh int port;
959 1.2.8.2 msaitoh };
960 1.2.8.2 msaitoh static struct valuelist *servicelist, *protolist;
961 1.2.8.2 msaitoh
962 1.2.8.2 msaitoh static void
963 1.2.8.2 msaitoh res_buildservicelist(void) {
964 1.2.8.2 msaitoh struct servent *sp;
965 1.2.8.2 msaitoh struct valuelist *slp;
966 1.2.8.2 msaitoh
967 1.2.8.2 msaitoh #ifdef MAYBE_HESIOD
968 1.2.8.2 msaitoh setservent(0);
969 1.2.8.2 msaitoh #else
970 1.2.8.2 msaitoh setservent(1);
971 1.2.8.2 msaitoh #endif
972 1.2.8.2 msaitoh while ((sp = getservent()) != NULL) {
973 1.2.8.2 msaitoh slp = (struct valuelist *)malloc(sizeof(struct valuelist));
974 1.2.8.2 msaitoh if (!slp)
975 1.2.8.2 msaitoh break;
976 1.2.8.2 msaitoh slp->name = strdup(sp->s_name);
977 1.2.8.2 msaitoh slp->proto = strdup(sp->s_proto);
978 1.2.8.2 msaitoh if ((slp->name == NULL) || (slp->proto == NULL)) {
979 1.2.8.2 msaitoh if (slp->name) free(slp->name);
980 1.2.8.2 msaitoh if (slp->proto) free(slp->proto);
981 1.2.8.2 msaitoh free(slp);
982 1.2.8.2 msaitoh break;
983 1.2.8.2 msaitoh }
984 1.2.8.2 msaitoh slp->port = ntohs((u_int16_t)sp->s_port); /*%< host byt order */
985 1.2.8.2 msaitoh slp->next = servicelist;
986 1.2.8.2 msaitoh slp->prev = NULL;
987 1.2.8.2 msaitoh if (servicelist)
988 1.2.8.2 msaitoh servicelist->prev = slp;
989 1.2.8.2 msaitoh servicelist = slp;
990 1.2.8.2 msaitoh }
991 1.2.8.2 msaitoh endservent();
992 1.2.8.2 msaitoh }
993 1.2.8.2 msaitoh
994 1.2.8.2 msaitoh void
995 1.2.8.2 msaitoh res_destroyservicelist(void) {
996 1.2.8.2 msaitoh struct valuelist *slp, *slp_next;
997 1.2.8.2 msaitoh
998 1.2.8.2 msaitoh for (slp = servicelist; slp != NULL; slp = slp_next) {
999 1.2.8.2 msaitoh slp_next = slp->next;
1000 1.2.8.2 msaitoh free(slp->name);
1001 1.2.8.2 msaitoh free(slp->proto);
1002 1.2.8.2 msaitoh free(slp);
1003 1.2.8.2 msaitoh }
1004 1.2.8.2 msaitoh servicelist = (struct valuelist *)0;
1005 1.2.8.2 msaitoh }
1006 1.2.8.2 msaitoh
1007 1.2.8.2 msaitoh void
1008 1.2.8.2 msaitoh res_buildprotolist(void) {
1009 1.2.8.2 msaitoh struct protoent *pp;
1010 1.2.8.2 msaitoh struct valuelist *slp;
1011 1.2.8.2 msaitoh
1012 1.2.8.2 msaitoh #ifdef MAYBE_HESIOD
1013 1.2.8.2 msaitoh setprotoent(0);
1014 1.2.8.2 msaitoh #else
1015 1.2.8.2 msaitoh setprotoent(1);
1016 1.2.8.2 msaitoh #endif
1017 1.2.8.2 msaitoh while ((pp = getprotoent()) != NULL) {
1018 1.2.8.2 msaitoh slp = (struct valuelist *)malloc(sizeof(struct valuelist));
1019 1.2.8.2 msaitoh if (!slp)
1020 1.2.8.2 msaitoh break;
1021 1.2.8.2 msaitoh slp->name = strdup(pp->p_name);
1022 1.2.8.2 msaitoh if (slp->name == NULL) {
1023 1.2.8.2 msaitoh free(slp);
1024 1.2.8.2 msaitoh break;
1025 1.2.8.2 msaitoh }
1026 1.2.8.2 msaitoh slp->port = pp->p_proto; /*%< host byte order */
1027 1.2.8.2 msaitoh slp->next = protolist;
1028 1.2.8.2 msaitoh slp->prev = NULL;
1029 1.2.8.2 msaitoh if (protolist)
1030 1.2.8.2 msaitoh protolist->prev = slp;
1031 1.2.8.2 msaitoh protolist = slp;
1032 1.2.8.2 msaitoh }
1033 1.2.8.2 msaitoh endprotoent();
1034 1.2.8.2 msaitoh }
1035 1.2.8.2 msaitoh
1036 1.2.8.2 msaitoh void
1037 1.2.8.2 msaitoh res_destroyprotolist(void) {
1038 1.2.8.2 msaitoh struct valuelist *plp, *plp_next;
1039 1.2.8.2 msaitoh
1040 1.2.8.2 msaitoh for (plp = protolist; plp != NULL; plp = plp_next) {
1041 1.2.8.2 msaitoh plp_next = plp->next;
1042 1.2.8.2 msaitoh free(plp->name);
1043 1.2.8.2 msaitoh free(plp);
1044 1.2.8.2 msaitoh }
1045 1.2.8.2 msaitoh protolist = (struct valuelist *)0;
1046 1.2.8.2 msaitoh }
1047 1.2.8.2 msaitoh
1048 1.2.8.2 msaitoh static int
1049 1.2.8.2 msaitoh findservice(const char *s, struct valuelist **list) {
1050 1.2.8.2 msaitoh struct valuelist *lp = *list;
1051 1.2.8.2 msaitoh int n;
1052 1.2.8.2 msaitoh
1053 1.2.8.2 msaitoh for (; lp != NULL; lp = lp->next)
1054 1.2.8.2 msaitoh if (strcasecmp(lp->name, s) == 0) {
1055 1.2.8.2 msaitoh if (lp != *list) {
1056 1.2.8.2 msaitoh lp->prev->next = lp->next;
1057 1.2.8.2 msaitoh if (lp->next)
1058 1.2.8.2 msaitoh lp->next->prev = lp->prev;
1059 1.2.8.2 msaitoh (*list)->prev = lp;
1060 1.2.8.2 msaitoh lp->next = *list;
1061 1.2.8.2 msaitoh *list = lp;
1062 1.2.8.2 msaitoh }
1063 1.2.8.2 msaitoh return (lp->port); /*%< host byte order */
1064 1.2.8.2 msaitoh }
1065 1.2.8.2 msaitoh if (sscanf(s, "%d", &n) != 1 || n <= 0)
1066 1.2.8.2 msaitoh n = -1;
1067 1.2.8.2 msaitoh return (n);
1068 1.2.8.2 msaitoh }
1069 1.2.8.2 msaitoh
1070 1.2.8.2 msaitoh /*%
1071 1.2.8.2 msaitoh * Convert service name or (ascii) number to int.
1072 1.2.8.2 msaitoh */
1073 1.2.8.2 msaitoh int
1074 1.2.8.2 msaitoh res_servicenumber(const char *p) {
1075 1.2.8.2 msaitoh if (servicelist == (struct valuelist *)0)
1076 1.2.8.2 msaitoh res_buildservicelist();
1077 1.2.8.2 msaitoh return (findservice(p, &servicelist));
1078 1.2.8.2 msaitoh }
1079 1.2.8.2 msaitoh
1080 1.2.8.2 msaitoh /*%
1081 1.2.8.2 msaitoh * Convert protocol name or (ascii) number to int.
1082 1.2.8.2 msaitoh */
1083 1.2.8.2 msaitoh int
1084 1.2.8.2 msaitoh res_protocolnumber(const char *p) {
1085 1.2.8.2 msaitoh if (protolist == (struct valuelist *)0)
1086 1.2.8.2 msaitoh res_buildprotolist();
1087 1.2.8.2 msaitoh return (findservice(p, &protolist));
1088 1.2.8.2 msaitoh }
1089 1.2.8.2 msaitoh
1090 1.2.8.2 msaitoh static struct servent *
1091 1.2.8.2 msaitoh cgetservbyport(u_int16_t port, const char *proto) { /*%< Host byte order. */
1092 1.2.8.2 msaitoh struct valuelist **list = &servicelist;
1093 1.2.8.2 msaitoh struct valuelist *lp = *list;
1094 1.2.8.2 msaitoh static struct servent serv;
1095 1.2.8.2 msaitoh
1096 1.2.8.2 msaitoh port = ntohs(port);
1097 1.2.8.2 msaitoh for (; lp != NULL; lp = lp->next) {
1098 1.2.8.2 msaitoh if (port != (u_int16_t)lp->port) /*%< Host byte order. */
1099 1.2.8.2 msaitoh continue;
1100 1.2.8.2 msaitoh if (strcasecmp(lp->proto, proto) == 0) {
1101 1.2.8.2 msaitoh if (lp != *list) {
1102 1.2.8.2 msaitoh lp->prev->next = lp->next;
1103 1.2.8.2 msaitoh if (lp->next)
1104 1.2.8.2 msaitoh lp->next->prev = lp->prev;
1105 1.2.8.2 msaitoh (*list)->prev = lp;
1106 1.2.8.2 msaitoh lp->next = *list;
1107 1.2.8.2 msaitoh *list = lp;
1108 1.2.8.2 msaitoh }
1109 1.2.8.2 msaitoh serv.s_name = lp->name;
1110 1.2.8.2 msaitoh serv.s_port = htons((u_int16_t)lp->port);
1111 1.2.8.2 msaitoh serv.s_proto = lp->proto;
1112 1.2.8.2 msaitoh return (&serv);
1113 1.2.8.2 msaitoh }
1114 1.2.8.2 msaitoh }
1115 1.2.8.2 msaitoh return (0);
1116 1.2.8.2 msaitoh }
1117 1.2.8.2 msaitoh
1118 1.2.8.2 msaitoh static struct protoent *
1119 1.2.8.2 msaitoh cgetprotobynumber(int proto) { /*%< Host byte order. */
1120 1.2.8.2 msaitoh struct valuelist **list = &protolist;
1121 1.2.8.2 msaitoh struct valuelist *lp = *list;
1122 1.2.8.2 msaitoh static struct protoent prot;
1123 1.2.8.2 msaitoh
1124 1.2.8.2 msaitoh for (; lp != NULL; lp = lp->next)
1125 1.2.8.2 msaitoh if (lp->port == proto) { /*%< Host byte order. */
1126 1.2.8.2 msaitoh if (lp != *list) {
1127 1.2.8.2 msaitoh lp->prev->next = lp->next;
1128 1.2.8.2 msaitoh if (lp->next)
1129 1.2.8.2 msaitoh lp->next->prev = lp->prev;
1130 1.2.8.2 msaitoh (*list)->prev = lp;
1131 1.2.8.2 msaitoh lp->next = *list;
1132 1.2.8.2 msaitoh *list = lp;
1133 1.2.8.2 msaitoh }
1134 1.2.8.2 msaitoh prot.p_name = lp->name;
1135 1.2.8.2 msaitoh prot.p_proto = lp->port; /*%< Host byte order. */
1136 1.2.8.2 msaitoh return (&prot);
1137 1.2.8.2 msaitoh }
1138 1.2.8.2 msaitoh return (0);
1139 1.2.8.2 msaitoh }
1140 1.2.8.2 msaitoh
1141 1.2.8.2 msaitoh const char *
1142 1.2.8.2 msaitoh res_protocolname(int num) {
1143 1.2.8.2 msaitoh static char number[8];
1144 1.2.8.2 msaitoh struct protoent *pp;
1145 1.2.8.2 msaitoh
1146 1.2.8.2 msaitoh if (protolist == (struct valuelist *)0)
1147 1.2.8.2 msaitoh res_buildprotolist();
1148 1.2.8.2 msaitoh pp = cgetprotobynumber(num);
1149 1.2.8.2 msaitoh if (pp == 0) {
1150 1.2.8.2 msaitoh (void) sprintf(number, "%d", num);
1151 1.2.8.2 msaitoh return (number);
1152 1.2.8.2 msaitoh }
1153 1.2.8.2 msaitoh return (pp->p_name);
1154 1.2.8.2 msaitoh }
1155 1.2.8.2 msaitoh
1156 1.2.8.2 msaitoh const char *
1157 1.2.8.2 msaitoh res_servicename(u_int16_t port, const char *proto) { /*%< Host byte order. */
1158 1.2.8.2 msaitoh static char number[8];
1159 1.2.8.2 msaitoh struct servent *ss;
1160 1.2.8.2 msaitoh
1161 1.2.8.2 msaitoh if (servicelist == (struct valuelist *)0)
1162 1.2.8.2 msaitoh res_buildservicelist();
1163 1.2.8.2 msaitoh ss = cgetservbyport(htons(port), proto);
1164 1.2.8.2 msaitoh if (ss == 0) {
1165 1.2.8.2 msaitoh (void) sprintf(number, "%d", port);
1166 1.2.8.2 msaitoh return (number);
1167 1.2.8.2 msaitoh }
1168 1.2.8.2 msaitoh return (ss->s_name);
1169 1.2.8.2 msaitoh }
1170