X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/fc6f112b40b9da56286ebc125f109e2889f5ebdb..01e8e1485fd8253c288a55bcd78dcd8d0e609bb4:/print-lldp.c diff --git a/print-lldp.c b/print-lldp.c index 1b736919..b7934861 100644 --- a/print-lldp.c +++ b/print-lldp.c @@ -12,23 +12,22 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * support for the IEEE Link Discovery Protocol as per 802.1AB - * * Original code by Hannes Gredler (hannes@juniper.net) * IEEE and TIA extensions by Carles Kishimoto * DCBX extensions by Kaladhar Musunuru */ -#define NETDISSECT_REWORKED +/* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "af.h" @@ -602,6 +601,14 @@ static const struct tok lldp_evb_mode_values[]={ #define LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH 9 #define LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH 8 +#define LLDP_IANA_SUBTYPE_MUDURL 1 + +static const struct tok lldp_iana_subtype_values[] = { + { LLDP_IANA_SUBTYPE_MUDURL, "MUD-URL" }, + { 0, NULL } +}; + + static void print_ets_priority_assignment_table(netdissect_options *ndo, const u_char *ptr) @@ -643,7 +650,7 @@ lldp_private_8021_print(netdissect_options *ndo, int subtype, hexdump = FALSE; u_int sublen; u_int tval; - u_int8_t i; + uint8_t i; if (tlv_len < 4) { return hexdump; @@ -904,10 +911,10 @@ lldp_private_8023_print(netdissect_options *ndo, /* * Extract 34bits of latitude/longitude coordinates. */ -static u_int64_t +static uint64_t lldp_extract_latlon(const u_char *tptr) { - u_int64_t latlon; + uint64_t latlon; latlon = *tptr & 0x3; latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1); @@ -915,6 +922,39 @@ lldp_extract_latlon(const u_char *tptr) return latlon; } +/* objects defined in IANA subtype 00 00 5e + * (right now there is only one) + */ + + +static int +lldp_private_iana_print(netdissect_options *ndo, + const u_char *tptr, u_int tlv_len) +{ + int subtype, hexdump = FALSE; + + if (tlv_len < 8) { + return hexdump; + } + subtype = *(tptr+3); + + ND_PRINT((ndo, "\n\t %s Subtype (%u)", + tok2str(lldp_iana_subtype_values, "unknown", subtype), + subtype)); + + switch (subtype) { + case LLDP_IANA_SUBTYPE_MUDURL: + ND_PRINT((ndo,"\n\t MUD-URL=%.*s",tlv_len-4,tptr+4)); + break; + default: + hexdump=TRUE; + } + + return hexdump; +} + + + /* * Print private TIA extensions. */ @@ -923,10 +963,10 @@ lldp_private_tia_print(netdissect_options *ndo, const u_char *tptr, u_int tlv_len) { int subtype, hexdump = FALSE; - u_int8_t location_format; - u_int16_t power_val; + uint8_t location_format; + uint16_t power_val; u_int lci_len; - u_int8_t ca_type, ca_len; + uint8_t ca_type, ca_len; if (tlv_len < 4) { return hexdump; @@ -1105,9 +1145,9 @@ lldp_private_dcbx_print(netdissect_options *ndo, const u_char *pptr, u_int len) { int subtype, hexdump = FALSE; - u_int8_t tval; - u_int16_t tlv; - u_int32_t i, pgval, uval; + uint8_t tval; + uint16_t tlv; + uint32_t i, pgval, uval; u_int tlen, tlv_type, tlv_len; const u_char *tptr, *mptr; @@ -1180,9 +1220,12 @@ lldp_private_dcbx_print(netdissect_options *ndo, ND_PRINT((ndo, "\n\t SubType: %d", *(tptr + 3))); ND_PRINT((ndo, "\n\t Priority Allocation")); + /* + * Array of 8 4-bit priority group ID values; we fetch all + * 32 bits and extract each nibble. + */ pgval = EXTRACT_32BITS(tptr+4); for (i = 0; i <= 7; i++) { - tval = *(tptr+4+(i/2)); ND_PRINT((ndo, "\n\t PgId_%d: %d", i, (pgval >> (28 - 4 * i)) & 0xF)); } @@ -1262,11 +1305,11 @@ lldp_private_dcbx_print(netdissect_options *ndo, } static char * -lldp_network_addr_print(const u_char *tptr, u_int len) { - - u_int8_t af; +lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len) +{ + uint8_t af; static char buf[BUFSIZE]; - const char * (*pfunc)(const u_char *); + const char * (*pfunc)(netdissect_options *, const u_char *); if (len < 1) return NULL; @@ -1276,15 +1319,15 @@ lldp_network_addr_print(const u_char *tptr, u_int len) { case AFNUM_INET: if (len < 4) return NULL; + /* This cannot be assigned to ipaddr_string(), which is a macro. */ pfunc = getname; break; -#ifdef INET6 case AFNUM_INET6: if (len < 16) return NULL; + /* This cannot be assigned to ip6addr_string(), which is a macro. */ pfunc = getname6; break; -#endif case AFNUM_802: if (len < 6) return NULL; @@ -1300,7 +1343,7 @@ lldp_network_addr_print(const u_char *tptr, u_int len) { tok2str(af_values, "Unknown", af), af); } else { snprintf(buf, sizeof(buf), "AFI %s (%u): %s", - tok2str(af_values, "Unknown", af), af, (*pfunc)(tptr+1)); + tok2str(af_values, "Unknown", af), af, (*pfunc)(ndo, tptr+1)); } return buf; @@ -1308,9 +1351,9 @@ lldp_network_addr_print(const u_char *tptr, u_int len) { static int lldp_mgmt_addr_tlv_print(netdissect_options *ndo, - const u_char *pptr, u_int len) { - - u_int8_t mgmt_addr_len, intf_num_subtype, oid_len; + const u_char *pptr, u_int len) +{ + uint8_t mgmt_addr_len, intf_num_subtype, oid_len; const u_char *tptr; u_int tlen; char *mgmt_addr; @@ -1328,7 +1371,7 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, return 0; } - mgmt_addr = lldp_network_addr_print(tptr, mgmt_addr_len); + mgmt_addr = lldp_network_addr_print(ndo, tptr, mgmt_addr_len); if (mgmt_addr == NULL) { return 0; } @@ -1370,10 +1413,10 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, void lldp_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) { - - u_int8_t subtype; - u_int16_t tlv, cap, ena_cap; + register const u_char *pptr, register u_int len) +{ + uint8_t subtype; + uint16_t tlv, cap, ena_cap; u_int oui, tlen, hexdump, tlv_type, tlv_len; const u_char *tptr; char *network_addr; @@ -1429,7 +1472,7 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 1+6) { goto trunc; } - ND_PRINT((ndo, "%s", etheraddr_string(tptr + 1))); + ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1))); break; case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */ @@ -1441,7 +1484,7 @@ lldp_print(netdissect_options *ndo, break; case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: - network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); + network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1); if (network_addr == NULL) { goto trunc; } @@ -1470,7 +1513,7 @@ lldp_print(netdissect_options *ndo, if (tlv_len < 1+6) { goto trunc; } - ND_PRINT((ndo, "%s", etheraddr_string(tptr + 1))); + ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1))); break; case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */ @@ -1482,7 +1525,7 @@ lldp_print(netdissect_options *ndo, break; case LLDP_PORT_NETWORK_ADDR_SUBTYPE: - network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); + network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1); if (network_addr == NULL) { goto trunc; } @@ -1571,6 +1614,9 @@ lldp_print(netdissect_options *ndo, case OUI_IEEE_8023_PRIVATE: hexdump = lldp_private_8023_print(ndo, tptr, tlv_len); break; + case OUI_IANA: + hexdump = lldp_private_iana_print(ndo,tptr,tlv_len); + break; case OUI_TIA: hexdump = lldp_private_tia_print(ndo, tptr, tlv_len); break;