]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Adapt lldpctl to display received systems for each port.
authorVincent Bernat <bernat@luffy.cx>
Sun, 24 May 2009 12:29:15 +0000 (14:29 +0200)
committerVincent Bernat <bernat@luffy.cx>
Sun, 24 May 2009 19:31:18 +0000 (21:31 +0200)
src/client.c
src/ctl.c
src/lldpctl.c
src/lldpd.h

index a8a2ed8b16d318a1ffd5af26d82874b98b8f1ed2..68a24153db9879e0ec4f98f6894f6bdf24107ce2 100644 (file)
@@ -19,8 +19,9 @@
 static struct client_handle client_handles[] = {
        { HMSG_NONE, client_handle_none },
        { HMSG_GET_INTERFACES, client_handle_get_interfaces },
-       { HMSG_GET_CHASSIS, client_handle_port_related },
+       { HMSG_GET_NB_PORTS, client_handle_port_related },
        { HMSG_GET_PORT, client_handle_port_related },
+       { HMSG_GET_CHASSIS, client_handle_port_related },
 #ifdef ENABLE_LLDPMED
        { HMSG_SET_LOCATION, client_handle_port_related },
 #endif
@@ -133,10 +134,9 @@ client_handle_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s)
 {
        char *ifname;
        struct lldpd_hardware *hardware;
+       struct lldpd_port *port;
        void *p;
-#ifdef ENABLE_LLDPMED
        int i;
-#endif
 
        ifname = (char*)(&r->data);
        if ((r->hdr.len < IFNAMSIZ) || (ifname[IFNAMSIZ - 1] != 0)) {
@@ -147,15 +147,6 @@ client_handle_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s)
        }
        TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
                if (strncmp(ifname, hardware->h_ifname, IFNAMSIZ) == 0) {
-                       if (r->hdr.type != HMSG_SET_LOCATION) {
-                               if ((hardware->h_rport == NULL) ||
-                                   (hardware->h_rchassis == NULL)) {
-                                       s->hdr.len = 0;
-                                       s->hdr.type = HMSG_NONE;
-                                       return;
-                               }
-                       }
-                       p = &s->data;
                        switch (r->hdr.type) {
 #ifdef ENABLE_LLDPMED
                        case HMSG_SET_LOCATION:
@@ -176,34 +167,72 @@ client_handle_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s)
                                hardware->h_lport.p_med_cap_enabled |= LLDPMED_CAP_LOCATION;
                                break;
 #endif
-#ifdef ENABLE_DOT1
+                       case HMSG_GET_NB_PORTS:
+                               p = &s->data;
+                               i = 0;
+                               TAILQ_FOREACH(port, &hardware->h_rports, p_entries) i++;
+                               memcpy(p, &i, sizeof(int));
+                               s->hdr.len = sizeof(int);
+                               break;
                        case HMSG_GET_VLANS:
-                               if (ctl_msg_pack_list(STRUCT_LLDPD_VLAN,
-                                       &hardware->h_rport->p_vlans,
-                                       sizeof(struct lldpd_vlan), s, &p) == -1) {
-                                       LLOG_WARNX("unable to send vlans information for "
-                                           "interface %s for %d", ifname, r->hdr.pid);
+                       case HMSG_GET_PORT:
+                       case HMSG_GET_CHASSIS:
+                               /* We read the index which is right after the interface name */
+                               if (r->hdr.len < IFNAMSIZ + sizeof(int)) {
+                                       LLOG_WARNX("too short message format for get "
+                                           "port related message (%d)", r->hdr.type);
                                        s->hdr.len = -1;
                                        return;
                                }
-                               break;
-#endif
-                       case HMSG_GET_PORT:
-                               if (ctl_msg_pack_structure(STRUCT_LLDPD_PORT,
-                                       hardware->h_rport,
-                                       sizeof(struct lldpd_port), s, &p) == -1) {
-                                       LLOG_WARNX("unable to send port information for "
-                                           "interface %s for %d", ifname, r->hdr.pid);
+                               p = (char*)&r->data + IFNAMSIZ;
+                               memcpy(&i, p, sizeof(int));
+                               p = &s->data;
+                               TAILQ_FOREACH(port, &hardware->h_rports, p_entries)
+                                   if (i-- == 0) break;
+                               if (!port) {
+                                       LLOG_INFO("out of range index requested for port "
+                                           "related information on interface %s for %d",
+                                           ifname, r->hdr.pid);
                                        s->hdr.len = -1;
                                        return;
                                }
-                               break;
-                       case HMSG_GET_CHASSIS:
-                               if (ctl_msg_pack_structure(STRUCT_LLDPD_CHASSIS,
-                                       hardware->h_rchassis,
-                                       sizeof(struct lldpd_chassis), s, &p) == -1) {
-                                       LLOG_WARNX("unable to send chassis information for "
-                                           "interface %s for %d", ifname, r->hdr.pid);
+                               p = (char*)&s->data;
+                               switch (r->hdr.type) {
+#ifdef ENABLE_DOT1
+                               case HMSG_GET_VLANS:
+                                       if (ctl_msg_pack_list(STRUCT_LLDPD_VLAN,
+                                               &port->p_vlans,
+                                               sizeof(struct lldpd_vlan), s, &p) == -1) {
+                                               LLOG_WARNX("unable to send vlans information for "
+                                                   "interface %s for %d", ifname, r->hdr.pid);
+                                               s->hdr.len = -1;
+                                               return;
+                                       }
+                                       break;
+#endif
+                               case HMSG_GET_PORT:
+                                       if (ctl_msg_pack_structure(STRUCT_LLDPD_PORT,
+                                               port,
+                                               sizeof(struct lldpd_port), s, &p) == -1) {
+                                               LLOG_WARNX("unable to send port information for "
+                                                   "interface %s for %d", ifname, r->hdr.pid);
+                                               s->hdr.len = -1;
+                                               return;
+                                       }
+                                       break;
+                               case HMSG_GET_CHASSIS:
+                                       if (ctl_msg_pack_structure(STRUCT_LLDPD_CHASSIS,
+                                               port->p_chassis,
+                                               sizeof(struct lldpd_chassis), s, &p) == -1) {
+                                               LLOG_WARNX("unable to send chassis information "
+                                                   "for interface %s for %d",
+                                                   ifname, r->hdr.pid);
+                                               s->hdr.len = -1;
+                                               return;
+                                       }
+                                       break;
+                               default:
+                                       LLOG_WARNX("don't know what to do");
                                        s->hdr.len = -1;
                                        return;
                                }
index 2268e0b888af647f5b21512dc79807c12bd0e6a0..6f2bce34faf4dddcefe0c057cb1ff8c7ba55a0ea 100644 (file)
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -156,10 +156,12 @@ TAILQ_HEAD(gc_l, gc);
 
 typedef struct { char c; int16_t x; } st_int16;
 typedef struct { char c; int32_t x; } st_int32;
+typedef struct { char c; time_t x; } st_timet;
 typedef struct { char c; void *x; } st_void_p;
 
 #define INT16_ALIGN (sizeof(st_int16) - sizeof(int16_t))
 #define INT32_ALIGN (sizeof(st_int32) - sizeof(int32_t))
+#define TIMET_ALIGN (sizeof(st_timet) - sizeof(time_t))
 #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
 
 struct formatdef {
@@ -353,6 +355,8 @@ static struct formatdef conv_table[] = {
         pack_copy,     unpack_copy},
        {'l',   4,                              INT32_ALIGN,
         pack_copy,     unpack_copy},
+       {'t',   sizeof(time_t),                 TIMET_ALIGN,
+        pack_copy,     unpack_copy},
        /* Null terminated string */
        {'s',   sizeof(void*),                  VOID_P_ALIGN,
         pack_string,   unpack_string},
index 8426f9a9024622692f7f81d34da105f2a3110ae5..c5e924db774455842fad27d1d13300de02483a6d 100644 (file)
@@ -188,7 +188,7 @@ get_interfaces(int s, struct interfaces *ifs)
 
 #ifdef ENABLE_DOT1
 static int
-get_vlans(int s, struct vlans *vls, char *interface)
+get_vlans(int s, struct vlans *vls, char *interface, int nb)
 {
        void *p;
        struct hmsg *h;
@@ -197,7 +197,8 @@ get_vlans(int s, struct vlans *vls, char *interface)
                fatal(NULL);
        ctl_msg_init(h, HMSG_GET_VLANS);
        strlcpy((char *)&h->data, interface, IFNAMSIZ);
-       h->hdr.len += IFNAMSIZ;
+       memcpy((char*)&h->data + IFNAMSIZ, &nb, sizeof(int));
+       h->hdr.len += IFNAMSIZ + sizeof(int);
        if (ctl_msg_send(s, h) == -1)
                fatalx("get_vlans: unable to send request");
        if (ctl_msg_recv(s, h) == -1)
@@ -213,7 +214,7 @@ get_vlans(int s, struct vlans *vls, char *interface)
 #endif
 
 static int
-get_chassis(int s, struct lldpd_chassis *chassis, char *interface)
+get_chassis(int s, struct lldpd_chassis *chassis, char *interface, int nb)
 {
        struct hmsg *h;
        void *p;
@@ -222,7 +223,8 @@ get_chassis(int s, struct lldpd_chassis *chassis, char *interface)
                fatal(NULL);
        ctl_msg_init(h, HMSG_GET_CHASSIS);
        strlcpy((char *)&h->data, interface, IFNAMSIZ);
-       h->hdr.len += IFNAMSIZ;
+       memcpy((char*)&h->data + IFNAMSIZ, &nb, sizeof(int));
+       h->hdr.len += IFNAMSIZ + sizeof(int);
        if (ctl_msg_send(s, h) == -1)
                fatalx("get_chassis: unable to send request to get chassis");
        if (ctl_msg_recv(s, h) == -1)
@@ -240,7 +242,7 @@ get_chassis(int s, struct lldpd_chassis *chassis, char *interface)
 }
 
 static int
-get_port(int s, struct lldpd_port *port, char *interface)
+get_port(int s, struct lldpd_port *port, char *interface, int nb)
 {
        struct hmsg *h;
        void *p;
@@ -249,7 +251,8 @@ get_port(int s, struct lldpd_port *port, char *interface)
                fatal(NULL);
        ctl_msg_init(h, HMSG_GET_PORT);
        strlcpy((char *)&h->data, interface, IFNAMSIZ);
-       h->hdr.len += IFNAMSIZ;
+       memcpy((char*)&h->data + IFNAMSIZ, &nb, sizeof(int));
+       h->hdr.len += IFNAMSIZ + sizeof(int);
        if (ctl_msg_send(s, h) == -1)
                fatalx("get_port: unable to send request to get port");
        if (ctl_msg_recv(s, h) == -1)
@@ -267,6 +270,29 @@ get_port(int s, struct lldpd_port *port, char *interface)
        return 1;
 }
 
+static int
+get_nb_port(int s, char *interface)
+{
+       struct hmsg *h;
+       int nb;
+
+       if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL)
+               fatal(NULL);
+       ctl_msg_init(h, HMSG_GET_NB_PORTS);
+       strlcpy((char *)&h->data, interface, IFNAMSIZ);
+       h->hdr.len += IFNAMSIZ;
+       if (ctl_msg_send(s, h) == -1)
+               fatalx("get_nb_port: unable to send request to get number of ports");
+       if (ctl_msg_recv(s, h) == -1)
+               fatalx("get_nb_port: unable to receive answer to get number of ports");
+       if (h->hdr.type == HMSG_NONE)
+               return -1;
+       if (h->hdr.len != sizeof(int))
+               fatalx("get_nb_port: bad message length");
+       memcpy(&nb, &h->data, sizeof(int));
+       return nb;
+}
+
 static void
 display_cap(struct lldpd_chassis *chassis, u_int8_t bit, char *symbol)
 {
@@ -791,7 +817,7 @@ display_vlans(struct lldpd_port *port)
 static void
 display_interfaces(int s, int argc, char *argv[])
 {
-       int i;
+       int i, nb;
        struct interfaces ifs;
 #ifdef ENABLE_DOT1
        struct vlans vls;
@@ -816,14 +842,27 @@ display_interfaces(int s, int argc, char *argv[])
                        if (i == argc)
                                continue;
                }
-               if ((get_chassis(s, &chassis, iff->name) != -1) &&
-                   (get_port(s, &port, iff->name) != -1)) {
-                       printf("Interface: %s\n", iff->name);
+               nb = get_nb_port(s, iff->name);
+               for (i = 0; i < nb; i++) {
+                       if (!((get_chassis(s, &chassis, iff->name, i) != -1) &&
+                               (get_port(s, &port, iff->name, i) != -1)))
+                               continue;
+                       printf("Interface: %s (via ", iff->name);
+                       switch (port.p_protocol) {
+                       case (LLDPD_MODE_LLDP): printf("LLDP"); break;
+                       case (LLDPD_MODE_CDPV1): printf("CDPv1"); break;
+                       case (LLDPD_MODE_CDPV2): printf("CDPv2"); break;
+                       case (LLDPD_MODE_EDP): printf("EDP"); break;
+                       case (LLDPD_MODE_FDP): printf("FDP"); break;
+                       case (LLDPD_MODE_SONMP): printf("SONMP"); break;
+                       default: printf("unknown protocol"); break;
+                       }
+                       printf(")      - RID: %d\n", chassis.c_index);
                        display_chassis(&chassis);
                        printf("\n");
                        display_port(&port);
 #ifdef ENABLE_DOT1
-                       if (get_vlans(s, &vls, iff->name) != -1) {
+                       if (get_vlans(s, &vls, iff->name, i) != -1) {
                                memcpy(&port.p_vlans, &vls, sizeof(struct vlans));
                                if (!TAILQ_EMPTY(&port.p_vlans)) {
                                        printf("\n");
index bca58ae8467e7c93f820bbe1a2ec78d2792c9a95..4765a6fb8480477c6c1853ff1ad981a72352c5a4 100644 (file)
@@ -183,7 +183,7 @@ struct lldpd_port {
 #endif
 };
 
-#define STRUCT_LLDPD_PORT "(LPllPbbCsw"                                \
+#define STRUCT_LLDPD_PORT "(LPttPbbCsw"                                \
        STRUCT_LLDPD_PORT_DOT3                                  \
        STRUCT_LLDPD_PORT_MED                                   \
        STRUCT_LLDPD_PORT_DOT1 ")"
@@ -278,8 +278,9 @@ struct lldpd {
 enum hmsg_type {
        HMSG_NONE,
        HMSG_GET_INTERFACES,
-       HMSG_GET_CHASSIS,
+       HMSG_GET_NB_PORTS,
        HMSG_GET_PORT,
+       HMSG_GET_CHASSIS,
        HMSG_GET_VLANS,
        HMSG_SET_LOCATION,
        HMSG_SHUTDOWN