interfaces-bpf.c \
interfaces-bsd.c \
dmi-dummy.c \
- priv-bpf.c
+ priv-bsd.c
endif
if HOST_OS_FREEBSD
liblldpd_la_SOURCES += \
interfaces-bpf.c \
interfaces-bsd.c \
dmi-freebsd.c \
- priv-bpf.c
+ priv-bsd.c
endif
if HOST_OS_OPENBSD
liblldpd_la_SOURCES += \
forward-bsd.c \
interfaces-bsd.c \
dmi-openbsd.c \
- priv-bpf.c
+ priv-bsd.c
endif
if HOST_OS_NETBSD
liblldpd_la_SOURCES += \
interfaces-bpf.c \
interfaces-bsd.c \
dmi-dummy.c \
- priv-bpf.c
+ priv-bsd.c
endif
if HOST_OS_OSX
liblldpd_la_SOURCES += \
interfaces-bpf.c \
interfaces-bsd.c \
dmi-osx.c \
- priv-bpf.c
+ priv-bsd.c
liblldpd_la_LDFLAGS = -framework Foundation
liblldpd_la_LDFLAGS += -framework CoreFoundation -framework IOKit
liblldpd_la_LDFLAGS += -framework IOKit
interfaces-bpf.c \
interfaces-solaris.c \
dmi-dummy.c \
- priv-bpf.c
+ priv-bsd.c
endif
# Add SNMP support if needed
free(hardware);
}
+static void
+lldpd_display_neighbors(struct lldpd *cfg)
+{
+ struct lldpd_hardware *hardware;
+ TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
+ struct lldpd_port *port;
+ char *description;
+ const char *neighbor = NULL;
+ unsigned neighbors = 0;
+ TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
+ if (SMART_HIDDEN(port)) continue;
+ neighbors++;
+ neighbor = port->p_chassis->c_name;
+ }
+ 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",
+ neighbor) != -1) {
+ priv_iface_description(hardware->h_ifname, description);
+ free(description);
+ }
+ } else {
+ if (asprintf(&description, "lldpd: %d neighbor%s",
+ neighbors, (neighbors > 1)?"s":"") != -1) {
+ priv_iface_description(hardware->h_ifname,
+ description);
+ free(description);
+ }
+ }
+ }
+}
+
static void
lldpd_count_neighbors(struct lldpd *cfg)
{
else
setproctitle("%d neighbor%s", neighbors,
(neighbors > 1)?"s":"");
-#else
- (void)cfg;
#endif
+ lldpd_display_neighbors(cfg);
}
static void
int priv_iface_init(int, char *);
int asroot_iface_init_os(int, char *, int *);
int priv_iface_multicast(const char *, u_int8_t *, int);
+int priv_iface_description(const char *, const char *);
+int asroot_iface_description_os(const char *, const char *);
int priv_snmp_socket(struct sockaddr_un *);
enum {
PRIV_ETHTOOL,
PRIV_IFACE_INIT,
PRIV_IFACE_MULTICAST,
+ PRIV_IFACE_DESCRIPTION,
PRIV_SNMP_SOCKET,
} priv_cmd;
#endif
return 0;
}
+
+int
+asroot_iface_description_os(const char *name, const char *description)
+{
+#ifdef IFDESCRSIZE
+#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 }
+ };
+#else
+ struct ifreq ifr = {
+ .ifr_data = (caddr_t)descr
+ };
+#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) {
+ rc = errno;
+ log_warnx("privsep", "unable to set description of %s",
+ name);
+ if (sock != -1) close(sock);
+ return rc;
+ }
+ close(sock);
+ return 0;
+#endif
+#endif /* IFDESCRSIZE */
+ static int once = 0;
+ if (!once) {
+ log_warnx("privsep", "cannot set interface description for this OS");
+ once = 1;
+ }
+ return 0;
+}
+
return 0;
}
+
+int
+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;
+ if (name[0] == '\0' || name[0] == '.') {
+ log_warnx("privsep", "odd interface name %s", name);
+ return -1;
+ }
+ if (asprintf(&file, SYSFS_CLASS_NET "%s/ifalias", name) == -1) {
+ log_warn("privsep", "unable to allocate memory for setting description");
+ return -1;
+ }
+ if ((fd = open(file, O_WRONLY)) == -1) {
+ free(file);
+ log_debug("privsep", "cannot set interface description for %s, file missing",
+ name);
+ return -1;
+ }
+ 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",
+ name);
+ return -1;
+ }
+ close(fd);
+ return 0;
+}
return rc;
}
+int
+priv_iface_description(const char *name, const char *description)
+{
+ int cmd, rc;
+ int len = strlen(description);
+ cmd = PRIV_IFACE_DESCRIPTION;
+ must_write(&cmd, sizeof(int));
+ must_write(name, IFNAMSIZ);
+ must_write(&len, sizeof(int));
+ must_write(description, len);
+ must_read(&rc, sizeof(int));
+ return rc;
+}
+
int
priv_snmp_socket(struct sockaddr_un *addr)
{
must_write(&rc, sizeof(rc));
}
+static void
+asroot_iface_description()
+{
+ char name[IFNAMSIZ];
+ char *description;
+ int len, rc;
+ must_read(&name, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
+ must_read(&len, sizeof(int));
+ if ((description = (char*)malloc(len+1)) == NULL)
+ fatal("description", NULL);
+
+ must_read(description, len);
+ description[len] = 0;
+ rc = asroot_iface_description_os(name, description);
+ must_write(&rc, sizeof(rc));
+}
+
static void
asroot_snmp_socket()
{
#endif
{PRIV_IFACE_INIT, asroot_iface_init},
{PRIV_IFACE_MULTICAST, asroot_iface_multicast},
+ {PRIV_IFACE_DESCRIPTION, asroot_iface_description},
{PRIV_SNMP_SOCKET, asroot_snmp_socket},
{-1, NULL}
};