* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * support for the IEEE Link Discovery Protocol as per 802.1AB
- *
*/
-#define NETDISSECT_REWORKED
+/* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
#include <stdio.h>
-#include "interface.h"
+#include "netdissect.h"
#include "extract.h"
#include "addrtoname.h"
#include "af.h"
#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)
int subtype, hexdump = FALSE;
u_int sublen;
u_int tval;
- u_int8_t i;
+ uint8_t i;
if (tlv_len < 4) {
return hexdump;
/*
* 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);
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.
*/
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;
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;
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));
}
}
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;
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;
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;
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;
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;
}
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;
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 */
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;
}
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 */
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;
}
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;