aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-zebra.c
diff options
context:
space:
mode:
authorHadriel Kaplan <hadriel@128technology.com>2014-12-27 13:29:06 -0500
committerHadriel Kaplan <hadrielk@yahoo.com>2014-12-27 19:40:46 +0000
commitea6f5a3c7e4c04ea804ebb14e7677cabe1ebf952 (patch)
treec44dd0cf37c1411998a86e91a1d847a4829db7a5 /epan/dissectors/packet-zebra.c
parent25c7e0d9df50c8764927922e724aaa18e7f6c738 (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.c163
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[] = {