Print bgp administrative shutdown messages (draft-ietf-idr-shutdown)
authorbenno <benno@openbsd.org>
Mon, 24 Apr 2017 20:35:35 +0000 (20:35 +0000)
committerbenno <benno@openbsd.org>
Mon, 24 Apr 2017 20:35:35 +0000 (20:35 +0000)
From Job Snijders <job -AT instituut -DOT- net>, thanks!

ok canacar@, deraadt@

usr.sbin/tcpdump/print-bgp.c

index d028d67..d8f233f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: print-bgp.c,v 1.20 2016/10/27 08:21:58 phessler Exp $ */
+/*     $OpenBSD: print-bgp.c,v 1.21 2017/04/24 20:35:35 benno Exp $    */
 
 /*
  * Copyright (C) 1999 WIDE Project.
@@ -228,9 +228,13 @@ static const char *bgpnotify_minor_update[] = {
 
 /* RFC 4486 */
 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX  1
+/* draft-ietf-idr-shutdown-07 */
+#define BGP_NOTIFY_MINOR_CEASE_SHUT                    2
+#define BGP_NOTIFY_MINOR_CEASE_RESET                   4
+#define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN      128
 static const char *bgpnotify_minor_cease[] = {
-       NULL, "Maximum Number of Prefixes Reached", "Administratively Shutdown",
-       "Peer De-configured", "Administratively Reset", "Connection Rejected",
+       NULL, "Maximum Number of Prefixes Reached", "Administrative Shutdown",
+       "Peer De-configured", "Administrative Reset", "Connection Rejected",
        "Other Configuration Change", "Connection Collision Resolution",
        "Out of Resources",
 };
@@ -996,6 +1000,8 @@ bgp_notification_print(const u_char *dat, int length)
        u_int16_t af;
        u_int8_t safi;
        const u_char *p;
+       uint8_t shutdown_comm_length;
+       char shutstring[BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN + 1];
 
        TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
        memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);
@@ -1026,9 +1032,43 @@ bgp_notification_print(const u_char *dat, int length)
 
                        printf(" Max Prefixes: %u", EXTRACT_32BITS(p+3));
                }
+
+               /*
+                * draft-ietf-idr-shutdown describes a method to send a
+                * message intended for human consumption regarding the
+                * Administrative Shutdown or Reset event. This is called
+                * the "Shutdown Communication". The communication is
+                * UTF-8 encoded and may be no longer than 128 bytes.
+                */
+               if ((bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT ||
+                   bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) &&
+                   (length >= BGP_NOTIFICATION_SIZE + 1)) {
+                       p = dat + BGP_NOTIFICATION_SIZE;
+                       TCHECK2(*p, 1);
+                       shutdown_comm_length = *(p);
+
+                       /* sanity checking */
+                       if (shutdown_comm_length == 0)
+                               return;
+                       if (shutdown_comm_length >
+                           BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN)
+                               return;
+                       if (length < (shutdown_comm_length + 1 + BGP_NOTIFICATION_SIZE))
+                               return;
+                       TCHECK2(*(p+1), shutdown_comm_length);
+                       
+                       /* a proper shutdown communication */
+                       printf(", Shutdown Communication [len %u]: \"",
+                           shutdown_comm_length);
+                       memset(shutstring, 0, BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN + 1);
+                       memcpy(shutstring, p+1, shutdown_comm_length);
+                       safeputs(shutstring);
+                       printf("\"");
+               }
        }
 
        return;
+
 trunc:
        printf("[|BGP]");
 }