+ if (ndo->ndo_eflag)
+ ether_addresses_print(ndo, src.addr, dst.addr);
+
+ /*
+ * Print the switch tag, if we have one, and skip past it.
+ */
+ if (print_switch_tag != NULL)
+ (*print_switch_tag)(ndo, p);
+
+ length -= switch_tag_len;
+ caplen -= switch_tag_len;
+ p += switch_tag_len;
+ hdrlen += switch_tag_len;
+
+ /*
+ * Get the length/type field, skip past it, and print it
+ * if we're printing the link-layer header.
+ */
+recurse:
+ length_type = GET_BE_U_2(p);
+
+ length -= 2;
+ caplen -= 2;
+ p += 2;
+ hdrlen += 2;
+
+ /*
+ * Process 802.1AE MACsec headers.
+ */
+ printed_length = 0;
+ if (length_type == ETHERTYPE_MACSEC) {
+ /*
+ * MACsec, aka IEEE 802.1AE-2006
+ * Print the header, and try to print the payload if it's not encrypted
+ */
+ if (ndo->ndo_eflag) {
+ ether_type_print(ndo, length_type);
+ ND_PRINT(", length %u: ", orig_length);
+ printed_length = 1;
+ }
+
+ int ret = macsec_print(ndo, &p, &length, &caplen, &hdrlen,
+ &src, &dst);
+
+ if (ret == 0) {
+ /* Payload is encrypted; print it as raw data. */
+ if (!ndo->ndo_suppress_default_print)
+ ND_DEFAULTPRINT(p, caplen);
+ return hdrlen;
+ } else if (ret > 0) {
+ /* Problem printing the header; just quit. */
+ return ret;
+ } else {
+ /*
+ * Keep processing type/length fields.
+ */
+ length_type = GET_BE_U_2(p);
+
+ ND_ICHECK_U(caplen, <, 2);
+ length -= 2;
+ caplen -= 2;
+ p += 2;
+ hdrlen += 2;
+ }
+ }
+
+ /*
+ * Process VLAN tag types.
+ */
+ while (length_type == ETHERTYPE_8021Q ||
+ length_type == ETHERTYPE_8021Q9100 ||
+ length_type == ETHERTYPE_8021Q9200 ||
+ length_type == ETHERTYPE_8021QinQ) {
+ /*
+ * It has a VLAN tag.
+ * Print VLAN information, and then go back and process
+ * the enclosed type field.
+ */
+ if (caplen < 4) {
+ ndo->ndo_protocol = "vlan";
+ nd_print_trunc(ndo);
+ return hdrlen + caplen;
+ }
+ if (length < 4) {
+ ndo->ndo_protocol = "vlan";
+ nd_print_trunc(ndo);
+ return hdrlen + length;
+ }
+ if (ndo->ndo_eflag) {
+ uint16_t tag = GET_BE_U_2(p);
+
+ ether_type_print(ndo, length_type);
+ if (!printed_length) {
+ ND_PRINT(", length %u: ", orig_length);
+ printed_length = 1;
+ } else
+ ND_PRINT(", ");
+ ND_PRINT("%s, ", ieee8021q_tci_string(tag));
+ }