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