From a5315407d4e776f146533d6bfe70b6bae65f31ea Mon Sep 17 00:00:00 2001 From: Lumin Shi Date: Mon, 26 Aug 2019 18:32:39 -0700 Subject: [PATCH 1/6] adding openbmp parsing support --- configure.ac | 3 +- lib/Makefile.am | 8 +- lib/bgp/Makefile.am | 3 +- lib/bmp/Makefile.am | 3 +- lib/mrt/Makefile.am | 3 +- lib/openbmp/.clang-format | 121 +++++++++++++++++ lib/openbmp/Makefile.am | 47 +++++++ lib/openbmp/parsebgp_openbmp.c | 203 ++++++++++++++++++++++++++++ lib/openbmp/parsebgp_openbmp.h | 48 +++++++ lib/openbmp/parsebgp_openbmp_opts.c | 0 lib/openbmp/parsebgp_openbmp_opts.h | 49 +++++++ lib/parsebgp.h.in | 3 +- lib/parsebgp_opts.h | 4 + tools/Makefile.am | 3 +- tools/parsebgp.c | 3 +- 15 files changed, 491 insertions(+), 10 deletions(-) create mode 100644 lib/openbmp/.clang-format create mode 100644 lib/openbmp/Makefile.am create mode 100644 lib/openbmp/parsebgp_openbmp.c create mode 100644 lib/openbmp/parsebgp_openbmp.h create mode 100644 lib/openbmp/parsebgp_openbmp_opts.c create mode 100644 lib/openbmp/parsebgp_openbmp_opts.h diff --git a/configure.ac b/configure.ac index 3e0335c..0d40d6a 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,7 @@ AC_CONFIG_FILES([Makefile lib/bgp/Makefile lib/bmp/Makefile lib/mrt/Makefile - tools/Makefile + lib/openbmp/Makefile + tools/Makefile ]) AC_OUTPUT diff --git a/lib/Makefile.am b/lib/Makefile.am index d5595ed..e3c1683 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -24,13 +24,14 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUBDIRS = bgp bmp mrt +SUBDIRS = bgp bmp mrt openbmp AM_CPPFLAGS = -I$(top_srcdir)/ \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/lib/bgp \ -I$(top_srcdir)/lib/bmp \ - -I$(top_srcdir)/lib/mrt + -I$(top_srcdir)/lib/mrt \ + -I$(top_srcdir)/lib/openbmp include_HEADERS = \ parsebgp.h \ @@ -52,7 +53,8 @@ libparsebgp_la_SOURCES = \ libparsebgp_la_LIBADD = \ $(top_builddir)/lib/bgp/libparsebgp_bgp.la \ $(top_builddir)/lib/bmp/libparsebgp_bmp.la \ - $(top_builddir)/lib/mrt/libparsebgp_mrt.la + $(top_builddir)/lib/mrt/libparsebgp_mrt.la \ + $(top_builddir)/lib/openbmp/libparsebgp_openbmp.la libparsebgp_la_LDFLAGS = -version-info @LIBPARSEBGP_SHLIB_CURRENT@:@LIBPARSEBGP_SHLIB_REVISION@:@LIBPARSEBGP_SHLIB_AGE@ diff --git a/lib/bgp/Makefile.am b/lib/bgp/Makefile.am index ba9ab82..ec45e4a 100644 --- a/lib/bgp/Makefile.am +++ b/lib/bgp/Makefile.am @@ -28,7 +28,8 @@ SUBDIRS = AM_CPPFLAGS = -I$(top_srcdir)/ \ -I$(top_srcdir)/lib \ - -I$(top_srcdir)/lib/bmp + -I$(top_srcdir)/lib/bmp \ + -I$(top_srcdir)/lib/openbmp include_HEADERS = \ parsebgp_bgp.h \ diff --git a/lib/bmp/Makefile.am b/lib/bmp/Makefile.am index fc86e02..08e34ef 100644 --- a/lib/bmp/Makefile.am +++ b/lib/bmp/Makefile.am @@ -29,7 +29,8 @@ SUBDIRS = AM_CPPFLAGS = \ -I$(top_srcdir)/ \ -I$(top_srcdir)/lib \ - -I$(top_srcdir)/lib/bgp + -I$(top_srcdir)/lib/bgp \ + -I$(top_srcdir)/lib/openbmp include_HEADERS = \ parsebgp_bmp.h \ diff --git a/lib/mrt/Makefile.am b/lib/mrt/Makefile.am index 6804b4b..4ded797 100644 --- a/lib/mrt/Makefile.am +++ b/lib/mrt/Makefile.am @@ -29,7 +29,8 @@ SUBDIRS = AM_CPPFLAGS = -I$(top_srcdir)/ \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/lib/bgp \ - -I$(top_srcdir)/lib/bmp + -I$(top_srcdir)/lib/bmp \ + -I$(top_srcdir)/lib/openbmp include_HEADERS = parsebgp_mrt.h diff --git a/lib/openbmp/.clang-format b/lib/openbmp/.clang-format new file mode 100644 index 0000000..a61b084 --- /dev/null +++ b/lib/openbmp/.clang-format @@ -0,0 +1,121 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +... + diff --git a/lib/openbmp/Makefile.am b/lib/openbmp/Makefile.am new file mode 100644 index 0000000..af815cc --- /dev/null +++ b/lib/openbmp/Makefile.am @@ -0,0 +1,47 @@ +# +# Copyright (C) 2019 The Regents of the University of California. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +SUBDIRS = + +AM_CPPFLAGS = \ + -I$(top_srcdir)/ \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/lib/bgp \ + -I$(top_srcdir)/lib/bmp + +include_HEADERS = \ + parsebgp_openbmp.h \ + parsebgp_openbmp_opts.h + +noinst_LTLIBRARIES = libparsebgp_openbmp.la + +libparsebgp_openbmp_la_SOURCES = \ + parsebgp_openbmp.c \ + parsebgp_openbmp.h \ + parsebgp_openbmp_opts.c \ + parsebgp_openbmp_opts.h + +CLEANFILES = *~ diff --git a/lib/openbmp/parsebgp_openbmp.c b/lib/openbmp/parsebgp_openbmp.c new file mode 100644 index 0000000..0aaccac --- /dev/null +++ b/lib/openbmp/parsebgp_openbmp.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2019 The Regents of the University of California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "parsebgp_openbmp.h" +#include "parsebgp_utils.h" + +#define BGPSTREAM_UTILS_STR_NAME_LEN 256 +#define IS_ROUTER_MSG (flags & 0x80) +#define IS_ROUTER_IPV6 (flags & 0x40) +#define DESERIALIZE_VAL(to) \ + do { \ + if (((len) - (nread)) < sizeof(to)) { \ + return -1; \ + } \ + memcpy(&(to), (buf), sizeof(to)); \ + nread += sizeof(to); \ + buf += sizeof(to); \ + } while (0) + + +parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, + parsebgp_openbmp_msg_t *msg, + const uint8_t *buf, size_t *buf_len) { + parsebgp_error_t err; + + // remaining bytes in buffer + size_t len = *buf_len; + // how many bytes are read so far + size_t nread = 0; + int newln = 0; + uint8_t ver_maj, ver_min, flags, u8; + uint16_t u16; + uint32_t u32; + int name_len = 0; + + // we want at least a few bytes to do header checks + if (len < 4) { + *buf_len = 0; + return 0; + } + + // is this an OpenBMP ASCII header (either "text" or "legacy-text")? + if (*buf == 'V') { + // skip until we find double-newlines + while ((len - nread) > 0) { + if (newln == 2) { + // this is the first byte of the payload + *buf_len = nread - 1; + return 0; + } + if (*buf == '\n') { + newln++; + } else { + newln = 0; + } + nread++; + buf++; + } + // if we reach here, then we've failed to parse the header. just give up + *buf_len = 0; + return 0; + } + + // double-check the magic number + if (memcmp(buf, "OBMP", 4) != 0) { + // it's not a known OpenBMP header, assume that it is raw BMP + *buf_len = 0; + return 0; + } + nread += 4; + buf += 4; + + // Confirm the version number + DESERIALIZE_VAL(ver_maj); + DESERIALIZE_VAL(ver_min); + if (ver_maj != 1 || ver_min != 7) { + /* + bgpstream_log(BGPSTREAM_LOG_WARN, + "Unrecognized OpenBMP header version (%" PRIu8 ".%" PRIu8 + ")", + ver_maj, ver_min); + */ + printf("Unrecognized OpenBMP header version (%" PRIu8 ".%" PRIu8 ")", + ver_maj, ver_min); + return 0; + } + + // skip past the header length and the message length (since we'll parse the + // entire header anyway). + nread += 2 + 4; + buf += 2 + 4; + + // read the flags + DESERIALIZE_VAL(flags); + // check the flags + if (!IS_ROUTER_MSG) { + // we only care about bmp raw messages, which are always router messages + return 0; + } + + // check the object type + DESERIALIZE_VAL(u8); + if (u8 != 12) { + // we only want BMP RAW messages, so skip this one + return 0; + } + + // load the time stamps into the record + DESERIALIZE_VAL(u32); + // record->time_sec = ntohl(u32); + DESERIALIZE_VAL(u32); + // record->time_usec = ntohl(u32); + + // skip past the collector hash + nread += 16; + buf += 16; + + // grab the collector admin ID as collector name + // TODO: if there is no admin ID, use the hash + DESERIALIZE_VAL(u16); + u16 = ntohs(u16); + // maybe truncate the collector name + if (u16 < BGPSTREAM_UTILS_STR_NAME_LEN) { + name_len = u16; + } else { + name_len = BGPSTREAM_UTILS_STR_NAME_LEN - 1; + } + // copy the collector name in + if ((len - nread) < u16) { + return -1; + } + // memcpy(record->collector_name, buf, name_len); + // record->collector_name[name_len] = '\0'; + nread += u16; + buf += u16; + + if ((len - nread) < 32) { + // not enough buffer left for router hash and IP + return -1; + } + + // skip past the router hash + nread += 16; + buf += 16; + + // grab the router IP + // if (IS_ROUTER_IPV6) { + // bgpstream_ipv6_addr_init(&record->router_ip, buf); + // } else { + // bgpstream_ipv4_addr_init(&record->router_ip, buf); + // } + nread += 16; + buf += 16; + + // router name + // TODO: if there is no name, or it is "default", use the IP + DESERIALIZE_VAL(u16); + u16 = ntohs(u16); + // maybe truncate the router name + if (u16 < BGPSTREAM_UTILS_STR_NAME_LEN) { + name_len = u16; + } else { + name_len = BGPSTREAM_UTILS_STR_NAME_LEN - 1; + } + // copy the router name in + if ((len - nread) < u16) { + return -1; + } + // memcpy(record->router_name, buf, name_len); + // record->router_name[name_len] = '\0'; + nread += u16; + buf += u16; + + // and then ignore the row count + nread += 4; + buf += 4; + + *buf_len = nread; + return 0; +} diff --git a/lib/openbmp/parsebgp_openbmp.h b/lib/openbmp/parsebgp_openbmp.h new file mode 100644 index 0000000..113edb3 --- /dev/null +++ b/lib/openbmp/parsebgp_openbmp.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 The Regents of the University of California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PARSEBGP_OPENBMP_H +#define __PARSEBGP_OPENBMP_H + +#include "parsebgp_opts.h" // the header includes all sub type opts including parsebgp_openbmp_opts.h +#include "parsebgp_bgp.h" // BMP encapsulates BGP messages +#include "parsebgp_bmp.h" // OPENBMP encapsulates BMP messages +#include "parsebgp_error.h" // for parsebgp_error_t +#include +#include + + +typedef struct parsebgp_openbmp_msg { + // will populate the bmp msg if full msg parsing is required + parsebgp_bmp_msg_t *bmp_msg; + +} parsebgp_openbmp_msg_t; + +parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, parsebgp_openbmp_msg_t *msg, + const uint8_t *buf, size_t *len); + +#endif /* __PARSEBGP_OPENBMP_H */ + diff --git a/lib/openbmp/parsebgp_openbmp_opts.c b/lib/openbmp/parsebgp_openbmp_opts.c new file mode 100644 index 0000000..e69de29 diff --git a/lib/openbmp/parsebgp_openbmp_opts.h b/lib/openbmp/parsebgp_openbmp_opts.h new file mode 100644 index 0000000..27172b9 --- /dev/null +++ b/lib/openbmp/parsebgp_openbmp_opts.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019 The Regents of the University of California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PARSEBGP_OPENBMP_OPTS_H +#define __PARSEBGP_OPENBMP_OPTS_H + +#include "parsebgp_bgp_common.h" +#include + +/** + * OpenBMP Parsing Options + */ +typedef struct parsebgp_openbmp_opts { + + +} parsebgp_openbmp_opts_t; + +/** + * Initialize parser options to default values + * + * @param opts pointer to an opts structure to initialize + */ +void parsebgp_openbmp_opts_init(parsebgp_openbmp_opts_t *opts); + +#endif /* __PARSEBGP_OPENBMP_OPTS_H */ + diff --git a/lib/parsebgp.h.in b/lib/parsebgp.h.in index a96e7c9..b6cac05 100644 --- a/lib/parsebgp.h.in +++ b/lib/parsebgp.h.in @@ -46,11 +46,12 @@ typedef enum parsebgp_msg_type { PARSEBGP_MSG_TYPE_BGP = 1, PARSEBGP_MSG_TYPE_BMP = 2, PARSEBGP_MSG_TYPE_MRT = 3, + PARSEBGP_MSG_TYPE_OPENBMP = 4, } parsebgp_msg_type_t; /** Convenience macro to allow iterating over all valid message types */ #define PARSEBGP_FOREACH_MSG_TYPE(iter) \ - for ((iter) = PARSEBGP_MSG_TYPE_BGP; (iter) <= PARSEBGP_MSG_TYPE_MRT; \ + for ((iter) = PARSEBGP_MSG_TYPE_BGP; (iter) <= PARSEBGP_MSG_TYPE_OPENBMP; \ (iter)++) /** Structure into which a message is parsed */ diff --git a/lib/parsebgp_opts.h b/lib/parsebgp_opts.h index 4fa9120..6886875 100644 --- a/lib/parsebgp_opts.h +++ b/lib/parsebgp_opts.h @@ -29,6 +29,7 @@ #include "parsebgp_bgp_opts.h" #include "parsebgp_bmp_opts.h" +#include "parsebgp_openbmp_opts.h" /** * Parsing Options @@ -89,6 +90,9 @@ typedef struct parsebgp_opts { /** BMP-specific parsing options */ parsebgp_bmp_opts_t bmp; + /** OpenBMP-specific parsing options */ + parsebgp_openbmp_opts_t openbmp; + } parsebgp_opts_t; /** diff --git a/tools/Makefile.am b/tools/Makefile.am index dc01e64..31a30dc 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -27,7 +27,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib \ -I$(top_srcdir)/lib/bgp \ -I$(top_srcdir)/lib/bmp \ - -I$(top_srcdir)/lib/mrt + -I$(top_srcdir)/lib/mrt \ + -I$(top_srcdir)/lib/openbmp dist_bin_SCRIPTS = diff --git a/tools/parsebgp.c b/tools/parsebgp.c index d3f79e6..f5dfa27 100644 --- a/tools/parsebgp.c +++ b/tools/parsebgp.c @@ -44,6 +44,7 @@ static const char *type_strs[] = { "bgp", // PARSEBGP_MSG_TYPE_BGP "bmp", // PARSEBGP_MSG_TYPE_BMP "mrt", // PARSEBGP_MSG_TYPE_MRT + "openbmp", // PARSEBGP_MSG_TYPE_OPENBMP }; // should messages NOT be dumped to stdout after parsing @@ -182,7 +183,7 @@ static void usage(void) fprintf( stderr, "usage: %s [options] [type:]file [[type:]file...]\n" - " where 'type' is one of 'bmp', 'bgp', or 'mrt'\n" + " where 'type' is one of 'bmp', 'bgp', 'mrt', or 'openbmp'\n" " (only required if using non-standard file extensions)\n" " -4 Force 4-byte ASN parsing\n" " -b Perform shallow BMP parsing\n" From e1a97749de674f9783f70e4743e67a15d7ab8ace Mon Sep 17 00:00:00 2001 From: Lumin Shi Date: Tue, 27 Aug 2019 16:41:43 -0700 Subject: [PATCH 2/6] preliminary openbmp raw msg parsing support. --- lib/openbmp/parsebgp_openbmp.c | 124 +++++++++++++++++++-------------- lib/openbmp/parsebgp_openbmp.h | 39 ++++++++++- lib/parsebgp.c | 15 ++++ lib/parsebgp.h.in | 4 ++ 4 files changed, 127 insertions(+), 55 deletions(-) diff --git a/lib/openbmp/parsebgp_openbmp.c b/lib/openbmp/parsebgp_openbmp.c index 0aaccac..85f2798 100644 --- a/lib/openbmp/parsebgp_openbmp.c +++ b/lib/openbmp/parsebgp_openbmp.c @@ -24,34 +24,43 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "parsebgp_openbmp.h" #include "parsebgp_utils.h" +#include "parsebgp_openbmp.h" +#include "parsebgp_bmp.h" -#define BGPSTREAM_UTILS_STR_NAME_LEN 256 -#define IS_ROUTER_MSG (flags & 0x80) -#define IS_ROUTER_IPV6 (flags & 0x40) -#define DESERIALIZE_VAL(to) \ - do { \ - if (((len) - (nread)) < sizeof(to)) { \ - return -1; \ - } \ - memcpy(&(to), (buf), sizeof(to)); \ - nread += sizeof(to); \ - buf += sizeof(to); \ - } while (0) +void parsebgp_openbmp_clear_msg(parsebgp_openbmp_msg_t *msg) { + // TODO: reset openbmp header values to zero + parsebgp_bmp_clear_msg(msg->bmp_msg); +} +void parsebgp_openbmp_destroy_msg(parsebgp_openbmp_msg_t *msg) { + parsebgp_bmp_destroy_msg(msg->bmp_msg); + free(msg); +} + +void parsebgp_openbmp_dump_msg(const parsebgp_openbmp_msg_t *msg, int depth) { + // dump openbmp header fields + PARSEBGP_DUMP_INT(depth, "Version major", msg->ver_maj); + PARSEBGP_DUMP_INT(depth, "Version minor", msg->ver_min); + PARSEBGP_DUMP_INT(depth, "Flags", msg->flags); + PARSEBGP_DUMP_INT(depth, "Time.sec", msg->time_sec); + PARSEBGP_DUMP_INT(depth, "Time.usec", msg->time_usec); + PARSEBGP_DUMP_INFO(depth, "Collector name" ": %*s\n", 20 - (int)sizeof("Collector name" ":"), msg->collector_name); + PARSEBGP_DUMP_INFO(depth, "Router name" ": %*s\n", 20 - (int)sizeof("Router name" ":"), msg->router_name); + + // dump bmp msg + parsebgp_bmp_dump_msg(msg->bmp_msg, depth); +} parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, parsebgp_openbmp_msg_t *msg, const uint8_t *buf, size_t *buf_len) { - parsebgp_error_t err; - // remaining bytes in buffer size_t len = *buf_len; // how many bytes are read so far size_t nread = 0; int newln = 0; - uint8_t ver_maj, ver_min, flags, u8; + uint8_t u8; uint16_t u16; uint32_t u32; int name_len = 0; @@ -59,6 +68,7 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, // we want at least a few bytes to do header checks if (len < 4) { *buf_len = 0; + printf("we want at least a few bytes to do header checks\n"); return 0; } @@ -88,23 +98,18 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, if (memcmp(buf, "OBMP", 4) != 0) { // it's not a known OpenBMP header, assume that it is raw BMP *buf_len = 0; + printf("it's not a known OpenBMP header, assume that it is raw BMP\n"); return 0; } nread += 4; buf += 4; // Confirm the version number - DESERIALIZE_VAL(ver_maj); - DESERIALIZE_VAL(ver_min); - if (ver_maj != 1 || ver_min != 7) { - /* - bgpstream_log(BGPSTREAM_LOG_WARN, - "Unrecognized OpenBMP header version (%" PRIu8 ".%" PRIu8 - ")", - ver_maj, ver_min); - */ + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->ver_maj); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->ver_min); + if (msg->ver_maj != 1 || msg->ver_min != 7) { printf("Unrecognized OpenBMP header version (%" PRIu8 ".%" PRIu8 ")", - ver_maj, ver_min); + msg->ver_maj, msg->ver_min); return 0; } @@ -114,25 +119,25 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, buf += 2 + 4; // read the flags - DESERIALIZE_VAL(flags); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->flags); // check the flags - if (!IS_ROUTER_MSG) { - // we only care about bmp raw messages, which are always router messages + // we only care about bmp raw messages, which are always router messages + if (!(msg->flags & 0x80)) { return 0; } // check the object type - DESERIALIZE_VAL(u8); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u8); if (u8 != 12) { // we only want BMP RAW messages, so skip this one return 0; } // load the time stamps into the record - DESERIALIZE_VAL(u32); - // record->time_sec = ntohl(u32); - DESERIALIZE_VAL(u32); - // record->time_usec = ntohl(u32); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u32); + msg->time_sec = ntohl(u32); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u32); + msg->time_usec = ntohl(u32); // skip past the collector hash nread += 16; @@ -140,20 +145,21 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, // grab the collector admin ID as collector name // TODO: if there is no admin ID, use the hash - DESERIALIZE_VAL(u16); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u16); u16 = ntohs(u16); // maybe truncate the collector name - if (u16 < BGPSTREAM_UTILS_STR_NAME_LEN) { + if (u16 < STR_NAME_LEN) { name_len = u16; } else { - name_len = BGPSTREAM_UTILS_STR_NAME_LEN - 1; + name_len = STR_NAME_LEN - 1; } // copy the collector name in if ((len - nread) < u16) { return -1; } - // memcpy(record->collector_name, buf, name_len); - // record->collector_name[name_len] = '\0'; + msg->collector_name_len = name_len; + memcpy(msg->collector_name, buf, name_len); + msg->collector_name[name_len] = '\0'; nread += u16; buf += u16; @@ -167,30 +173,31 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, buf += 16; // grab the router IP - // if (IS_ROUTER_IPV6) { - // bgpstream_ipv6_addr_init(&record->router_ip, buf); - // } else { - // bgpstream_ipv4_addr_init(&record->router_ip, buf); - // } - nread += 16; - buf += 16; + if (msg->flags & 0x40) { // IS_ROUTER_IPV6 + msg->router_ip_afi = PARSEBGP_BGP_AFI_IPV6; + } else { + msg->router_ip_afi = PARSEBGP_BGP_AFI_IPV4; + } + // this marco should automatically increment nread and buf + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->router_ip); // router name // TODO: if there is no name, or it is "default", use the IP - DESERIALIZE_VAL(u16); + PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u16); u16 = ntohs(u16); // maybe truncate the router name - if (u16 < BGPSTREAM_UTILS_STR_NAME_LEN) { + if (u16 < STR_NAME_LEN) { name_len = u16; } else { - name_len = BGPSTREAM_UTILS_STR_NAME_LEN - 1; + name_len = STR_NAME_LEN - 1; } // copy the router name in if ((len - nread) < u16) { return -1; } - // memcpy(record->router_name, buf, name_len); - // record->router_name[name_len] = '\0'; + msg->router_name_len = name_len; + memcpy(msg->router_name, buf, name_len); + msg->router_name[name_len] = '\0'; nread += u16; buf += u16; @@ -198,6 +205,19 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, nread += 4; buf += 4; + // see whether the raw bmp msg is parsed. + size_t slen = len - nread; + PARSEBGP_MAYBE_MALLOC_ZERO(msg->bmp_msg); + parsebgp_error_t bmp_parse_err = parsebgp_bmp_decode(opts, msg->bmp_msg, buf, &slen); + // return err msg from bmp parsing if any. + if (bmp_parse_err != PARSEBGP_OK) { + return bmp_parse_err; + } + // increment read len + nread += slen; + + // set how many bytes were read to parse this openbmp msg. *buf_len = nread; - return 0; + // return an openbmp msg was parsed. + return PARSEBGP_OK; } diff --git a/lib/openbmp/parsebgp_openbmp.h b/lib/openbmp/parsebgp_openbmp.h index 113edb3..39219a6 100644 --- a/lib/openbmp/parsebgp_openbmp.h +++ b/lib/openbmp/parsebgp_openbmp.h @@ -33,16 +33,49 @@ #include "parsebgp_error.h" // for parsebgp_error_t #include #include +#include +#include +#define STR_NAME_LEN 256 typedef struct parsebgp_openbmp_msg { - // will populate the bmp msg if full msg parsing is required + // OpenBMP version numbers + uint8_t ver_maj, ver_min; + + // OpenBMP msg flags + uint8_t flags; + + // Collection time (seconds component) + uint32_t time_sec; + + // Collection time (microseconds component) + uint32_t time_usec; + + // Collector name + int collector_name_len; + char collector_name[STR_NAME_LEN]; + + // Router name + int router_name_len; + char router_name[STR_NAME_LEN]; + + // Router IP + uint8_t router_ip[16]; + // Router IP Address AFI (based on openbmp header flags) + parsebgp_bgp_afi_t router_ip_afi; + + // Parsed bmp msg if full msg parsing is required parsebgp_bmp_msg_t *bmp_msg; } parsebgp_openbmp_msg_t; +void parsebgp_openbmp_clear_msg(parsebgp_openbmp_msg_t *msg); + +void parsebgp_openbmp_destroy_msg(parsebgp_openbmp_msg_t *msg); + +void parsebgp_openbmp_dump_msg(const parsebgp_openbmp_msg_t *msg, int depth); + parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, parsebgp_openbmp_msg_t *msg, - const uint8_t *buf, size_t *len); + const uint8_t *buf, size_t *len); #endif /* __PARSEBGP_OPENBMP_H */ - diff --git a/lib/parsebgp.c b/lib/parsebgp.c index 422a7a8..5b7ed8d 100644 --- a/lib/parsebgp.c +++ b/lib/parsebgp.c @@ -28,6 +28,7 @@ #include "parsebgp_bgp.h" #include "parsebgp_bmp.h" #include "parsebgp_mrt.h" +#include "parsebgp_openbmp.h" #include "parsebgp_utils.h" #include #include @@ -54,6 +55,11 @@ parsebgp_error_t parsebgp_decode(parsebgp_opts_t opts, parsebgp_msg_type_t type, return parsebgp_bgp_decode(&opts, msg->types.bgp, buffer, len); break; + case PARSEBGP_MSG_TYPE_OPENBMP: + PARSEBGP_MAYBE_MALLOC_ZERO(msg->types.openbmp); + return parsebgp_openbmp_decode(&opts, msg->types.openbmp, buffer, len); + break; + default: PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -90,6 +96,10 @@ void parsebgp_clear_msg(parsebgp_msg_t *msg) parsebgp_bgp_clear_msg(msg->types.bgp); break; + case PARSEBGP_MSG_TYPE_OPENBMP: + parsebgp_openbmp_clear_msg(msg->types.openbmp); + break; + default: // invalid message, give up break; @@ -105,6 +115,7 @@ void parsebgp_destroy_msg(parsebgp_msg_t *msg) parsebgp_mrt_destroy_msg(msg->types.mrt); parsebgp_bmp_destroy_msg(msg->types.bmp); parsebgp_bgp_destroy_msg(msg->types.bgp); + parsebgp_openbmp_destroy_msg(msg->types.openbmp); free(msg); } @@ -127,6 +138,10 @@ void parsebgp_dump_msg(const parsebgp_msg_t *msg) parsebgp_bgp_dump_msg(msg->types.bgp, 1); break; + case PARSEBGP_MSG_TYPE_OPENBMP: + parsebgp_openbmp_dump_msg(msg->types.openbmp, 1); + break; + default: PARSEBGP_DUMP_INFO(0, "UNKNOWN MESSAGE TYPE\n"); break; diff --git a/lib/parsebgp.h.in b/lib/parsebgp.h.in index b6cac05..ae39115 100644 --- a/lib/parsebgp.h.in +++ b/lib/parsebgp.h.in @@ -30,6 +30,7 @@ #include "parsebgp_bgp.h" #include "parsebgp_bmp.h" #include "parsebgp_mrt.h" +#include "parsebgp_openbmp.h" #include "parsebgp_opts.h" #include #include @@ -72,6 +73,9 @@ typedef struct parsebgp_msg { /** Parsed MRT message */ parsebgp_mrt_msg_t *mrt; + /** Parsed OpenBMP message */ + parsebgp_openbmp_msg_t *openbmp; + } types; } parsebgp_msg_t; From 1f3439d0b725d698fd35bce0b1b649b1a538c681 Mon Sep 17 00:00:00 2001 From: Lumin Shi Date: Wed, 28 Aug 2019 09:57:55 -0700 Subject: [PATCH 3/6] openbmp clear msg function should be complete now. --- lib/openbmp/parsebgp_openbmp.c | 28 +++++++++++++++++++++++----- lib/openbmp/parsebgp_openbmp.h | 4 ++-- lib/openbmp/parsebgp_openbmp_opts.h | 3 +-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/openbmp/parsebgp_openbmp.c b/lib/openbmp/parsebgp_openbmp.c index 85f2798..49fb1ab 100644 --- a/lib/openbmp/parsebgp_openbmp.c +++ b/lib/openbmp/parsebgp_openbmp.c @@ -29,12 +29,26 @@ #include "parsebgp_bmp.h" void parsebgp_openbmp_clear_msg(parsebgp_openbmp_msg_t *msg) { - // TODO: reset openbmp header values to zero + // reset openbmp header values to zero + msg->ver_maj = 0; + msg->ver_min = 0; + msg->flags = 0; + msg->time_sec = 0; + msg->time_usec = 0; + msg->collector_name_len = 0; + memset(msg->collector_name, 0, sizeof(msg->collector_name)); + msg->router_name_len = 0; + memset(msg->router_name, 0, sizeof(msg->router_name)); + + // clear bmp msg too parsebgp_bmp_clear_msg(msg->bmp_msg); } void parsebgp_openbmp_destroy_msg(parsebgp_openbmp_msg_t *msg) { + // free bmp msg parsebgp_bmp_destroy_msg(msg->bmp_msg); + + // now free openbmp msg itself free(msg); } @@ -45,8 +59,12 @@ void parsebgp_openbmp_dump_msg(const parsebgp_openbmp_msg_t *msg, int depth) { PARSEBGP_DUMP_INT(depth, "Flags", msg->flags); PARSEBGP_DUMP_INT(depth, "Time.sec", msg->time_sec); PARSEBGP_DUMP_INT(depth, "Time.usec", msg->time_usec); - PARSEBGP_DUMP_INFO(depth, "Collector name" ": %*s\n", 20 - (int)sizeof("Collector name" ":"), msg->collector_name); - PARSEBGP_DUMP_INFO(depth, "Router name" ": %*s\n", 20 - (int)sizeof("Router name" ":"), msg->router_name); + + PARSEBGP_DUMP_INFO(depth, "Collector name" ": %*s\n", + msg->collector_name_len, msg->collector_name); + PARSEBGP_DUMP_INFO(depth, "Router name" ": %*s\n", + msg->router_name_len, msg->router_name); + PARSEBGP_DUMP_IP(depth, "Router IP", msg->router_afi, msg->router_ip); // dump bmp msg parsebgp_bmp_dump_msg(msg->bmp_msg, depth); @@ -174,9 +192,9 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, // grab the router IP if (msg->flags & 0x40) { // IS_ROUTER_IPV6 - msg->router_ip_afi = PARSEBGP_BGP_AFI_IPV6; + msg->router_afi = PARSEBGP_BGP_AFI_IPV6; } else { - msg->router_ip_afi = PARSEBGP_BGP_AFI_IPV4; + msg->router_afi = PARSEBGP_BGP_AFI_IPV4; } // this marco should automatically increment nread and buf PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->router_ip); diff --git a/lib/openbmp/parsebgp_openbmp.h b/lib/openbmp/parsebgp_openbmp.h index 39219a6..c4f5eec 100644 --- a/lib/openbmp/parsebgp_openbmp.h +++ b/lib/openbmp/parsebgp_openbmp.h @@ -29,7 +29,7 @@ #include "parsebgp_opts.h" // the header includes all sub type opts including parsebgp_openbmp_opts.h #include "parsebgp_bgp.h" // BMP encapsulates BGP messages -#include "parsebgp_bmp.h" // OPENBMP encapsulates BMP messages +#include "parsebgp_bmp.h" // OpenBMP encapsulates BMP messages #include "parsebgp_error.h" // for parsebgp_error_t #include #include @@ -62,7 +62,7 @@ typedef struct parsebgp_openbmp_msg { // Router IP uint8_t router_ip[16]; // Router IP Address AFI (based on openbmp header flags) - parsebgp_bgp_afi_t router_ip_afi; + parsebgp_bgp_afi_t router_afi; // Parsed bmp msg if full msg parsing is required parsebgp_bmp_msg_t *bmp_msg; diff --git a/lib/openbmp/parsebgp_openbmp_opts.h b/lib/openbmp/parsebgp_openbmp_opts.h index 27172b9..776486f 100644 --- a/lib/openbmp/parsebgp_openbmp_opts.h +++ b/lib/openbmp/parsebgp_openbmp_opts.h @@ -34,8 +34,7 @@ * OpenBMP Parsing Options */ typedef struct parsebgp_openbmp_opts { - - + /* placeholder for openbmp opts */ } parsebgp_openbmp_opts_t; /** From 22cb65803433d103a462f7eb07812116f45af89a Mon Sep 17 00:00:00 2001 From: Lumin Shi Date: Wed, 28 Aug 2019 10:29:48 -0700 Subject: [PATCH 4/6] removed .clang-format from openbmp folder. --- lib/openbmp/.clang-format | 121 -------------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 lib/openbmp/.clang-format diff --git a/lib/openbmp/.clang-format b/lib/openbmp/.clang-format deleted file mode 100644 index a61b084..0000000 --- a/lib/openbmp/.clang-format +++ /dev/null @@ -1,121 +0,0 @@ ---- -Language: Cpp -# BasedOnStyle: LLVM -AccessModifierOffset: -2 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlines: Right -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: MultiLine -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 80 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - - Regex: '.*' - Priority: 1 -IncludeIsMainRegex: '(Test)?$' -IndentCaseLabels: false -IndentPPDirectives: None -IndentWidth: 4 -IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 4 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 60 -PointerAlignment: Right -ReflowComments: true -SortIncludes: true -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 8 -UseTab: Never -... - From 15f825bba254e478e2d52b106dbfc6a6f5251f32 Mon Sep 17 00:00:00 2001 From: Lumin Shi Date: Wed, 28 Aug 2019 13:14:10 -0700 Subject: [PATCH 5/6] openbmp decode function now returns only the parsebgp_error msgs. also removed printf statements. --- lib/openbmp/parsebgp_openbmp.c | 46 ++++++++-------------------------- 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/lib/openbmp/parsebgp_openbmp.c b/lib/openbmp/parsebgp_openbmp.c index 49fb1ab..233f05e 100644 --- a/lib/openbmp/parsebgp_openbmp.c +++ b/lib/openbmp/parsebgp_openbmp.c @@ -73,7 +73,7 @@ void parsebgp_openbmp_dump_msg(const parsebgp_openbmp_msg_t *msg, int depth) { parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, parsebgp_openbmp_msg_t *msg, const uint8_t *buf, size_t *buf_len) { - // remaining bytes in buffer + // remember the buf_len size_t len = *buf_len; // how many bytes are read so far size_t nread = 0; @@ -86,38 +86,14 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, // we want at least a few bytes to do header checks if (len < 4) { *buf_len = 0; - printf("we want at least a few bytes to do header checks\n"); - return 0; + return PARSEBGP_PARTIAL_MSG; } - // is this an OpenBMP ASCII header (either "text" or "legacy-text")? - if (*buf == 'V') { - // skip until we find double-newlines - while ((len - nread) > 0) { - if (newln == 2) { - // this is the first byte of the payload - *buf_len = nread - 1; - return 0; - } - if (*buf == '\n') { - newln++; - } else { - newln = 0; - } - nread++; - buf++; - } - // if we reach here, then we've failed to parse the header. just give up - *buf_len = 0; - return 0; - } - - // double-check the magic number + // check if buf starts with the magic number if (memcmp(buf, "OBMP", 4) != 0) { // it's not a known OpenBMP header, assume that it is raw BMP *buf_len = 0; - printf("it's not a known OpenBMP header, assume that it is raw BMP\n"); - return 0; + return PARSEBGP_INVALID_MSG; } nread += 4; buf += 4; @@ -126,9 +102,7 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->ver_maj); PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->ver_min); if (msg->ver_maj != 1 || msg->ver_min != 7) { - printf("Unrecognized OpenBMP header version (%" PRIu8 ".%" PRIu8 ")", - msg->ver_maj, msg->ver_min); - return 0; + return PARSEBGP_INVALID_MSG; } // skip past the header length and the message length (since we'll parse the @@ -141,14 +115,14 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, // check the flags // we only care about bmp raw messages, which are always router messages if (!(msg->flags & 0x80)) { - return 0; + return PARSEBGP_NOT_IMPLEMENTED; } // check the object type PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u8); if (u8 != 12) { // we only want BMP RAW messages, so skip this one - return 0; + return PARSEBGP_NOT_IMPLEMENTED; } // load the time stamps into the record @@ -173,7 +147,7 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, } // copy the collector name in if ((len - nread) < u16) { - return -1; + return PARSEBGP_PARTIAL_MSG; } msg->collector_name_len = name_len; memcpy(msg->collector_name, buf, name_len); @@ -183,7 +157,7 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, if ((len - nread) < 32) { // not enough buffer left for router hash and IP - return -1; + return PARSEBGP_PARTIAL_MSG; } // skip past the router hash @@ -211,7 +185,7 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, } // copy the router name in if ((len - nread) < u16) { - return -1; + return PARSEBGP_PARTIAL_MSG; } msg->router_name_len = name_len; memcpy(msg->router_name, buf, name_len); From 3bcb01035ea576b222caf73334bd0d9085b55c6c Mon Sep 17 00:00:00 2001 From: Lumin Shi Date: Tue, 3 Sep 2019 10:48:07 -0700 Subject: [PATCH 6/6] added openbmp topic type to differentiate collector msgs from raw_bmp msgs. --- lib/openbmp/parsebgp_openbmp.c | 4 +++- lib/openbmp/parsebgp_openbmp.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/openbmp/parsebgp_openbmp.c b/lib/openbmp/parsebgp_openbmp.c index 233f05e..7beccf6 100644 --- a/lib/openbmp/parsebgp_openbmp.c +++ b/lib/openbmp/parsebgp_openbmp.c @@ -57,6 +57,7 @@ void parsebgp_openbmp_dump_msg(const parsebgp_openbmp_msg_t *msg, int depth) { PARSEBGP_DUMP_INT(depth, "Version major", msg->ver_maj); PARSEBGP_DUMP_INT(depth, "Version minor", msg->ver_min); PARSEBGP_DUMP_INT(depth, "Flags", msg->flags); + PARSEBGP_DUMP_INT(depth, "Topic type", msg->topic_type); PARSEBGP_DUMP_INT(depth, "Time.sec", msg->time_sec); PARSEBGP_DUMP_INT(depth, "Time.usec", msg->time_usec); @@ -118,12 +119,13 @@ parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts, return PARSEBGP_NOT_IMPLEMENTED; } - // check the object type + // check the openbmp topic type PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u8); if (u8 != 12) { // we only want BMP RAW messages, so skip this one return PARSEBGP_NOT_IMPLEMENTED; } + msg->topic_type = u8; // load the time stamps into the record PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u32); diff --git a/lib/openbmp/parsebgp_openbmp.h b/lib/openbmp/parsebgp_openbmp.h index c4f5eec..f2780be 100644 --- a/lib/openbmp/parsebgp_openbmp.h +++ b/lib/openbmp/parsebgp_openbmp.h @@ -44,6 +44,9 @@ typedef struct parsebgp_openbmp_msg { // OpenBMP msg flags uint8_t flags; + // + // OpenBMP topic type (collector or raw_bmp) + uint8_t topic_type; // Collection time (seconds component) uint32_t time_sec;