f += size;
hardware->h_rx_unrecognized_cnt++;
#else
+ u_int32_t policy;
+ int loctype;
+
subtype = *(u_int8_t*)(frame + f + 3);
switch (subtype) {
case LLDP_TLV_MED_CAP:
hardware->h_ifname);
goto malformed;
}
- chassis->c_med_policy =
- ntohl(*(u_int32_t*)(frame + f));
+ policy = ntohl(*((u_int32_t *)(frame + f)));
+ if (((policy >> 24) < 1) ||
+ ((policy >> 24) > LLDPMED_APPTYPE_LAST)) {
+ LLOG_INFO("unknown policy field %d "
+ "received on %s",
+ hardware->h_ifname);
+ f += 4;
+ break;
+ }
+ chassis->c_med_policy[(policy >> 24) - 1].type =
+ (policy >> 24);
+ chassis->c_med_policy[(policy >> 24) - 1].unknown =
+ ((policy & 0x800000) != 0);
+ chassis->c_med_policy[(policy >> 24) - 1].tagged =
+ ((policy & 0x400000) != 0);
+ chassis->c_med_policy[(policy >> 24) - 1].vid =
+ (policy & 0x001FFE00) >> 9;
+ chassis->c_med_policy[(policy >> 24) - 1].priority =
+ (policy & 0x1C0) >> 6;
+ chassis->c_med_policy[(policy >> 24) - 1].dscp =
+ policy & 0x3F;
f += 4;
chassis->c_med_cap_enabled |=
LLDPMED_CAP_POLICY;
hardware->h_ifname);
goto malformed;
}
- chassis->c_med_locformat =
- *(u_int8_t*)(frame + f);
+ loctype = *(u_int8_t*)(frame + f);
f += 1;
- if ((chassis->c_med_locdata =
+ if ((loctype < 1) || (loctype > LLDPMED_LOCFORMAT_LAST)) {
+ LLOG_INFO("unknown location type "
+ "received on %s",
+ hardware->h_ifname);
+ f += size - 5;
+ break;
+ }
+ if ((chassis->c_med_location[loctype - 1].data =
(char*)malloc(size - 5)) == NULL) {
LLOG_WARN("unable to allocate memory "
"for LLDP-MED location for "
hardware->h_ifname);
goto malformed;
}
- memcpy(chassis->c_med_locdata,
+ memcpy(chassis->c_med_location[loctype - 1].data,
(char*)(frame + f),
size - 5);
- chassis->c_med_locdata_len = size - 5;
+ chassis->c_med_location[loctype - 1].data_len =
+ size - 5;
+ chassis->c_med_location[loctype - 1].format = loctype;
f += size - 5;
chassis->c_med_cap_enabled |=
LLDPMED_CAP_LOCATION;
void
display_med(struct lldpd_chassis *chassis)
{
+ int i;
printf(" LLDP-MED Device Type: ");
switch (chassis->c_med_type) {
case LLDPMED_CLASS_I:
if (chassis->c_med_cap_enabled & LLDPMED_CAP_IV)
printf(" Inventory");
printf("\n");
- if (chassis->c_med_policy) {
- printf(" LLDP-MED Network Policy:\n");
- printf(" Application Type: ");
- switch(chassis->c_med_policy >> 24) {
- case LLDPMED_APPTYPE_VOICE:
- printf("Voice");
- break;
- case LLDPMED_APPTYPE_VOICESIGNAL:
- printf("Voice Signaling");
- break;
- case LLDPMED_APPTYPE_GUESTVOICE:
- printf("Guest Voice");
- break;
- case LLDPMED_APPTYPE_GUESTVOICESIGNAL:
- printf("Guest Voice Signaling");
- break;
- case LLDPMED_APPTYPE_SOFTPHONEVOICE:
- printf("Softphone Voice");
- break;
- case LLDPMED_APPTYPE_VIDEOCONFERENCE:
- printf("Video Conferencing");
- break;
- case LLDPMED_APPTYPE_VIDEOSTREAM:
- printf("Streaming Video");
- break;
- case LLDPMED_APPTYPE_VIDEOSIGNAL:
- printf("Video Signaling");
- break;
- default:
- printf("Reserved");
- }
- printf("\n Policy: ");
- if((chassis->c_med_policy & 0x00800000) == 0x00800000) {
- printf("unknown, ");
- } else {
- printf("defined, ");
- }
- if((chassis->c_med_policy & 0x00400000) != 0x00400000) {
- printf("un");
- }
- printf("tagged");
- printf("\n VLAN ID: ");
- if((chassis->c_med_policy & 0x001FFE00) >> 9 == 0) {
- printf("Priority Tagged");
- } else if((chassis->c_med_policy & 0x001FFE00) >> 9 == 4095) {
- printf("reserved");
- } else {
- printf("%u", (chassis->c_med_policy & 0x001FFE00) >> 9);
+ for (i = 0; i < LLDPMED_APPTYPE_LAST; i++) {
+ if (i+1 == chassis->c_med_policy[i].type) {
+ printf(" LLDP-MED Network Policy for ");
+ switch(chassis->c_med_policy[i].type) {
+ case LLDPMED_APPTYPE_VOICE:
+ printf("Voice");
+ break;
+ case LLDPMED_APPTYPE_VOICESIGNAL:
+ printf("Voice Signaling");
+ break;
+ case LLDPMED_APPTYPE_GUESTVOICE:
+ printf("Guest Voice");
+ break;
+ case LLDPMED_APPTYPE_GUESTVOICESIGNAL:
+ printf("Guest Voice Signaling");
+ break;
+ case LLDPMED_APPTYPE_SOFTPHONEVOICE:
+ printf("Softphone Voice");
+ break;
+ case LLDPMED_APPTYPE_VIDEOCONFERENCE:
+ printf("Video Conferencing");
+ break;
+ case LLDPMED_APPTYPE_VIDEOSTREAM:
+ printf("Streaming Video");
+ break;
+ case LLDPMED_APPTYPE_VIDEOSIGNAL:
+ printf("Video Signaling");
+ break;
+ default:
+ printf("Reserved");
+ }
+ printf(":\n Policy: ");
+ if (chassis->c_med_policy[i].unknown) {
+ printf("unknown, ");
+ } else {
+ printf("defined, ");
+ }
+ if (!chassis->c_med_policy[i].tagged) {
+ printf("un");
+ }
+ printf("tagged");
+ printf("\n VLAN ID: ");
+ if (chassis->c_med_policy[i].vid == 0) {
+ printf("Priority Tagged");
+ } else if (chassis->c_med_policy[i].vid == 4095) {
+ printf("reserved");
+ } else {
+ printf("%u", chassis->c_med_policy[i].vid);
+ }
+ printf("\n Layer 2 Priority: ");
+ printf("%u", chassis->c_med_policy[i].priority);
+ printf("\n DSCP Value: ");
+ printf("%u\n", chassis->c_med_policy[i].dscp);
}
- printf("\n Layer 2 Priority: ");
- printf("%u", (chassis->c_med_policy & 0x000001C0) >> 6);
- printf("\n DSCP Value: ");
- printf("%u", (chassis->c_med_policy & 0x0000003F));
- printf("\n");
}
- if (chassis->c_med_locformat) {
- printf(" LLDP-MED Location Identification:\n");
- switch(chassis->c_med_locformat) {
- case LLDPMED_LOCFORMAT_COORD:
- printf(" Coordinate-based data");
- break;
- case LLDPMED_LOCFORMAT_CIVIC:
- printf(" Civic address");
- break;
- case LLDPMED_LOCFORMAT_ELIN:
- printf(" ECS ELIN");
- break;
- default:
- printf("unknown location data format: %s",
- dump(chassis->c_med_locdata,
- chassis->c_med_locdata_len, 20, ' '));
+ for (i = 0; i < LLDPMED_LOCFORMAT_LAST; i++) {
+ if (i+1 == chassis->c_med_location[i].format) {
+ printf(" LLDP-MED Location Identification: ");
+ switch(chassis->c_med_location[i].format) {
+ case LLDPMED_LOCFORMAT_COORD:
+ printf("Coordinate-based data");
+ break;
+ case LLDPMED_LOCFORMAT_CIVIC:
+ printf("Civic address");
+ break;
+ case LLDPMED_LOCFORMAT_ELIN:
+ printf("ECS ELIN");
+ break;
+ default:
+ printf("unknown location data format: \n %s",
+ dump(chassis->c_med_location[i].data,
+ chassis->c_med_location[i].data_len, 20, ' '));
+ }
+ printf("\n");
}
- printf("\n");
}
if (chassis->c_med_powtype) {
printf(" LLDP-MED Extended Power-over-Ethernet:\n");
} else {
printf("reserved");
}
- printf("\n Power Priority: ");
+ printf("\n Power Priority: ");
if((chassis->c_med_powtype & 0x0F) == 0x00) {
printf("unknown");
} else if((chassis->c_med_powtype & 0x0F) == 0x01) {
} else {
printf("reserved");
}
- printf("\n Power Value: ");
+ printf("\n Power Value: ");
if(chassis->c_med_powval < 1024) {
printf("%u mW", chassis->c_med_powval * 100);
} else {
#define STRUCT_LLDPD_VLAN "Lsw"
#endif
+#ifdef ENABLE_LLDPMED
+#define STRUCT_LLDPD_MED_POLICY "bbbwbbP"
+struct lldpd_med_policy {
+ u_int8_t type;
+ u_int8_t unknown;
+ u_int8_t tagged;
+ u_int16_t vid;
+ u_int8_t priority;
+ u_int8_t dscp;
+ void *padding;
+};
+
+#define STRUCT_LLDPD_MED_LOC "bCP"
+struct lldpd_med_loc {
+ u_int8_t format;
+ char *data;
+ int data_len;
+ void *padding;
+};
+#endif
+
struct lldpd_chassis {
u_int8_t c_id_subtype;
char *c_id;
u_int32_t c_mgmt_if;
#ifdef ENABLE_LLDPMED
-#define STRUCT_LLDPD_CHASSIS_MED "wwblbCbwsssssss"
+#define STRUCT_LLDPD_CHASSIS_MED \
+ "P" \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_LOC \
+ STRUCT_LLDPD_MED_LOC \
+ STRUCT_LLDPD_MED_LOC \
+ "Pwwbbwsssssss"
+
+ void *c_padding1; /* We force alignment */
+ struct lldpd_med_policy c_med_policy[LLDPMED_APPTYPE_LAST];
+ struct lldpd_med_loc c_med_location[LLDPMED_LOCFORMAT_LAST];
+ void *c_padding2; /* We force alignment */
u_int16_t c_med_cap_available;
u_int16_t c_med_cap_enabled;
u_int8_t c_med_type;
- u_int32_t c_med_policy;
- u_int8_t c_med_locformat;
- char *c_med_locdata;
- int c_med_locdata_len;
u_int8_t c_med_powtype;
u_int16_t c_med_powval;
char *c_med_hw;