1 /* $NetBSD: t_master.c,v 1.6 2014/12/10 04:37:53 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2013 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 44 static isc_result_t 45 t1_add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset); 46 47 isc_mem_t *T1_mctx; 48 char *Tokens[T_MAXTOKS + 1]; 49 50 static isc_result_t 51 t1_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 67 static int 68 test_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 137 static int 138 test_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 184 static const char *a1 = "dns_master_loadfile loads a valid master file and " 185 "returns ISC_R_SUCCESS"; 186 static void 187 t1(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 194 static const char *a2 = 195 "dns_master_loadfile returns ISC_R_UNEXPECTEDEND when the " 196 "masterfile input ends unexpectedly"; 197 198 static void 199 t2(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 206 static const char *a3 = "dns_master_loadfile returns DNS_R_NOOWNER when the " 207 "an ownername is not specified"; 208 209 static void 210 t3() { 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 217 static 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 221 static void 222 t4() { 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 229 static const char *a5 = "dns_master_loadfile returns DNS_R_BADCLASS when the " 230 "the record class did not match the zone class"; 231 232 static void 233 t5() { 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 242 static const char *a6 = 243 "dns_master_loadfile understands DNSKEY RR specifications " 244 "containing key material"; 245 246 static void 247 t6() { 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 256 static const char *a7 = 257 "dns_master_loadfile understands DNSKEY RR specifications " 258 "containing no key material"; 259 260 static void 261 t7() { 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 270 static const char *a8 = 271 "dns_master_loadfile understands $INCLUDE"; 272 273 static void 274 t8() { 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 283 static const char *a9 = 284 "dns_master_loadfile understands $INCLUDE with failure"; 285 286 static void 287 t9() { 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 296 static const char *a10 = 297 "dns_master_loadfile non-empty blank lines"; 298 299 static void 300 t10() { 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 309 static const char *a11 = 310 "dns_master_loadfile allow leading zeros in SOA"; 311 312 static void 313 t11() { 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 323 testspec_t T_testlist[] = { 324 { (PFV) t1, "ISC_R_SUCCESS" }, 325 { (PFV) t2, "ISC_R_UNEXPECTEDEND" }, 326 { (PFV) t3, "DNS_NOOWNER" }, 327 { (PFV) t4, "DNS_NOTTL" }, 328 { (PFV) t5, "DNS_BADCLASS" }, 329 { (PFV) t6, "DNSKEY RR 1" }, 330 { (PFV) t7, "DNSKEY RR 2" }, 331 { (PFV) t8, "$INCLUDE" }, 332 { (PFV) t9, "$INCLUDE w/ DNS_BADCLASS" }, 333 { (PFV) t10, "non empty blank lines" }, 334 { (PFV) t11, "leading zeros in serial" }, 335 { (PFV) 0, NULL } 336 }; 337 338 #ifdef WIN32 339 int 340 main(int argc, char **argv) { 341 t_settests(T_testlist); 342 return (t_main(argc, argv)); 343 } 344 #endif 345