This diffs adds timestamps similar to kdump to bgpctl show mrt output
when messages or states are shown.
Currently it looks like this:
1531425344.000000 153.5.146.105[23456] -> 62.48.0.253[0]: size 63
0.000000 153.5.146.105[23456] -> 62.48.0.253[0]: Connect -> OpenSent
0.000000 153.5.146.105[23456] -> 62.48.0.252[0]: size 63
0.000000 153.5.146.105[23456] -> 62.48.0.252[0]: Connect -> OpenSent
0.000000 153.5.146.105[196618] -> 62.48.0.253[8271]: size 19
0.000000 153.5.146.105[196618] -> 62.48.0.253[8271]: OpenSent -> OpenConfirm
0.000000 153.5.146.105[196618] -> 62.48.0.252[8271]: size 19
0.000000 153.5.146.105[196618] -> 62.48.0.252[8271]: OpenSent -> OpenConfirm
0.000000 153.5.146.105[196618] -> 62.48.0.253[8271]: OpenConfirm -> Established
0.000000 153.5.146.105[196618] -> 62.48.0.252[8271]: OpenConfirm -> Established
0.000000 153.5.146.105[196618] -> 62.48.0.253[8271]: size 23
0.000000 153.5.146.105[196618] -> 62.48.0.252[8271]: size 23
My dump did not include microseconds yet so they are all 0.
OK?
--
:wq Claudio
Index: bgpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.205
diff -u -p -r1.205 bgpctl.c
--- bgpctl.c 12 Jul 2018 21:45:37 -0000 1.205
+++ bgpctl.c 17 Jul 2018 16:29:48 -0000
@@ -2010,6 +2010,20 @@ network_mrt_dump(struct mrt_rib *mr, str
}
}
+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)
{
@@ -2017,7 +2031,8 @@ show_mrt_state(struct mrt_bgp_state *ms,
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]);
}
@@ -2029,7 +2044,8 @@ show_mrt_msg(struct mrt_bgp_msg *mm, voi
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);
}
Index: mrtparser.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/mrtparser.c,v
retrieving revision 1.8
diff -u -p -r1.8 mrtparser.c
--- mrtparser.c 23 Dec 2015 20:42:20 -0000 1.8
+++ mrtparser.c 17 Jul 2018 16:26:09 -0000
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#include "mrt.h"
@@ -990,14 +991,26 @@ mrt_extract_addr(void *msg, u_int len, u
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, voi
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
if ((m = calloc(1, sizeof(struct mrt_bgp_msg))) == NULL)
err(1, "calloc");
+ m->time = t;
m->src_as = sas;
m->dst_as = das;
Index: mrtparser.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/mrtparser.h,v
retrieving revision 1.1
diff -u -p -r1.1 mrtparser.h
--- mrtparser.h 21 Sep 2011 10:37:51 -0000 1.1
+++ mrtparser.h 17 Jul 2018 16:26:09 -0000
@@ -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;