From: Vincent Bernat Date: Wed, 29 Oct 2008 08:02:32 +0000 (+0100) Subject: Move client handling in a separate file X-Git-Tag: 0.2~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a552a72e6dcf55626c48d6aa38833b7872b92f07;p=thirdparty%2Flldpd.git Move client handling in a separate file --- diff --git a/src/Makefile.am b/src/Makefile.am index e84f5bf1..5696b8ab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ sbin_PROGRAMS = lldpd lldpctl COMMON = log.c ctl.c lldpd.h lldp.h cdp.h compat.h sonmp.h llc.h edp.h -lldpd_SOURCES = lldpd.c lldp.c cdp.c sonmp.c edp.c iov.c features.c $(COMMON) +lldpd_SOURCES = lldpd.c lldp.c cdp.c sonmp.c edp.c iov.c features.c client.c $(COMMON) lldpctl_SOURCES = lldpctl.c $(COMMON) lldpd_LDADD = @LIBOBJS@ diff --git a/src/client.c b/src/client.c new file mode 100644 index 00000000..e7377775 --- /dev/null +++ b/src/client.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2008 Vincent Bernat + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lldpd.h" + +struct client_handle client_handles[] = { + { HMSG_NONE, client_handle_none }, + { HMSG_GET_INTERFACES, client_handle_get_interfaces }, + { HMSG_GET_CHASSIS, client_handle_get_port_related }, + { HMSG_GET_PORT, client_handle_get_port_related }, + { HMSG_GET_VLANS, client_handle_get_port_related }, + { HMSG_SHUTDOWN, client_handle_shutdown }, + { 0, NULL } }; + +void +client_handle_client(struct lldpd *cfg, struct lldpd_client *client, + char *buffer, int n) +{ + struct hmsg *h; /* Reception */ + struct hmsg *t; /* Sending */ + struct client_handle *ch; + + if (n < sizeof(struct hmsg_hdr)) { + LLOG_WARNX("too short message request received"); + return; + } + h = (struct hmsg *)buffer; + n -= sizeof(struct hmsg_hdr); + if (n != h->hdr.len) { + LLOG_WARNX("incorrect message size received from %d", + h->hdr.pid); + return; + } + + if ((t = (struct hmsg*)calloc(1, MAX_HMSGSIZE)) == NULL) { + LLOG_WARNX("unable to allocate memory to answer to %d", + h->hdr.pid); + return; + } + ctl_msg_init(t, h->hdr.type); + for (ch = client_handles; ch->handle != NULL; ch++) { + if (ch->type == h->hdr.type) { + ch->handle(cfg, h, t); + if (t->hdr.len == -1) { + t->hdr.len = 0; + t->hdr.type = HMSG_NONE; + } + if (ctl_msg_send(client->fd, t) == -1) + LLOG_WARN("unable to send answer to client %d", + h->hdr.pid); + free(t); + return; + } + } + + LLOG_WARNX("unknown message request (%d) received from %d", + h->hdr.type, h->hdr.pid); + free(t); + return; +} + +void +client_handle_shutdown(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) +{ + LLOG_INFO("received shutdown request from client %d", + r->hdr.pid); + exit(0); +} + +void +client_handle_none(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) +{ + LLOG_INFO("received noop request from client %d", + r->hdr.pid); + s->hdr.len = -1; +} + +void +client_handle_get_interfaces(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) +{ + struct lldpd_interface *iff, *iff_next; + struct lldpd_hardware *hardware; + void *p; + + /* Build the list of interfaces */ + TAILQ_HEAD(, lldpd_interface) ifs; + TAILQ_INIT(&ifs); + TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) { + if ((iff = (struct lldpd_interface*)malloc(sizeof( + struct lldpd_interface))) == NULL) + fatal(NULL); + iff->name = hardware->h_ifname; + TAILQ_INSERT_TAIL(&ifs, iff, next); + } + + p = &s->data; + if (ctl_msg_pack_list(STRUCT_LLDPD_INTERFACE, &ifs, + sizeof(struct lldpd_interface), s, &p) == -1) { + LLOG_WARNX("unable to pack list of interfaces"); + s->hdr.len = -1; + } + + /* Free the temporary list */ + for (iff = TAILQ_FIRST(&ifs); + iff != NULL; + iff = iff_next) { + iff_next = TAILQ_NEXT(iff, next); + TAILQ_REMOVE(&ifs, iff, next); + free(iff); + } +} + +void +client_handle_get_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) +{ + char *ifname; + struct lldpd_hardware *hardware; + void *p; + + ifname = (char*)(&r->data); + if (ifname[r->hdr.len - 1] != 0) { + LLOG_WARNX("bad message format for get port related message"); + s->hdr.len = -1; + return; + } + TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) { + if (strncmp(ifname, hardware->h_ifname, IFNAMSIZ) == 0) { + 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) { + 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); + s->hdr.len = -1; + return; + } + break; + 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); + 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); + s->hdr.len = -1; + return; + } + break; + default: + LLOG_WARNX("don't know what to do"); + s->hdr.len = -1; + return; + } + return; + } + } + LLOG_WARNX("requested interface %s by %d was not found", + ifname, r->hdr.pid); + s->hdr.len = -1; + return; +} diff --git a/src/lldpd.c b/src/lldpd.c index 697bd06b..3d0253dd 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -141,31 +141,6 @@ void lldpd_recv_all(struct lldpd *); int lldpd_guess_type(struct lldpd *, char *, int); void lldpd_decode(struct lldpd *, char *, int, struct lldpd_hardware *, int); -void lldpd_handle_client(struct lldpd *, struct lldpd_client *, - char *, int); - -void lldpd_handle_none(struct lldpd *, struct hmsg *, - struct hmsg *); -void lldpd_handle_get_interfaces(struct lldpd *, struct hmsg *, - struct hmsg *); -void lldpd_handle_get_port_related(struct lldpd *, struct hmsg *, - struct hmsg *); -void lldpd_handle_shutdown(struct lldpd *, struct hmsg *, - struct hmsg *); - -struct client_handle { - enum hmsg_type type; - void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*); -}; - -struct client_handle client_handles[] = { - { HMSG_NONE, lldpd_handle_none }, - { HMSG_GET_INTERFACES, lldpd_handle_get_interfaces }, - { HMSG_GET_CHASSIS, lldpd_handle_get_port_related }, - { HMSG_GET_PORT, lldpd_handle_get_port_related }, - { HMSG_GET_VLANS, lldpd_handle_get_port_related }, - { HMSG_SHUTDOWN, lldpd_handle_shutdown }, - { 0, NULL } }; char **saved_argv; @@ -969,171 +944,6 @@ cleanup: return; } -void -lldpd_handle_client(struct lldpd *cfg, struct lldpd_client *client, - char *buffer, int n) -{ - struct hmsg *h; /* Reception */ - struct hmsg *t; /* Sending */ - struct client_handle *ch; - - if (n < sizeof(struct hmsg_hdr)) { - LLOG_WARNX("too short message request received"); - return; - } - h = (struct hmsg *)buffer; - n -= sizeof(struct hmsg_hdr); - if (n != h->hdr.len) { - LLOG_WARNX("incorrect message size received from %d", - h->hdr.pid); - return; - } - - if ((t = (struct hmsg*)calloc(1, MAX_HMSGSIZE)) == NULL) { - LLOG_WARNX("unable to allocate memory to answer to %d", - h->hdr.pid); - return; - } - ctl_msg_init(t, h->hdr.type); - for (ch = client_handles; ch->handle != NULL; ch++) { - if (ch->type == h->hdr.type) { - ch->handle(cfg, h, t); - if (t->hdr.len == -1) { - t->hdr.len = 0; - t->hdr.type = HMSG_NONE; - } - if (ctl_msg_send(client->fd, t) == -1) - LLOG_WARN("unable to send answer to client %d", - h->hdr.pid); - free(t); - return; - } - } - - LLOG_WARNX("unknown message request (%d) received from %d", - h->hdr.type, h->hdr.pid); - free(t); - return; -} - -void -lldpd_handle_shutdown(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) -{ - LLOG_INFO("received shutdown request from client %d", - r->hdr.pid); - exit(0); -} - -void -lldpd_handle_none(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) -{ - LLOG_INFO("received noop request from client %d", - r->hdr.pid); - s->hdr.len = -1; -} - -void -lldpd_handle_get_interfaces(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) -{ - struct lldpd_interface *iff, *iff_next; - struct lldpd_hardware *hardware; - void *p; - - /* Build the list of interfaces */ - TAILQ_HEAD(, lldpd_interface) ifs; - TAILQ_INIT(&ifs); - TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) { - if ((iff = (struct lldpd_interface*)malloc(sizeof( - struct lldpd_interface))) == NULL) - fatal(NULL); - iff->name = hardware->h_ifname; - TAILQ_INSERT_TAIL(&ifs, iff, next); - } - - p = &s->data; - if (ctl_msg_pack_list(STRUCT_LLDPD_INTERFACE, &ifs, - sizeof(struct lldpd_interface), s, &p) == -1) { - LLOG_WARNX("unable to pack list of interfaces"); - s->hdr.len = -1; - } - - /* Free the temporary list */ - for (iff = TAILQ_FIRST(&ifs); - iff != NULL; - iff = iff_next) { - iff_next = TAILQ_NEXT(iff, next); - TAILQ_REMOVE(&ifs, iff, next); - free(iff); - } -} - -void -lldpd_handle_get_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s) -{ - char *ifname; - struct lldpd_hardware *hardware; - void *p; - - ifname = (char*)(&r->data); - if (ifname[r->hdr.len - 1] != 0) { - LLOG_WARNX("bad message format for get port related message"); - s->hdr.len = -1; - return; - } - TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) { - if (strncmp(ifname, hardware->h_ifname, IFNAMSIZ) == 0) { - 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) { - 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); - s->hdr.len = -1; - return; - } - break; - 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); - 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); - s->hdr.len = -1; - return; - } - break; - default: - LLOG_WARNX("don't know what to do"); - s->hdr.len = -1; - return; - } - return; - } - } - LLOG_WARNX("requested interface %s by %d was not found", - ifname, r->hdr.pid); - s->hdr.len = -1; - return; -} - void lldpd_recv_all(struct lldpd *cfg) { @@ -1327,7 +1137,7 @@ lldpd_recv_all(struct lldpd *cfg) continue; } if (n > 0) - lldpd_handle_client(cfg, client, buffer, n); + client_handle_client(cfg, client, buffer, n); else ctl_close(cfg, client->fd); /* Will use TAILQ_REMOVE ! */ free(buffer); diff --git a/src/lldpd.h b/src/lldpd.h index fa83501e..6d27c847 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -306,4 +306,21 @@ size_t strlcpy(char *, const char *, size_t); void iov_dump(struct lldpd_frame **, struct iovec *, int); u_int16_t iov_checksum(struct iovec *, int, int); +/* client.c */ +struct client_handle { + enum hmsg_type type; + void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*); +}; + +void client_handle_client(struct lldpd *, struct lldpd_client *, + char *, int); +void client_handle_none(struct lldpd *, struct hmsg *, + struct hmsg *); +void client_handle_get_interfaces(struct lldpd *, struct hmsg *, + struct hmsg *); +void client_handle_get_port_related(struct lldpd *, struct hmsg *, + struct hmsg *); +void client_handle_shutdown(struct lldpd *, struct hmsg *, + struct hmsg *); + #endif /* _LLDPD_H */