1 /* 2 * util.c 3 * some handy function needed in drill and not implemented 4 * in ldns 5 * (c) 2005 NLnet Labs 6 * 7 * See the file LICENSE for the license 8 * 9 */ 10 11 #include "drill.h" 12 #include <ldns/ldns.h> 13 14 #include <errno.h> 15 16 static int 17 read_line(FILE *input, char *line, size_t len) 18 { 19 int i; 20 21 char c; 22 for (i = 0; i < (int)len-1; i++) { 23 c = (char)getc(input); 24 if (c == EOF) { 25 return -1; 26 } else if (c != '\n') { 27 line[i] = c; 28 } else { 29 break; 30 } 31 } 32 line[i] = '\0'; 33 return i; 34 } 35 36 /* key_list must be initialized with ldns_rr_list_new() */ 37 ldns_status 38 read_key_file(const char *filename, ldns_rr_list *key_list, bool silently) 39 { 40 int line_len = 0; 41 int line_nr = 0; 42 int key_count = 0; 43 char line[LDNS_MAX_LINELEN]; 44 ldns_status status; 45 FILE *input_file; 46 ldns_rr *rr; 47 48 input_file = fopen(filename, "r"); 49 if (!input_file) { 50 if (! silently) { 51 fprintf(stderr, "Error opening %s: %s\n", 52 filename, strerror(errno)); 53 } 54 return LDNS_STATUS_ERR; 55 } 56 while (line_len >= 0) { 57 line_len = (int) read_line(input_file, line, sizeof(line)); 58 line_nr++; 59 if (line_len > 0 && line[0] != ';') { 60 status = ldns_rr_new_frm_str(&rr, line, 0, NULL, NULL); 61 if (status != LDNS_STATUS_OK) { 62 if (! silently) { 63 fprintf(stderr, 64 "Error parsing DNSKEY RR " 65 "in line %d: %s\n", line_nr, 66 ldns_get_errorstr_by_id(status) 67 ); 68 } 69 } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY || 70 ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) { 71 ldns_rr_list_push_rr(key_list, rr); 72 key_count++; 73 } else { 74 ldns_rr_free(rr); 75 } 76 } 77 } 78 fclose(input_file); 79 if (key_count > 0) { 80 return LDNS_STATUS_OK; 81 } else { 82 /*fprintf(stderr, "No keys read\n");*/ 83 return LDNS_STATUS_ERR; 84 } 85 } 86 87 ldns_rdf * 88 ldns_rdf_new_addr_frm_str(char *str) 89 { 90 ldns_rdf *a; 91 92 a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str); 93 if (!a) { 94 /* maybe ip6 */ 95 a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str); 96 if (!a) { 97 return NULL; 98 } 99 } 100 return a; 101 } 102 103 static inline void 104 local_print_ds(FILE* out, const char* pre, ldns_rr* ds) 105 { 106 if (out && ds) { 107 fprintf(out, "%s", pre); 108 ldns_rr_print(out, ds); 109 ldns_rr_free(ds); 110 } 111 } 112 113 /* 114 * For all keys in a packet print the DS 115 */ 116 void 117 print_ds_of_keys(ldns_pkt *p) 118 { 119 ldns_rr_list *keys; 120 uint16_t i; 121 ldns_rr *ds; 122 123 /* TODO fix the section stuff, here or in ldns */ 124 keys = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_DNSKEY, 125 LDNS_SECTION_ANSWER); 126 127 /* this also returns the question section rr, which does not 128 * have any data.... and this inturn crashes everything */ 129 130 if (keys) { 131 for (i = 0; i < ldns_rr_list_rr_count(keys); i++) { 132 fprintf(stdout, ";\n; equivalent DS records for key %u:\n", 133 (unsigned int)ldns_calc_keytag(ldns_rr_list_rr(keys, i))); 134 135 ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA1); 136 local_print_ds(stdout, "; sha1: ", ds); 137 ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA256); 138 local_print_ds(stdout, "; sha256: ", ds); 139 } 140 ldns_rr_list_deep_free(keys); 141 } 142 } 143 144 static void 145 print_class_type(FILE *fp, ldns_rr *r) 146 { 147 ldns_lookup_table *lt; 148 lt = ldns_lookup_by_id(ldns_rr_classes, ldns_rr_get_class(r)); 149 if (lt) { 150 fprintf(fp, " %s", lt->name); 151 } else { 152 fprintf(fp, " CLASS%d", ldns_rr_get_class(r)); 153 } 154 /* okay not THE way - but the quickest */ 155 switch (ldns_rr_get_type(r)) { 156 case LDNS_RR_TYPE_RRSIG: 157 fprintf(fp, " RRSIG "); 158 break; 159 case LDNS_RR_TYPE_DNSKEY: 160 fprintf(fp, " DNSKEY "); 161 break; 162 case LDNS_RR_TYPE_DS: 163 fprintf(fp, " DS "); 164 break; 165 default: 166 break; 167 } 168 } 169 170 171 void 172 print_ds_abbr(FILE *fp, ldns_rr *ds) 173 { 174 if (!ds || (ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS)) { 175 return; 176 } 177 178 ldns_rdf_print(fp, ldns_rr_owner(ds)); 179 fprintf(fp, " %d", (int)ldns_rr_ttl(ds)); 180 print_class_type(fp, ds); 181 ldns_rdf_print(fp, ldns_rr_rdf(ds, 0)); fprintf(fp, " "); 182 ldns_rdf_print(fp, ldns_rr_rdf(ds, 1)); fprintf(fp, " "); 183 ldns_rdf_print(fp, ldns_rr_rdf(ds, 2)); fprintf(fp, " "); 184 ldns_rdf_print(fp, ldns_rr_rdf(ds, 3)); fprintf(fp, " "); 185 } 186 187 /* print some of the elements of a signature */ 188 void 189 print_rrsig_abbr(FILE *fp, ldns_rr *sig) { 190 if (!sig || (ldns_rr_get_type(sig) != LDNS_RR_TYPE_RRSIG)) { 191 return; 192 } 193 194 ldns_rdf_print(fp, ldns_rr_owner(sig)); 195 fprintf(fp, " %d", (int)ldns_rr_ttl(sig)); 196 print_class_type(fp, sig); 197 198 /* print a number of rdf's */ 199 /* typecovered */ 200 ldns_rdf_print(fp, ldns_rr_rdf(sig, 0)); fprintf(fp, " "); 201 /* algo */ 202 ldns_rdf_print(fp, ldns_rr_rdf(sig, 1)); fprintf(fp, " "); 203 /* labels */ 204 ldns_rdf_print(fp, ldns_rr_rdf(sig, 2)); fprintf(fp, " (\n\t\t\t"); 205 /* expir */ 206 ldns_rdf_print(fp, ldns_rr_rdf(sig, 4)); fprintf(fp, " "); 207 /* incep */ 208 ldns_rdf_print(fp, ldns_rr_rdf(sig, 5)); fprintf(fp, " "); 209 /* key-id */ 210 ldns_rdf_print(fp, ldns_rr_rdf(sig, 6)); fprintf(fp, " "); 211 /* key owner */ 212 ldns_rdf_print(fp, ldns_rr_rdf(sig, 7)); fprintf(fp, ")"); 213 } 214 215 void 216 print_dnskey_abbr(FILE *fp, ldns_rr *key) 217 { 218 if (!key || (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY)) { 219 return; 220 } 221 222 ldns_rdf_print(fp, ldns_rr_owner(key)); 223 fprintf(fp, " %d", (int)ldns_rr_ttl(key)); 224 print_class_type(fp, key); 225 226 /* print a number of rdf's */ 227 /* flags */ 228 ldns_rdf_print(fp, ldns_rr_rdf(key, 0)); fprintf(fp, " "); 229 /* proto */ 230 ldns_rdf_print(fp, ldns_rr_rdf(key, 1)); fprintf(fp, " "); 231 /* algo */ 232 ldns_rdf_print(fp, ldns_rr_rdf(key, 2)); 233 234 if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 256) { 235 fprintf(fp, " ;{id = %u (zsk), size = %db}", (unsigned int)ldns_calc_keytag(key), 236 (int)ldns_rr_dnskey_key_size(key)); 237 return; 238 } 239 if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 257) { 240 fprintf(fp, " ;{id = %u (ksk), size = %db}", (unsigned int)ldns_calc_keytag(key), 241 (int)ldns_rr_dnskey_key_size(key)); 242 return; 243 } 244 fprintf(fp, " ;{id = %u, size = %db}", (unsigned int)ldns_calc_keytag(key), 245 (int)ldns_rr_dnskey_key_size(key)); 246 } 247 248 void 249 print_rr_list_abbr(FILE *fp, ldns_rr_list *rrlist, const char *usr) 250 { 251 size_t i; 252 ldns_rr_type tp; 253 254 for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) { 255 tp = ldns_rr_get_type(ldns_rr_list_rr(rrlist, i)); 256 if (i == 0 && tp != LDNS_RR_TYPE_RRSIG) { 257 if (usr) { 258 fprintf(fp, "%s ", usr); 259 } 260 } 261 switch(tp) { 262 case LDNS_RR_TYPE_DNSKEY: 263 print_dnskey_abbr(fp, ldns_rr_list_rr(rrlist, i)); 264 break; 265 case LDNS_RR_TYPE_RRSIG: 266 print_rrsig_abbr(fp, ldns_rr_list_rr(rrlist, i)); 267 break; 268 case LDNS_RR_TYPE_DS: 269 print_ds_abbr(fp, ldns_rr_list_rr(rrlist, i)); 270 break; 271 default: 272 /* not handled */ 273 break; 274 } 275 fputs("\n", fp); 276 } 277 } 278 279 void * 280 xmalloc(size_t s) 281 { 282 void *p; 283 284 p = malloc(s); 285 if (!p) { 286 printf("Mem failure\n"); 287 exit(EXIT_FAILURE); 288 } 289 return p; 290 } 291 292 void * 293 xrealloc(void *p, size_t size) 294 { 295 void *q; 296 297 q = realloc(p, size); 298 if (!q) { 299 printf("Mem failure\n"); 300 exit(EXIT_FAILURE); 301 } 302 return q; 303 } 304 305 void 306 xfree(void *p) 307 { 308 if (p) { 309 free(p); 310 } 311 } 312