mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-17 00:06:59 +00:00
output: add json format support
Reviewed-by: Sami Kerola <kerolasa@iki.fi> Signed-off-by: Gilles Bouthenot <gilles.bouthenot@univ-fcomte.fr>
This commit is contained in:
parent
179e2ac147
commit
a302bc6829
7 changed files with 156 additions and 5 deletions
1
THANKS
1
THANKS
|
|
@ -24,3 +24,4 @@ Robert Viou
|
|||
Enno Gröper
|
||||
Ryan Malek
|
||||
Cheer Xiao
|
||||
Gilles Bouthenot
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ are equal next one is used. The IP field is default sort key.
|
|||
\fB\-r\fR, \fB\-\-reverse\fR
|
||||
Sort results in reverse order.
|
||||
.TP
|
||||
\fB\-f\fR, \fB\-\-format\fR=\fI[thHcxX]\fR
|
||||
\fB\-f\fR, \fB\-\-format\fR=\fI[thHcxXjJ]\fR
|
||||
Output format.
|
||||
Text
|
||||
.RI ( t ).
|
||||
|
|
@ -77,7 +77,11 @@ stands for comma-separated values. Output format xml
|
|||
.RI ( x )
|
||||
is similar to the dhcpstatus Perl module output. The extended xml
|
||||
.RI ( X )
|
||||
format will print ethernet address details.
|
||||
format will print ethernet address details. The
|
||||
.RI ( j )
|
||||
will output in json format, which can be extended with
|
||||
.RI ( J )
|
||||
to include ethernet address.
|
||||
.IP
|
||||
The default format is
|
||||
.IR @OUTPUT_FORMAT@ .
|
||||
|
|
|
|||
|
|
@ -207,6 +207,12 @@ int main(int argc, char **argv)
|
|||
case 'X':
|
||||
output_analysis = output_xml;
|
||||
break;
|
||||
case 'j':
|
||||
output_analysis = output_json;
|
||||
break;
|
||||
case 'J':
|
||||
output_analysis = output_json;
|
||||
break;
|
||||
case 'c':
|
||||
output_analysis = output_csv;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ int (*output_analysis) (void);
|
|||
int output_txt(void);
|
||||
int output_html(void);
|
||||
int output_xml(void);
|
||||
int output_json(void);
|
||||
int output_csv(void);
|
||||
int output_alarming(void);
|
||||
/* Memory release, file closing etc */
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ int parse_leases(void)
|
|||
|
||||
line = xmalloc(sizeof(char) * MAXLEN);
|
||||
ipstring = xmalloc(sizeof(char) * MAXLEN);
|
||||
if (config.output_format[0] == 'X') {
|
||||
if (config.output_format[0] == 'X' || config.output_format[0] == 'J') {
|
||||
macstring = xmalloc(sizeof(char) * 18);
|
||||
macaddr = xmalloc(sizeof(struct macaddr_t));
|
||||
macaddr_p = macaddr;
|
||||
|
|
|
|||
|
|
@ -219,13 +219,16 @@ This is ISC dhcpd pools usage analyzer.\n\
|
|||
\n", program_invocation_short_name);
|
||||
fprintf(out, "\
|
||||
-c, --config=FILE path to the dhcpd.conf file\n\
|
||||
-l, --leases=FILE path to the dhcpd.leases file\n\
|
||||
-f, --format=[thHcxX] output format\n\
|
||||
-l, --leases=FILE path to the dhcpd.leases file\n");
|
||||
fprintf(out, "\
|
||||
-f, --format=[thHcxXjJ] output format\n\
|
||||
t for text\n\
|
||||
h for html table\n\
|
||||
H for full html page\n\
|
||||
x for xml\n\
|
||||
X for xml with active lease details\n\
|
||||
j for json\n\
|
||||
J for json with active lease details\n\
|
||||
c for comma separated values\n");
|
||||
fprintf(out, "\
|
||||
-s, --sort=[nimcptTe] sort ranges by\n\
|
||||
|
|
|
|||
136
src/output.c
136
src/output.c
|
|
@ -322,6 +322,142 @@ int output_xml(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int output_json(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct range_t *range_p;
|
||||
unsigned long range_size;
|
||||
struct shared_network_t *shared_p;
|
||||
struct macaddr_t *macaddr_p;
|
||||
int ret;
|
||||
FILE *outfile;
|
||||
char sep;
|
||||
|
||||
if (config.output_file[0]) {
|
||||
outfile = fopen(config.output_file, "w+");
|
||||
if (outfile == NULL) {
|
||||
err(EXIT_FAILURE, "output_json: %s",
|
||||
config.output_file);
|
||||
}
|
||||
} else {
|
||||
outfile = stdout;
|
||||
}
|
||||
|
||||
range_p = ranges;
|
||||
range_size = get_range_size(range_p);
|
||||
shared_p = shared_networks;
|
||||
sep = ' ';
|
||||
|
||||
fprintf(outfile, "{\n");
|
||||
|
||||
if (macaddr != NULL) {
|
||||
fprintf(outfile, " %c\"active_leases\": [\n", sep);
|
||||
for (i = 0, macaddr_p = macaddr; macaddr_p->next != NULL;
|
||||
macaddr_p = macaddr_p->next) {
|
||||
if (0 != i) {
|
||||
fprintf(outfile, ",\n ");
|
||||
} else {
|
||||
fprintf(outfile, "\n ");
|
||||
}
|
||||
fprintf(outfile,
|
||||
"{ \"ip\":\"%s\", \"macaddress\":\"%s\" }",
|
||||
macaddr_p->ip, macaddr_p->ethernet);
|
||||
i++;
|
||||
}
|
||||
fprintf(outfile, "\n ]"); /* end of active_leases */
|
||||
sep = ',';
|
||||
}
|
||||
|
||||
if (config.output_limit[1] & output_limit_bit_1) {
|
||||
if (sep == ',')
|
||||
printf(",\n");
|
||||
fprintf(outfile, " \"subnets\": [\n");
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
fprintf(outfile, " ");
|
||||
fprintf(outfile, "{ ");
|
||||
if (range_p->shared_net) {
|
||||
fprintf(outfile,
|
||||
"\"location\":\"%s\", ",
|
||||
range_p->shared_net->name);
|
||||
} else {
|
||||
fprintf(outfile, "\"location\":\"\", ");
|
||||
}
|
||||
|
||||
fprintf(outfile, "\"network\":\"\", ");
|
||||
fprintf(outfile, "\"netmask\":\"\", ");
|
||||
fprintf(outfile, "\"range\":\"%s\", ",
|
||||
ntop_ipaddr(&range_p->first_ip));
|
||||
fprintf(outfile, "\"gateway\":\"\", ");
|
||||
fprintf(outfile, "\"defined\":%lu, ", range_size);
|
||||
fprintf(outfile, "\"used\":%lu, ", range_p->count);
|
||||
fprintf(outfile, "\"free\":%lu ",
|
||||
range_size - range_p->count);
|
||||
range_p++;
|
||||
range_size = get_range_size(range_p);
|
||||
if (i + 1 < num_ranges)
|
||||
fprintf(outfile, "},\n");
|
||||
else
|
||||
fprintf(outfile, "}\n");
|
||||
}
|
||||
fprintf(outfile, " ]"); /* end of subnets */
|
||||
sep = ',';
|
||||
}
|
||||
|
||||
if (config.output_limit[1] & output_limit_bit_2) {
|
||||
if (sep == ',')
|
||||
printf(",\n");
|
||||
fprintf(outfile, " \"shared-networks\": [\n");
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
fprintf(outfile, " ");
|
||||
shared_p++;
|
||||
fprintf(outfile, "{ ");
|
||||
fprintf(outfile, "\"location\":\"%s\", ",
|
||||
shared_p->name);
|
||||
fprintf(outfile, "\"defined\":%lu, ",
|
||||
shared_p->available);
|
||||
fprintf(outfile, "\"used\":%lu, ", shared_p->used);
|
||||
fprintf(outfile, "\"free\":%lu ",
|
||||
shared_p->available - shared_p->used);
|
||||
if (i + 1 < num_shared_networks)
|
||||
fprintf(outfile, "},\n");
|
||||
else
|
||||
fprintf(outfile, "}\n");
|
||||
}
|
||||
fprintf(outfile, " ]"); /* end of shared-networks */
|
||||
sep = ',';
|
||||
}
|
||||
|
||||
if (config.output_limit[0] & output_limit_bit_3) {
|
||||
if (sep == ',')
|
||||
printf(",\n");
|
||||
fprintf(outfile, " \"summary\": {\n");
|
||||
fprintf(outfile, " \"location\":\"%s\",\n",
|
||||
shared_networks->name);
|
||||
fprintf(outfile, " \"defined\":%lu,\n",
|
||||
shared_networks->available);
|
||||
fprintf(outfile, " \"used\":%lu,\n",
|
||||
shared_networks->used);
|
||||
fprintf(outfile, " \"free\":%lu\n",
|
||||
shared_networks->available - shared_networks->used);
|
||||
fprintf(outfile, " }"); /* end of summary */
|
||||
}
|
||||
|
||||
fprintf(outfile, "\n}");
|
||||
if (outfile == stdout) {
|
||||
ret = fflush(stdout);
|
||||
if (ret) {
|
||||
warn("output_json: fflush");
|
||||
}
|
||||
} else {
|
||||
ret = close_stream(outfile);
|
||||
if (ret) {
|
||||
warn("output_json: fclose");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void html_header(FILE *restrict f)
|
||||
{
|
||||
char outstr[200];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue