]> git.ipfire.org Git - thirdparty/lldpd.git/blobdiff - src/priv.c
Rework autoconf stuff.
[thirdparty/lldpd.git] / src / priv.c
index 513bc0051e8eeaa65f118619f253039581382381..1129e3756ca51a96672c45ebd28a45c828cf9e17 100644 (file)
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <regex.h>
 #include <linux/sockios.h>
 #include <linux/if_packet.h>
 
+/* Use resolv.h */
+#ifdef HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h> /* DNS HEADER struct */
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#include <resolv.h>
+
 enum {
        PRIV_PING,
        PRIV_CREATE_CTL_SOCKET,
@@ -54,19 +67,19 @@ enum {
 
 static int may_read(int, void *, size_t);
 static void must_read(int, void *, size_t);
-static void must_write(int, void *, size_t);
+static void must_write(int, const void *, size_t);
 
-int remote;                    /* Other side */
-int monitored = -1;            /* Child */
-int sock = -1;
+static int remote;                     /* Other side */
+static int monitored = -1;             /* Child */
+static int sock = -1;
 
 /* UID/GID of unprivileged user */
-gid_t gid = 0;
-uid_t uid = 0;
+static gid_t gid = 0;
+static uid_t uid = 0;
 
 /* Proxies */
 
-void
+static void
 priv_ping()
 {
        int cmd, rc;
@@ -149,22 +162,19 @@ priv_ethtool(char *ifname, struct ethtool_cmd *ethc)
 }
 
 int
-priv_iface_init(struct lldpd_hardware *hardware, int master)
+priv_iface_init(const char *name)
 {
        int cmd, rc;
        cmd = PRIV_IFACE_INIT;
        must_write(remote, &cmd, sizeof(int));
-       must_write(remote, &master, sizeof(int));
-       must_write(remote, hardware->h_ifname, IFNAMSIZ);
+       must_write(remote, name, IFNAMSIZ);
        must_read(remote, &rc, sizeof(int));
-       if (rc != 0)
-               return rc;      /* It's errno */
-       hardware->h_raw = receive_fd(remote);
-       return 0;
+       if (rc != 0) return -1;
+       return receive_fd(remote);
 }
 
 int
-priv_iface_multicast(char *name, u_int8_t *mac, int add)
+priv_iface_multicast(const char *name, u_int8_t *mac, int add)
 {
        int cmd, rc;
        cmd = PRIV_IFACE_MULTICAST;
@@ -189,14 +199,14 @@ priv_snmp_socket(struct sockaddr_un *addr)
        return receive_fd(remote);
 }
 
-void
+static void
 asroot_ping()
 {
        int rc = 1;
        must_write(remote, &rc, sizeof(int));
 }
 
-void
+static void
 asroot_ctl_create()
 {
        int rc;
@@ -216,7 +226,7 @@ asroot_ctl_create()
        close(rc);
 }
 
-void
+static void
 asroot_ctl_cleanup()
 {
        int rc = 0;
@@ -226,7 +236,7 @@ asroot_ctl_cleanup()
        must_write(remote, &rc, sizeof(int));
 }
 
-void
+static void
 asroot_gethostbyname()
 {
        struct utsname un;
@@ -234,23 +244,39 @@ asroot_gethostbyname()
        int len;
        if (uname(&un) != 0)
                fatal("[priv]: failed to get system information");
-       if ((hp = gethostbyname(un.nodename)) == NULL)
-               fatal("[priv]: failed to get system name");
-       len = strlen(hp->h_name);
-       must_write(remote, &len, sizeof(int));
-       must_write(remote, hp->h_name, strlen(hp->h_name) + 1);
+       if ((hp = gethostbyname(un.nodename)) == NULL) {
+               LLOG_INFO("[priv]: unable to get system name");
+               res_init();
+                len = strlen(un.nodename);
+                must_write(remote, &len, sizeof(int));
+                must_write(remote, un.nodename, len + 1);
+        } else {
+                len = strlen(hp->h_name);
+                must_write(remote, &len, sizeof(int));
+                must_write(remote, hp->h_name, len + 1);
+        }
 }
 
-void
+static void
 asroot_open()
 {
        const char* authorized[] = {
                "/proc/sys/net/ipv4/ip_forward",
-               "/sys/class/net/[^.][^/]*/brforward",
-               "/sys/class/net/[^.][^/]*/brport",
+               "/proc/net/bonding/[^.][^/]*",
+               "/proc/self/net/bonding/[^.][^/]*",
+               SYSFS_CLASS_NET "[^.][^/]*/brforward",
+               SYSFS_CLASS_NET "[^.][^/]*/brport",
+               SYSFS_CLASS_NET "[^.][^/]*/brif/[^.][^/]*/port_no",
+               SYSFS_CLASS_NET "[^.][^/]*/ifalias",
+               SYSFS_CLASS_DMI "product_version",
+               SYSFS_CLASS_DMI "product_serial",
+               SYSFS_CLASS_DMI "product_name",
+               SYSFS_CLASS_DMI "bios_version",
+               SYSFS_CLASS_DMI "sys_vendor",
+               SYSFS_CLASS_DMI "chassis_asset_tag",
                NULL
        };
-       char **f;
+       const char **f;
        char *file;
        int fd, len, rc;
        regex_t preg;
@@ -290,7 +316,7 @@ asroot_open()
        close(fd);
 }
 
-void
+static void
 asroot_ethtool()
 {
        struct ifreq ifr;
@@ -310,25 +336,20 @@ asroot_ethtool()
        ifr.ifr_data = (caddr_t)&ethc;
        ethc.cmd = ETHTOOL_GSET;
        if ((rc = ioctl(sock, SIOCETHTOOL, &ifr)) != 0) {
-               LLOG_DEBUG("[priv]: unable to ioctl ETHTOOL for %s",
-                   ifr.ifr_name);
                must_write(remote, &rc, sizeof(int));
-               close(sock);
                return;
        }
        must_write(remote, &rc, sizeof(int));
        must_write(remote, &ethc, sizeof(struct ethtool_cmd));
 }
 
-void
+static void
 asroot_iface_init()
 {
        struct sockaddr_ll sa;
-       int un = 1;
-       int s, master;
+       int s;
        char ifname[IFNAMSIZ];
 
-       must_read(remote, &master, sizeof(int));
        must_read(remote, ifname, IFNAMSIZ);
        ifname[IFNAMSIZ-1] = '\0';
 
@@ -341,34 +362,19 @@ asroot_iface_init()
        memset(&sa, 0, sizeof(sa));
        sa.sll_family = AF_PACKET;
        sa.sll_protocol = 0;
-       if (master == -1)
-               sa.sll_ifindex = if_nametoindex(ifname);
-       else
-               sa.sll_ifindex = master;
+       sa.sll_ifindex = if_nametoindex(ifname);
        if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
                must_write(remote, &errno, sizeof(errno));
                close(s);
                return;
        }
-
-       if (master != -1) {
-               /* With bonding, we need to listen to bond device. We use
-                * setsockopt() PACKET_ORIGDEV to get physical device instead of
-                * bond device */
-               if (setsockopt(s, SOL_PACKET,
-                       PACKET_ORIGDEV, &un, sizeof(un)) == -1) {
-                       LLOG_WARN("[priv]: unable to setsockopt for master bonding device of %s. "
-                            "You will get inaccurate results",
-                           ifname);
-                }
-       }
        errno = 0;
        must_write(remote, &errno, sizeof(errno));
        send_fd(remote, s);
        close(s);
 }
 
-void
+static void
 asroot_iface_multicast()
 {
        int add, rc = 0;
@@ -430,7 +436,7 @@ struct dispatch_actions {
        void(*function)(void);
 };
 
-struct dispatch_actions actions[] = {
+static struct dispatch_actions actions[] = {
        {PRIV_PING, asroot_ping},
        {PRIV_CREATE_CTL_SOCKET, asroot_ctl_create},
        {PRIV_DELETE_CTL_SOCKET, asroot_ctl_cleanup},
@@ -444,7 +450,7 @@ struct dispatch_actions actions[] = {
 };
 
 /* Main loop, run as root */
-void
+static void
 priv_loop()
 {
        int cmd;
@@ -463,7 +469,7 @@ priv_loop()
        /* Should never be there */
 }
 
-void
+static void
 priv_exit()
 {
        int status;
@@ -627,9 +633,9 @@ must_read(int fd, void *buf, size_t n)
 /* Write data with the assertion that it all has to be written, or
  * else abort the process.  Based on atomicio() from openssh. */
 static void
-must_write(int fd, void *buf, size_t n)
+must_write(int fd, const void *buf, size_t n)
 {
-       char *s = buf;
+       const char *s = buf;
        ssize_t res, pos = 0;
 
        while (n > pos) {