+ tlen -= sizeof(tlv);
+ tptr += sizeof(tlv);
+
+ /* loop check */
+ if (!tlv_type || !tlv_len) {
+ break;
+ }
+
+ ND_TCHECK_LEN(tptr, tlv_len);
+ if (tlen < tlv_len) {
+ goto trunc;
+ }
+
+ /* decode every tlv */
+ switch (tlv_type) {
+ case LLDP_DCBX_CONTROL_TLV:
+ if (tlv_len < 10) {
+ goto trunc;
+ }
+ ND_PRINT("\n\t Control - Protocol Control (type 0x%x, length %u)",
+ LLDP_DCBX_CONTROL_TLV, tlv_len);
+ ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr));
+ ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1));
+ ND_PRINT("\n\t Sequence Number: %u", GET_BE_U_4(tptr + 2));
+ ND_PRINT("\n\t Acknowledgement Number: %u",
+ GET_BE_U_4(tptr + 6));
+ break;
+ case LLDP_DCBX_PRIORITY_GROUPS_TLV:
+ if (tlv_len < 17) {
+ goto trunc;
+ }
+ ND_PRINT("\n\t Feature - Priority Group (type 0x%x, length %u)",
+ LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len);
+ ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr));
+ ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1));
+ ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2));
+ tval = GET_U_1(tptr + 2);
+ ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u",
+ (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
+ (tval & 0x20) ? 1 : 0);
+ ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3));
+ ND_PRINT("\n\t Priority Allocation");
+
+ /*
+ * Array of 8 4-bit priority group ID values; we fetch all
+ * 32 bits and extract each nibble.
+ */
+ pgval = GET_BE_U_4(tptr + 4);
+ for (i = 0; i <= 7; i++) {
+ ND_PRINT("\n\t PgId_%u: %u",
+ i, (pgval >> (28 - 4 * i)) & 0xF);
+ }
+ ND_PRINT("\n\t Priority Group Allocation");
+ for (i = 0; i <= 7; i++)
+ ND_PRINT("\n\t Pg percentage[%u]: %u", i,
+ GET_U_1(tptr + 8 + i));
+ ND_PRINT("\n\t NumTCsSupported: %u", GET_U_1(tptr + 8 + 8));
+ break;
+ case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV:
+ if (tlv_len < 6) {
+ goto trunc;
+ }
+ ND_PRINT("\n\t Feature - Priority Flow Control");
+ ND_PRINT(" (type 0x%x, length %u)",
+ LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len);
+ ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr));
+ ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1));
+ ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2));
+ tval = GET_U_1(tptr + 2);
+ ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u",
+ (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
+ (tval & 0x20) ? 1 : 0);
+ ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3));
+ tval = GET_U_1(tptr + 4);
+ ND_PRINT("\n\t PFC Config (0x%02X)", GET_U_1(tptr + 4));
+ for (i = 0; i <= 7; i++)
+ ND_PRINT("\n\t Priority Bit %u: %s",
+ i, (tval & (1 << i)) ? "Enabled" : "Disabled");
+ ND_PRINT("\n\t NumTCPFCSupported: %u", GET_U_1(tptr + 5));
+ break;
+ case LLDP_DCBX_APPLICATION_TLV:
+ if (tlv_len < 4) {
+ goto trunc;
+ }
+ ND_PRINT("\n\t Feature - Application (type 0x%x, length %u)",
+ LLDP_DCBX_APPLICATION_TLV, tlv_len);
+ ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr));
+ ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1));
+ ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2));
+ tval = GET_U_1(tptr + 2);
+ ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u",
+ (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
+ (tval & 0x20) ? 1 : 0);
+ ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3));
+ tval = tlv_len - 4;
+ mptr = tptr + 4;
+ while (tval >= 6) {
+ ND_PRINT("\n\t Application Value");
+ ND_PRINT("\n\t Application Protocol ID: 0x%04x",
+ GET_BE_U_2(mptr));
+ uval = GET_BE_U_3(mptr + 2);
+ ND_PRINT("\n\t SF (0x%x) Application Protocol ID is %s",
+ (uval >> 22),
+ (uval >> 22) ? "Socket Number" : "L2 EtherType");
+ ND_PRINT("\n\t OUI: 0x%06x", uval & 0x3fffff);
+ ND_PRINT("\n\t User Priority Map: 0x%02x",
+ GET_U_1(mptr + 5));
+ tval = tval - 6;
+ mptr = mptr + 6;
+ }
+ break;
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ /* do we also want to see a hex dump ? */
+ if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
+ print_unknown_data(ndo, tptr, "\n\t ", tlv_len);
+ }
+
+ tlen -= tlv_len;
+ tptr += tlv_len;
+ }
+
+ trunc:
+ return hexdump;
+}
+
+static char *
+lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len)
+{
+ uint8_t af;