diff options
author | Hadriel Kaplan <hadriel@128technology.com> | 2014-12-27 13:29:06 -0500 |
---|---|---|
committer | Hadriel Kaplan <hadrielk@yahoo.com> | 2014-12-27 19:40:46 +0000 |
commit | ea6f5a3c7e4c04ea804ebb14e7677cabe1ebf952 (patch) | |
tree | c44dd0cf37c1411998a86e91a1d847a4829db7a5 /epan/dissectors/packet-zebra.c | |
parent | 25c7e0d9df50c8764927922e724aaa18e7f6c738 (diff) |
Zebra dissector highlights wrong byte for version and is missing some fields
Bug: 10809
Change-Id: I916d3ee0644570b689b35575e7277fc7d5ee3396
Reviewed-on: https://code.wireshark.org/review/6081
Petri-Dish: Hadriel Kaplan <hadrielk@yahoo.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Hadriel Kaplan <hadrielk@yahoo.com>
Tested-by: Hadriel Kaplan <hadrielk@yahoo.com>
Diffstat (limited to 'epan/dissectors/packet-zebra.c')
-rw-r--r-- | epan/dissectors/packet-zebra.c | 163 |
1 files changed, 145 insertions, 18 deletions
diff --git a/epan/dissectors/packet-zebra.c b/epan/dissectors/packet-zebra.c index f9e235fc37..0fe3f61093 100644 --- a/epan/dissectors/packet-zebra.c +++ b/epan/dissectors/packet-zebra.c @@ -22,6 +22,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +/* + * The Zebra Protocol is the protocol used between the Zebra routing daemon and other + * protocol daemons (ones for BGP, OSPF, etc.) within the Zebra and Quagga open-source + * routing suites. Zebra itself (https://www.gnu.org/software/zebra) is discontinued, + * and its successor is Quagga (http://www.nongnu.org/quagga). + * + * Both Zebra and Quagga use a "Zebra Protocol", but starting with Quagga v0.99 the + * Zebra Protocol has changed, with a different header format and more commands/types. + * Quagga 0.99.0 was version 1, and 0.99.20 or so changed it to version 2. + * + * See http://www.nongnu.org/quagga/docs/docs-info.html#Zebra-Protocol for some details. + */ + #include "config.h" @@ -38,7 +51,8 @@ static int hf_zebra_request = -1; static int hf_zebra_interface = -1; static int hf_zebra_index = -1; static int hf_zebra_indexnum = -1; -static int hf_zebra_type = -1; +static int hf_zebra_type_v0 = -1; +static int hf_zebra_type_v1 = -1; static int hf_zebra_intflags = -1; static int hf_zebra_rtflags = -1; static int hf_zebra_distance = -1; @@ -49,6 +63,7 @@ static int hf_zebra_bandwidth = -1; static int hf_zebra_family = -1; static int hf_zebra_flags = -1; static int hf_zebra_message = -1; +static int hf_zebra_route_safi = -1; static int hf_zebra_msg_nexthop = -1; static int hf_zebra_msg_index = -1; static int hf_zebra_msg_distance = -1; @@ -62,10 +77,12 @@ static int hf_zebra_prefixlen = -1; static int hf_zebra_prefix4 = -1; static int hf_zebra_prefix6 = -1; static int hf_zebra_version = -1; +static int hf_zebra_marker = -1; static int hf_zebra_intstatus = -1; static int hf_zebra_routeridaddress = -1; static int hf_zebra_routeridmask = -1; static int hf_zebra_mac = -1; +static int hf_zebra_redist_default = -1; static gint ett_zebra = -1; static gint ett_zebra_request = -1; @@ -96,6 +113,7 @@ static gint ett_message = -1; #define ZEBRA_ROUTER_ID_ADD 20 #define ZEBRA_ROUTER_ID_DELETE 21 #define ZEBRA_ROUTER_ID_UPDATE 22 +#define ZEBRA_HELLO 23 static const value_string messages[] = { @@ -121,6 +139,7 @@ static const value_string messages[] = { { ZEBRA_ROUTER_ID_ADD, "Router ID Add" }, { ZEBRA_ROUTER_ID_DELETE, "Router ID Delete" }, { ZEBRA_ROUTER_ID_UPDATE, "Router ID Update" }, + { ZEBRA_HELLO, "Hello" }, { 0, NULL }, }; @@ -135,7 +154,7 @@ static const value_string messages[] = { #define ZEBRA_ROUTE_OSPF6 7 #define ZEBRA_ROUTE_BGP 8 -static const value_string routes[] = { +static const value_string routes_v0[] = { { ZEBRA_ROUTE_SYSTEM, "System Route" }, { ZEBRA_ROUTE_KERNEL, "Kernel Route" }, { ZEBRA_ROUTE_CONNECT, "Connected Route" }, @@ -148,6 +167,33 @@ static const value_string routes[] = { { 0, NULL }, }; +/* + * In Quagga, ISIS is type 8 and BGP is type 9, but Zebra didn't have ISIS... + * so for Zebra BGP is type 8. So we dup the value_string table for quagga. + */ +#define QUAGGA_ROUTE_ISIS 8 +#define QUAGGA_ROUTE_BGP 9 +#define QUAGGA_ROUTE_HSLS 10 +#define QUAGGA_ROUTE_OLSR 11 +#define QUAGGA_ROUTE_BABEL 12 + +static const value_string routes_v1[] = { + { ZEBRA_ROUTE_SYSTEM, "System Route" }, + { ZEBRA_ROUTE_KERNEL, "Kernel Route" }, + { ZEBRA_ROUTE_CONNECT, "Connected Route" }, + { ZEBRA_ROUTE_STATIC, "Static Route" }, + { ZEBRA_ROUTE_RIP, "RIP Route" }, + { ZEBRA_ROUTE_RIPNG, "RIPnG Route" }, + { ZEBRA_ROUTE_OSPF, "OSPF Route" }, + { ZEBRA_ROUTE_OSPF6, "OSPF6 Route" }, + { QUAGGA_ROUTE_ISIS, "ISIS Route" }, + { QUAGGA_ROUTE_BGP, "BGP Route" }, + { QUAGGA_ROUTE_HSLS, "HSLS Route" }, + { QUAGGA_ROUTE_OLSR, "OLSR Route" }, + { QUAGGA_ROUTE_BABEL, "BABEL Route" }, + { 0, NULL }, +}; + /* Zebra's family types. */ #define ZEBRA_FAMILY_IPV4 2 #define ZEBRA_FAMILY_IPV6 10 @@ -179,6 +225,20 @@ static const value_string families[] = { #define ZEBRA_NEXTHOP_TYPE_IPV6_IFINDEX 0x07 #define ZEBRA_NEXTHOP_TYPE_IPV6_IFNAME 0x08 +/* Subsequent Address Family Identifier. */ +#define ZEBRA_SAFI_UNICAST 1 +#define ZEBRA_SAFI_MULTICAST 2 +#define ZEBRA_SAFI_RESERVED_3 3 +#define ZEBRA_SAFI_MPLS_VPN 4 + +static const value_string safi[] = { + { ZEBRA_SAFI_UNICAST, "Unicast" }, + { ZEBRA_SAFI_MULTICAST, "Multicast" }, + { ZEBRA_SAFI_RESERVED_3 , "Reserved" }, + { ZEBRA_SAFI_MPLS_VPN, "MPLS VPN" }, + { 0, NULL }, +}; + #define INTERFACE_NAMSIZ 20 @@ -272,13 +332,18 @@ zebra_route_message(proto_tree *tree, tvbuff_t *tvb, int offset) static int zebra_route(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 len, - guint8 family) + guint8 family, guint8 version) { guint32 prefix4; guint8 message, prefixlen, buffer6[16]; - proto_tree_add_item(tree, hf_zebra_type, tvb, - offset, 1, ENC_BIG_ENDIAN); + if (version == 0) { + proto_tree_add_item(tree, hf_zebra_type_v0, tvb, + offset, 1, ENC_BIG_ENDIAN); + } else { + proto_tree_add_item(tree, hf_zebra_type_v1, tvb, + offset, 1, ENC_BIG_ENDIAN); + } offset += 1; proto_tree_add_item(tree, hf_zebra_rtflags, tvb, @@ -288,6 +353,13 @@ zebra_route(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 len, message = tvb_get_guint8(tvb, offset); offset = zebra_route_message(tree, tvb, offset); + if (version > 1) { + /* version 2 added safi */ + proto_tree_add_item(tree, hf_zebra_route_safi, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + } + prefixlen = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb, offset, 1, prefixlen); @@ -469,9 +541,11 @@ dissect_zebra_request(proto_tree *tree, gboolean request, tvbuff_t *tvb, proto_tree_add_uint(tree, hf_zebra_len, tvb, offset, 2, len); offset += 2; if (version != 0) { + proto_tree_add_item(tree, hf_zebra_marker, tvb, offset, 1, ENC_NA); + offset += 1; proto_tree_add_uint(tree, hf_zebra_version, tvb, offset, 1, version); - offset += 2; + offset += 1; proto_tree_add_uint(tree, hf_zebra_command, tvb, offset, 2, command); offset += 2; @@ -499,17 +573,22 @@ dissect_zebra_request(proto_tree *tree, gboolean request, tvbuff_t *tvb, case ZEBRA_IPV4_ROUTE_ADD: case ZEBRA_IPV4_ROUTE_DELETE: offset = zebra_route(tree, tvb, offset, len, - ZEBRA_FAMILY_IPV4); + ZEBRA_FAMILY_IPV4, version); break; case ZEBRA_IPV6_ROUTE_ADD: case ZEBRA_IPV6_ROUTE_DELETE: offset = zebra_route(tree, tvb, offset, len, - ZEBRA_FAMILY_IPV6); + ZEBRA_FAMILY_IPV6, version); break; case ZEBRA_REDISTRIBUTE_ADD: case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: - proto_tree_add_item(tree, hf_zebra_type, tvb, - offset, 1, ENC_BIG_ENDIAN); + if (version == 0) { + proto_tree_add_item(tree, hf_zebra_type_v0, tvb, + offset, 1, ENC_BIG_ENDIAN); + } else { + proto_tree_add_item(tree, hf_zebra_type_v1, tvb, + offset, 1, ENC_BIG_ENDIAN); + } offset = 1; break; case ZEBRA_IPV4_IMPORT_LOOKUP: @@ -525,14 +604,44 @@ dissect_zebra_request(proto_tree *tree, gboolean request, tvbuff_t *tvb, case ZEBRA_ROUTER_ID_UPDATE: offset = zerba_router_update(tree, tvb, offset); break; + case ZEBRA_ROUTER_ID_ADD: + case ZEBRA_ROUTER_ID_DELETE: case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: - case ZEBRA_REDISTRIBUTE_DELETE: /* nothing to do */ break; + case ZEBRA_REDISTRIBUTE_DELETE: + /* in version 1+, there's a route type field */ + if (version > 0) { + proto_tree_add_item(tree, hf_zebra_type_v1, tvb, + offset, 1, ENC_BIG_ENDIAN); + } + break; + case ZEBRA_HELLO: + proto_tree_add_item(tree, hf_zebra_redist_default, tvb, + offset, 1, ENC_BIG_ENDIAN); + break; } return offset; } +/* + Zebra Protocol header version 0: + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-------------------------------+---------------+ + | Length (2) | Command (1) | + +-------------------------------+---------------+ + + Zebra Protocol header version 1: + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-------------------------------+---------------+-------------+ + | Length (2) | Marker (1) | Version (1) | + +-------------------------------+---------------+-------------+ + | Command (2) | + +-------------------------------+ + The Marker is 0xFF to distinguish it from a version 0 header. + */ static void dissect_zebra(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -548,7 +657,7 @@ dissect_zebra(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset = 0; col_set_str(pinfo->cinfo, COL_INFO, - request? "ZEBRA Request" : "ZEBRA Reply"); + request? "Zebra Request" : "Zebra Reply"); if (tree) { ti = proto_tree_add_item(tree, proto_zebra, tvb, offset, -1, @@ -577,6 +686,8 @@ dissect_zebra(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) version = tvb_get_guint8(tvb, offset+3); command = tvb_get_ntohs(tvb, offset+4); } + col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", + val_to_str(command, messages, "Command Type 0x%02d")); ti = proto_tree_add_uint(zebra_tree, hf_zebra_command, tvb, offset, len, command); @@ -598,23 +709,27 @@ proto_register_zebra(void) { &hf_zebra_len, { "Length", "zebra.len", FT_UINT16, BASE_DEC, NULL, 0x0, - "Length of ZEBRA request", HFILL }}, + "Length of Zebra request", HFILL }}, { &hf_zebra_version, { "Version", "zebra.version", FT_UINT8, BASE_DEC, NULL, 0x0, "Zerbra srv version", HFILL }}, + { &hf_zebra_marker, + { "Marker", "zebra.marker", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Zerbra srv marker", HFILL }}, { &hf_zebra_request, { "Request", "zebra.request", FT_BOOLEAN, BASE_NONE, NULL, 0x0, - "TRUE if ZEBRA request", HFILL }}, + "TRUE if Zebra request", HFILL }}, { &hf_zebra_command, { "Command", "zebra.command", FT_UINT8, BASE_DEC, VALS(messages), 0x0, - "ZEBRA command", HFILL }}, + "Zebra command", HFILL }}, { &hf_zebra_interface, { "Interface", "zebra.interface", FT_STRING, BASE_NONE, NULL, 0x0, - "Interface name of ZEBRA request", HFILL }}, + "Interface name of Zebra request", HFILL }}, { &hf_zebra_index, { "Index", "zebra.index", FT_UINT32, BASE_DEC, NULL, 0x0, @@ -639,6 +754,10 @@ proto_register_zebra(void) { "Message", "zebra.message", FT_UINT8, BASE_DEC, NULL, 0x0, "Message type of route", HFILL }}, + { &hf_zebra_route_safi, + { "SAFI", "zebra.safi", + FT_UINT16, BASE_DEC, VALS(safi), 0x0, + "Subsequent Address Family Identifier", HFILL }}, { &hf_zebra_msg_nexthop, { "Message Nexthop", "zebra.message.nexthop", FT_BOOLEAN, 8, NULL, ZEBRA_ZAPI_MESSAGE_NEXTHOP, @@ -655,9 +774,13 @@ proto_register_zebra(void) { "Message Metric", "zebra.message.metric", FT_BOOLEAN, 8, NULL, ZEBRA_ZAPI_MESSAGE_METRIC, "Message contains metric", HFILL }}, - { &hf_zebra_type, + { &hf_zebra_type_v0, { "Type", "zebra.type", - FT_UINT8, BASE_DEC, VALS(routes), 0x0, + FT_UINT8, BASE_DEC, VALS(routes_v0), 0x0, + "Type of route", HFILL }}, + { &hf_zebra_type_v1, + { "Type", "zebra.type", + FT_UINT8, BASE_DEC, VALS(routes_v1), 0x0, "Type of route", HFILL }}, { &hf_zebra_distance, { "Distance", "zebra.distance", @@ -731,6 +854,10 @@ proto_register_zebra(void) { "MAC address", "zebra.macaddress", FT_ETHER, BASE_NONE, NULL, 0x0, "MAC address of interface", HFILL }}, + { &hf_zebra_redist_default, + { "Redistribute default", "zebra.redist_default", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "TRUE if redistribute default", HFILL }} }; static gint *ett[] = { |