]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Accept to receive several location and several network policy for
authorVincent Bernat <vbernat@wanadooportails.com>
Mon, 8 Dec 2008 13:45:00 +0000 (14:45 +0100)
committerVincent Bernat <vbernat@wanadooportails.com>
Mon, 8 Dec 2008 13:45:00 +0000 (14:45 +0100)
LLDP-MED

src/lldp.c
src/lldp.h
src/lldpctl.c
src/lldpd.c
src/lldpd.h

index 7bba88ae469e302fbfd885eaf772c81b45edf3a6..1aad0b1f55ecdef4117df9856458569f9a968e79 100644 (file)
@@ -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;
index 7f74f9add6a84a44d221fc7b5a96bb536503a991..b830cde05f8eebc97656b89fa2cd74ffe4e43b6a 100644 (file)
@@ -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
index 3672b594e351c1df615ec02c20cf261d55d4d25b..083103c55b45a8bc14c189023f715ddf70234929 100644 (file)
@@ -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 {
index d45447395a0190ed281ce688b3f53c9a91348102..fb33e45dfa1cbe9041cb8872daf665d5e1d89c14 100644 (file)
@@ -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);
index d564a094f21bb84a8a48319551b0e87524d8a1e0..8143667af1cd3c17df253a72e228d5fe8bd908a2 100644 (file)
@@ -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;