Print the timestamp embedded in mrt files for update and status messages.
authorclaudio <claudio@openbsd.org>
Fri, 20 Jul 2018 12:49:49 +0000 (12:49 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 20 Jul 2018 12:49:49 +0000 (12:49 +0000)
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
usr.sbin/bgpctl/mrtparser.c
usr.sbin/bgpctl/mrtparser.h

index 17703be..1305934 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 #include <util.h>
 
@@ -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);
 }
 
index 1bdfd34..5b11098 100644 (file)
@@ -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 <claudio@openbsd.org>
  *
@@ -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, 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;
 
index 39144f8..35d870e 100644 (file)
@@ -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 <claudio@openbsd.org>
  *
@@ -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;