00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "config.h"
00010 #include <unistd.h>
00011 #include <stdlib.h>
00012
00013 #include <ldns/ldns.h>
00014 #include <ldns/host2str.h>
00015
00016 #include <errno.h>
00017
00018 void print_usage(const char* progname)
00019 {
00020 printf("Usage: %s [OPTIONS] <zonefile>\n", progname);
00021 printf("\tReads the zonefile and prints it.\n");
00022 printf("\tThe RR count of the zone is printed to stderr.\n");
00023 printf("\t-b include Bubble Babble encoding of DS's.\n");
00024 printf("\t-0 zeroize timestamps and signature in RRSIG records.\n");
00025 printf("\t-c canonicalize all rrs in the zone.\n");
00026 printf("\t-d only show DNSSEC data from the zone\n");
00027 printf("\t-h show this text\n");
00028 printf("\t-n do not print the SOA record\n");
00029 printf("\t-p prepend SOA serial with spaces so"
00030 " it takes exactly ten characters.\n");
00031 printf("\t-s strip DNSSEC data from the zone\n");
00032 printf("\t-S [[+|-]<number> | YYYYMMDDxx | "
00033 " unixtime ]\n"
00034 "\t\tSet serial number to <number> or,"
00035 " when preceded by a sign,\n"
00036 "\t\toffset the existing number with "
00037 "<number>. With YYYYMMDDxx\n"
00038 "\t\tthe serial is formatted as a datecounter"
00039 ", and with unixtime as\n"
00040 "\t\tthe number of seconds since 1-1-1970."
00041 " However, on serial\n"
00042 "\t\tnumber decrease, +1 is used in stead"
00043 ". (implies -s)\n");
00044 printf("\t-u <rr type>\n");
00045 printf("\t\tMark <rr type> for printing in unknown type format.\n");
00046 printf("\t\tThis option may be given multiple times.\n");
00047 printf("\t\t-u is not meant to be used together with -U.\n");
00048 printf("\t-U <rr type>\n");
00049 printf("\t\tMark <rr type> for not printing in unknown type format.\n");
00050 printf("\t\tThis option may be given multiple times.\n");
00051 printf(
00052 "\t\tThe first occurrence of the -U option marks all RR types for"
00053 "\n\t\tprinting in unknown type format except for the given <rr type>."
00054 "\n\t\tSubsequent -U options will clear the mark for those <rr type>s"
00055 "\n\t\ttoo, so that only the given <rr type>s will be printed in the"
00056 "\n\t\tpresentation format specific for those <rr type>s.\n");
00057 printf("\t\t-U is not meant to be used together with -u.\n");
00058 printf("\t-v shows the version and exits\n");
00059 printf("\t-z sort the zone (implies -c).\n");
00060 printf("\nif no file is given standard input is read\n");
00061 exit(EXIT_SUCCESS);
00062 }
00063
00064 int
00065 main(int argc, char **argv)
00066 {
00067 char *filename;
00068 FILE *fp;
00069 ldns_zone *z;
00070 int line_nr = 0;
00071 int c;
00072 bool canonicalize = false;
00073 bool sort = false;
00074 bool strip = false;
00075 bool only_dnssec = false;
00076 bool print_soa = true;
00077 ldns_status s;
00078 size_t i;
00079 ldns_rr_list *stripped_list;
00080 ldns_rr *cur_rr;
00081 ldns_rr_type cur_rr_type;
00082 ldns_output_format_storage fmt_storage;
00083 ldns_output_format* fmt = ldns_output_format_init(&fmt_storage);
00084
00085 ldns_soa_serial_increment_func_t soa_serial_increment_func = NULL;
00086 int soa_serial_increment_func_data = 0;
00087
00088 while ((c = getopt(argc, argv, "0bcdhnpsu:U:vzS:")) != -1) {
00089 switch(c) {
00090 case 'b':
00091 fmt->flags |=
00092 ( LDNS_COMMENT_BUBBLEBABBLE |
00093 LDNS_COMMENT_FLAGS );
00094 break;
00095 case '0':
00096 fmt->flags |= LDNS_FMT_ZEROIZE_RRSIGS;
00097 break;
00098 case 'c':
00099 canonicalize = true;
00100 break;
00101 case 'd':
00102 only_dnssec = true;
00103 if (strip) {
00104 fprintf(stderr, "Warning: stripping both DNSSEC and non-DNSSEC records. Output will be sparse.\n");
00105 }
00106 break;
00107 case 'h':
00108 print_usage("ldns-read-zone");
00109 break;
00110 case 'n':
00111 print_soa = false;
00112 break;
00113 case 'p':
00114 fmt->flags |= LDNS_FMT_PAD_SOA_SERIAL;
00115 break;
00116 case 's':
00117 strip = true;
00118 if (only_dnssec) {
00119 fprintf(stderr, "Warning: stripping both DNSSEC and non-DNSSEC records. Output will be sparse.\n");
00120 }
00121 break;
00122 case 'u':
00123 s = ldns_output_format_set_type(fmt,
00124 ldns_get_rr_type_by_name(optarg));
00125 if (s != LDNS_STATUS_OK) {
00126 fprintf( stderr
00127 , "Cannot set rr type %s "
00128 "in output format to "
00129 "print as unknown type: %s\n"
00130 , ldns_rr_descript(
00131 ldns_get_rr_type_by_name(optarg)
00132 )->_name
00133 , ldns_get_errorstr_by_id(s)
00134 );
00135 exit(EXIT_FAILURE);
00136 }
00137 break;
00138 case 'U':
00139 s = ldns_output_format_clear_type(fmt,
00140 ldns_get_rr_type_by_name(optarg));
00141 if (s != LDNS_STATUS_OK) {
00142 fprintf( stderr
00143 , "Cannot set rr type %s "
00144 "in output format to not "
00145 "print as unknown type: %s\n"
00146 , ldns_rr_descript(
00147 ldns_get_rr_type_by_name(optarg)
00148 )->_name
00149 , ldns_get_errorstr_by_id(s)
00150 );
00151 exit(EXIT_FAILURE);
00152 }
00153 break;
00154 case 'v':
00155 printf("read zone version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
00156 exit(EXIT_SUCCESS);
00157 break;
00158 case 'z':
00159 canonicalize = true;
00160 sort = true;
00161 break;
00162 case 'S':
00163 strip = true;
00164 if (*optarg == '+' || *optarg == '-') {
00165 soa_serial_increment_func_data =
00166 atoi(optarg);
00167 soa_serial_increment_func =
00168 ldns_soa_serial_increment_by;
00169 } else if (! strtok(optarg, "0123456789")) {
00170 soa_serial_increment_func_data =
00171 atoi(optarg);
00172 soa_serial_increment_func =
00173 ldns_soa_serial_identity;
00174 } else if (!strcasecmp(optarg, "YYYYMMDDxx")){
00175 soa_serial_increment_func =
00176 ldns_soa_serial_datecounter;
00177 } else if (!strcasecmp(optarg, "unixtime")){
00178 soa_serial_increment_func =
00179 ldns_soa_serial_unixtime;
00180 } else {
00181 fprintf(stderr, "-S expects a number "
00182 "optionally preceded by a "
00183 "+ or - sign to indicate an "
00184 "offset, or the text YYYYMM"
00185 "DDxx or unixtime\n");
00186 exit(EXIT_FAILURE);
00187 }
00188 break;
00189 }
00190 }
00191
00192 argc -= optind;
00193 argv += optind;
00194
00195 if (argc == 0) {
00196 fp = stdin;
00197 } else {
00198 filename = argv[0];
00199
00200 fp = fopen(filename, "r");
00201 if (!fp) {
00202 fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
00203 exit(EXIT_FAILURE);
00204 }
00205 }
00206
00207 s = ldns_zone_new_frm_fp_l(&z, fp, NULL, 0, LDNS_RR_CLASS_IN, &line_nr);
00208
00209 fclose(fp);
00210 if (s != LDNS_STATUS_OK) {
00211 fprintf(stderr, "%s at %d\n",
00212 ldns_get_errorstr_by_id(s),
00213 line_nr);
00214 exit(EXIT_FAILURE);
00215 }
00216
00217
00218 if (strip) {
00219 stripped_list = ldns_rr_list_new();
00220 while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(z)))) {
00221 cur_rr_type = ldns_rr_get_type(cur_rr);
00222 if (cur_rr_type == LDNS_RR_TYPE_RRSIG ||
00223 cur_rr_type == LDNS_RR_TYPE_NSEC ||
00224 cur_rr_type == LDNS_RR_TYPE_NSEC3 ||
00225 cur_rr_type == LDNS_RR_TYPE_NSEC3PARAM
00226 ) {
00227 ldns_rr_free(cur_rr);
00228 } else {
00229 ldns_rr_list_push_rr(stripped_list, cur_rr);
00230 }
00231 }
00232 ldns_rr_list_free(ldns_zone_rrs(z));
00233 ldns_zone_set_rrs(z, stripped_list);
00234 }
00235 if (only_dnssec) {
00236 stripped_list = ldns_rr_list_new();
00237 while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(z)))) {
00238 cur_rr_type = ldns_rr_get_type(cur_rr);
00239 if (cur_rr_type == LDNS_RR_TYPE_RRSIG ||
00240 cur_rr_type == LDNS_RR_TYPE_NSEC ||
00241 cur_rr_type == LDNS_RR_TYPE_NSEC3 ||
00242 cur_rr_type == LDNS_RR_TYPE_NSEC3PARAM
00243 ) {
00244 ldns_rr_list_push_rr(stripped_list, cur_rr);
00245 } else {
00246 ldns_rr_free(cur_rr);
00247 }
00248 }
00249 ldns_rr_list_free(ldns_zone_rrs(z));
00250 ldns_zone_set_rrs(z, stripped_list);
00251 }
00252
00253 if (canonicalize) {
00254 ldns_rr2canonical(ldns_zone_soa(z));
00255 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z)); i++) {
00256 ldns_rr2canonical(ldns_rr_list_rr(ldns_zone_rrs(z), i));
00257 }
00258 }
00259 if (sort) {
00260 ldns_zone_sort(z);
00261 }
00262
00263 if (print_soa && ldns_zone_soa(z)) {
00264 if (soa_serial_increment_func) {
00265 ldns_rr_soa_increment_func_int(
00266 ldns_zone_soa(z)
00267 , soa_serial_increment_func
00268 , soa_serial_increment_func_data
00269 );
00270 }
00271 ldns_rr_print_fmt(stdout, fmt, ldns_zone_soa(z));
00272 }
00273 ldns_rr_list_print_fmt(stdout, fmt, ldns_zone_rrs(z));
00274
00275 ldns_zone_deep_free(z);
00276
00277 exit(EXIT_SUCCESS);
00278 }