diff --git a/tools/bgpscanner/bgpscanner b/tools/bgpscanner/bgpscanner new file mode 100755 index 0000000..a0cc6dd --- /dev/null +++ b/tools/bgpscanner/bgpscanner @@ -0,0 +1,326 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Legacy Isolario bgpscanner compatible wrapper for ubgpsuite tools. +# Emulates most of the classic bgpscanner CLI. +# +# Copyright The DoubleFourteen Code Forge (C) All Rights Reserved +# Author: Lorenzo Cogotti + +NAME=$(basename "$0") +TGT=bgpgrep +OPTS="" + +PEERAS="" +PEERASF="" +PEERADDR="" +PEERADDRF="" +ATTRS="" +COMMS="" +NCOMMS="" +EXACT="" +EXACTF="" +SUBNETS="" +SUBNETSF="" +SUPNETS="" +SUPNETSF="" +RELATED="" +RELATEDF="" +LOOPS="unspec" +REXPS="" +NREXPS="" +DUMPBYTEC="no" +OUTREDIR="" + +die() { + echo "$NAME: $*" >&2 + exit 1 +} + +usage() { + echo "$NAME: Legacy bgpscanner-compatible wrapper for ubgpsuite tools" >&2 + echo "Usage:" >&2 + echo " $NAME [-cdlL] [-mM COMMSTRING] [-pP PATHEXPR] [-i ADDR] [-I FILE] [-a AS] [-A FILE] [-e PREFIX] [-E FILE] [-t ATTR_CODE] [-T FILE] [-o FILE] [FILE...]" >&2 + echo " $NAME [-cdlL] [-mM COMMSTRING] [-pP PATHEXPR] [-i ADDR] [-I FILE] [-a AS] [-A FILE] [-s PREFIX] [-S FILE] [-t ATTR_CODE] [-T FILE] [-o FILE] [FILE...]" >&2 + echo " $NAME [-cdlL] [-mM COMMSTRING] [-pP PATHEXPR] [-i ADDR] [-I FILE] [-a AS] [-A FILE] [-u PREFIX] [-U FILE] [-t ATTR_CODE] [-T FILE] [-o FILE] [FILE...]" >&2 + echo " $NAME [-cdlL] [-mM COMMSTRING] [-pP PATHEXPR] [-i ADDR] [-I FILE] [-a AS] [-A FILE] [-r PREFIX] [-R FILE] [-t ATTR_CODE] [-T FILE] [-o FILE] [FILE...]" >&2 + echo >&2 + echo "Available options:" >&2 + echo " -a " >&2 + echo " Print only entries coming from the given peer AS" >&2 + echo " -A " >&2 + echo " Print only entries coming from any peer AS listed in file" >&2 +# echo " -c" >&2 +# echo " Dump BGP messages in hexadecimal C array format" >&2 + echo " -d" >&2 + echo " Dump BGP filter bytecode to stderr (debug option)" >&2 + echo " -e " >&2 + echo " Print only entries containing the exact prefix of interest" >&2 + echo " -E " >&2 + echo " Print only entries containing exactly any prefix of interest listed in file" >&2 + echo " -f" >&2 + echo " Print every peer IP address in the RIB provided" >&2 + echo " -i " + echo " Print only entries coming from a given peer IP address" >&2 + echo " -I " >&2 + echo " Print only entries coming from any peer IP address listed in file" >&2 + echo " -l" >&2 + echo " Print only entries with loops in their AS PATH" >&2 + echo " -L" >&2 + echo " Print only entries without loops in their AS PATH" >&2 + echo " -o " >&2 + echo " Redirect output to file (defaults to stdout)" >&2 + echo " -m " >&2 + echo " Print only entries whose COMMUNITY attribute contains the given communities (in any order)" >&2 + echo " -M " >&2 + echo " Print only entries whose COMMUNITY attribute does not contain the given communities (in any order)" >&2 + echo " -p " >&2 + echo " Print only entries whose AS PATH matches the given expression" >&2 + echo " -P " >&2 + echo " Print only entries whose AS PATH does not match the given expression" >&2 + echo " -r " >&2 + echo " Print only entries containing subnets or supernets of the given prefix (including the prefix itself)" >&2 + echo " -R " >&2 + echo " Print only entries containing subnets or supernets of any prefix listed in file (including the prefix itself)" >&2 + echo " -s " >&2 + echo " Print only entries containing subnets of the given prefix" >&2 + echo " -S " >&2 + echo " Print only entries containing subnets of any prefix listed in file" >&2 + echo " -t " >&2 + echo " Print only entries containing the given interesting attribute" >&2 +# echo " -T " >&2 +# echo " Print only entries containing any of the interesting attributes listed in file" >&2 + echo " -u " + echo " Print only entries containing supernets of the given prefix (including the prefix itself)" >&2 + echo " -U " >&2 + echo " Print only entries containing supernets of any prefix listed in file (including the prefix itself)" >&2 + exit 1 +} + +chkint() { + case "$1" in + ''|*[!0-9]*) die "'$1': Non negative integer expected";; + *) ;; + esac +} +isip4() { + for i in 1 2 3 4; do + case $(echo "$1" | cut -d. -f"$i") in + [0-9]|[0-9][0-9]|[0-1][0-9][0-9]|2[0-4][0-9]|25[0-5]) ;; + *) return 1;; + esac + done +} +isip6() { + test "$( \ + echo "$1" | \ + grep -Ec '^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$' \ + )" -eq 1 +} +chkip() { + isip4 "$1" || isip6 "$1" || die "'$1': Invalid IP address" +} +chkprefix() { + case "$1" in + */*) chkint "${1#*/}" && chkip "${1%/*}";; + *) chkip "$1";; + esac +} +chknospc() { + case "$1" in + ''|*[![:space:]]*) die "'$1': Invalid argument";; + *) ;; + esac +} +chkcomm() { + case "$1" in + ''|*[![:space:][:alnum:]\:]*) die "'$1': Invalid COMMUNITY expression";; + *) ;; + esac +} +chkrexp() { + case "$1" in + ''|*[![:digit:][:space:]^$\?\*]*) die "'$1': Invalid AS_PATH expression";; + *) ;; + esac +} + +templatef() { + TPL=$(mktemp) + [ $? -eq 0 ] || exit 1 + + sed -e 's/#.*$//g' "$1" | awk 'BEGIN { + FPAT = "([^ ]*)|(\"[^\"]*\")" + } { + for (i=1; i<=NF; i++) { print $i } + }' | while read -r TOK; do + [ -z "$TOK" ] && continue + + UNQL="${TOK%\"}" + UNQR="${TOK#\"}" + UNQ="${UNQL#\"}" + [ "$UNQL" != "$UNQR" ] && die "'$TOK': Illegal misquoted or multiline token" + + [ -n "$2" ] && "$2" "$UNQ" + [ $? -ne 0 ] && exit 1 + + echo "$UNQ" + done > "$TPL" || die "'$1': File conversion failed" + + echo "$TPL" +} + +append() { + echo "${1:+${1}${3:+ ${3}} }${2}" +} + +TERM="" +EXPR="" + +appendtermargs() { + _T=$1; shift + TERM="$_T ( $* )" +} + +appendtermfiles() { + _T=$1; shift + + for i in "$@"; do _L=$(append "$_L" "$_T $i" "-or"); done + + [ -n "$TERM" ] && TERM="( $TERM -or $_L )" || TERM="$_L" +} + +pushterm() { + if [ -n "$TERM" ]; then EXPR=$(append "$EXPR" "$TERM"); TERM=""; fi +} + +exprcompile() { + [ -n "$PEERAS" ] || [ -n "$PEERADDR" ] && appendtermargs -peer $PEERAS $PEERADDR + [ -n "$PEERASF" ] || [ -n "$PEERADDRF" ] && appendtermfiles -peer $PEERASF $PEERADDRF + pushterm + + for i in $ATTRS; do TERM=$(append "$TERM" "-attr $i" "-or"); done + [ "$(echo "$ATTRS" | wc -w)" -gt 1 ] && TERM="( $TERM )" + pushterm + + [ -n "$NCOMMS" ] && TERM="-not -communities ( $NCOMMS )" + [ -n "$COMMS" ] && TERM=$(append "$TERM" "-all-communities ( $COMMS )" "-or") + [ -n "$NCOMMS" ] && [ -n "$COMMS" ] && TERM="( $TERM )" + pushterm + + [ -n "$EXACT" ] && appendtermargs -exact $EXACT + [ -n "$EXACTF" ] && appendtermfiles -exact $EXACTF + pushterm + [ -n "$SUBNETS" ] && appendtermargs -subnet $SUBNETS + [ -n "$SUBNETSF" ] && appendtermfiles -subnet $SUBNETSF + pushterm + [ -n "$SUPNETS" ] && appendtermargs -supernet $SUPNETS + [ -n "$SUPNETSF" ] && appendtermfiles -supernet $SUPNETSF + pushterm + [ -n "$RELATED" ] && appendtermargs -related $RELATED + [ -n "$RELATEDF" ] && appendtermfiles -related $RELATEDF + pushterm + + if [ "$LOOPS" != unspec ]; then + [ "$LOOPS" = yes ] && TERM="-loops" || TERM="-not -loops" + pushterm + fi + + [ -n "$REXPS" ] && TERM="-aspath \"$REXPS\"" + [ -n "$NREXPS" ] && TERM=$(append "$TERM" "-not -aspath \"$NREXPS\"" "-or") + [ -n "$REXPS" ] && [ -n "$NREXPS" ] && TERM="( $TERM )" + pushterm +} + +GOTEXACT=""; GOTRELATED=""; GOTSUBNETS=""; GOTSUPNETS="" +while getopts "a:A:cde:E:fi:I:lLo:m:M:p:P:r:R:s:S:t:T:u:U:" o; do + case $o in + a) chkint "$OPTARG" + PEERAS=$(append "$PEERAS" "$OPTARG") + ;; + A) TPL=$(templatef "$OPTARG" chkint) || exit 1 + PEERASF=$(append "$PEERASF" "$TPL") + ;; + c) die "Sorry, option -c is not supported yet!" + ;; + d) DUMPBYTEC=yes + ;; + e) chkprefix "$OPTARG" + GOTEXACT=y; EXACT=$(append "$EXACT" "$OPTARG") + ;; + E) TPL=$(templatef "$OPTARG" chkprefix) || exit 1 + GOTEXACT=y; EXACTF=$(append "$EXACTF" "$TPL") + ;; + f) TGT=peerindex + ;; + i) chkip "$OPTARG" + PEERADDR=$(append "$PEERADDR" "$OPTARG") + ;; + I) TPL=$(templatef "$OPTARG" chkip) || exit 1 + PEERADDRF=$(append "$PEERADDRF" "$TPL") + ;; + l) LOOPS=yes + ;; + L) LOOPS=no + ;; + m) chkcomm "$OPTARG" + COMMS=$(append "$COMMS" "$OPTARG") + ;; + M) chkcomm "$OPTARG" + NCOMMS=$(append "$NCOMMS" "$OPTARG") + ;; + o) OUTREDIR="$OPTARG" + ;; + p) chkrexp "$OPTARG" + REXPS=$(append "$REXPS" "$(echo "$OPTARG" | tr "?" ".")" "|") + ;; + P) chkrexp "$OPTARG" + NREXPS=$(append "$NREXPS" "$(echo "$OPTARG" | tr "?" "." )" "|") + ;; + r) chkprefix "$OPTARG" + GOTRELATED=y; RELATED=$(append "$RELATED" "$OPTARG") + ;; + R) TPL=$(templatef "$OPTARG" chkprefix) || exit 1 + GOTRELATED=y; RELATEDF=$(append "$RELATEDF" "$TPL") + ;; + s) chkprefix "$OPTARG" + GOTSUBNETS=y; SUBNETS=$(append "$SUBNETS" "$OPTARG") + ;; + S) TPL=$(templatef "$OPTARG" chkprefix) || exit 1 + GOTSUBNETS=y; SUBNETSF=$(append "$SUBNETSF" "$TPL") + ;; + t) chknospc "$OPTARG" + ATTRS=$(append "$ATTRS" "$OPTARG") + ;; + T) die "Sorry, option -T is not supported yet!" + ;; + u) chkprefix "$OPTARG" + GOTSUPNETS=y; SUPNETS=$(append "$SUPNETS" "$OPTARG") + ;; + U) TPL=$(templatef "$OPTARG" chkprefix) || exit 1 + GOTSUPNETS=y; SUPNETSF=$(append "$SUPNETSF" "$TPL") + ;; + ?) usage + ;; + esac +done + +GOTNETS="${GOTSUBNETS}${GOTSUPNETS}${GOTEXACT}${GOTRELATED}" + +shift $(( OPTIND-1 )) + +exprcompile + +[ -n "$EXPR" ] && [ "$TGT" != bgpgrep ] && die "Conflicting options" +[ -n "$GOTNETS" ] && [ "$GOTNETS" != "y" ] && die "Conflicting options" + +[ "$TGT" = bgpgrep ] && [ "$DUMPBYTEC" = yes ] && OPTS=$(append "$OPTS" --dump-bytecode) +[ "$TGT" != bgpgrep ] && OPTS=-r + +[ -n "$OUTREDIR" ] && OPTS=$(append "$OPTS" "-o $OUTREDIR") + +CMD="echo" +[ -n "$PRETEND" ] && [ "$PRETEND" = 1 ] || [ "$PRETEND" = y ] || [ "$PRETEND" = yes ] && CMD="echo" + +"$CMD" "$TGT" $OPTS -- "$@" $EXPR diff --git a/tools/bgpscanner/bgpscanner.1.in b/tools/bgpscanner/bgpscanner.1.in new file mode 100755 index 0000000..d30aec6 --- /dev/null +++ b/tools/bgpscanner/bgpscanner.1.in @@ -0,0 +1,484 @@ +'\" et +.TH BGPSCANNER 1 @VERSION@ BGPSCANNER "User Commands" +.\" +.SH NAME +@UTILITY@ +\(em legacy wrapper script for backwards compatibility with Isolario +.IR bgpscanner +CLI +.SH SYNOPSIS +.LP +.nf +@UTILITY@ \fB[\fIOPTIONS\fB]\fR... \fB[\fIFILES\fB]\fR... +.fi + +.SH DESCRIPTION +The legacy +.IR @UTILITY@ +wrapper script is a drop in wrapper script to remap most invocations of the +Isolario +.IR bgpscanner +CLI to any relevant +.IR \[*m]bgpsuite +utility. + +The legacy +.IR @UTILITY@ +wrapper may be used to ease transition phase to tools offered by the +.IR "\[*m]bgpsuite" . +A pretend mode is also available, to print the command that would need to +be executed to perform the same operations as the provided +.IR bgpscanner +CLI invocation. +This is especially useful to users familiar with the old +.IR bgpscanner +CLI to learn the new syntax. +See the +.IR "PRETEND MODE" +section below for details. + +Anyone unfamiliar with Isolario +.IR bgpscanner +and wishing to take advantage of the +.IR "\[*m]bgpsuite" +tools is probably reading the wrong man page. +See +.IR bgpgrep (1) +and +.IR peerindex (1) +for equivalent and more advanced functionality. + +For reference, Isolario +.IR bgpscanner +supports a more rudimentary filtering model compared to +.IR bgpgrep (1). +For every MRT dump in +.IR FILES +Isolario +.IR bgpscanner +reconstructs the original BGP message and applies the filtering rules specified by +.IR OPTIONS +(if any). Failing to meet such rules causes the BGP message to be dropped +from output. +The filtering process follows the sequence: +.IP +.PD 0 +.IP 1 5 +Filtering by peer (aka feeder in Isolario jargon), which may discard a message based on the announcing peer. +.IP 2 5 +Filtering by attributes, which may discard a message based on the presence of specific attributes of interest. +.IP 3 5 +Filtering by AS_PATH, which may discard a message based on the routes it contains. +.IP 4 5 +Filtering by prefixes, which may discard a message based on the prefixes available in its NLRI and WITHDRAWN fields. +.PD +.PP +Multiple criteria may be occur for each phase, resulting in implicitly +.IR OR ing +together multiple conditions. + +.SH OPTIONS +The following backwards compatibility options are supported: + +.IP "\fB\-a \fI\fP" 10 +Print only entries coming from the given peer ASN. + +.IP "\fB\-A \fI\fP" 10 +Print only entries coming from any peer ASN listed in a template file, see +.IR "FILTER TEMPLATE FILES" +section below for details. + +.IP "\fB\-d\fP" 10 +Dump BGP filter bytecode to stderr (debug option). + +.IP "\fB\-e \fI\fP" 10 +Print only entries containing the exact prefix of interest. +.IP "\fB\-E \fI\fP" 10 +Print only entries containing exactly any prefix of interest listed in file, +see +.IR "FILTER TEMPLATE FILES" +section below for details. + +.IP "\fB\-f\fP" 10 +Print every peer IP address inside RIBs provided as input files. + +.IP "\fB\-i \fI\fP" 10 +Print only entries coming from a given peer IP address. + +.IP "\fB\-I \fI\fP" 10 +(The uppercase letter i.) Print only entries coming from any peer IP address listed in file, +see +.IR "FILTER TEMPLATE FILES" +section below for details. + +.IP "\fB\-l\fP" 10 +(The letter ell.) Print only entries with loops in their AS_PATH. + +.IP "\fB\-L\fP" 10 +Opposite of +.IR \-l , +print only entries without loops in their AS_PATH. + +.IP "\fB\-o \fI\fP" 10 +Redirect output to file (defaults to standard output). +If option occurs multiple times, last one prevails. + +.IP "\fB\-m \fI\fP" 10 +Print only entries whose COMMUNITY attribute contains the given communities (in any order). +Communities must be specified in canonical form and space separated, for example: `1234:567 8910:1112'. +Well\-known communities can also be specified according to IANA (see +.IR STANDARDS ), +for example NO_EXPORT. + +.IP "\fB\-M \fI\fP" 10 +Opposite of +.IR \-m , +only prints entries whose COMMUNITY attribute does +.B not +contain the given communities (in any order). + +.IP "\fB\-p \fI\fP" 10 +Print only entries whose AS_PATH matches the provided expression. +This option accepts expressions in a syntax resembling a heavily simplified +form of POSIX basic regular expressions. +See section +.IR "AS PATH MATCH EXPRESSIONS" +for details. + +.IP "\fB\-P \fI\fP" 10 +Opposite of +.IR \-p , +only prints entries whose AS_PATH does +.B not +match the provided expression. + +.IP "\fB\-r \fI\fP" 10 +Print only entries containing subnets or supernets of the given prefix (including the prefix itself). + +.IP "\fB\-R \fI\fP" 10 +Print only entries containing subnets or supernets of any prefix listed in file (including the prefix itself), +see section +.IR "FILTER TEMPLATE FILES" +for details. + +.IP "\fB\-s \fI\fP" 10 +Print only entries containing subnets of the given prefix. + +.IP "\fB\-S \fI\fP" 10 +Print only entries containing subnets of any prefix listed in file, +see section +.IR "FILTER TEMPLATE FILES" +for details. + +.IP "\fB\-t \fI\fP" 10 +Print only entries containing the given interesting attribute. + +.IP "\fB\-u \fI\fP" 10 +Print only entries containing supernets of the given prefix +(including the prefix itself). + +.IP "\fB\-U \fI\fP" 10 +Print only entries containing supernets of any prefix listed in file +(including the prefix itself), +see section +.IR "FILTER TEMPLATE FILES" +for details. + +.SH OPERANDS +The following operands are supported: +.TP +.B FILE +A pathname of an input file. If no file operands are specified, the standard input is used. +If a file is `-', +.IR @UTILITY@ +shall read from the standard input at that point in the sequence. +.B bgpscanner +does not close and reopen standard input when it is referenced in this way, but accepts multiple occurrences of `-' as a file operand. +See the +.IR "INPUT FILES" +section for details on the supported file formats. + +.SH "AS PATH MATCH EXPRESSIONS" +AS_PATH match expressions (accepted by +.IR \-p +and +.IR \-P +options) use a simplified format based on typical conventions estabilished by +POSIX regular expressions. The most basic example is the position idependent AS_PATH matching, +an expression such as: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "1\ 2" +.in +\& +.fi +matches any message whose AS_PATH crosses link `AS1 AS2'. The `AS1 AS2' link may appear anywhere in +AS_PATH. The expression can be arbitrarily complex, for example: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "1\ 2\ 3\ 4\ 5\ 6\ 7\ 8" +.in +\& +.fi +matches any message with the corresponding ASN subsequence appearing anywhere in its AS_PATH. +A `?' (question mark) may be placed anywhere in the expression to signal the fact that any ASN may +appear in that position, for example: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "1\ ?\ 3" +.in +\& +.fi +matches any message whose AS_PATH contains a subsequence of length 3, whose first ASN is AS1 and the last one is AS3. +.P +Matching expressions may be constrained to operate to the beginning or the end of the AS PATH. +By prepending `^' (caret) to the expression, the following ASN are required to appear at the beginning of the path, +for example: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "^1\ 2" +.in +\& +.fi +matches any message whose AS_PATH starts with the link `AS1 AS2'. +In a similar fashion, the expression may be forced to match at the end of the path by appending a `$' (dollar sign) at the end. +.nf +\& +.in +2m +@UTILITY@\ \-p\ "1\ 2$" +.in +\& +.fi +matches any message whose AS_PATH ends with the link `AS1 AS2'. +A `?' may be used to match any ASN in the corresponding position, for example: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "1\ ?$" +.in +\& +.fi +matches any message whose AS_PATH is ending with the second to last ASN being AS1. +The `^' and `$' symbols may be used to create exact matches, such as: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "^1\ 2\ 3\ 4$" +.in +\& +.fi +matches any message whose AS PATH is exactly `AS1 AS2 AS3 AS4'. +.nf +\& +.in +2m +@UTILITY@\ \-p\ "^1\ 2\ ?\ 4$" +.in +\& +.fi +matches any message whose AS_PATH starts with `AS1 AS2' and ends with AS4, but may have any ASN +in the second to last position. +A `*' (star) may be used to match zero or more ASN in the position. +Note that if the intended usage is to match +.B one +or more ASN, then a `?' symbol +should be used before the `*'. For example: +.nf +\& +.in +2m +@UTILITY@\ \-p\ "^1\ 2\ *\ 4$" +.in +\& +.fi +matches any message whose AS PATH starts with `AS1 AS2', then contains +.B zero +or more ASN and ends with AS4. +.nf +\& +.in +2m +@UTILITY@\ \-p\ "^1\ 2\ ?\ *\ 4$" +.in +\& +.fi +matches any message whose AS_PATH starts with `AS1 AS2', then contains +.B one +or more ASN and terminates with AS4. +The metacharacters explained above may be mixed to create arbitrarily complex expressions. +.P +As a backwards compatibility note, please note that Isolario +.IR bgpscanner +AS_PATH expression syntax differs from +.IR bgpgrep (1)'s +in that a `?' character signifies "any ASN" rather than "match zero or one time" +(see section +.IR "AS_PATH REGULAR EXPRESSIONS" +of +.IR bgpgrep (1) +documentation for details). There is no equivalent to +.IR bgpgrep (1)'s +`?' in Isolario +.IR bgpscanner +AS_PATH matching expressions. + +.SH FILTER TEMPLATE FILES +A number of options offer variants reading their arguments from a template file +(for example the +.IR \-e +option allows an alternate +.IR \-E +variant to read each prefix directly from file). This provides means to create +filter templates that may be further refined by additional inline options. +Writing a template file may eliminate the burden of repeatedly typing prefixes that are known +to be always relevant across multiple executions, leaving only prefixes that may genuinely +change to be specified, for example: +.nf +\& +.in +2m +@UTILITY@\ \-E\ template.txt\ \-e\ "192.65.121.0/24" +.in +\& +.fi +Template file is expected to contain a space separated list of tokens in the same format as +the ones expected by the non-template variant of the option. Note that newlines are considered +spaces. +Comments may be freely inserted in the file by prepending them with the `#' (hash) character, anything following +`#' is ignored up to the next newline. +Tokens containing spaces may be enclosed in `"' (quotes) to preserve them. +Template files support the usual C-style character escape sequences. +.P +As an implementation note, the +.IR @UTILITY@ +wrapper translates every historical Isolario +.IR bgpscanner +template file to an equivalent +.IR bgpgrep (1) +template inside a temporary file, that is later feed to +.IR bgpgrep (1), +an interested user may inspect the resulting file to learn about the differences +in syntax. +.P +Also note that Isolario +.IR bgpscanner +used the `#' character to mark comments, while +.IR bgpgrep (1) +uses C and C++ style comments. + +.SH "LINE ORIENTED OUTPUT" +The +.IR @UTILITY@ +wrapper output is identical to the output produced by +.IR bgpgrep (1) +and +.IR peerindex (1), +depending on the +.IR OPTIONS +specified. +See +.IR bgpgrep (1) +and +.IR peerindex (1) +documentation for details. + +.SH "PRETEND MODE" +The +.IR @UTILITY@ +wrapper may operate in pretend mode, whenever the +.B PRETEND +environment variable is set and equal to any of the values +documented in the +.IR "ENVIRONMENT VARIABLES" +section. +In pretend mode, the +.IR @UTILITY@ +wrapper will not execute any command, instead it will print the command +that would be executed. This may serve as a debug tool, or a learning tool +to display how to perform a known Isolario +.IR bgpscanner +task using +.IR \[*m]bgpsuite +native tools. + +.SH "ENVIRONMENT VARIABLES" +The following environment variables affect the execution of the +.IR @UTILITY@ +wrapper: + +.IP "\fBPRETEND\fP" 10 +Determines whether pretend mode is enabled (see +.IR "PRETEND MODE" +for details). +.IR "PRETEND MODE" +is enabled whenever +.B PRETEND +is defined and its value is equal to 1, `y' or `yes` (in a case sensitive way). + +.SH "EXIT STATUS" +The +.IR @UTILITY@ +wrapper has the same exit values as +.IR bgpgrep (1) +and +.IR peerindex (1), +see their respective documentation for details. + +.SH STDIN +The +.IR @UTILITY@ +standard input usage is identical to +.IR bgpgrep (1) +and +.IR peerindex (1). +See their respective documentation for details. + +.SH "INPUT FILES" +The +.IR @UTILITY@ +supports any input file supported by +.IR bgpgrep (1) +and +.IR peerindex (1). +See their respective documentation for details. + +.SH STDOUT +Unless redirected explicitly via +.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@ +may detect and treat as error whenever the standard output is a regular file, +and is the same file as any of the +.IR FILES +arguments. +The default output format used by +.IR @UTILITY@ +is documented in the +.IR "LINE ORIENTED OUTPUT" +section. + +.SH STDERR +The standard error is used only for diagnostic messages and error reporting. + +.SH SEE ALSO +.IR bgpgrep (1), +.IR peerindex (1) + +.SH STANDARDS +The +.IR @UTILITY@ +adheres to the same standards as +.IR bgpgrep (1) +and +.IR peerindex (1) +see their respective documentations for details. + +.SH AUTHOR +The +.IR @UTILITY@ +wrapper script was written by +.UR lcg@\:inventati.\:org +Lorenzo Cogotti +.UE .