+ ND_PRINT(", vport_no %u", GET_BE_U_4(cp));
+ break;
+ case BSN_SHELL_COMMAND:
+ /*
+ * 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 |
+ * +---------------+---------------+---------------+---------------+
+ * | service |
+ * +---------------+---------------+---------------+---------------+
+ * | data ...
+ * +---------------+---------------+--------
+ *
+ */
+ if (len < 4)
+ goto invalid;
+ /* service */
+ ND_PRINT(", service %u", GET_BE_U_4(cp));
+ OF_FWD(4);
+ /* data */
+ ND_PRINT(", data '");
+ nd_printn(ndo, cp, len, NULL);
+ ND_PRINT("'");
+ break;
+ case BSN_SHELL_OUTPUT:
+ /*
+ * 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 |
+ * +---------------+---------------+---------------+---------------+
+ * | data ...
+ * +---------------+---------------+--------
+ *
+ */
+ /* already checked that len >= 4 */
+ /* data */
+ ND_PRINT(", data '");
+ nd_printn(ndo, cp, len, NULL);
+ ND_PRINT("'");
+ break;
+ case BSN_SHELL_STATUS:
+ /*
+ * 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 |
+ * +---------------+---------------+---------------+---------------+
+ * | status |
+ * +---------------+---------------+---------------+---------------+
+ *
+ */
+ if (len != 4)
+ goto invalid;
+ /* status */
+ ND_PRINT(", status 0x%08x", GET_BE_U_4(cp));
+ break;
+ default:
+ ND_TCHECK_LEN(cp, len);
+ }
+ return;
+
+invalid: /* skip the undersized data */
+ nd_print_invalid(ndo);
+ ND_TCHECK_LEN(cp, len);
+}
+
+static void
+of10_bsn_actions_print(netdissect_options *ndo,
+ const u_char *cp, u_int len)
+{
+ uint32_t subtype, vlan_tag;
+
+ if (len < 4)
+ goto invalid;
+ /* subtype */
+ subtype = GET_BE_U_4(cp);
+ OF_FWD(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 != 12)
+ goto invalid;
+ /* dest_port */
+ ND_PRINT(", dest_port %u", GET_BE_U_4(cp));
+ OF_FWD(4);
+ /* vlan_tag */
+ vlan_tag = GET_BE_U_4(cp);
+ OF_FWD(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_PRINT(", copy_stage %s",
+ tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", GET_U_1(cp)));
+ OF_FWD(1);
+ /* pad */
+ /* Always the last field, check bounds. */
+ ND_TCHECK_3(cp);