fort_SOURCES += config/log_conf.h config/log_conf.c
fort_SOURCES += config/mode.c config/mode.h
fort_SOURCES += config/incidences.h config/incidences.c
+fort_SOURCES += config/output_format.h config/output_format.c
fort_SOURCES += config/rrdp_conf.h config/rrdp_conf.c
fort_SOURCES += config/rsync_strategy.h config/rsync_strategy.c
fort_SOURCES += config/str.c config/str.h
char *roa;
/** File where the validated BGPsec certs will be stored */
char *bgpsec;
- /** File where the validated ROAs will be stored in JSON format */
- char *roa_json;
+ /** Format for the output */
+ enum output_format format;
} output;
/* ASN1 decoder max stack size allowed */
.name = "output.roa",
.type = >_string,
.offset = offsetof(struct rpki_config, output.roa),
- .doc = "File where ROAs will be stored in CSV format, use '-' to print at console",
+ .doc = "File where ROAs will be stored, use '-' to print at console",
.arg_doc = "<file>",
}, {
.id = 6001,
.name = "output.bgpsec",
.type = >_string,
.offset = offsetof(struct rpki_config, output.bgpsec),
- .doc = "File where BGPsec Router Keys will be stored in CSV format, use '-' to print at console",
+ .doc = "File where BGPsec Router Keys will be stored, use '-' to print at console",
.arg_doc = "<file>",
}, {
- .id = 6002,
- .name = "output.roa.json",
- .type = >_string,
- .offset = offsetof(struct rpki_config, output.roa_json),
- .doc = "File where ROAs will be stored in JSON format, use '-' to print at console",
- .arg_doc = "<file>",
+ .id = 6002,
+ .name = "output.format",
+ .type = >_output_format,
+ .offset = offsetof(struct rpki_config, output.format),
+ .doc = "Format to print ROAs and BGPsec Router Keys",
},
{
}
rpki_config.output.roa = NULL;
- rpki_config.output.roa_json = NULL;
rpki_config.output.bgpsec = NULL;
+ rpki_config.output.format = OFM_CSV;
rpki_config.asn1_decode_max_stack = 4096; /* 4kB */
rpki_config.stale_repository_period = 43200; /* 12 hours */
}
char const *
-config_get_output_roa_json(void)
+config_get_output_bgpsec(void)
{
- return rpki_config.output.roa_json;
+ return rpki_config.output.bgpsec;
}
-char const *
-config_get_output_bgpsec(void)
+enum output_format
+config_get_output_format(void)
{
- return rpki_config.output.bgpsec;
+ return rpki_config.output.format;
}
unsigned int
#include "config/filename_format.h"
#include "config/log_conf.h"
#include "config/mode.h"
+#include "config/output_format.h"
#include "config/rsync_strategy.h"
#include "config/string_array.h"
#include "config/types.h"
unsigned int config_get_http_retry_count(void);
unsigned int config_get_http_retry_interval(void);
char const *config_get_output_roa(void);
-char const *config_get_output_roa_json(void);
char const *config_get_output_bgpsec(void);
+enum output_format config_get_output_format(void);
unsigned int config_get_asn1_decode_max_stack(void);
unsigned int config_get_stale_repository_period(void);
--- /dev/null
+#include "config/output_format.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "log.h"
+#include "config/str.h"
+
+#define OFM_VALUE_CSV "csv"
+#define OFM_VALUE_JSON "json"
+
+#define DEREFERENCE(void_value) (*((enum output_format *) void_value))
+
+static void
+print_output_format(struct option_field const *field, void *value)
+{
+ char const *str = "<unknown>";
+
+ switch (DEREFERENCE(value)) {
+ case OFM_CSV:
+ str = OFM_VALUE_CSV;
+ break;
+ case OFM_JSON:
+ str = OFM_VALUE_JSON;
+ break;
+ }
+
+ pr_op_info("%s: %s", field->name, str);
+}
+
+static int
+parse_argv_output_format(struct option_field const *field, char const *str,
+ void *result)
+{
+ if (strcmp(str, OFM_VALUE_CSV) == 0)
+ DEREFERENCE(result) = OFM_CSV;
+ else if (strcmp(str, OFM_VALUE_JSON) == 0)
+ DEREFERENCE(result) = OFM_JSON;
+ else
+ return pr_op_err("Unknown output format %s: '%s'",
+ field->name, str);
+
+ return 0;
+}
+
+static int
+parse_json_output_format(struct option_field const *opt, json_t *json,
+ void *result)
+{
+ char const *string;
+ int error;
+
+ error = parse_json_string(json, opt->name, &string);
+ return error ? error : parse_argv_output_format(opt, string, result);
+}
+
+const struct global_type gt_output_format = {
+ .has_arg = required_argument,
+ .size = sizeof(enum output_format),
+ .print = print_output_format,
+ .parse.argv = parse_argv_output_format,
+ .parse.json = parse_json_output_format,
+ .arg_doc = OFM_VALUE_CSV "|" OFM_VALUE_JSON,
+};
--- /dev/null
+#ifndef SRC_CONFIG_OUTPUT_FORMAT_H_
+#define SRC_CONFIG_OUTPUT_FORMAT_H_
+
+#include "config/types.h"
+
+enum output_format {
+ /* CSV format */
+ OFM_CSV,
+ /* JSON format */
+ OFM_JSON,
+};
+
+extern const struct global_type gt_output_format;
+
+#endif /* SRC_CONFIG_OUTPUT_FORMAT_H_ */
static char addr_buf[INET6_ADDRSTRLEN];
+typedef struct json_out {
+ FILE *file;
+ bool first;
+} JSON_OUT;
+
static int
load_output_file(char const *output, FILE **result, bool *fopen)
{
}
static int
-print_roa(struct vrp const *vrp, void *arg)
+print_roa_csv(struct vrp const *vrp, void *arg)
{
FILE *out = arg;
return 0;
}
-typedef struct json_out { FILE *file; int first; } JSON_OUT;
-
static int
print_roa_json(struct vrp const *vrp, void *arg)
{
JSON_OUT *json_out = arg;
- FILE *out = json_out->file;
+ FILE *out;
+ out = json_out->file;
if (!json_out->first)
fprintf(out, ",");
-
switch (vrp->addr_fam) {
case AF_INET:
- fprintf(out, "\n { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }", vrp->asn,
- addr2str4(&vrp->prefix.v4, addr_buf), vrp->prefix_length,
- vrp->max_prefix_length);
+ fprintf(out,
+ "\n { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }",
+ vrp->asn,
+ addr2str4(&vrp->prefix.v4, addr_buf),
+ vrp->prefix_length,
+ vrp->max_prefix_length);
break;
case AF_INET6:
- fprintf(out, "\n { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }", vrp->asn,
- addr2str6(&vrp->prefix.v6, addr_buf), vrp->prefix_length,
- vrp->max_prefix_length);
+ fprintf(out,
+ "\n { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }",
+ vrp->asn,
+ addr2str6(&vrp->prefix.v6, addr_buf),
+ vrp->prefix_length,
+ vrp->max_prefix_length);
break;
default:
pr_crit("Unknown family type");
}
- json_out->first = 0;
+ json_out->first = false;
return 0;
}
/* Print as base64url strings without trailing pad */
static int
-print_router_key(struct router_key const *key, void *arg)
+print_router_key_csv(struct router_key const *key, void *arg)
{
FILE *out = arg;
char *buf1, *buf2;
return error;
}
+/* Print as base64url strings without trailing pad */
+static int
+print_router_key_json(struct router_key const *key, void *arg)
+{
+ JSON_OUT *json_out = arg;
+ FILE *out;
+ char *buf1, *buf2;
+ int error;
+
+ error = base64url_encode(key->ski, RK_SKI_LEN, &buf1);
+ if (error)
+ return error;
+
+ error = base64url_encode(key->spk, RK_SPKI_LEN, &buf2);
+ if (error)
+ goto free1;
+
+ out = json_out->file;
+ if (!json_out->first)
+ fprintf(out, ",");
+
+ fprintf(out,
+ "\n { \"asn\" : \"AS%u\", \"ski\" : \"%s\", \"spki\" : \"%s\" }",
+ key->as,
+ buf1,
+ buf2);
+
+ free(buf2);
+free1:
+ free(buf1);
+ json_out->first = false;
+ return error;
+}
+
static int
open_file(char const *loc, FILE **out, bool *fopen)
{
print_roas(struct db_table *db)
{
FILE *out;
+ JSON_OUT json_out;
bool fopen;
int error;
if (error)
return;
- fprintf(out, "ASN,Prefix,Max prefix length\n");
- error = db_table_foreach_roa(db, print_roa, out);
- if (fopen)
- file_close(out);
- if (error)
- pr_op_err("Error printing ROAs");
-}
-
-static void
-print_roas_json(struct db_table *db)
-{
- FILE *out;
- bool fopen;
- int error;
-
- out = NULL;
- error = open_file(config_get_output_roa_json(), &out, &fopen);
- if (error)
- return;
+ if (config_get_output_format() == OFM_CSV) {
+ fprintf(out, "ASN,Prefix,Max prefix length\n");
+ error = db_table_foreach_roa(db, print_roa_csv, out);
+ } else {
+ json_out.file = out;
+ json_out.first = true;
- JSON_OUT json_out;
- json_out.file = out;
- json_out.first = 1;
+ fprintf(out, "{ \"roas\" : [");
+ error = db_table_foreach_roa(db, print_roa_json, &json_out);
+ fprintf(out, "\n]}\n");
+ }
- fprintf(out, "{ \"roas\" : [");
- error = db_table_foreach_roa(db, print_roa_json, &json_out);
- fprintf(out, "\n]}\n");
if (fopen)
file_close(out);
if (error)
print_router_keys(struct db_table *db)
{
FILE *out;
+ JSON_OUT json_out;
bool fopen;
int error;
if (error)
return;
- fprintf(out, "ASN,Subject Key Identifier,Subject Public Key Info\n");
- error = db_table_foreach_router_key(db, print_router_key, out);
+ if (config_get_output_format() == OFM_CSV) {
+ fprintf(out,
+ "ASN,Subject Key Identifier,Subject Public Key Info\n");
+ error = db_table_foreach_router_key(db, print_router_key_csv,
+ out);
+ } else {
+ json_out.file = out;
+ json_out.first = true;
+
+ fprintf(out, "{ \"router_keys\" : [");
+ error = db_table_foreach_router_key(db, print_router_key_json,
+ &json_out);
+ fprintf(out, "\n]}\n");
+ }
+
if (fopen)
file_close(out);
if (error)
output_print_data(struct db_table *db)
{
print_roas(db);
- print_roas_json(db);
print_router_keys(db);
}