ldns/drill: Update vendor branch to 1.6.9
[dragonfly.git] / contrib / ldns / drill / drill_util.c
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 static inline void
99 local_print_ds(FILE* out, const char* pre, ldns_rr* ds)
100 {
101         if (out && ds) {
102                 fprintf(out, "%s", pre);
103                 ldns_rr_print(out, ds);
104                 ldns_rr_free(ds);
105         }
106 }
107
108 /*
109  * For all keys in a packet print the DS 
110  */
111 void
112 print_ds_of_keys(ldns_pkt *p)
113 {
114         ldns_rr_list *keys;
115         uint16_t i;
116         ldns_rr *ds;
117
118         /* TODO fix the section stuff, here or in ldns */
119         keys = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_DNSKEY,
120                         LDNS_SECTION_ANSWER);
121
122         /* this also returns the question section rr, which does not
123          * have any data.... and this inturn crashes everything */
124
125         if (keys) {
126                 for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
127                         fprintf(stdout, ";\n; equivalent DS records for key %u:\n",
128                                 (unsigned int)ldns_calc_keytag(ldns_rr_list_rr(keys, i)));
129
130                         ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA1);
131                         local_print_ds(stdout, "; sha1: ", ds);
132                         ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA256);
133                         local_print_ds(stdout, "; sha256: ", ds);
134                 }
135         }
136 }
137
138 static void
139 print_class_type(FILE *fp, ldns_rr *r)
140 {
141         ldns_lookup_table *lt;
142         lt = ldns_lookup_by_id(ldns_rr_classes, ldns_rr_get_class(r));
143         if (lt) {
144                 fprintf(fp, " %s", lt->name);
145         } else {
146                 fprintf(fp, " CLASS%d", ldns_rr_get_class(r));
147         }
148         /* okay not THE way - but the quickest */
149         switch (ldns_rr_get_type(r)) {
150                 case LDNS_RR_TYPE_RRSIG:
151                         fprintf(fp, " RRSIG ");
152                         break;
153                 case LDNS_RR_TYPE_DNSKEY:
154                         fprintf(fp, " DNSKEY ");
155                         break;
156                 case LDNS_RR_TYPE_DS:
157                         fprintf(fp, " DS ");
158                         break;
159                 default:
160                         break;
161         }
162 }
163
164
165 void
166 print_ds_abbr(FILE *fp, ldns_rr *ds)
167 {
168         if (!ds || (ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS)) {
169                 return;
170         }
171
172         ldns_rdf_print(fp, ldns_rr_owner(ds));
173         fprintf(fp, " %d", (int)ldns_rr_ttl(ds));
174         print_class_type(fp, ds);
175         ldns_rdf_print(fp, ldns_rr_rdf(ds, 0)); fprintf(fp, " ");
176         ldns_rdf_print(fp, ldns_rr_rdf(ds, 1)); fprintf(fp, " ");
177         ldns_rdf_print(fp, ldns_rr_rdf(ds, 2)); fprintf(fp, " ");
178         ldns_rdf_print(fp, ldns_rr_rdf(ds, 3)); fprintf(fp, " ");
179 }
180
181 /* print some of the elements of a signature */
182 void
183 print_rrsig_abbr(FILE *fp, ldns_rr *sig) {
184         if (!sig || (ldns_rr_get_type(sig) != LDNS_RR_TYPE_RRSIG)) {
185                 return;
186         }
187
188         ldns_rdf_print(fp, ldns_rr_owner(sig));
189         fprintf(fp, " %d", (int)ldns_rr_ttl(sig));
190         print_class_type(fp, sig);
191
192         /* print a number of rdf's */
193         /* typecovered */
194         ldns_rdf_print(fp, ldns_rr_rdf(sig, 0)); fprintf(fp, " ");
195         /* algo */
196         ldns_rdf_print(fp, ldns_rr_rdf(sig, 1)); fprintf(fp, " ");
197         /* labels */
198         ldns_rdf_print(fp, ldns_rr_rdf(sig, 2)); fprintf(fp, " (\n\t\t\t");
199         /* expir */
200         ldns_rdf_print(fp, ldns_rr_rdf(sig, 4)); fprintf(fp, " ");
201         /* incep */     
202         ldns_rdf_print(fp, ldns_rr_rdf(sig, 5)); fprintf(fp, " ");
203         /* key-id */    
204         ldns_rdf_print(fp, ldns_rr_rdf(sig, 6)); fprintf(fp, " ");
205         /* key owner */
206         ldns_rdf_print(fp, ldns_rr_rdf(sig, 7)); fprintf(fp, ")");
207 }
208
209 void
210 print_dnskey_abbr(FILE *fp, ldns_rr *key)
211 {
212         if (!key || (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY)) {
213                 return;
214         }
215
216         ldns_rdf_print(fp, ldns_rr_owner(key));
217         fprintf(fp, " %d", (int)ldns_rr_ttl(key));
218         print_class_type(fp, key);
219
220         /* print a number of rdf's */
221         /* flags */
222         ldns_rdf_print(fp, ldns_rr_rdf(key, 0)); fprintf(fp, " ");
223         /* proto */
224         ldns_rdf_print(fp, ldns_rr_rdf(key, 1)); fprintf(fp, " ");
225         /* algo */
226         ldns_rdf_print(fp, ldns_rr_rdf(key, 2));
227
228         if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 256) {
229                 fprintf(fp, " ;{id = %u (zsk), size = %db}", (unsigned int)ldns_calc_keytag(key),
230                                 (int)ldns_rr_dnskey_key_size(key));
231                 return;
232         }
233         if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 257) {
234                 fprintf(fp, " ;{id = %u (ksk), size = %db}", (unsigned int)ldns_calc_keytag(key),
235                                 (int)ldns_rr_dnskey_key_size(key));
236                 return;
237         }
238         fprintf(fp, " ;{id = %u, size = %db}", (unsigned int)ldns_calc_keytag(key),
239                         (int)ldns_rr_dnskey_key_size(key));
240 }
241
242 void
243 print_rr_list_abbr(FILE *fp, ldns_rr_list *rrlist, char *usr) 
244 {
245         size_t i;
246         ldns_rr_type tp;
247
248         for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
249                 tp = ldns_rr_get_type(ldns_rr_list_rr(rrlist, i));
250                 if (i == 0 && tp != LDNS_RR_TYPE_RRSIG) {
251                         if (usr) {
252                                 fprintf(fp, "%s ", usr);
253                         }
254                 }
255                 switch(tp) {
256                 case LDNS_RR_TYPE_DNSKEY:
257                         print_dnskey_abbr(fp, ldns_rr_list_rr(rrlist, i));
258                         break;
259                 case LDNS_RR_TYPE_RRSIG:
260                         print_rrsig_abbr(fp, ldns_rr_list_rr(rrlist, i));
261                         break;
262                 case LDNS_RR_TYPE_DS:
263                         print_ds_abbr(fp, ldns_rr_list_rr(rrlist, i));
264                         break;
265                 default:
266                         /* not handled */
267                         break;
268                 }
269                 fputs("\n", fp);
270         }
271 }
272
273 void *
274 xmalloc(size_t s)
275 {
276         void *p;
277
278         p = malloc(s);
279         if (!p) {
280                 printf("Mem failure\n");
281                 exit(EXIT_FAILURE);
282         }
283         return p;
284 }
285
286 void *
287 xrealloc(void *p, size_t size)
288 {
289         void *q;
290
291         q = realloc(p, size);
292         if (!q) {
293                 printf("Mem failure\n");
294                 exit(EXIT_FAILURE);
295         }
296         return q;
297 }
298
299 void
300 xfree(void *p)
301 {
302         if (p) {
303                 free(p);
304         }
305 }