summaryrefslogtreecommitdiff
path: root/print-bgp.c
diff options
context:
space:
mode:
authorJob Snijders <job@instituut.net>2017-04-17 13:40:10 +0200
committerFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2017-04-17 14:46:38 +0200
commitedf4c90c3402de5a5f69334bc4594415e7c0216d (patch)
tree38a58ac498b3aafd5fea59dc8a6bc772018c2109 /print-bgp.c
parent9c4af7213cc2543a1f5586d8f2c19f86aa0cbe72 (diff)
downloadtcpdump-edf4c90c3402de5a5f69334bc4594415e7c0216d.tar.gz
Add support to decode a BGP Shutdown Communication
The draft-ietf-idr-shutdown-07 document specifies a mechanism to transmit a short free form UTF-8 [RFC3629] message as part of a Cease NOTIFICATION message [RFC4486] to inform the peer why the BGP session is being shutdown or reset. Hat tip to Peter van Dijk <peter.van.dijk@powerdns.com>
Diffstat (limited to 'print-bgp.c')
-rw-r--r--print-bgp.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/print-bgp.c b/print-bgp.c
index 79afeab4..5bc3d4f3 100644
--- a/print-bgp.c
+++ b/print-bgp.c
@@ -259,11 +259,15 @@ static const struct tok bgp_notify_major_values[] = {
/* draft-ietf-idr-cease-subcode-02 */
#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 struct tok bgp_notify_minor_cease_values[] = {
{ BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"},
- { 2, "Administratively Shutdown"},
+ { BGP_NOTIFY_MINOR_CEASE_SHUT, "Administrative Shutdown"},
{ 3, "Peer Unconfigured"},
- { 4, "Administratively Reset"},
+ { BGP_NOTIFY_MINOR_CEASE_RESET, "Administrative Reset"},
{ 5, "Connection Rejected"},
{ 6, "Other Configuration Change"},
{ 7, "Connection Collision Resolution"},
@@ -2604,6 +2608,8 @@ bgp_notification_print(netdissect_options *ndo,
{
struct bgp_notification bgpn;
const u_char *tptr;
+ uint8_t shutdown_comm_length;
+ uint8_t remainder_offset;
ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);
@@ -2669,8 +2675,41 @@ bgp_notification_print(netdissect_options *ndo,
*(tptr+2),
EXTRACT_32BITS(tptr+3)));
}
- break;
- default:
+ /*
+ * draft-ietf-idr-shutdown describes a method to send a communication
+ * intended for human consumption regarding the Administrative Shutdown
+ */
+ if((bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT ||
+ bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) &&
+ length >= BGP_NOTIFICATION_SIZE + 1) {
+ tptr = dat + BGP_NOTIFICATION_SIZE;
+ ND_TCHECK2(*tptr, 1);
+ shutdown_comm_length = *(tptr);
+ remainder_offset = 0;
+ /* garbage, hexdump it all */
+ if (shutdown_comm_length > BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN) {
+ ND_PRINT((ndo, ", invalid Shutdown Communication length"));
+ }
+ else if (shutdown_comm_length == 0) {
+ ND_PRINT((ndo, ", empty Shutdown Communication"));
+ remainder_offset += 1;
+ }
+ /* a proper shutdown communication */
+ else {
+ ND_TCHECK2(*(tptr+1), shutdown_comm_length);
+ ND_PRINT((ndo, ", Shutdown Communication (length: %u): \"", shutdown_comm_length));
+ safeputs(ndo, tptr+1, shutdown_comm_length);
+ ND_PRINT((ndo, "\""));
+ remainder_offset += shutdown_comm_length + 1;
+ }
+ /* if there is trailing data, hexdump it */
+ if(length - (remainder_offset + BGP_NOTIFICATION_SIZE) > 0) {
+ ND_PRINT((ndo, ", Data: (length: %u)", length - (remainder_offset + BGP_NOTIFICATION_SIZE)));
+ hex_print(ndo, "\n\t\t", tptr + remainder_offset, length - (remainder_offset + BGP_NOTIFICATION_SIZE));
+ }
+ }
+ break;
+ default:
break;
}