[tools/bgpgrep] Add support for -o option
This commit is contained in:
parent
11dc537d21
commit
49e4ee3bfa
|
@ -17,7 +17,9 @@ utility reads each possibly compressed Multithreaded Routing Toolkit
|
||||||
(MRT)
|
(MRT)
|
||||||
dump file specified by
|
dump file specified by
|
||||||
.IR FILES
|
.IR FILES
|
||||||
and formats its contents to standard output.
|
and formats its contents to standard output (or any custom output file
|
||||||
|
as specified by
|
||||||
|
.IR OPTIONS ).
|
||||||
.IR @UTILITY@
|
.IR @UTILITY@
|
||||||
may optionally evaluate a predicate defined by
|
may optionally evaluate a predicate defined by
|
||||||
.IR EXPRESSION
|
.IR EXPRESSION
|
||||||
|
@ -37,8 +39,8 @@ regardless of any filtering rule.
|
||||||
prints diagnostics to standard error,
|
prints diagnostics to standard error,
|
||||||
it detects and tolerates data corruption as much as possible.
|
it detects and tolerates data corruption as much as possible.
|
||||||
Corruption within a BGP message causes only the affected message to be
|
Corruption within a BGP message causes only the affected message to be
|
||||||
dropped. Unrecoverable corruption within the entire MRT dump file causes
|
dropped. Though unrecoverable errors affecting the entire MRT dump file may
|
||||||
the whole file to be dropped,
|
require it to be dropped as a whole,
|
||||||
.IR @UTILITY@
|
.IR @UTILITY@
|
||||||
will then move to the next file in
|
will then move to the next file in
|
||||||
.IR FILES ,
|
.IR FILES ,
|
||||||
|
@ -46,7 +48,7 @@ if any.
|
||||||
.P
|
.P
|
||||||
Such events are always reported with reasonable diagnostic errors.
|
Such events are always reported with reasonable diagnostic errors.
|
||||||
Parsed data up to the corruption point may still be printed to
|
Parsed data up to the corruption point may still be printed to
|
||||||
standard output.
|
regular output.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.IR @UTILITY@
|
.IR @UTILITY@
|
||||||
|
@ -74,6 +76,15 @@ may ease visualization by surrounding some output with color escape sequences,
|
||||||
on terminals that support this feature. This option forces colored text
|
on terminals that support this feature. This option forces colored text
|
||||||
output off.
|
output off.
|
||||||
|
|
||||||
|
.IP "\fB\-o \fI<file>\fP" 10
|
||||||
|
Write output to
|
||||||
|
.BR file .
|
||||||
|
Instead of using standard output,
|
||||||
|
.IR @UTILITY@
|
||||||
|
shall format MRT contents to the specified file. If option occurs
|
||||||
|
multiple times, last specified file is used. This option forces colored
|
||||||
|
text output off.
|
||||||
|
|
||||||
.IP "\fB\-h or \-\-help\fP" 10
|
.IP "\fB\-h or \-\-help\fP" 10
|
||||||
Prints a short help message, summarizing
|
Prints a short help message, summarizing
|
||||||
.IR @UTILITY@
|
.IR @UTILITY@
|
||||||
|
@ -582,8 +593,11 @@ supported compression formats. If the file extension is not recognized,
|
||||||
or there is no extension, then it is assumed to be uncompressed.
|
or there is no extension, then it is assumed to be uncompressed.
|
||||||
|
|
||||||
.SH STDOUT
|
.SH STDOUT
|
||||||
The standard output is used to print a human readable text representation of
|
Unless redirected explicitly via
|
||||||
BGP message data, nothing else shall be written to the standard output.
|
.IR OPTIONS ,
|
||||||
|
the standard output is used to print a human readable text
|
||||||
|
representation of BGP message data, nothing else shall be written
|
||||||
|
to the standard output.
|
||||||
.IR @UTILITY@
|
.IR @UTILITY@
|
||||||
may detect and treat as error whenever the standard output is a regular file,
|
may detect and treat as error whenever the standard output is a regular file,
|
||||||
and is the same file as any of the
|
and is the same file as any of the
|
||||||
|
@ -597,7 +611,9 @@ section.
|
||||||
|
|
||||||
.SH STDERR
|
.SH STDERR
|
||||||
The standard error is used only for diagnostic messages and error reporting.
|
The standard error is used only for diagnostic messages and error reporting.
|
||||||
Any BGP message output is exclusive to standard output.
|
Any BGP message output is exclusive to standard output or any file explicitly
|
||||||
|
specified by
|
||||||
|
.IR OPTIONS .
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
This section contains some useful examples, starting from trivial ones,
|
This section contains some useful examples, starting from trivial ones,
|
||||||
|
|
|
@ -38,6 +38,7 @@ BgpgrepState S;
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NO_COLOR_FLAG,
|
NO_COLOR_FLAG,
|
||||||
DUMP_BYTECODE_FLAG,
|
DUMP_BYTECODE_FLAG,
|
||||||
|
OUTPUT_FLAG,
|
||||||
|
|
||||||
NUM_FLAGS
|
NUM_FLAGS
|
||||||
} BgpgrepOpt;
|
} BgpgrepOpt;
|
||||||
|
@ -49,6 +50,9 @@ static Optflag options[] = {
|
||||||
[DUMP_BYTECODE_FLAG] = {
|
[DUMP_BYTECODE_FLAG] = {
|
||||||
'-', "dump-bytecode", NULL, "Dump BGP VM bytecode to stderr (debug)", ARG_NONE
|
'-', "dump-bytecode", NULL, "Dump BGP VM bytecode to stderr (debug)", ARG_NONE
|
||||||
},
|
},
|
||||||
|
[OUTPUT_FLAG] = {
|
||||||
|
'o', NULL, "file", "Write output to file", ARG_REQ
|
||||||
|
},
|
||||||
|
|
||||||
[NUM_FLAGS] = { '\0' }
|
[NUM_FLAGS] = { '\0' }
|
||||||
};
|
};
|
||||||
|
@ -63,34 +67,14 @@ static void Bgpgrep_SetupCommandLine(char *argv0)
|
||||||
com_shortDescr = "Filter and print BGP data within MRT dumps";
|
com_shortDescr = "Filter and print BGP data within MRT dumps";
|
||||||
com_longDescr =
|
com_longDescr =
|
||||||
"Reads MRT dumps in various formats, applying filtering rules\n"
|
"Reads MRT dumps in various formats, applying filtering rules\n"
|
||||||
"to each BGP message therein, then outputs every passing message to stdout.\n"
|
"to each BGP message therein, then outputs every passing message\n"
|
||||||
|
"to stdout (or any custom output file defined by OPTIONS).\n"
|
||||||
"If - is found inside FILES, then input is read from stdin.\n"
|
"If - is found inside FILES, then input is read from stdin.\n"
|
||||||
"If no FILES arguments are provided, then input\n"
|
"If no FILES arguments are provided, then input\n"
|
||||||
"is implicitly expected from stdin.\n"
|
"is implicitly expected from stdin.\n"
|
||||||
"Any diagnostic message is logged to stderr.";
|
"Any diagnostic message is logged to stderr.";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Bgpgrep_ApplyProgramOptions(void)
|
|
||||||
{
|
|
||||||
S.noColor = options[NO_COLOR_FLAG].flagged;
|
|
||||||
S.dumpBytecode = options[DUMP_BYTECODE_FLAG].flagged;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CountFileArguments(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
const char *arg = argv[i];
|
|
||||||
if (arg[0] == '-' && arg[1] != '\0')
|
|
||||||
break;
|
|
||||||
if (strcmp(arg, "(") == 0 || strcmp(arg, "!") == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bgpgrep_Fatal(const char *fmt, ...)
|
void Bgpgrep_Fatal(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
|
@ -126,6 +110,46 @@ void Bgpgrep_Warning(const char *fmt, ...)
|
||||||
Sys_Print(STDERR, "\n");
|
Sys_Print(STDERR, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Bgpgrep_ApplyProgramOptions(void)
|
||||||
|
{
|
||||||
|
S.noColor = options[NO_COLOR_FLAG].flagged;
|
||||||
|
S.dumpBytecode = options[DUMP_BYTECODE_FLAG].flagged;
|
||||||
|
if (options[OUTPUT_FLAG].flagged) {
|
||||||
|
const char *filename = options[OUTPUT_FLAG].optarg;
|
||||||
|
|
||||||
|
Fildes fd = Sys_Fopen(filename, FM_WRITE, /*hints=*/0);
|
||||||
|
if (fd == FILDES_BAD)
|
||||||
|
Bgpgrep_Fatal("Can't open output file \"%s\"", filename);
|
||||||
|
|
||||||
|
S.outf = STM_FILDES(fd);
|
||||||
|
S.outfOps = Stm_FildesOps;
|
||||||
|
|
||||||
|
S.noColor = TRUE;
|
||||||
|
} else {
|
||||||
|
S.outf = STM_CONHN(STDOUT);
|
||||||
|
S.outfOps = Stm_ConOps;
|
||||||
|
}
|
||||||
|
if (!S.noColor && Sys_IsVt100Console(STDOUT))
|
||||||
|
S.outFmt = Bgp_IsolarioFmtWc; // console supports colors
|
||||||
|
else
|
||||||
|
S.outFmt = Bgp_IsolarioFmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CountFileArguments(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
const char *arg = argv[i];
|
||||||
|
if (arg[0] == '-' && arg[1] != '\0')
|
||||||
|
break;
|
||||||
|
if (strcmp(arg, "(") == 0 || strcmp(arg, "!") == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
void Bgpgrep_DropMessage(const char *fmt, ...)
|
void Bgpgrep_DropMessage(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
|
@ -278,11 +302,6 @@ NOINLINE static void Bgpgrep_HandleBgpError(BgpRet err, Srcloc *loc, void *obj)
|
||||||
|
|
||||||
static void Bgpgrep_Init(void)
|
static void Bgpgrep_Init(void)
|
||||||
{
|
{
|
||||||
if (!S.noColor && Sys_IsVt100Console(STDOUT))
|
|
||||||
S.outFmt = Bgp_IsolarioFmtWc; // console supports colors
|
|
||||||
else
|
|
||||||
S.outFmt = Bgp_IsolarioFmt;
|
|
||||||
|
|
||||||
Mrtrecord *rec = &S.rec;
|
Mrtrecord *rec = &S.rec;
|
||||||
Bgpmsg *msg = &S.msg;
|
Bgpmsg *msg = &S.msg;
|
||||||
|
|
||||||
|
@ -389,6 +408,9 @@ static int Bgpgrep_CleanupAndExit(void)
|
||||||
|
|
||||||
t = tn;
|
t = tn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (S.outfOps->Close) S.outfOps->Close(S.outf);
|
||||||
|
|
||||||
return (S.nerrors > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
|
return (S.nerrors > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ static void FixBgpAttributeTableForRib(Bgpattrtab tab, Boolean isRibv2)
|
||||||
static void OutputBgp4mp(const Mrthdr *hdr, Bgpattrtab tab)
|
static void OutputBgp4mp(const Mrthdr *hdr, Bgpattrtab tab)
|
||||||
{
|
{
|
||||||
S.lenientBgpErrors = TRUE;
|
S.lenientBgpErrors = TRUE;
|
||||||
S.outFmt->DumpBgp4mp(hdr, STM_CONHN(STDOUT), Stm_ConOps, tab);
|
S.outFmt->DumpBgp4mp(hdr, S.outf, S.outfOps, tab);
|
||||||
S.lenientBgpErrors = FALSE;
|
S.lenientBgpErrors = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ void BgpgrepD_Bgp4mp(void)
|
||||||
static void OutputZebra(const Mrthdr *hdr, Bgpattrtab tab)
|
static void OutputZebra(const Mrthdr *hdr, Bgpattrtab tab)
|
||||||
{
|
{
|
||||||
S.lenientBgpErrors = TRUE;
|
S.lenientBgpErrors = TRUE;
|
||||||
S.outFmt->DumpZebra(hdr, STM_CONHN(STDOUT), Stm_ConOps, tab);
|
S.outFmt->DumpZebra(hdr, S.outf, S.outfOps, tab);
|
||||||
S.lenientBgpErrors = FALSE;
|
S.lenientBgpErrors = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ static void OutputRibv2(const Mrthdr *hdr,
|
||||||
Bgpattrtab tab)
|
Bgpattrtab tab)
|
||||||
{
|
{
|
||||||
S.lenientBgpErrors = TRUE;
|
S.lenientBgpErrors = TRUE;
|
||||||
S.outFmt->DumpRibv2(hdr, peerent, ent, STM_CONHN(STDOUT), Stm_ConOps, tab);
|
S.outFmt->DumpRibv2(hdr, peerent, ent, S.outf, S.outfOps, tab);
|
||||||
S.lenientBgpErrors = FALSE;
|
S.lenientBgpErrors = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ void BgpgrepD_TableDumpv2(void)
|
||||||
static void OutputRib(const Mrthdr *hdr, const Mrtribent *ent, Bgpattrtab tab)
|
static void OutputRib(const Mrthdr *hdr, const Mrtribent *ent, Bgpattrtab tab)
|
||||||
{
|
{
|
||||||
S.lenientBgpErrors = TRUE;
|
S.lenientBgpErrors = TRUE;
|
||||||
S.outFmt->DumpRib(hdr, ent, STM_CONHN(STDOUT), Stm_ConOps, tab);
|
S.outFmt->DumpRib(hdr, ent, S.outf, S.outfOps, tab);
|
||||||
S.lenientBgpErrors = FALSE;
|
S.lenientBgpErrors = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,10 +104,13 @@ typedef jmp_buf frame_buf;
|
||||||
|
|
||||||
typedef struct BgpgrepState BgpgrepState;
|
typedef struct BgpgrepState BgpgrepState;
|
||||||
struct BgpgrepState {
|
struct BgpgrepState {
|
||||||
const char *filename; // current file being processed
|
// Output
|
||||||
const BgpDumpfmt *outFmt;
|
const BgpDumpfmt *outFmt;
|
||||||
|
void *outf;
|
||||||
|
const StmOps *outfOps;
|
||||||
|
|
||||||
// MRT input file stream
|
// MRT input file stream
|
||||||
|
const char *filename; // current file being processed
|
||||||
void *inf; // NOTE: may be NULL even in a file is open
|
void *inf; // NOTE: may be NULL even in a file is open
|
||||||
const StmOps *infOps; // if NULL no file is open
|
const StmOps *infOps; // if NULL no file is open
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue