[tools/bgpgrep] Add bogon ASN filtering option: -bogon-asn

This commit is contained in:
Lorenzo Cogotti 2021-08-04 19:31:11 +02:00
parent 0d6093a74b
commit f222daa08f
4 changed files with 101 additions and 3 deletions

View File

@ -155,6 +155,39 @@ section below.
.IP "\fB\-loops\fR" 10 .IP "\fB\-loops\fR" 10
Evaluates as true if BGP message is an UPDATE whose AS_PATH contains loops. Evaluates as true if BGP message is an UPDATE whose AS_PATH contains loops.
.IP "\fB\-bogon\-asn\fR" 10
Evaluates as true if BGP message is an UPDATE whose AS_PATH contains bogon ASN.
Any of the following is classified as a bogon ASN:
.RS
.IP "\fI0\fR" 25
Reserved by
.IR "RFC 7607" .
.IP "\fI23456\fR" 25
.IR AS_TRANS ,
see
.IR "RFC 6793" .
.IP "\fI64496\-64511\fR" 25
Reserved for use in docs and code by
.IR "RFC 5398" .
.IP "\fI64512\-65534\fR" 25
Reserved for private use by
.IR "RFC 6996" .
.IP "\fI65535\fR" 25
Reserved by
.IR "RFC 7300" .
.IP "\fI65536\-65551\fR" 25
Reserved for use in docs and code by
.IR "RFC 5398" .
.IP "\fI65552\-131071\fR" 25
Reserved by IANA.
.IP "\fI4200000000\-4294967294\fR" 25
Reserved for private use by
.IR "RFC 6996" .
.IP "\fI4294967295\fR" 25
Reserved by
.IR "RFC 7300" .
.RE
.IP "\fB\-exact\ \fIprefix\-expression\fR" 10 .IP "\fB\-exact\ \fIprefix\-expression\fR" 10
Evaluates as true if BGP message is an UPDATE and contains at least one of the Evaluates as true if BGP message is an UPDATE and contains at least one of the
relevant networks of interest specified in relevant networks of interest specified in

View File

@ -62,6 +62,7 @@ typedef struct {
Sint32 loopsFn; Sint32 loopsFn;
Sint32 peerMatchFn; Sint32 peerMatchFn;
Sint32 timestampCmpFn; Sint32 timestampCmpFn;
Sint32 bogonAsnFn;
Uint16 ncode; Uint16 ncode;
Boolean8 wasImplicitAnd; Boolean8 wasImplicitAnd;
@ -332,6 +333,10 @@ static Expridx GetTerm(void)
c[n++] = BGP_VMOP(BGP_VMOP_CALL, C.loopsFn); c[n++] = BGP_VMOP(BGP_VMOP_CALL, C.loopsFn);
return PushLeaf(c, n); return PushLeaf(c, n);
} else if (strcmp(C.curterm, "-bogon-asn") == 0) {
c[n++] = BGP_VMOP(BGP_VMOP_CALL, C.bogonAsnFn);
return PushLeaf(c, n);
} else if (strcmp(C.curterm, "-exact") == 0) { } else if (strcmp(C.curterm, "-exact") == 0) {
return ParsePrefixOp(BGP_VMOP_EXCT); return ParsePrefixOp(BGP_VMOP_EXCT);
@ -710,9 +715,14 @@ void Bgpgrep_CompileVmProgram(int argc, char **argv)
C.timestampCmpFn = BGP_VMSETFN(&S.vm, C.timestampCmpFn = BGP_VMSETFN(&S.vm,
Bgp_VmNewFn(&S.vm), Bgp_VmNewFn(&S.vm),
BgpgrepF_TimestampCompare); BgpgrepF_TimestampCompare);
C.bogonAsnFn = BGP_VMSETFN(&S.vm,
Bgp_VmNewFn(&S.vm),
BgpgrepF_BogonAsn);
assert(C.loopsFn >= 0); assert(C.loopsFn >= 0);
assert(C.peerMatchFn >= 0); assert(C.peerMatchFn >= 0);
assert(C.timestampCmpFn >= 0); assert(C.timestampCmpFn >= 0);
assert(C.bogonFn >= 0);
// Actual compilation // Actual compilation
if (C.argc > 0) { if (C.argc > 0) {

View File

@ -177,6 +177,7 @@ Sint32 BgpgrepC_ParseCommunity(BgpVmOpt);
void BgpgrepF_FindAsLoops(Bgpvm *); void BgpgrepF_FindAsLoops(Bgpvm *);
void BgpgrepF_PeerAddrMatch(Bgpvm *); void BgpgrepF_PeerAddrMatch(Bgpvm *);
void BgpgrepF_TimestampCompare(Bgpvm *); void BgpgrepF_TimestampCompare(Bgpvm *);
void BgpgrepF_BogonAsn(Bgpvm *);
// ================== // ==================
// MRT Dump functions // MRT Dump functions

View File

@ -12,6 +12,7 @@
#include "bgpgrep_local.h" #include "bgpgrep_local.h"
#include "bgp/vmintrin.h" #include "bgp/vmintrin.h"
#include "sys/endian.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -156,8 +157,8 @@ void BgpgrepF_TimestampCompare(Bgpvm *vm)
} }
nomatch: nomatch:
// XXX: include match info // XXX: include match info
BGP_VMPUSH(vm, res); BGP_VMPUSH(vm, res);
} }
@ -169,6 +170,7 @@ void BgpgrepF_FindAsLoops(Bgpvm *vm)
* PUSHES: * PUSHES:
* TRUE if loops are found inside AS PATH, FALSE otherwise * TRUE if loops are found inside AS PATH, FALSE otherwise
*/ */
Aspathiter it; Aspathiter it;
Asntree t; Asntree t;
@ -188,7 +190,7 @@ void BgpgrepF_FindAsLoops(Bgpvm *vm)
while ((asn = Bgp_NextAsPath(&it)) != -1) { while ((asn = Bgp_NextAsPath(&it)) != -1) {
Asn32 as32 = ASN(asn); Asn32 as32 = ASN(asn);
if (as32 == AS4_TRANS) { if (as32 == AS4_TRANS) {
// AS_TRANS are irrelevant for loops // AS_TRANS are irrelevant for loops (they are, in fact, bogons)
pos++; pos++;
continue; continue;
} }
@ -212,8 +214,60 @@ void BgpgrepF_FindAsLoops(Bgpvm *vm)
Bgp_VmTempFree(vm, t.n * ALIGNEDNODESIZ); Bgp_VmTempFree(vm, t.n * ALIGNEDNODESIZ);
nomatch: nomatch:
// XXX: include match info // XXX: include match info
if (BGP_VMCHKSTK(vm, 1)) if (BGP_VMCHKSTK(vm, 1))
BGP_VMPUSH(vm, foundLoop); BGP_VMPUSH(vm, foundLoop);
} }
void BgpgrepF_BogonAsn(Bgpvm *vm)
{
/* POPS:
* NONE
*
* PUSHES:
* TRUE if bogons are found inside AS PATH, FALSE otherwise
*/
Aspathiter it;
Asn asn;
Boolean foundBogon = FALSE;
const Bgphdr *hdr = BGP_HDR(vm->msg);
if (hdr->type != BGP_UPDATE)
goto nomatch;
if (Bgp_StartMsgRealAsPath(&it, vm->msg) != OK)
goto nomatch;
while ((asn = Bgp_NextAsPath(&it)) != -1) {
Asn32 n = beswap32(ASN(asn));
// https://ripe72.ripe.net/wp-content/uploads/presentations/151-RIPE72_bogon_ASNs_JobSnijders.pdf
// https://www.manrs.org/2021/01/routing-security-terms-bogons-vogons-and-martians/
// Breakdown:
// 0 Reserved can't use in BGP RFC 7607
// 23456 AS_TRANS RFC 6793
// 64496-64511 Reserved for use in docs and code RFC 5398
// 64512-65534 Reserved for Private Use RFC 6996
// 65535 Reserved RFC 7300
// 65536-65551 Reserved for use in docs and code RFC 5398
// 65552-131071 Reserved by IANA
// 4200000000-4294967294 Reserved for Private Use RFC 6996
// 4294967295 Reserved RFC 7300
foundBogon |= (n == 0u || n == 23456u);
foundBogon |= (n >= 64496u && n <= 131071u);
foundBogon |= (n >= 4200000000u && n <= 4294967295u);
if (foundBogon)
break;
}
if (Bgp_GetErrStat(NULL)) {
vm->errCode = BGPEVMMSGERR;
return;
}
nomatch:
// XXX: include match info
if (BGP_VMCHKSTK(vm, 1))
BGP_VMPUSH(vm, foundBogon);
}