From 85411ad92584fc667075d2ff21133c5dddfd28a2 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 20 Jul 2018 12:49:49 +0000 Subject: [PATCH] Print the timestamp embedded in mrt files for update and status messages. Also implemented the extended precision format so microseconds are printed as well when available. The output is relative to the previous message and follows what kdump does. OK benno@ --- usr.sbin/bgpctl/bgpctl.c | 23 ++++++++++++++++++++--- usr.sbin/bgpctl/mrtparser.c | 33 ++++++++++++++++++++++++++++++--- usr.sbin/bgpctl/mrtparser.h | 4 +++- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c index 17703be446e..130593438a3 100644 --- a/usr.sbin/bgpctl/bgpctl.c +++ b/usr.sbin/bgpctl/bgpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpctl.c,v 1.206 2018/07/20 12:42:45 claudio Exp $ */ +/* $OpenBSD: bgpctl.c,v 1.207 2018/07/20 12:49:49 claudio Exp $ */ /* * Copyright (c) 2003 Henning Brauer @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -2017,6 +2018,20 @@ network_mrt_dump(struct mrt_rib *mr, struct mrt_peer *mp, void *arg) } } +static const char * +print_time(struct timespec *t) +{ + static char timebuf[32]; + static struct timespec prevtime; + struct timespec temp; + + timespecsub(t, &prevtime, &temp); + snprintf(timebuf, sizeof(timebuf), "%lld.%06ld", + (long long)temp.tv_sec, temp.tv_nsec / 1000); + prevtime = *t; + return (timebuf); +} + void show_mrt_state(struct mrt_bgp_state *ms, void *arg) { @@ -2024,7 +2039,8 @@ show_mrt_state(struct mrt_bgp_state *ms, void *arg) mrt_to_bgpd_addr(&ms->src, &src); mrt_to_bgpd_addr(&ms->dst, &dst); - printf("%s[%u] -> ", log_addr(&src), ms->src_as); + printf("%s %s[%u] -> ", print_time(&ms->time), + log_addr(&src), ms->src_as); printf("%s[%u]: %s -> %s\n", log_addr(&dst), ms->dst_as, statenames[ms->old_state], statenames[ms->new_state]); } @@ -2036,7 +2052,8 @@ show_mrt_msg(struct mrt_bgp_msg *mm, void *arg) mrt_to_bgpd_addr(&mm->src, &src); mrt_to_bgpd_addr(&mm->dst, &dst); - printf("%s[%u] -> ", log_addr(&src), mm->src_as); + printf("%s %s[%u] -> ", print_time(&mm->time), + log_addr(&src), mm->src_as); printf("%s[%u]: size %u\n", log_addr(&dst), mm->dst_as, mm->msg_len); } diff --git a/usr.sbin/bgpctl/mrtparser.c b/usr.sbin/bgpctl/mrtparser.c index 1bdfd342cf3..5b11098b182 100644 --- a/usr.sbin/bgpctl/mrtparser.c +++ b/usr.sbin/bgpctl/mrtparser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mrtparser.c,v 1.8 2015/12/23 20:42:20 mmcc Exp $ */ +/* $OpenBSD: mrtparser.c,v 1.9 2018/07/20 12:49:49 claudio Exp $ */ /* * Copyright (c) 2011 Claudio Jeker * @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "mrt.h" @@ -990,14 +991,26 @@ mrt_extract_addr(void *msg, u_int len, union mrt_addr *addr, sa_family_t af) struct mrt_bgp_state * mrt_parse_state(struct mrt_hdr *hdr, void *msg) { + struct timespec t; struct mrt_bgp_state *s; u_int8_t *b = msg; u_int len = ntohl(hdr->length); - u_int32_t sas, das; + u_int32_t sas, das, usec; u_int16_t tmp16, afi; int r; sa_family_t af; + t.tv_sec = ntohl(hdr->timestamp); + t.tv_nsec = 0; + + /* handle the microsec field for _ET header */ + if (ntohs(hdr->type) == MSG_PROTOCOL_BGP4MP_ET) { + memcpy(&usec, b, sizeof(usec)); + b += sizeof(usec); + len -= sizeof(usec); + t.tv_nsec = ntohl(usec) * 1000; + } + switch (ntohs(hdr->subtype)) { case BGP4MP_STATE_CHANGE: if (len < 8) @@ -1061,6 +1074,7 @@ mrt_parse_state(struct mrt_hdr *hdr, void *msg) if ((s = calloc(1, sizeof(struct mrt_bgp_state))) == NULL) err(1, "calloc"); + s->time = t; s->src_as = sas; s->dst_as = das; @@ -1093,14 +1107,26 @@ fail: struct mrt_bgp_msg * mrt_parse_msg(struct mrt_hdr *hdr, void *msg) { + struct timespec t; struct mrt_bgp_msg *m; u_int8_t *b = msg; u_int len = ntohl(hdr->length); - u_int32_t sas, das; + u_int32_t sas, das, usec; u_int16_t tmp16, afi; int r; sa_family_t af; + t.tv_sec = ntohl(hdr->timestamp); + t.tv_nsec = 0; + + /* handle the microsec field for _ET header */ + if (ntohs(hdr->type) == MSG_PROTOCOL_BGP4MP_ET) { + memcpy(&usec, b, sizeof(usec)); + b += sizeof(usec); + len -= sizeof(usec); + t.tv_nsec = ntohl(usec) * 1000; + } + switch (ntohs(hdr->subtype)) { case BGP4MP_MESSAGE: if (len < 8) @@ -1164,6 +1190,7 @@ mrt_parse_msg(struct mrt_hdr *hdr, void *msg) if ((m = calloc(1, sizeof(struct mrt_bgp_msg))) == NULL) err(1, "calloc"); + m->time = t; m->src_as = sas; m->dst_as = das; diff --git a/usr.sbin/bgpctl/mrtparser.h b/usr.sbin/bgpctl/mrtparser.h index 39144f8c893..35d870eff35 100644 --- a/usr.sbin/bgpctl/mrtparser.h +++ b/usr.sbin/bgpctl/mrtparser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mrtparser.h,v 1.1 2011/09/21 10:37:51 claudio Exp $ */ +/* $OpenBSD: mrtparser.h,v 1.2 2018/07/20 12:49:49 claudio Exp $ */ /* * Copyright (c) 2011 Claudio Jeker * @@ -77,6 +77,7 @@ struct mrt_rib { /* data structures for the BGP4MP MESSAGE and STATE types */ struct mrt_bgp_state { + struct timespec time; union mrt_addr src; union mrt_addr dst; u_int32_t src_as; @@ -86,6 +87,7 @@ struct mrt_bgp_state { }; struct mrt_bgp_msg { + struct timespec time; union mrt_addr src; union mrt_addr dst; u_int32_t src_as; -- 2.20.1