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
{
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)) {
}
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:
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;
}
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 {
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},
#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;
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)
#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;
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)
}
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;
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)
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)
{
static void
display_interfaces(int s, int argc, char *argv[])
{
- int i;
+ int i, nb;
struct interfaces ifs;
#ifdef ENABLE_DOT1
struct vlans vls;
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");
#endif
};
-#define STRUCT_LLDPD_PORT "(LPllPbbCsw" \
+#define STRUCT_LLDPD_PORT "(LPttPbbCsw" \
STRUCT_LLDPD_PORT_DOT3 \
STRUCT_LLDPD_PORT_MED \
STRUCT_LLDPD_PORT_DOT1 ")"
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