pack_string(struct hmsg *h, void **p, void *s,
const struct formatdef *ct)
{
- int len = strlen(*(char**)s);
+ int len, ss;
+ if ((*(char**)s) == NULL)
+ len = -1;
+ else
+ len = strlen(*(char**)s);
if (h->hdr.len + len + sizeof(int) > MAX_HMSGSIZE -
sizeof(struct hmsg_hdr)) {
LLOG_WARNX("message became too large");
}
memcpy(*p, &len, sizeof(int));
*p += sizeof(int);
- memcpy(*p, *(char **)s, len);
- *p += len;
- h->hdr.len += sizeof(int) + len;
- return sizeof(int) + len;
+ ss = sizeof(int);
+ if (len != -1) {
+ memcpy(*p, *(char **)s, len);
+ *p += len;
+ ss += len;
+ }
+ h->hdr.len += ss;
+ return ss;
}
int
char *string;
int len = *(int*)*p;
*p += sizeof(int);
- if ((string = (char *)calloc(1, len + 1)) == NULL) {
- LLOG_WARNX("unable to allocate new string");
- return -1;
- }
- if (_ctl_alloc_pointer(pointers, string) == -1) {
- free(string);
- return -1;
+ if (len == -1) {
+ string = NULL;
+ } else {
+ if ((string = (char *)calloc(1, len + 1)) == NULL) {
+ LLOG_WARNX("unable to allocate new string");
+ return -1;
+ }
+ if (_ctl_alloc_pointer(pointers, string) == -1) {
+ free(string);
+ return -1;
+ }
+ memcpy(string, *p, len);
+ *p += len;
}
- memcpy(string, *p, len);
- *p += len;
memcpy(s, &string, sizeof(char *));
return sizeof(char*);
}
const char lldpaddr[] = LLDP_MULTICAST_ADDR;
const char dot1[] = LLDP_TLV_ORG_DOT1;
const char dot3[] = LLDP_TLV_ORG_DOT3;
+ const char med[] = LLDP_TLV_ORG_MED;
int f; /* Current position in frame */
int size, type, subtype; /* TLV header */
char *b;
f += size;
hardware->h_rx_unrecognized_cnt++;
}
+ } else if (memcmp(med, frame + f, 3) == 0) {
+ /* LLDP-MED */
+#ifndef ENABLE_LLDPMED
+ f += size;
+ hardware->h_rx_unrecognized_cnt++;
+#else
+ subtype = *(u_int8_t*)(frame + f + 3);
+ switch (subtype) {
+ case LLDP_TLV_MED_CAP:
+ f += 4;
+ if (size != 7) {
+ LLOG_WARN("too short LLDP-MED cap "
+ "tlv received on %s",
+ hardware->h_ifname);
+ goto malformed;
+ }
+ chassis->c_med_cap =
+ ntohs(*(u_int16_t*)(frame + f));
+ f += 2;
+ chassis->c_med_type =
+ *(u_int8_t*)(frame + f);
+ f += 1;
+ break;
+ case LLDP_TLV_MED_IV_HW:
+ case LLDP_TLV_MED_IV_SW:
+ case LLDP_TLV_MED_IV_FW:
+ case LLDP_TLV_MED_IV_SN:
+ case LLDP_TLV_MED_IV_MANUF:
+ case LLDP_TLV_MED_IV_MODEL:
+ case LLDP_TLV_MED_IV_ASSET:
+ f += 4;
+ if (size <= 4)
+ b = NULL;
+ else {
+ b = (char*)malloc(size - 4);
+ strlcpy(b,
+ (char*)(frame + f),
+ size - 4);
+ }
+ switch (subtype) {
+ case LLDP_TLV_MED_IV_HW:
+ chassis->c_med_hw = b;
+ break;
+ case LLDP_TLV_MED_IV_FW:
+ chassis->c_med_fw = b;
+ break;
+ case LLDP_TLV_MED_IV_SW:
+ chassis->c_med_sw = b;
+ break;
+ case LLDP_TLV_MED_IV_SN:
+ chassis->c_med_sn = b;
+ break;
+ case LLDP_TLV_MED_IV_MANUF:
+ chassis->c_med_manuf = b;
+ break;
+ case LLDP_TLV_MED_IV_MODEL:
+ chassis->c_med_fw = b;
+ break;
+ case LLDP_TLV_MED_IV_ASSET:
+ chassis->c_med_fw = b;
+ break;
+ default:
+ LLOG_WARNX("should not be there!");
+ free(b);
+ break;
+ }
+ f += size - 4;
+ break;
+ default:
+ /* Unknown LLDP MED, ignore it */
+ f += size;
+ hardware->h_rx_unrecognized_cnt++;
+ }
+#endif /* ENABLE_LLDPMED */
} else {
LLOG_INFO("unknown org tlv received on %s",
hardware->h_ifname);
*newport = port;
return 1;
malformed:
+#ifdef ENABLE_LLDPMED
+ free(chassis->c_med_hw);
+ free(chassis->c_med_fw);
+ free(chassis->c_med_sn);
+ free(chassis->c_med_manuf);
+ free(chassis->c_med_model);
+ free(chassis->c_med_asset);
+#endif
free(chassis->c_id);
free(chassis->c_name);
free(chassis->c_descr);
printf(" %s\n", string);
}
+#ifdef ENABLE_LLDPMED
+void
+display_med(struct lldpd_chassis *chassis)
+{
+ printf(" LLDP-MED device type: ");
+ switch (chassis->c_med_type) {
+ case LLDPMED_CLASS_I:
+ printf("Generic Endpoint (Class I)");
+ break;
+ case LLDPMED_CLASS_II:
+ printf("Media Endpoint (Class II)");
+ break;
+ case LLDPMED_CLASS_III:
+ printf("Communication Device Endpoint (Class III)");
+ break;
+ case LLDPMED_NETWORK_DEVICE:
+ printf("Network Connectivity Device");
+ break;
+ default:
+ printf("Unknown (%d)", chassis->c_med_type);
+ break;
+ }
+ printf("\n LLDP-MED capabilities:");
+ if (chassis->c_med_cap & LLDPMED_CAP_CAP)
+ printf(" Capabilities");
+ if (chassis->c_med_cap & LLDPMED_CAP_POLICY)
+ printf(" Policy");
+ if (chassis->c_med_cap & LLDPMED_CAP_LOCATION)
+ printf(" Location");
+ if (chassis->c_med_cap & (LLDPMED_CAP_MDI1 | LLDPMED_CAP_MDI2))
+ printf(" MDI");
+ if (chassis->c_med_cap & LLDPMED_CAP_IV)
+ printf(" Inventory");
+ printf("\n");
+ if (chassis->c_med_hw ||
+ chassis->c_med_sw ||
+ chassis->c_med_fw ||
+ chassis->c_med_sn ||
+ chassis->c_med_manuf ||
+ chassis->c_med_model ||
+ chassis->c_med_asset) {
+ printf(" LLDP-MED Inventory:\n");
+ if (chassis->c_med_hw)
+ printf(" Hardware Revision: %s\n", chassis->c_med_hw);
+ if (chassis->c_med_sw)
+ printf(" Software Revision: %s\n", chassis->c_med_sw);
+ if (chassis->c_med_fw)
+ printf(" Firmware Revision: %s\n", chassis->c_med_fw);
+ if (chassis->c_med_sn)
+ printf(" Serial Number: %s\n", chassis->c_med_sn);
+ if (chassis->c_med_manuf)
+ printf(" Manufacturer: %s\n",
+ chassis->c_med_manuf);
+ if (chassis->c_med_model)
+ printf(" Model: %s\n",
+ chassis->c_med_model);
+ if (chassis->c_med_asset)
+ printf(" Asset ID: %s\n",
+ chassis->c_med_asset);
+ }
+}
+#endif
+
void
display_chassis(struct lldpd_chassis *chassis)
{
display_vlans(&port);
}
}
+#ifdef ENABLE_LLDPMED
+ if (chassis.c_med_cap) {
+ printf("\n");
+ display_med(&chassis);
+ }
+#endif
printf("%s\n", sep);
}
}
#endif
};
-#ifndef ENABLE_LLDP_MED
+#ifndef ENABLE_LLDPMED
#define STRUCT_LLDPD_CHASSIS "bCsswwwll"
#else
#define STRUCT_LLDPD_CHASSIS "bCsswwwllwbsssssss"