+ nd_print_trunc(ndo);
+ return ep;
+}
+
+static const u_char *
+of10_bsn_actions_print(netdissect_options *ndo,
+ const u_char *cp, const u_char *ep, const u_int len)
+{
+ const u_char *cp0 = cp;
+ uint32_t subtype, vlan_tag;
+
+ if (len < 4)
+ goto invalid;
+ /* subtype */
+ ND_TCHECK_4(cp);
+ subtype = GET_BE_U_4(cp);
+ cp += 4;
+ ND_PRINT("\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype));
+ switch (subtype) {
+ case BSN_ACTION_MIRROR:
+ /*
+ * 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
+ * +---------------+---------------+---------------+---------------+
+ * | subtype |
+ * +---------------+---------------+---------------+---------------+
+ * | dest_port |
+ * +---------------+---------------+---------------+---------------+
+ * | vlan_tag |
+ * +---------------+---------------+---------------+---------------+
+ * | copy_stage | pad |
+ * +---------------+---------------+---------------+---------------+
+ *
+ */
+ if (len != 16)
+ goto invalid;
+ /* dest_port */
+ ND_TCHECK_4(cp);
+ ND_PRINT(", dest_port %u", GET_BE_U_4(cp));
+ cp += 4;
+ /* vlan_tag */
+ ND_TCHECK_4(cp);
+ vlan_tag = GET_BE_U_4(cp);
+ cp += 4;
+ switch (vlan_tag >> 16) {
+ case 0:
+ ND_PRINT(", vlan_tag none");
+ break;
+ case ETHERTYPE_8021Q:
+ ND_PRINT(", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff));
+ break;
+ default:
+ ND_PRINT(", vlan_tag unknown (0x%04x)", vlan_tag >> 16);
+ }
+ /* copy_stage */
+ ND_TCHECK_1(cp);
+ ND_PRINT(", copy_stage %s",
+ tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", GET_U_1(cp)));
+ cp += 1;
+ /* pad */
+ ND_TCHECK_3(cp);
+ cp += 3;
+ break;
+ default:
+ ND_TCHECK_LEN(cp, len - 4);
+ cp += len - 4;
+ }
+
+ return cp;
+
+invalid:
+ nd_print_invalid(ndo);
+ ND_TCHECK_LEN(cp0, len);
+ return cp0 + len;
+trunc:
+ nd_print_trunc(ndo);
+ return ep;
+}
+
+static const u_char *
+of10_vendor_action_print(netdissect_options *ndo,
+ const u_char *cp, const u_char *ep, const u_int len)
+{
+ uint32_t vendor;
+ const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, const u_int);
+
+ if (len < 4)
+ goto invalid;
+ /* vendor */
+ ND_TCHECK_4(cp);
+ vendor = GET_BE_U_4(cp);
+ cp += 4;
+ ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
+ /* data */
+ decoder =
+ vendor == OUI_BSN ? of10_bsn_actions_print :
+ of10_data_print;
+ return decoder(ndo, cp, ep, len - 4);
+
+invalid: /* skip the undersized data */
+ nd_print_invalid(ndo);
+ ND_TCHECK_LEN(cp, len);
+ return cp + len;
+trunc:
+ nd_print_trunc(ndo);