]>
Commit | Line | Data |
---|---|---|
beaaa3b7 OM |
1 | /** @file\r |
2 | Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>\r | |
3 | This program and the accompanying materials are licensed and made available\r | |
4 | under the terms and conditions of the BSD License which accompanies this\r | |
5 | distribution. The full text of the license may be found at\r | |
6 | http://opensource.org/licenses/bsd-license.php.\r | |
7 | \r | |
8 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
9 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
10 | **/\r | |
d7ce7006 | 11 | /*\r |
12 | * Copyright (c) 1996 by Internet Software Consortium.\r | |
13 | *\r | |
14 | * Permission to use, copy, modify, and distribute this software for any\r | |
15 | * purpose with or without fee is hereby granted, provided that the above\r | |
16 | * copyright notice and this permission notice appear in all copies.\r | |
17 | *\r | |
18 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r | |
19 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r | |
20 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r | |
21 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r | |
22 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r | |
23 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r | |
24 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r | |
25 | * SOFTWARE.\r | |
26 | */\r | |
27 | \r | |
28 | /*\r | |
29 | * Portions copyright (c) 1999, 2000\r | |
30 | * Intel Corporation.\r | |
31 | * All rights reserved.\r | |
32 | *\r | |
33 | * Redistribution and use in source and binary forms, with or without\r | |
34 | * modification, are permitted provided that the following conditions\r | |
35 | * are met:\r | |
36 | *\r | |
37 | * 1. Redistributions of source code must retain the above copyright\r | |
38 | * notice, this list of conditions and the following disclaimer.\r | |
39 | *\r | |
40 | * 2. Redistributions in binary form must reproduce the above copyright\r | |
41 | * notice, this list of conditions and the following disclaimer in the\r | |
42 | * documentation and/or other materials provided with the distribution.\r | |
43 | *\r | |
44 | * 3. All advertising materials mentioning features or use of this software\r | |
45 | * must display the following acknowledgement:\r | |
46 | *\r | |
47 | * This product includes software developed by Intel Corporation and\r | |
48 | * its contributors.\r | |
49 | *\r | |
50 | * 4. Neither the name of Intel Corporation or its contributors may be\r | |
51 | * used to endorse or promote products derived from this software\r | |
52 | * without specific prior written permission.\r | |
53 | *\r | |
54 | * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r | |
55 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r | |
56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r | |
57 | * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r | |
58 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r | |
59 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r | |
60 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r | |
61 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r | |
62 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r | |
63 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r | |
64 | * THE POSSIBILITY OF SUCH DAMAGE.\r | |
65 | *\r | |
66 | */\r | |
67 | \r | |
68 | /*\r | |
69 | * Based on the Dynamic DNS reference implementation by Viraj Bais\r | |
70 | * <viraj_bais@ccm.fm.intel.com>\r | |
71 | */\r | |
72 | \r | |
73 | #include <sys/param.h>\r | |
74 | #include <sys/socket.h>\r | |
75 | #include <sys/time.h>\r | |
76 | #include <netinet/in.h>\r | |
77 | #include <arpa/inet.h>\r | |
78 | #include <arpa/nameser.h>\r | |
79 | #include <errno.h>\r | |
80 | #include <limits.h>\r | |
81 | #include <netdb.h>\r | |
82 | #include <resolv.h>\r | |
83 | #include <stdio.h>\r | |
84 | #include <stdlib.h>\r | |
85 | #include <string.h>\r | |
86 | \r | |
87 | /*\r | |
88 | * Separate a linked list of records into groups so that all records\r | |
89 | * in a group will belong to a single zone on the nameserver.\r | |
90 | * Create a dynamic update packet for each zone and send it to the\r | |
91 | * nameservers for that zone, and await answer.\r | |
92 | * Abort if error occurs in updating any zone.\r | |
93 | * Return the number of zones updated on success, < 0 on error.\r | |
94 | *\r | |
95 | * On error, caller must deal with the unsynchronized zones\r | |
96 | * eg. an A record might have been successfully added to the forward\r | |
97 | * zone but the corresponding PTR record would be missing if error\r | |
98 | * was encountered while updating the reverse zone.\r | |
99 | */\r | |
100 | \r | |
101 | #define NSMAX 16\r | |
102 | \r | |
103 | struct ns1 {\r | |
104 | char nsname[MAXDNAME];\r | |
105 | struct in_addr nsaddr1;\r | |
106 | };\r | |
107 | \r | |
108 | struct zonegrp {\r | |
109 | char z_origin[MAXDNAME];\r | |
110 | int16_t z_class;\r | |
111 | char z_soardata[MAXDNAME + 5 * INT32SZ];\r | |
112 | struct ns1 z_ns[NSMAX];\r | |
113 | int z_nscount;\r | |
114 | ns_updrec * z_rr;\r | |
115 | struct zonegrp *z_next;\r | |
116 | };\r | |
117 | \r | |
118 | \r | |
119 | int\r | |
120 | res_update(ns_updrec *rrecp_in) {\r | |
121 | ns_updrec *rrecp, *tmprrecp;\r | |
122 | u_char buf[PACKETSZ], answer[PACKETSZ], packet[2*PACKETSZ];\r | |
123 | char name[MAXDNAME], zname[MAXDNAME], primary[MAXDNAME],\r | |
124 | mailaddr[MAXDNAME];\r | |
125 | u_char soardata[2*MAXCDNAME+5*INT32SZ];\r | |
126 | char *dname, *svdname, *cp1, *target;\r | |
127 | u_char *cp, *eom;\r | |
128 | HEADER *hp = (HEADER *) answer;\r | |
129 | struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start = NULL;\r | |
130 | int i, j, k = 0, n, ancount, nscount, arcount, rcode, rdatasize,\r | |
131 | newgroup, done, myzone, seen_before, numzones = 0;\r | |
132 | u_int16_t dlen, class, qclass, type, qtype;\r | |
133 | u_int32_t ttl;\r | |
134 | \r | |
135 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r | |
136 | h_errno = NETDB_INTERNAL;\r | |
137 | return (-1);\r | |
138 | }\r | |
139 | \r | |
140 | for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {\r | |
141 | dname = rrecp->r_dname;\r | |
142 | n = (int)strlen(dname);\r | |
143 | if (dname[n-1] == '.')\r | |
144 | dname[n-1] = '\0';\r | |
145 | qtype = T_SOA;\r | |
146 | qclass = rrecp->r_class;\r | |
147 | done = 0;\r | |
148 | seen_before = 0;\r | |
149 | \r | |
150 | while (!done && dname) {\r | |
151 | if (qtype == T_SOA) {\r | |
152 | for (tmpzptr = zgrp_start;\r | |
153 | tmpzptr && !seen_before;\r | |
154 | tmpzptr = tmpzptr->z_next) {\r | |
155 | if (strcasecmp(dname,\r | |
156 | tmpzptr->z_origin) == 0 &&\r | |
157 | tmpzptr->z_class == qclass)\r | |
158 | seen_before++;\r | |
159 | for (tmprrecp = tmpzptr->z_rr;\r | |
160 | tmprrecp && !seen_before;\r | |
161 | tmprrecp = tmprrecp->r_grpnext)\r | |
162 | if (strcasecmp(dname, tmprrecp->r_dname) == 0\r | |
163 | && tmprrecp->r_class == qclass) {\r | |
164 | seen_before++;\r | |
165 | break;\r | |
166 | }\r | |
167 | if (seen_before) {\r | |
168 | /*\r | |
169 | * Append to the end of\r | |
170 | * current group.\r | |
171 | */\r | |
172 | for (tmprrecp = tmpzptr->z_rr;\r | |
173 | tmprrecp->r_grpnext;\r | |
174 | tmprrecp = tmprrecp->r_grpnext)\r | |
175 | (void)NULL;\r | |
176 | tmprrecp->r_grpnext = rrecp;\r | |
177 | rrecp->r_grpnext = NULL;\r | |
178 | done = 1;\r | |
179 | break;\r | |
180 | }\r | |
181 | }\r | |
182 | } else if (qtype == T_A) {\r | |
183 | for (tmpzptr = zgrp_start;\r | |
184 | tmpzptr && !done;\r | |
185 | tmpzptr = tmpzptr->z_next)\r | |
186 | for (i = 0; i < tmpzptr->z_nscount; i++)\r | |
187 | if (tmpzptr->z_class == qclass &&\r | |
188 | strcasecmp(tmpzptr->z_ns[i].nsname,\r | |
189 | dname) == 0 &&\r | |
190 | tmpzptr->z_ns[i].nsaddr1.s_addr != 0) {\r | |
191 | zptr->z_ns[k].nsaddr1.s_addr =\r | |
192 | tmpzptr->z_ns[i].nsaddr1.s_addr;\r | |
193 | done = 1;\r | |
194 | break;\r | |
195 | }\r | |
196 | }\r | |
197 | if (done)\r | |
198 | break;\r | |
199 | n = res_mkquery(QUERY, dname, qclass, qtype, NULL,\r | |
200 | 0, NULL, buf, sizeof buf);\r | |
201 | if (n <= 0) {\r | |
202 | fprintf(stderr, "res_update: mkquery failed\n");\r | |
203 | return (n);\r | |
204 | }\r | |
205 | n = res_send(buf, n, answer, sizeof answer);\r | |
206 | if (n < 0) {\r | |
207 | fprintf(stderr, "res_update: send error for %s\n",\r | |
208 | rrecp->r_dname);\r | |
209 | return (n);\r | |
210 | }\r | |
211 | if (n < HFIXEDSZ)\r | |
212 | return (-1);\r | |
213 | ancount = ntohs(hp->ancount);\r | |
214 | nscount = ntohs(hp->nscount);\r | |
215 | arcount = ntohs(hp->arcount);\r | |
216 | rcode = hp->rcode;\r | |
217 | cp = answer + HFIXEDSZ;\r | |
218 | eom = answer + n;\r | |
219 | /* skip the question section */\r | |
220 | n = dn_skipname(cp, eom);\r | |
221 | if (n < 0 || cp + n + 2 * INT16SZ > eom)\r | |
222 | return (-1);\r | |
223 | cp += n + 2 * INT16SZ;\r | |
224 | \r | |
225 | if (qtype == T_SOA) {\r | |
226 | if (ancount == 0 && nscount == 0 && arcount == 0) {\r | |
227 | /*\r | |
228 | * if (rcode == NOERROR) then the dname exists but\r | |
229 | * has no soa record associated with it.\r | |
230 | * if (rcode == NXDOMAIN) then the dname does not\r | |
231 | * exist and the server is replying out of NCACHE.\r | |
232 | * in either case, proceed with the next try\r | |
233 | */\r | |
234 | dname = strchr(dname, '.');\r | |
235 | if (dname != NULL)\r | |
236 | dname++;\r | |
237 | continue;\r | |
238 | } else if ((rcode == NOERROR || rcode == NXDOMAIN) &&\r | |
239 | ancount == 0 &&\r | |
240 | nscount == 1 && arcount == 0) {\r | |
241 | /*\r | |
242 | * name/data does not exist, soa record supplied in the\r | |
243 | * authority section\r | |
244 | */\r | |
245 | /* authority section must contain the soa record */\r | |
246 | if ((n = dn_expand(answer, eom, cp, zname,\r | |
247 | sizeof zname)) < 0)\r | |
248 | return (n);\r | |
249 | cp += n;\r | |
250 | if (cp + 2 * INT16SZ > eom)\r | |
251 | return (-1);\r | |
252 | GETSHORT(type, cp);\r | |
253 | GETSHORT(class, cp);\r | |
254 | if (type != T_SOA || class != qclass) {\r | |
255 | fprintf(stderr, "unknown answer\n");\r | |
256 | return (-1);\r | |
257 | }\r | |
258 | myzone = 0;\r | |
259 | svdname = dname;\r | |
260 | while (dname)\r | |
261 | if (strcasecmp(dname, zname) == 0) {\r | |
262 | myzone = 1;\r | |
263 | break;\r | |
264 | } else if ((dname = strchr(dname, '.')) != NULL)\r | |
265 | dname++;\r | |
266 | if (!myzone) {\r | |
267 | dname = strchr(svdname, '.');\r | |
268 | if (dname != NULL)\r | |
269 | dname++;\r | |
270 | continue;\r | |
271 | }\r | |
272 | nscount = 0;\r | |
273 | /* fallthrough */\r | |
274 | } else if (rcode == NOERROR && ancount == 1) {\r | |
275 | /*\r | |
276 | * found the zone name\r | |
277 | * new servers will supply NS records for the zone\r | |
278 | * in authority section and A records for those\r | |
279 | * nameservers in the additional section\r | |
280 | * older servers have to be explicitly queried for\r | |
281 | * NS records for the zone\r | |
282 | */\r | |
283 | /* answer section must contain the soa record */\r | |
284 | if ((n = dn_expand(answer, eom, cp, zname,\r | |
285 | sizeof zname)) < 0)\r | |
286 | return (n);\r | |
287 | else\r | |
288 | cp += n;\r | |
289 | if (cp + 2 * INT16SZ > eom)\r | |
290 | return (-1);\r | |
291 | GETSHORT(type, cp);\r | |
292 | GETSHORT(class, cp);\r | |
293 | if (type == T_CNAME) {\r | |
294 | dname = strchr(dname, '.');\r | |
295 | if (dname != NULL)\r | |
296 | dname++;\r | |
297 | continue;\r | |
298 | }\r | |
299 | if (strcasecmp(dname, zname) != 0 ||\r | |
300 | type != T_SOA ||\r | |
301 | class != rrecp->r_class) {\r | |
302 | fprintf(stderr, "unknown answer\n");\r | |
303 | return (-1);\r | |
304 | }\r | |
305 | /* FALLTHROUGH */\r | |
306 | } else {\r | |
307 | fprintf(stderr,\r | |
308 | "unknown response: ans=%d, auth=%d, add=%d, rcode=%d\n",\r | |
309 | ancount, nscount, arcount, hp->rcode);\r | |
310 | return (-1);\r | |
311 | }\r | |
312 | if (cp + INT32SZ + INT16SZ > eom)\r | |
313 | return (-1);\r | |
314 | /* continue processing the soa record */\r | |
315 | GETLONG(ttl, cp);\r | |
316 | GETSHORT(dlen, cp);\r | |
317 | if (cp + dlen > eom)\r | |
318 | return (-1);\r | |
319 | newgroup = 1;\r | |
320 | zptr = zgrp_start;\r | |
321 | prevzptr = NULL;\r | |
322 | while (zptr) {\r | |
323 | if (strcasecmp(zname, zptr->z_origin) == 0 &&\r | |
324 | type == T_SOA && class == qclass) {\r | |
325 | newgroup = 0;\r | |
326 | break;\r | |
327 | }\r | |
328 | prevzptr = zptr;\r | |
329 | zptr = zptr->z_next;\r | |
330 | }\r | |
331 | if (!newgroup) {\r | |
332 | for (tmprrecp = zptr->z_rr;\r | |
333 | tmprrecp->r_grpnext;\r | |
334 | tmprrecp = tmprrecp->r_grpnext)\r | |
335 | ;\r | |
336 | tmprrecp->r_grpnext = rrecp;\r | |
337 | rrecp->r_grpnext = NULL;\r | |
338 | done = 1;\r | |
339 | cp += dlen;\r | |
340 | break;\r | |
341 | } else {\r | |
342 | if ((n = dn_expand(answer, eom, cp, primary,\r | |
343 | sizeof primary)) < 0)\r | |
344 | return (n);\r | |
345 | cp += n;\r | |
346 | /*\r | |
347 | * We don't have to bounds check here because the\r | |
348 | * next use of 'cp' is in dn_expand().\r | |
349 | */\r | |
350 | cp1 = (char *)soardata;\r | |
351 | strcpy(cp1, primary);\r | |
352 | cp1 += strlen(cp1) + 1;\r | |
353 | if ((n = dn_expand(answer, eom, cp, mailaddr,\r | |
354 | sizeof mailaddr)) < 0)\r | |
355 | return (n);\r | |
356 | cp += n;\r | |
357 | strcpy(cp1, mailaddr);\r | |
358 | cp1 += strlen(cp1) + 1;\r | |
359 | if (cp + 5*INT32SZ > eom)\r | |
360 | return (-1);\r | |
361 | memcpy(cp1, cp, 5*INT32SZ);\r | |
362 | cp += 5*INT32SZ;\r | |
363 | cp1 += 5*INT32SZ;\r | |
364 | rdatasize = (int)((u_char *)cp1 - soardata);\r | |
365 | zptr = calloc(1, sizeof(struct zonegrp));\r | |
366 | if (zptr == NULL)\r | |
367 | return (-1);\r | |
368 | if (zgrp_start == NULL)\r | |
369 | zgrp_start = zptr;\r | |
370 | else\r | |
371 | prevzptr->z_next = zptr;\r | |
372 | zptr->z_rr = rrecp;\r | |
373 | rrecp->r_grpnext = NULL;\r | |
374 | strcpy(zptr->z_origin, zname);\r | |
375 | zptr->z_class = class;\r | |
376 | memcpy(zptr->z_soardata, soardata, rdatasize);\r | |
377 | /* fallthrough to process NS and A records */\r | |
378 | }\r | |
379 | } else if (qtype == T_NS) {\r | |
380 | if (rcode == NOERROR && ancount > 0) {\r | |
381 | strcpy(zname, dname);\r | |
382 | for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {\r | |
383 | if (strcasecmp(zname, zptr->z_origin) == 0)\r | |
384 | break;\r | |
385 | }\r | |
386 | if (zptr == NULL)\r | |
387 | /* should not happen */\r | |
388 | return (-1);\r | |
389 | if (nscount > 0) {\r | |
390 | /*\r | |
391 | * answer and authority sections contain\r | |
392 | * the same information, skip answer section\r | |
393 | */\r | |
394 | for (j = 0; j < ancount; j++) {\r | |
395 | n = dn_skipname(cp, eom);\r | |
396 | if (n < 0)\r | |
397 | return (-1);\r | |
398 | n += 2*INT16SZ + INT32SZ;\r | |
399 | if (cp + n + INT16SZ > eom)\r | |
400 | return (-1);\r | |
401 | cp += n;\r | |
402 | GETSHORT(dlen, cp);\r | |
403 | cp += dlen;\r | |
404 | }\r | |
405 | } else\r | |
406 | nscount = ancount;\r | |
407 | /* fallthrough to process NS and A records */\r | |
408 | } else {\r | |
409 | fprintf(stderr, "cannot determine nameservers for %s:\\r | |
410 | ans=%d, auth=%d, add=%d, rcode=%d\n",\r | |
411 | dname, ancount, nscount, arcount, hp->rcode);\r | |
412 | return (-1);\r | |
413 | }\r | |
414 | } else if (qtype == T_A) {\r | |
415 | if (rcode == NOERROR && ancount > 0) {\r | |
416 | arcount = ancount;\r | |
417 | ancount = nscount = 0;\r | |
418 | /* fallthrough to process A records */\r | |
419 | } else {\r | |
420 | fprintf(stderr, "cannot determine address for %s:\\r | |
421 | ans=%d, auth=%d, add=%d, rcode=%d\n",\r | |
422 | dname, ancount, nscount, arcount, hp->rcode);\r | |
423 | return (-1);\r | |
424 | }\r | |
425 | }\r | |
426 | /* process NS records for the zone */\r | |
427 | j = 0;\r | |
428 | for (i = 0; i < nscount; i++) {\r | |
429 | if ((n = dn_expand(answer, eom, cp, name,\r | |
430 | sizeof name)) < 0)\r | |
431 | return (n);\r | |
432 | cp += n;\r | |
433 | if (cp + 3 * INT16SZ + INT32SZ > eom)\r | |
434 | return (-1);\r | |
435 | GETSHORT(type, cp);\r | |
436 | GETSHORT(class, cp);\r | |
437 | GETLONG(ttl, cp);\r | |
438 | GETSHORT(dlen, cp);\r | |
439 | if (cp + dlen > eom)\r | |
440 | return (-1);\r | |
441 | if (strcasecmp(name, zname) == 0 &&\r | |
442 | type == T_NS && class == qclass) {\r | |
443 | if ((n = dn_expand(answer, eom, cp,\r | |
444 | name, sizeof name)) < 0)\r | |
445 | return (n);\r | |
446 | target = zptr->z_ns[j++].nsname;\r | |
447 | strcpy(target, name);\r | |
448 | }\r | |
449 | cp += dlen;\r | |
450 | }\r | |
451 | if (zptr->z_nscount == 0)\r | |
452 | zptr->z_nscount = j;\r | |
453 | /* get addresses for the nameservers */\r | |
454 | for (i = 0; i < arcount; i++) {\r | |
455 | if ((n = dn_expand(answer, eom, cp, name,\r | |
456 | sizeof name)) < 0)\r | |
457 | return (n);\r | |
458 | cp += n;\r | |
459 | if (cp + 3 * INT16SZ + INT32SZ > eom)\r | |
460 | return (-1);\r | |
461 | GETSHORT(type, cp);\r | |
462 | GETSHORT(class, cp);\r | |
463 | GETLONG(ttl, cp);\r | |
464 | GETSHORT(dlen, cp);\r | |
465 | if (cp + dlen > eom)\r | |
466 | return (-1);\r | |
467 | if (type == T_A && dlen == INT32SZ && class == qclass) {\r | |
468 | for (j = 0; j < zptr->z_nscount; j++)\r | |
469 | if (strcasecmp(name, zptr->z_ns[j].nsname) == 0) {\r | |
470 | memcpy(&zptr->z_ns[j].nsaddr1.s_addr, cp,\r | |
471 | INT32SZ);\r | |
472 | break;\r | |
473 | }\r | |
474 | }\r | |
475 | cp += dlen;\r | |
476 | }\r | |
477 | if (zptr->z_nscount == 0) {\r | |
478 | dname = zname;\r | |
479 | qtype = T_NS;\r | |
480 | continue;\r | |
481 | }\r | |
482 | done = 1;\r | |
483 | for (k = 0; k < zptr->z_nscount; k++)\r | |
484 | if (zptr->z_ns[k].nsaddr1.s_addr == 0) {\r | |
485 | done = 0;\r | |
486 | dname = zptr->z_ns[k].nsname;\r | |
487 | qtype = T_A;\r | |
488 | }\r | |
d7ce7006 | 489 | } /* while */\r |
490 | }\r | |
beaaa3b7 | 491 | --ttl; // Suppress the "Set but not used" warning/error for ttl.\r |
d7ce7006 | 492 | \r |
493 | _res.options |= RES_DEBUG;\r | |
494 | for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {\r | |
495 | \r | |
496 | /* append zone section */\r | |
497 | rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,\r | |
498 | zptr->z_class, ns_t_soa, 0);\r | |
499 | if (rrecp == NULL) {\r | |
500 | fprintf(stderr, "saverrec error\n");\r | |
501 | fflush(stderr);\r | |
502 | return (-1);\r | |
503 | }\r | |
504 | rrecp->r_grpnext = zptr->z_rr;\r | |
505 | zptr->z_rr = rrecp;\r | |
506 | \r | |
507 | n = res_mkupdate(zptr->z_rr, packet, sizeof packet);\r | |
508 | if (n < 0) {\r | |
509 | fprintf(stderr, "res_mkupdate error\n");\r | |
510 | fflush(stderr);\r | |
511 | return (-1);\r | |
512 | } else\r | |
513 | fprintf(stdout, "res_mkupdate: packet size = %d\n", n);\r | |
514 | \r | |
beaaa3b7 | 515 | /* Override the list of NS records from res_init() with\r |
d7ce7006 | 516 | * the authoritative nameservers for the zone being updated.\r |
517 | * Sort primary to be the first in the list of nameservers.\r | |
518 | */\r | |
519 | for (i = 0; i < zptr->z_nscount; i++) {\r | |
520 | if (strcasecmp(zptr->z_ns[i].nsname,\r | |
521 | zptr->z_soardata) == 0) {\r | |
522 | struct in_addr tmpaddr;\r | |
523 | \r | |
524 | if (i != 0) {\r | |
525 | strcpy(zptr->z_ns[i].nsname,\r | |
526 | zptr->z_ns[0].nsname);\r | |
527 | strcpy(zptr->z_ns[0].nsname,\r | |
528 | zptr->z_soardata);\r | |
529 | tmpaddr = zptr->z_ns[i].nsaddr1;\r | |
530 | zptr->z_ns[i].nsaddr1 =\r | |
531 | zptr->z_ns[0].nsaddr1;\r | |
532 | zptr->z_ns[0].nsaddr1 = tmpaddr;\r | |
533 | }\r | |
534 | break;\r | |
535 | }\r | |
536 | }\r | |
537 | for (i = 0; i < MAXNS; i++) {\r | |
538 | _res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;\r | |
539 | _res.nsaddr_list[i].sin_family = AF_INET;\r | |
540 | _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);\r | |
541 | }\r | |
542 | _res.nscount = (zptr->z_nscount < MAXNS) ?\r | |
543 | zptr->z_nscount : MAXNS;\r | |
544 | n = res_send(packet, n, answer, sizeof(answer));\r | |
545 | if (n < 0) {\r | |
546 | fprintf(stderr, "res_send: send error, n=%d\n", n);\r | |
547 | break;\r | |
548 | } else\r | |
549 | numzones++;\r | |
550 | }\r | |
551 | \r | |
552 | /* free malloc'ed memory */\r | |
553 | while(zgrp_start) {\r | |
554 | zptr = zgrp_start;\r | |
555 | zgrp_start = zgrp_start->z_next;\r | |
556 | res_freeupdrec(zptr->z_rr); /* Zone section we allocated. */\r | |
557 | free((char *)zptr);\r | |
558 | }\r | |
559 | \r | |
560 | return (numzones);\r | |
561 | }\r |