Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenBMP support #73

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 5 additions & 3 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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@

Expand Down
3 changes: 2 additions & 1 deletion lib/bgp/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
3 changes: 2 additions & 1 deletion lib/bmp/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
3 changes: 2 additions & 1 deletion lib/mrt/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
47 changes: 47 additions & 0 deletions lib/openbmp/Makefile.am
Original file line number Diff line number Diff line change
@@ -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 = *~
217 changes: 217 additions & 0 deletions lib/openbmp/parsebgp_openbmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* 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_utils.h"
#include "parsebgp_openbmp.h"
#include "parsebgp_bmp.h"

void parsebgp_openbmp_clear_msg(parsebgp_openbmp_msg_t *msg) {
// 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);
}

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, "Topic type", msg->topic_type);
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",
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);
}

parsebgp_error_t parsebgp_openbmp_decode(parsebgp_opts_t *opts,
parsebgp_openbmp_msg_t *msg,
const uint8_t *buf, size_t *buf_len) {
// remember the buf_len
size_t len = *buf_len;
// how many bytes are read so far
size_t nread = 0;
int newln = 0;
uint8_t 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 PARSEBGP_PARTIAL_MSG;
}

// 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;
return PARSEBGP_INVALID_MSG;
}
nread += 4;
buf += 4;

// Confirm the version number
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) {
return PARSEBGP_INVALID_MSG;
}

// 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
PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, msg->flags);
// check the flags
// we only care about bmp raw messages, which are always router messages
if (!(msg->flags & 0x80)) {
return PARSEBGP_NOT_IMPLEMENTED;
}

// 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);
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;
buf += 16;

// grab the collector admin ID as collector name
// TODO: if there is no admin ID, use the hash
PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u16);
u16 = ntohs(u16);
// maybe truncate the collector name
if (u16 < STR_NAME_LEN) {
name_len = u16;
} else {
name_len = STR_NAME_LEN - 1;
}
// copy the collector name in
if ((len - nread) < u16) {
return PARSEBGP_PARTIAL_MSG;
}
msg->collector_name_len = name_len;
memcpy(msg->collector_name, buf, name_len);
msg->collector_name[name_len] = '\0';
nread += u16;
buf += u16;

if ((len - nread) < 32) {
// not enough buffer left for router hash and IP
return PARSEBGP_PARTIAL_MSG;
}

// skip past the router hash
nread += 16;
buf += 16;

// grab the router IP
if (msg->flags & 0x40) { // IS_ROUTER_IPV6
msg->router_afi = PARSEBGP_BGP_AFI_IPV6;
} else {
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);

// router name
// TODO: if there is no name, or it is "default", use the IP
PARSEBGP_DESERIALIZE_VAL(buf, len - nread, nread, u16);
u16 = ntohs(u16);
// maybe truncate the router name
if (u16 < STR_NAME_LEN) {
name_len = u16;
} else {
name_len = STR_NAME_LEN - 1;
}
// copy the router name in
if ((len - nread) < u16) {
return PARSEBGP_PARTIAL_MSG;
}
msg->router_name_len = name_len;
memcpy(msg->router_name, buf, name_len);
msg->router_name[name_len] = '\0';
nread += u16;
buf += u16;

// and then ignore the row count
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 an openbmp msg was parsed.
return PARSEBGP_OK;
}
Loading