diff options
author | Job Snijders <job@instituut.net> | 2017-04-17 13:40:10 +0200 |
---|---|---|
committer | Francois-Xavier Le Bail <devel.fx.lebail@orange.fr> | 2017-04-17 14:46:38 +0200 |
commit | edf4c90c3402de5a5f69334bc4594415e7c0216d (patch) | |
tree | 38a58ac498b3aafd5fea59dc8a6bc772018c2109 /print-bgp.c | |
parent | 9c4af7213cc2543a1f5586d8f2c19f86aa0cbe72 (diff) | |
download | tcpdump-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.c | 47 |
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; } |