1/* $NetBSD: t_master.c,v 1.3.4.1 2012/06/05 21:15:53 bouyer Exp $ */ 2 3/* 4 * Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1998-2001, 2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20/* Id: t_master.c,v 1.41 2011/03/12 04:59:46 tbox Exp */ 21 22#include <config.h> 23 24#include <ctype.h> 25#include <stdlib.h> 26 27#include <isc/buffer.h> 28#include <isc/mem.h> 29#include <isc/string.h> /* Required for HP/UX (and others?) */ 30#include <isc/util.h> 31 32#include <dns/callbacks.h> 33#include <dns/master.h> 34#include <dns/name.h> 35#include <dns/rdataclass.h> 36#include <dns/rdataset.h> 37#include <dns/result.h> 38 39#include <tests/t_api.h> 40 41#define BUFLEN 255 42#define BIGBUFLEN (64 * 1024) 43 44static isc_result_t 45t1_add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset); 46 47isc_mem_t *T1_mctx; 48char *Tokens[T_MAXTOKS + 1]; 49 50static isc_result_t 51t1_add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) { 52 char buf[BIGBUFLEN]; 53 isc_buffer_t target; 54 isc_result_t result; 55 56 UNUSED(arg); 57 58 isc_buffer_init(&target, buf, BIGBUFLEN); 59 result = dns_rdataset_totext(dataset, owner, ISC_FALSE, ISC_FALSE, 60 &target); 61 if (result != ISC_R_SUCCESS) 62 t_info("dns_rdataset_totext: %s\n", dns_result_totext(result)); 63 64 return(result); 65} 66 67static int 68test_master(char *testfile, char *origin, char *class, isc_result_t exp_result) 69{ 70 int result; 71 int len; 72 isc_result_t isc_result; 73 isc_result_t dns_result; 74 dns_name_t dns_origin; 75 isc_buffer_t source; 76 isc_buffer_t target; 77 unsigned char name_buf[BUFLEN]; 78 dns_rdatacallbacks_t callbacks; 79 dns_rdataclass_t rdataclass; 80 isc_textregion_t textregion; 81 82 if (T1_mctx == NULL) 83 isc_result = isc_mem_create(0, 0, &T1_mctx); 84 else 85 isc_result = ISC_R_SUCCESS; 86 if (isc_result != ISC_R_SUCCESS) { 87 t_info("isc_mem_create failed %d\n", isc_result); 88 return(T_UNRESOLVED); 89 } 90 91 len = strlen(origin); 92 isc_buffer_init(&source, origin, len); 93 isc_buffer_add(&source, len); 94 isc_buffer_setactive(&source, len); 95 isc_buffer_init(&target, name_buf, BUFLEN); 96 dns_name_init(&dns_origin, NULL); 97 dns_result = dns_name_fromtext(&dns_origin, &source, dns_rootname, 98 0, &target); 99 if (dns_result != ISC_R_SUCCESS) { 100 t_info("dns_name_fromtext failed %s\n", 101 dns_result_totext(dns_result)); 102 return(T_UNRESOLVED); 103 } 104 105 dns_rdatacallbacks_init_stdio(&callbacks); 106 callbacks.add = t1_add_callback; 107 108 textregion.base = class; 109 textregion.length = strlen(class); 110 111 dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion); 112 if (dns_result != ISC_R_SUCCESS) { 113 t_info("dns_rdataclass_fromtext failed %s\n", 114 dns_result_totext(dns_result)); 115 return(T_UNRESOLVED); 116 } 117 118 dns_result = dns_master_loadfile( testfile, 119 &dns_origin, 120 &dns_origin, 121 rdataclass, 122 ISC_TRUE, 123 &callbacks, 124 T1_mctx); 125 126 if (dns_result == exp_result) 127 result = T_PASS; 128 else { 129 t_info("dns_master_loadfile: got %s, expected %s\n", 130 dns_result_totext(dns_result), 131 dns_result_totext(exp_result)); 132 result = T_FAIL; 133 } 134 return(result); 135} 136 137static int 138test_master_x(const char *filename) { 139 FILE *fp; 140 char *p; 141 int line; 142 int cnt; 143 int result; 144 145 result = T_UNRESOLVED; 146 147 fp = fopen(filename, "r"); 148 if (fp != NULL) { 149 line = 0; 150 while ((p = t_fgetbs(fp)) != NULL) { 151 152 ++line; 153 154 /* 155 * Skip comment lines. 156 */ 157 if ((isspace(*p & 0xff)) || (*p == '#')) { 158 (void)free(p); 159 continue; 160 } 161 162 /* 163 * Name of data file, origin, zclass, expected result. 164 */ 165 cnt = t_bustline(p, Tokens); 166 if (cnt == 4) { 167 result = test_master(Tokens[0], Tokens[1], 168 Tokens[2], 169 t_dns_result_fromtext(Tokens[3])); 170 } else { 171 t_info("bad format in %s at line %d\n", 172 filename, line); 173 } 174 175 (void)free(p); 176 } 177 (void)fclose(fp); 178 } else { 179 t_info("Missing datafile %s\n", filename); 180 } 181 return(result); 182} 183 184static const char *a1 = "dns_master_loadfile loads a valid master file and " 185 "returns ISC_R_SUCCESS"; 186static void 187t1(void) { 188 int result; 189 t_assert("dns_master_loadfile", 1, T_REQUIRED, "%s", a1); 190 result = test_master_x("dns_master_load_1_data"); 191 t_result(result); 192} 193 194static const char *a2 = 195 "dns_master_loadfile returns ISC_R_UNEXPECTEDEND when the " 196 "masterfile input ends unexpectedly"; 197 198static void 199t2(void) { 200 int result; 201 t_assert("dns_master_loadfile", 2, T_REQUIRED, "%s", a2); 202 result = test_master_x("dns_master_load_2_data"); 203 t_result(result); 204} 205 206static const char *a3 = "dns_master_loadfile returns DNS_R_NOOWNER when the " 207 "an ownername is not specified"; 208 209static void 210t3() { 211 int result; 212 t_assert("dns_master_loadfile", 3, T_REQUIRED, "%s", a3); 213 result = test_master_x("dns_master_load_3_data"); 214 t_result(result); 215} 216 217static const char *a4 = "dns_master_loadfile accepts broken zone files " 218 "where the first record has an undefined TTL, " 219 "as long as it is a SOA"; 220 221static void 222t4() { 223 int result; 224 t_assert("dns_master_loadfile", 4, T_REQUIRED, "%s", a4); 225 result = test_master_x("dns_master_load_4_data"); 226 t_result(result); 227} 228 229static const char *a5 = "dns_master_loadfile returns DNS_R_BADCLASS when the " 230 "the record class did not match the zone class"; 231 232static void 233t5() { 234 int result; 235 236 t_assert("dns_master_loadfile", 5, T_REQUIRED, "%s", a5); 237 result = test_master_x("dns_master_load_5_data"); 238 239 t_result(result); 240} 241 242static const char *a6 = 243 "dns_master_loadfile understands DNSKEY RR specifications " 244 "containing key material"; 245 246static void 247t6() { 248 int result; 249 250 t_assert("dns_master_loadfile", 6, T_REQUIRED, "%s", a6); 251 result = test_master_x("dns_master_load_6_data"); 252 253 t_result(result); 254} 255 256static const char *a7 = 257 "dns_master_loadfile understands DNSKEY RR specifications " 258 "containing no key material"; 259 260static void 261t7() { 262 int result; 263 264 t_assert("dns_master_loadfile", 7, T_REQUIRED, "%s", a7); 265 result = test_master_x("dns_master_load_7_data"); 266 267 t_result(result); 268} 269 270static const char *a8 = 271 "dns_master_loadfile understands $INCLUDE"; 272 273static void 274t8() { 275 int result; 276 277 t_assert("dns_master_loadfile", 8, T_REQUIRED, "%s", a8); 278 result = test_master_x("dns_master_load_8_data"); 279 280 t_result(result); 281} 282 283static const char *a9 = 284 "dns_master_loadfile understands $INCLUDE with failure"; 285 286static void 287t9() { 288 int result; 289 290 t_assert("dns_master_loadfile", 9, T_REQUIRED, "%s", a9); 291 result = test_master_x("dns_master_load_9_data"); 292 293 t_result(result); 294} 295 296static const char *a10 = 297 "dns_master_loadfile non-empty blank lines"; 298 299static void 300t10() { 301 int result; 302 303 t_assert("dns_master_loadfile", 10, T_REQUIRED, "%s", a10); 304 result = test_master_x("dns_master_load_10_data"); 305 306 t_result(result); 307} 308 309static const char *a11 = 310 "dns_master_loadfile allow leading zeros in SOA"; 311 312static void 313t11() { 314 int result; 315 316 t_assert("dns_master_loadfile", 11, T_REQUIRED, "%s", a11); 317 result = test_master_x("dns_master_load_11_data"); 318 319 t_result(result); 320} 321 322 323testspec_t T_testlist[] = { 324 { t1, "ISC_R_SUCCESS" }, 325 { t2, "ISC_R_UNEXPECTEDEND" }, 326 { t3, "DNS_NOOWNER" }, 327 { t4, "DNS_NOTTL" }, 328 { t5, "DNS_BADCLASS" }, 329 { t6, "DNSKEY RR 1" }, 330 { t7, "DNSKEY RR 2" }, 331 { t8, "$INCLUDE" }, 332 { t9, "$INCLUDE w/ DNS_BADCLASS" }, 333 { t10, "non empty blank lines" }, 334 { t11, "leading zeros in serial" }, 335 { NULL, NULL } 336}; 337 338