From e3a44efb9d3cb099c8bfe27a4cfc15331ef6bafd Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 8 Dec 2008 14:45:00 +0100 Subject: [PATCH] Accept to receive several location and several network policy for LLDP-MED --- src/lldp.c | 44 ++++++++++++--- src/lldp.h | 2 + src/lldpctl.c | 147 +++++++++++++++++++++++++------------------------- src/lldpd.c | 4 +- src/lldpd.h | 45 ++++++++++++++-- 5 files changed, 157 insertions(+), 85 deletions(-) diff --git a/src/lldp.c b/src/lldp.c index 7bba88ae..1aad0b1f 100644 --- a/src/lldp.c +++ b/src/lldp.c @@ -624,6 +624,9 @@ lldp_decode(struct lldpd *cfg, char *frame, int s, 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: @@ -651,8 +654,27 @@ lldp_decode(struct lldpd *cfg, char *frame, int s, 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; @@ -665,10 +687,16 @@ lldp_decode(struct lldpd *cfg, char *frame, int s, 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 " @@ -676,10 +704,12 @@ lldp_decode(struct lldpd *cfg, char *frame, int s, 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; diff --git a/src/lldp.h b/src/lldp.h index 7f74f9ad..b830cde0 100644 --- a/src/lldp.h +++ b/src/lldp.h @@ -259,10 +259,12 @@ enum { #define LLDPMED_APPTYPE_VIDEOCONFERENCE 6 #define LLDPMED_APPTYPE_VIDEOSTREAM 7 #define LLDPMED_APPTYPE_VIDEOSIGNAL 8 +#define LLDPMED_APPTYPE_LAST LLDPMED_APPTYPE_VIDEOSIGNAL #define LLDPMED_LOCFORMAT_COORD 1 #define LLDPMED_LOCFORMAT_CIVIC 2 #define LLDPMED_LOCFORMAT_ELIN 3 +#define LLDPMED_LOCFORMAT_LAST LLDPMED_LOCFORMAT_ELIN #define LLDPMED_CAP_CAP 0x01 #define LLDPMED_CAP_POLICY 0x02 diff --git a/src/lldpctl.c b/src/lldpctl.c index 3672b594..083103c5 100644 --- a/src/lldpctl.c +++ b/src/lldpctl.c @@ -251,6 +251,7 @@ pretty_print(char *string) void display_med(struct lldpd_chassis *chassis) { + int i; printf(" LLDP-MED Device Type: "); switch (chassis->c_med_type) { case LLDPMED_CLASS_I: @@ -281,79 +282,81 @@ display_med(struct lldpd_chassis *chassis) 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"); @@ -381,7 +384,7 @@ display_med(struct lldpd_chassis *chassis) } 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) { @@ -393,7 +396,7 @@ display_med(struct lldpd_chassis *chassis) } 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 { diff --git a/src/lldpd.c b/src/lldpd.c index d4544739..fb33e45d 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -379,13 +379,15 @@ void lldpd_chassis_cleanup(struct lldpd_chassis *chassis) { #ifdef ENABLE_LLDPMED + int i; 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); - free(chassis->c_med_locdata); + for (i=0; i < LLDPMED_LOCFORMAT_LAST; i++) + free(chassis->c_med_location[i].data); #endif free(chassis->c_id); free(chassis->c_name); diff --git a/src/lldpd.h b/src/lldpd.h index d564a094..8143667a 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -68,6 +68,27 @@ struct lldpd_vlan { #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; @@ -84,14 +105,28 @@ struct lldpd_chassis { 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; -- 2.39.5