Initial vendor import of ldns-1.6.4 into contrib.
[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 /*
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 }