#include <glib.h>
#include <epan/packet.h>
+#include <epan/expert.h>
#include "packet-llc.h"
#include <epan/etypes.h>
static gint ett_macctrl_cbfc_enbv = -1;
static gint ett_macctrl_cbfc_pause_times = -1;
+static expert_field ei_macctrl_opcode = EI_INIT;
+static expert_field ei_macctrl_cbfc_enbv = EI_INIT;
+static expert_field ei_macctrl_dst_address = EI_INIT;
+
static const int *macctrl_cbfc_enbv_list[] = {
&hf_macctrl_cbfc_enbv_c0,
&hf_macctrl_cbfc_enbv_c1,
{ 0, NULL }
};
-
+static const guint8 dst_addr[] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x01};
+static const address macctrl_dst_address = { AT_ETHER, -1, 6, dst_addr};
static void
dissect_macctrl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_tree *ti;
+ proto_item *ti, *opcode_item;
proto_tree *macctrl_tree = NULL;
proto_tree *pause_times_tree = NULL;
guint16 opcode;
ti = proto_tree_add_item(tree, proto_macctrl, tvb, 0, 46, ENC_NA);
macctrl_tree = proto_item_add_subtree(ti, ett_macctrl);
- proto_tree_add_uint(macctrl_tree, hf_macctrl_opcode, tvb, 0, 2, opcode);
+ opcode_item = proto_tree_add_uint(macctrl_tree, hf_macctrl_opcode, tvb, 0, 2, opcode);
proto_tree_add_item(macctrl_tree, hf_macctrl_timestamp, tvb, 2, 4, ENC_BIG_ENDIAN);
col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, opcode_vals, "Unknown"));
switch (opcode) {
case MACCTRL_PAUSE:
+ if (!addresses_equal(&pinfo->dst, &macctrl_dst_address)) {
+ expert_add_info(pinfo, opcode_item, &ei_macctrl_dst_address);
+ }
+
pause_time = tvb_get_ntohs(tvb, 6);
col_append_fstr(pinfo->cinfo, COL_INFO, ": pause_time: %u quanta",
pause_time);
break;
case MACCTRL_CLASS_BASED_FLOW_CNTRL_PAUSE:
- proto_tree_add_bitmask(macctrl_tree, tvb, 2, hf_macctrl_cbfc_enbv,
+ if (!addresses_equal(&pinfo->dst, &macctrl_dst_address)) {
+ expert_add_info(pinfo, opcode_item, &ei_macctrl_dst_address);
+ }
+
+ ti = proto_tree_add_bitmask(macctrl_tree, tvb, 2, hf_macctrl_cbfc_enbv,
ett_macctrl_cbfc_enbv, macctrl_cbfc_enbv_list, ENC_BIG_ENDIAN);
+ if (tvb_get_guint8(tvb, 2) != 0) {
+ expert_add_info(pinfo, ti, &ei_macctrl_cbfc_enbv);
+ }
pause_times_tree = proto_tree_add_subtree(macctrl_tree, tvb, 4, 8*2, ett_macctrl_cbfc_pause_times, NULL, "CBFC Class Pause Times");
proto_tree_add_item(pause_times_tree, *macctrl_cbfc_pause_times_list[i], tvb, 4+i*2, 2, ENC_BIG_ENDIAN);
}
break;
-
+ default:
+ expert_add_info(pinfo, opcode_item, &ei_macctrl_opcode);
+ break;
}
}
&ett_macctrl_cbfc_enbv,
&ett_macctrl_cbfc_pause_times
};
+
+ static ei_register_info ei[] = {
+ { &ei_macctrl_opcode, { "macc.opcode.unknown", PI_PROTOCOL, PI_WARN, "Unknown opcode", EXPFILL }},
+ { &ei_macctrl_cbfc_enbv, { "macc.cbfc.enbv.not_zero", PI_PROTOCOL, PI_WARN, "8 MSbs of ENBV must be 0", EXPFILL }},
+ { &ei_macctrl_dst_address, { "macc.dst_address_invalid", PI_PROTOCOL, PI_WARN, "Destination address must be 01-80-C2-00-00-01", EXPFILL }},
+ };
+
+ expert_module_t* expert_macctrl;
+
proto_macctrl = proto_register_protocol("MAC Control", "MACC", "macc");
proto_register_field_array(proto_macctrl, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ expert_macctrl = expert_register_protocol(proto_macctrl);
+ expert_register_field_array(expert_macctrl, ei, array_length(ei));
}
void