1238104Sdes/* 2238104Sdes * util.c 3238104Sdes * some handy function needed in drill and not implemented 4238104Sdes * in ldns 5238104Sdes * (c) 2005 NLnet Labs 6238104Sdes * 7238104Sdes * See the file LICENSE for the license 8238104Sdes * 9238104Sdes */ 10238104Sdes 11238104Sdes#include "drill.h" 12238104Sdes#include <ldns/ldns.h> 13238104Sdes 14238104Sdes#include <errno.h> 15238104Sdes 16246854Sdesstatic int 17238104Sdesread_line(FILE *input, char *line, size_t len) 18238104Sdes{ 19246854Sdes int i; 20269257Sdes int c; 21269257Sdes 22246854Sdes for (i = 0; i < (int)len-1; i++) { 23269257Sdes c = getc(input); 24238104Sdes if (c == EOF) { 25238104Sdes return -1; 26238104Sdes } else if (c != '\n') { 27238104Sdes line[i] = c; 28238104Sdes } else { 29238104Sdes break; 30238104Sdes } 31238104Sdes } 32238104Sdes line[i] = '\0'; 33238104Sdes return i; 34238104Sdes} 35238104Sdes 36238104Sdes/* key_list must be initialized with ldns_rr_list_new() */ 37238104Sdesldns_status 38246854Sdesread_key_file(const char *filename, ldns_rr_list *key_list, bool silently) 39238104Sdes{ 40238104Sdes int line_len = 0; 41238104Sdes int line_nr = 0; 42238104Sdes int key_count = 0; 43246854Sdes char line[LDNS_MAX_LINELEN]; 44238104Sdes ldns_status status; 45238104Sdes FILE *input_file; 46238104Sdes ldns_rr *rr; 47238104Sdes 48238104Sdes input_file = fopen(filename, "r"); 49238104Sdes if (!input_file) { 50246854Sdes if (! silently) { 51246854Sdes fprintf(stderr, "Error opening %s: %s\n", 52246854Sdes filename, strerror(errno)); 53246854Sdes } 54238104Sdes return LDNS_STATUS_ERR; 55238104Sdes } 56238104Sdes while (line_len >= 0) { 57238104Sdes line_len = (int) read_line(input_file, line, sizeof(line)); 58238104Sdes line_nr++; 59238104Sdes if (line_len > 0 && line[0] != ';') { 60238104Sdes status = ldns_rr_new_frm_str(&rr, line, 0, NULL, NULL); 61238104Sdes if (status != LDNS_STATUS_OK) { 62246854Sdes if (! silently) { 63246854Sdes fprintf(stderr, 64246854Sdes "Error parsing DNSKEY RR " 65246854Sdes "in line %d: %s\n", line_nr, 66246854Sdes ldns_get_errorstr_by_id(status) 67246854Sdes ); 68246854Sdes } 69238104Sdes } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY || 70238104Sdes ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) { 71238104Sdes ldns_rr_list_push_rr(key_list, rr); 72238104Sdes key_count++; 73238104Sdes } else { 74238104Sdes ldns_rr_free(rr); 75238104Sdes } 76238104Sdes } 77238104Sdes } 78246854Sdes fclose(input_file); 79238104Sdes if (key_count > 0) { 80238104Sdes return LDNS_STATUS_OK; 81238104Sdes } else { 82238104Sdes /*fprintf(stderr, "No keys read\n");*/ 83238104Sdes return LDNS_STATUS_ERR; 84238104Sdes } 85238104Sdes} 86238104Sdes 87238104Sdesldns_rdf * 88238104Sdesldns_rdf_new_addr_frm_str(char *str) 89238104Sdes{ 90238104Sdes ldns_rdf *a; 91238104Sdes 92238104Sdes a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str); 93238104Sdes if (!a) { 94238104Sdes /* maybe ip6 */ 95238104Sdes a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str); 96238104Sdes if (!a) { 97238104Sdes return NULL; 98238104Sdes } 99238104Sdes } 100238104Sdes return a; 101238104Sdes} 102238104Sdes 103238104Sdesstatic inline void 104238104Sdeslocal_print_ds(FILE* out, const char* pre, ldns_rr* ds) 105238104Sdes{ 106238104Sdes if (out && ds) { 107238104Sdes fprintf(out, "%s", pre); 108238104Sdes ldns_rr_print(out, ds); 109238104Sdes ldns_rr_free(ds); 110238104Sdes } 111238104Sdes} 112238104Sdes 113238104Sdes/* 114238104Sdes * For all keys in a packet print the DS 115238104Sdes */ 116238104Sdesvoid 117238104Sdesprint_ds_of_keys(ldns_pkt *p) 118238104Sdes{ 119238104Sdes ldns_rr_list *keys; 120238104Sdes uint16_t i; 121238104Sdes ldns_rr *ds; 122238104Sdes 123238104Sdes /* TODO fix the section stuff, here or in ldns */ 124238104Sdes keys = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_DNSKEY, 125238104Sdes LDNS_SECTION_ANSWER); 126238104Sdes 127238104Sdes /* this also returns the question section rr, which does not 128238104Sdes * have any data.... and this inturn crashes everything */ 129238104Sdes 130238104Sdes if (keys) { 131238104Sdes for (i = 0; i < ldns_rr_list_rr_count(keys); i++) { 132238104Sdes fprintf(stdout, ";\n; equivalent DS records for key %u:\n", 133238104Sdes (unsigned int)ldns_calc_keytag(ldns_rr_list_rr(keys, i))); 134238104Sdes 135238104Sdes ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA1); 136238104Sdes local_print_ds(stdout, "; sha1: ", ds); 137238104Sdes ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA256); 138238104Sdes local_print_ds(stdout, "; sha256: ", ds); 139238104Sdes } 140246854Sdes ldns_rr_list_deep_free(keys); 141238104Sdes } 142238104Sdes} 143238104Sdes 144238104Sdesstatic void 145238104Sdesprint_class_type(FILE *fp, ldns_rr *r) 146238104Sdes{ 147238104Sdes ldns_lookup_table *lt; 148238104Sdes lt = ldns_lookup_by_id(ldns_rr_classes, ldns_rr_get_class(r)); 149238104Sdes if (lt) { 150238104Sdes fprintf(fp, " %s", lt->name); 151238104Sdes } else { 152238104Sdes fprintf(fp, " CLASS%d", ldns_rr_get_class(r)); 153238104Sdes } 154238104Sdes /* okay not THE way - but the quickest */ 155238104Sdes switch (ldns_rr_get_type(r)) { 156238104Sdes case LDNS_RR_TYPE_RRSIG: 157238104Sdes fprintf(fp, " RRSIG "); 158238104Sdes break; 159238104Sdes case LDNS_RR_TYPE_DNSKEY: 160238104Sdes fprintf(fp, " DNSKEY "); 161238104Sdes break; 162238104Sdes case LDNS_RR_TYPE_DS: 163238104Sdes fprintf(fp, " DS "); 164238104Sdes break; 165238104Sdes default: 166238104Sdes break; 167238104Sdes } 168238104Sdes} 169238104Sdes 170238104Sdes 171238104Sdesvoid 172238104Sdesprint_ds_abbr(FILE *fp, ldns_rr *ds) 173238104Sdes{ 174238104Sdes if (!ds || (ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS)) { 175238104Sdes return; 176238104Sdes } 177238104Sdes 178238104Sdes ldns_rdf_print(fp, ldns_rr_owner(ds)); 179238104Sdes fprintf(fp, " %d", (int)ldns_rr_ttl(ds)); 180238104Sdes print_class_type(fp, ds); 181238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(ds, 0)); fprintf(fp, " "); 182238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(ds, 1)); fprintf(fp, " "); 183238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(ds, 2)); fprintf(fp, " "); 184238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(ds, 3)); fprintf(fp, " "); 185238104Sdes} 186238104Sdes 187238104Sdes/* print some of the elements of a signature */ 188238104Sdesvoid 189238104Sdesprint_rrsig_abbr(FILE *fp, ldns_rr *sig) { 190238104Sdes if (!sig || (ldns_rr_get_type(sig) != LDNS_RR_TYPE_RRSIG)) { 191238104Sdes return; 192238104Sdes } 193238104Sdes 194238104Sdes ldns_rdf_print(fp, ldns_rr_owner(sig)); 195238104Sdes fprintf(fp, " %d", (int)ldns_rr_ttl(sig)); 196238104Sdes print_class_type(fp, sig); 197238104Sdes 198238104Sdes /* print a number of rdf's */ 199238104Sdes /* typecovered */ 200238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 0)); fprintf(fp, " "); 201238104Sdes /* algo */ 202238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 1)); fprintf(fp, " "); 203238104Sdes /* labels */ 204238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 2)); fprintf(fp, " (\n\t\t\t"); 205238104Sdes /* expir */ 206238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 4)); fprintf(fp, " "); 207238104Sdes /* incep */ 208238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 5)); fprintf(fp, " "); 209238104Sdes /* key-id */ 210238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 6)); fprintf(fp, " "); 211238104Sdes /* key owner */ 212238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(sig, 7)); fprintf(fp, ")"); 213238104Sdes} 214238104Sdes 215238104Sdesvoid 216238104Sdesprint_dnskey_abbr(FILE *fp, ldns_rr *key) 217238104Sdes{ 218238104Sdes if (!key || (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY)) { 219238104Sdes return; 220238104Sdes } 221238104Sdes 222238104Sdes ldns_rdf_print(fp, ldns_rr_owner(key)); 223238104Sdes fprintf(fp, " %d", (int)ldns_rr_ttl(key)); 224238104Sdes print_class_type(fp, key); 225238104Sdes 226238104Sdes /* print a number of rdf's */ 227238104Sdes /* flags */ 228238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(key, 0)); fprintf(fp, " "); 229238104Sdes /* proto */ 230238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(key, 1)); fprintf(fp, " "); 231238104Sdes /* algo */ 232238104Sdes ldns_rdf_print(fp, ldns_rr_rdf(key, 2)); 233238104Sdes 234238104Sdes if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 256) { 235238104Sdes fprintf(fp, " ;{id = %u (zsk), size = %db}", (unsigned int)ldns_calc_keytag(key), 236238104Sdes (int)ldns_rr_dnskey_key_size(key)); 237238104Sdes return; 238238104Sdes } 239238104Sdes if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 257) { 240238104Sdes fprintf(fp, " ;{id = %u (ksk), size = %db}", (unsigned int)ldns_calc_keytag(key), 241238104Sdes (int)ldns_rr_dnskey_key_size(key)); 242238104Sdes return; 243238104Sdes } 244238104Sdes fprintf(fp, " ;{id = %u, size = %db}", (unsigned int)ldns_calc_keytag(key), 245238104Sdes (int)ldns_rr_dnskey_key_size(key)); 246238104Sdes} 247238104Sdes 248238104Sdesvoid 249238104Sdesprint_rr_list_abbr(FILE *fp, ldns_rr_list *rrlist, const char *usr) 250238104Sdes{ 251238104Sdes size_t i; 252238104Sdes ldns_rr_type tp; 253238104Sdes 254238104Sdes for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) { 255238104Sdes tp = ldns_rr_get_type(ldns_rr_list_rr(rrlist, i)); 256238104Sdes if (i == 0 && tp != LDNS_RR_TYPE_RRSIG) { 257238104Sdes if (usr) { 258238104Sdes fprintf(fp, "%s ", usr); 259238104Sdes } 260238104Sdes } 261238104Sdes switch(tp) { 262238104Sdes case LDNS_RR_TYPE_DNSKEY: 263238104Sdes print_dnskey_abbr(fp, ldns_rr_list_rr(rrlist, i)); 264238104Sdes break; 265238104Sdes case LDNS_RR_TYPE_RRSIG: 266238104Sdes print_rrsig_abbr(fp, ldns_rr_list_rr(rrlist, i)); 267238104Sdes break; 268238104Sdes case LDNS_RR_TYPE_DS: 269238104Sdes print_ds_abbr(fp, ldns_rr_list_rr(rrlist, i)); 270238104Sdes break; 271238104Sdes default: 272238104Sdes /* not handled */ 273238104Sdes break; 274238104Sdes } 275238104Sdes fputs("\n", fp); 276238104Sdes } 277238104Sdes} 278238104Sdes 279238104Sdesvoid * 280238104Sdesxmalloc(size_t s) 281238104Sdes{ 282238104Sdes void *p; 283238104Sdes 284238104Sdes p = malloc(s); 285238104Sdes if (!p) { 286238104Sdes printf("Mem failure\n"); 287238104Sdes exit(EXIT_FAILURE); 288238104Sdes } 289238104Sdes return p; 290238104Sdes} 291238104Sdes 292238104Sdesvoid * 293238104Sdesxrealloc(void *p, size_t size) 294238104Sdes{ 295238104Sdes void *q; 296238104Sdes 297238104Sdes q = realloc(p, size); 298238104Sdes if (!q) { 299238104Sdes printf("Mem failure\n"); 300238104Sdes exit(EXIT_FAILURE); 301238104Sdes } 302238104Sdes return q; 303238104Sdes} 304238104Sdes 305238104Sdesvoid 306238104Sdesxfree(void *p) 307238104Sdes{ 308238104Sdes if (p) { 309238104Sdes free(p); 310238104Sdes } 311238104Sdes} 312