From: Vincent Bernat Date: Sun, 24 May 2009 12:29:15 +0000 (+0200) Subject: Adapt lldpctl to display received systems for each port. X-Git-Tag: 0.5.0~74 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=84853b9208a7a5e85fbd294419f163c18a3860b1;p=thirdparty%2Flldpd.git Adapt lldpctl to display received systems for each port. --- diff --git a/src/client.c b/src/client.c index a8a2ed8b..68a24153 100644 --- a/src/client.c +++ b/src/client.c @@ -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; } diff --git a/src/ctl.c b/src/ctl.c index 2268e0b8..6f2bce34 100644 --- 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}, diff --git a/src/lldpctl.c b/src/lldpctl.c index 8426f9a9..c5e924db 100644 --- a/src/lldpctl.c +++ b/src/lldpctl.c @@ -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"); diff --git a/src/lldpd.h b/src/lldpd.h index bca58ae8..4765a6fb 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -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