172 lines
4.1 KiB
C
172 lines
4.1 KiB
C
|
/*
|
||
|
* read a zone that is split up with ldns-zsplit and re-create
|
||
|
* the original zone
|
||
|
*
|
||
|
* From:
|
||
|
* zone1: SOA a b c d e f
|
||
|
* zone2: SOA f g h i k l
|
||
|
*
|
||
|
* Go back to:
|
||
|
* zone: SOA a b c d e f g h i j k l
|
||
|
*
|
||
|
* This is useful in combination with ldns-zsplit
|
||
|
*
|
||
|
* See the file LICENSE for the license
|
||
|
*/
|
||
|
|
||
|
#include "config.h"
|
||
|
#include <errno.h>
|
||
|
#include <ldns/ldns.h>
|
||
|
|
||
|
#define FIRST_ZONE 0
|
||
|
#define MIDDLE_ZONE 1
|
||
|
#define LAST_ZONE 2
|
||
|
|
||
|
static void
|
||
|
usage(FILE *f, char *progname)
|
||
|
{
|
||
|
fprintf(f, "Usage: %s [OPTIONS] <zonefiles>\n", progname);
|
||
|
fprintf(f, " Concatenate signed zone snippets created with ldns-zsplit\n");
|
||
|
fprintf(f, " back together. The generate zone file is printed to stdout\n");
|
||
|
fprintf(f, " The new zone should be equal to the original zone (before splitting)\n");
|
||
|
fprintf(f, "OPTIONS:\n");
|
||
|
fprintf(f, "-o ORIGIN\tUse this as initial origin, for zones starting with @\n");
|
||
|
fprintf(f, "-v\t\tShow the version number and exit\n");
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(int argc, char **argv)
|
||
|
{
|
||
|
char *progname;
|
||
|
FILE *fp;
|
||
|
int c;
|
||
|
ldns_rdf *origin;
|
||
|
size_t i, j;
|
||
|
int where;
|
||
|
ldns_zone *z;
|
||
|
ldns_rr_list *zrr;
|
||
|
ldns_rr *current_rr;
|
||
|
ldns_rr *soa;
|
||
|
ldns_rdf *last_owner;
|
||
|
ldns_rr *last_rr;
|
||
|
ldns_rr *pop_rr;
|
||
|
|
||
|
progname = strdup(argv[0]);
|
||
|
origin = NULL;
|
||
|
|
||
|
while ((c = getopt(argc, argv, "n:o:v")) != -1) {
|
||
|
switch(c) {
|
||
|
case 'o':
|
||
|
origin = ldns_dname_new_frm_str(strdup(optarg));
|
||
|
if (!origin) {
|
||
|
fprintf(stderr, "Cannot convert the origin %s to a domainname\n", optarg);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
break;
|
||
|
case 'v':
|
||
|
printf("zone file concatenator version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
|
||
|
exit(EXIT_SUCCESS);
|
||
|
break;
|
||
|
default:
|
||
|
fprintf(stderr, "Unrecognized option\n");
|
||
|
usage(stdout, progname);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
argc -= optind;
|
||
|
argv += optind;
|
||
|
|
||
|
if (argc < 1) {
|
||
|
usage(stdout, progname);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < (size_t)argc; i++) {
|
||
|
|
||
|
if (!(fp = fopen(argv[i], "r"))) {
|
||
|
fprintf(stderr, "Error opening key file %s: %s\n", argv[i], strerror(errno));
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
if (ldns_zone_new_frm_fp(&z, fp, origin, 0, 0) != LDNS_STATUS_OK) {
|
||
|
fprintf(stderr, "Zone file %s could not be parsed correctly\n", argv[i]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
zrr = ldns_zone_rrs(z);
|
||
|
soa = ldns_zone_soa(z); /* SOA is stored seperately */
|
||
|
|
||
|
fprintf(stderr, "%s\n", argv[i]);
|
||
|
|
||
|
if (0 == i) {
|
||
|
where = FIRST_ZONE;
|
||
|
|
||
|
/* remove the last equal named RRs */
|
||
|
last_rr = ldns_rr_list_pop_rr(zrr);
|
||
|
last_owner = ldns_rr_owner(last_rr);
|
||
|
/* remove until no match */
|
||
|
do {
|
||
|
pop_rr = ldns_rr_list_pop_rr(zrr);
|
||
|
} while(ldns_rdf_compare(last_owner, ldns_rr_owner(pop_rr)) == 0) ;
|
||
|
/* we popped one to many, put it back */
|
||
|
ldns_rr_list_push_rr(zrr, pop_rr);
|
||
|
} else if ((size_t)(argc - 1) == i) {
|
||
|
where = LAST_ZONE;
|
||
|
} else {
|
||
|
where = MIDDLE_ZONE;
|
||
|
|
||
|
/* remove the last equal named RRs */
|
||
|
last_rr = ldns_rr_list_pop_rr(zrr);
|
||
|
last_owner = ldns_rr_owner(last_rr);
|
||
|
/* remove until no match */
|
||
|
do {
|
||
|
pop_rr = ldns_rr_list_pop_rr(zrr);
|
||
|
} while(ldns_rdf_compare(last_owner, ldns_rr_owner(pop_rr)) == 0) ;
|
||
|
/* we popped one to many, put it back */
|
||
|
ldns_rr_list_push_rr(zrr, pop_rr);
|
||
|
}
|
||
|
|
||
|
/* printing the RRs */
|
||
|
for (j = 0; j < ldns_rr_list_rr_count(zrr); j++) {
|
||
|
|
||
|
current_rr = ldns_rr_list_rr(zrr, j);
|
||
|
|
||
|
switch(where) {
|
||
|
case FIRST_ZONE:
|
||
|
if (soa) {
|
||
|
ldns_rr_print(stdout, soa);
|
||
|
soa = NULL;
|
||
|
}
|
||
|
break;
|
||
|
case MIDDLE_ZONE:
|
||
|
/* rm SOA */
|
||
|
/* SOA isn't printed by default */
|
||
|
|
||
|
/* rm SOA aux records
|
||
|
* this also takes care of the DNSKEYs + RRSIGS
|
||
|
*/
|
||
|
if (ldns_rdf_compare(ldns_rr_owner(current_rr),
|
||
|
ldns_rr_owner(soa)) == 0) {
|
||
|
continue;
|
||
|
}
|
||
|
break;
|
||
|
case LAST_ZONE:
|
||
|
/* rm SOA */
|
||
|
/* SOA isn't printed by default */
|
||
|
|
||
|
/* rm SOA aux records
|
||
|
* this also takes care of the DNSKEYs + RRSIGS
|
||
|
*/
|
||
|
if (ldns_rdf_compare(ldns_rr_owner(current_rr),
|
||
|
ldns_rr_owner(soa)) == 0) {
|
||
|
continue;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
ldns_rr_print(stdout, current_rr);
|
||
|
}
|
||
|
}
|
||
|
exit(EXIT_SUCCESS);
|
||
|
}
|