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