From 015ecdd5f6ac032cc53c6ebe0451ac0da0dfe27d Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Wed, 3 Jul 2013 22:57:00 +0200 Subject: [PATCH] lldpd: append "was" to an interface description when a neighbor disappear This allows a user to know what neighbor was connected to a server. This should closes #16. --- src/daemon/lldpd.c | 6 +++--- src/daemon/priv-bsd.c | 43 ++++++++++++++++++++++++++++++++++++----- src/daemon/priv-linux.c | 40 ++++++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index ff854c3e..e07b3696 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -230,15 +230,15 @@ lldpd_display_neighbors(struct lldpd *cfg) } if (neighbors == 0) priv_iface_description(hardware->h_ifname, - "lldpd: no neighbor found"); + ""); else if (neighbors == 1 && neighbor) { - if (asprintf(&description, "lldpd: connected to %s", + if (asprintf(&description, "%s", neighbor) != -1) { priv_iface_description(hardware->h_ifname, description); free(description); } } else { - if (asprintf(&description, "lldpd: %d neighbor%s", + if (asprintf(&description, "%d neighbor%s", neighbors, (neighbors > 1)?"s":"") != -1) { priv_iface_description(hardware->h_ifname, description); diff --git a/src/daemon/priv-bsd.c b/src/daemon/priv-bsd.c index 2f9c5d3b..2a08875c 100644 --- a/src/daemon/priv-bsd.c +++ b/src/daemon/priv-bsd.c @@ -24,6 +24,7 @@ #include #include #include +#include int asroot_iface_init_os(int ifindex, char *name, int *fd) @@ -142,11 +143,10 @@ asroot_iface_description_os(const char *name, const char *description) #if defined HOST_OS_FREEBSD || defined HOST_OS_OPENBSD char descr[IFDESCRSIZE]; int rc, sock = -1; - strlcpy(descr, description, IFDESCRSIZE); #if defined HOST_OS_FREEBSD struct ifreq ifr = { .ifr_buffer = { .buffer = descr, - .length = strlen(descr) + 1 } + .length = IFDESCRSIZE } }; #else struct ifreq ifr = { @@ -154,12 +154,45 @@ asroot_iface_description_os(const char *name, const char *description) }; #endif strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1 || - ioctl(sock, SIOCSIFDESCR, (caddr_t)&ifr) < 0) { + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == 1) { + rc = errno; + log_warnx("privsep", "unable to open inet socket"); + return rc; + } + if (strlen(description) == 0) { + /* No neighbor, try to append "was" to the current description */ + if (ioctl(sock, SIOCGIFDESCR, (caddr_t)&ifr) < 0) { + rc = errno; + log_warnx("privsep", "unable to get description of %s", + name); + close(sock); + return rc; + } + if (strncmp(descr, "lldpd: ", 7) == 0) { + if (strncmp(descr + 7, "was ", 4) == 0) { + /* Already has an old neighbor */ + close(sock); + return 0; + } else { + /* Append was */ + memmove(descr + 11, descr + 7, + sizeof(descr) - 11); + memcpy(descr, "lldpd: was ", 11); + } + } else { + /* No description, no neighbor */ + strlcpy(descr, "lldpd: no neighbor", sizeof(descr)); + } + } else + snprintf(descr, sizeof(descr), "lldpd: connected to %s", description); +#if defined HOST_OS_FREEBSD + ift.ifr_buffer.length = strlen(descr); +#endif + if (ioctl(sock, SIOCSIFDESCR, (caddr_t)&ifr) < 0) { rc = errno; log_warnx("privsep", "unable to set description of %s", name); - if (sock != -1) close(sock); + close(sock); return rc; } close(sock); diff --git a/src/daemon/priv-linux.c b/src/daemon/priv-linux.c index 5efa3f01..8a762bcd 100644 --- a/src/daemon/priv-linux.c +++ b/src/daemon/priv-linux.c @@ -206,7 +206,9 @@ asroot_iface_description_os(const char *name, const char *description) /* We could use netlink but this is a lot to do in a privileged * process. Just write to /sys/class/net/XXXX/ifalias. */ char *file; - int fd, rc; + char descr[IFALIASZ]; + FILE *fp; + int rc; if (name[0] == '\0' || name[0] == '.') { log_warnx("privsep", "odd interface name %s", name); return -1; @@ -215,20 +217,38 @@ asroot_iface_description_os(const char *name, const char *description) log_warn("privsep", "unable to allocate memory for setting description"); return -1; } - if ((fd = open(file, O_WRONLY)) == -1) { + if ((fp = fopen(file, "r+")) == NULL) { + rc = errno; free(file); - log_debug("privsep", "cannot set interface description for %s, file missing", - name); - return -1; + log_debug("privsep", "cannot open interface description for %s", + name); + return rc; } free(file); - while ((rc = write(fd, description, strlen(description)) == -1) && - ((errno == EINTR || errno == EAGAIN))); - if (rc == -1) { - log_debug("privsep", "cannot write interface description for %s", + if (strlen(description) == 0 && + fgets(descr, sizeof(descr), fp) != NULL) { + if (strncmp(descr, "lldpd: ", 7) == 0) { + if (strncmp(descr + 7, "was ", 4) == 0) { + /* Already has an old neighbor */ + fclose(fp); + return 0; + } else { + /* Append was */ + memmove(descr + 11, descr + 7, + sizeof(descr) - 11); + memcpy(descr, "lldpd: was ", 11); + } + } else { + /* No description, no neighbor */ + strlcpy(descr, "lldpd: no neighbor", sizeof(descr)); + } + } else + snprintf(descr, sizeof(descr), "lldpd: connected to %s", description); + if (fputs(descr, fp) == EOF) { + log_debug("privsep", "cannot set interface description for %s", name); return -1; } - close(fd); + fclose(fp); return 0; } -- 2.39.5