installer - Several improvements
[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, 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 }