]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: append "was" to an interface description when a neighbor disappear
authorVincent Bernat <bernat@luffy.cx>
Wed, 3 Jul 2013 20:57:00 +0000 (22:57 +0200)
committerVincent Bernat <bernat@luffy.cx>
Wed, 3 Jul 2013 20:57:00 +0000 (22:57 +0200)
This allows a user to know what neighbor was connected to a
server. This should closes #16.

src/daemon/lldpd.c
src/daemon/priv-bsd.c
src/daemon/priv-linux.c

index ff854c3e1f0084a43386aef2a2004ba8fb3bedf5..e07b3696a7b848ff8a7410e116cefd5d44e0f5d6 100644 (file)
@@ -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);
index 2f9c5d3b772ad241b34f05f04874ba9ea7f31fe3..2a08875c067f9e55d3e80e8a44407ae2f2b72f3f 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <string.h>
 
 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);
index 5efa3f014afcc974132973a82cc8215502214d8d..8a762bcd1246b5b36a4f0aca5133bbb2e2cbfe0b 100644 (file)
@@ -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;
 }