]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
OpenBSD support.
authorVincent Bernat <bernat@luffy.cx>
Thu, 27 Dec 2012 22:25:26 +0000 (23:25 +0100)
committerVincent Bernat <bernat@luffy.cx>
Thu, 27 Dec 2012 22:25:26 +0000 (23:25 +0100)
With VLAN, bonding and bridge support as well. Tested with OpenBSD
5.2.

To ease porting, we also shop `netinet/if_ether.h` which is a stripped
down version of the one contained in OpenBSD (without kernel and ARP
stuff). Including correctly this header has always been a pain, even
when supporting only Linux.

14 files changed:
.gitignore
NEWS
configure.ac
include/netinet/if_ether.h [new file with mode: 0644]
m4/os.m4
src/compat/compat.h
src/ctl.c
src/daemon/Makefile.am
src/daemon/interfaces-bsd.c [moved from src/daemon/interfaces-freebsd.c with 94% similarity]
src/daemon/lldp-tlv.h
src/daemon/lldpd.c
src/daemon/lldpd.h
src/daemon/priv.c
src/lldpd-structs.h

index 3e5acad714ac8a2d666cb35b6668efe486f6a3c3..bf795e60a4f02cfaa0f932560e95adcc7dc087a3 100644 (file)
@@ -3,7 +3,7 @@
 *.lo
 *.a
 *.la
-/build/
+/build*/
 
 # autotools stuff
 /m4/lt*.m4
diff --git a/NEWS b/NEWS
index cf88c852293bf3c7044b246ed4c5dc76d6fb11e8..e5405f75c826d10a7755adcfed06548c1cefa83d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 lldpd (0.6.2)
-  * Features:
+  * Global changes:
     + FreeBSD support.
+    + OpenBSD support.
+  * Features:
     + Allow to disable LLDP protocol (with `-ll`). In this case, the
       first enabled protocol will be used when no neighbor is detected.
     + Allow to filter debug logs using tokens. Add more debug logs.
index 8ec60e027c3740db5b7994994d421b1f6e458167..11fa363ddd4a18c524d5f871edc06eb0760f8670 100644 (file)
@@ -80,9 +80,6 @@ AC_CACHE_SAVE
 AC_HEADER_RESOLV
 AC_CHECK_HEADERS([valgrind/valgrind.h])
 
-# Check for ETHERTYPE_VLAN, put it in compat.h if not defined
-AC_CHECK_DECLS([ETHERTYPE_VLAN],[],[],[[@%:@include <net/ethernet.h>]])
-
 AC_CACHE_SAVE
 
 # Checks for typedefs, structures, and compiler characteristics.
diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h
new file mode 100644 (file)
index 0000000..fa65914
--- /dev/null
@@ -0,0 +1,92 @@
+/*     $OpenBSD: if_ether.h,v 1.47 2010/02/08 13:32:50 claudio Exp $   */
+/*     $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $    */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)if_ether.h  8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IF_ETHER_H_
+#define _NETINET_IF_ETHER_H_
+
+/*
+ * Some basic Ethernet constants.
+ */
+#define        ETHER_ADDR_LEN  6       /* Ethernet address length              */
+#define ETHER_TYPE_LEN 2       /* Ethernet type field length           */
+#define ETHER_CRC_LEN  4       /* Ethernet CRC length                  */
+#define ETHER_HDR_LEN  ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)
+#define ETHER_MIN_LEN  64      /* Minimum frame length, CRC included   */
+#define ETHER_MAX_LEN  1518    /* Maximum frame length, CRC included   */
+#define ETHER_MAX_DIX_LEN      1536    /* Maximum DIX frame length     */
+
+/*
+ * Some Ethernet extensions.
+ */
+#define ETHER_VLAN_ENCAP_LEN   4       /* len of 802.1Q VLAN encapsulation */
+
+/*
+ * Mbuf adjust factor to force 32-bit alignment of IP header.
+ * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a
+ * receive so the upper layers get the IP header properly aligned
+ * past the 14-byte Ethernet header.
+ */
+#define ETHER_ALIGN    2       /* driver adjust for IP hdr alignment */
+
+/*
+ * Ethernet address - 6 octets
+ */
+struct ether_addr {
+       u_int8_t ether_addr_octet[ETHER_ADDR_LEN];
+};
+
+/*
+ * The length of the combined header.
+ */
+struct ether_header {
+       u_int8_t  ether_dhost[ETHER_ADDR_LEN];
+       u_int8_t  ether_shost[ETHER_ADDR_LEN];
+       u_int16_t ether_type;
+};
+
+#define ETHERTYPE_VLAN          0x8100  /* IEEE 802.1Q VLAN tagging (XXX conflicts) */
+#define ETHERTYPE_LLDP          0x88CC  /* Link Layer Discovery Protocol */
+
+#define        ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+#define        ETHERMTU        (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+#define        ETHERMIN        (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+/*
+ * Ethernet CRC32 polynomials (big- and little-endian verions).
+ */
+#define        ETHER_CRC_POLY_LE       0xedb88320
+#define        ETHER_CRC_POLY_BE       0x04c11db6
+
+#endif /* _NETINET_IF_ETHER_H_ */
index dfb69650df283f0c5192315dfb97ec35d373a2f7..0f3dbb1776d5a37493be483b77b03e30ba651112 100644 (file)
--- a/m4/os.m4
+++ b/m4/os.m4
@@ -19,6 +19,7 @@ AC_DEFUN([lldp_CHECK_OS], [
 
   lldp_DEFINE_OS(linux*, Linux, LINUX)
   lldp_DEFINE_OS(freebsd*|kfreebsd*, FreeBSD, FREEBSD)
+  lldp_DEFINE_OS(openbsd*, OpenBSD, OPENBSD)
 
   if test x$os = x; then
      AC_MSG_RESULT(no)
index 74e35a78e5bfa125c72294d1b38768a03d72afb4..9f432866cbdb8a822c605619e6e0f6fe449ea63d 100644 (file)
 
 #include <stddef.h>
 
-#if !HAVE_DECL_ETHERTYPE_VLAN
-#define ETHERTYPE_VLAN 0x8100
-#endif
-
 #if !HAVE_STRLCPY
 size_t strlcpy(char *, const char *, size_t);
 #endif
index 8562720b35266b4818bf18b46907380c06c6a87c..1d8cae65b36af66303d4fc7b613eb81e5a4edeed 100644 (file)
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -29,7 +29,8 @@
 #include "log.h"
 #include "compat/compat.h"
 
-#define UNIX_PATH_MAX  108
+/* Linux: 108. OpenBSD: 104. */
+#define UNIX_PATH_MAX  104
 
 /**
  * Create a new listening Unix socket for control protocol.
index b838501495a01f01f156d203b9eb647e7f5c8afe..7c269e3790ad2436701f70b317df3cc990cb09cf 100644 (file)
@@ -28,7 +28,10 @@ liblldpd_la_SOURCES += \
        netlink.c
 endif
 if HOST_OS_FREEBSD
-liblldpd_la_SOURCES += interfaces-freebsd.c
+liblldpd_la_SOURCES += interfaces-bsd.c
+endif
+if HOST_OS_OPENBSD
+liblldpd_la_SOURCES += interfaces-bsd.c
 endif
 
 # Add SNMP support if needed
similarity index 94%
rename from src/daemon/interfaces-freebsd.c
rename to src/daemon/interfaces-bsd.c
index 0d4cb117f4f4c2fde8ef6835b381d5f448c32b29..d60fc573d79f7267cf483ddcedb4db9313333272 100644 (file)
 
 #include <unistd.h>
 #include <ifaddrs.h>
+#include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/ioctl.h>
 #include <net/bpf.h>
 #include <net/if_types.h>
-#include <net/if_mib.h>
 #include <net/if_media.h>
 #include <net/if_vlan_var.h>
-#include <net/if_bridgevar.h>
-#include <net/if_lagg.h>
 #include <net/if_dl.h>
+#if defined HOST_OS_FREEBSD
+# include <net/if_bridgevar.h>
+# include <net/if_lagg.h>
+#elif defined HOST_OS_OPENBSD
+# include <net/if_bridge.h>
+# include <net/if_trunk.h>
+#endif
 
 #ifndef IFDESCRSIZE
 #define IFDESCRSIZE 64
 #endif
 
-static int
-ifbsd_check_driver(struct lldpd *cfg,
-    struct ifaddrs *ifaddr,
-    struct interfaces_device *iface)
-{
-       int name[6];
-       char dname[IFNAMSIZ+1] = {};
-       size_t len = IFNAMSIZ;
-
-       name[0] = CTL_NET;
-       name[1] = PF_LINK;
-       name[2] = NETLINK_GENERIC;
-       name[3] = IFMIB_IFDATA;
-       name[4] = iface->index;
-       name[5] = IFDATA_DRIVERNAME;
-
-       if (sysctl(name, 6, dname, &len, 0, 0) == -1 || len == 0) {
-               log_info("interfaces", "unable to get driver name for %s",
-                   iface->name);
-               return -1;
-       }
-       iface->driver = strdup(dname);
-       return 0;
-}
-
 static int
 ifbsd_check_wireless(struct lldpd *cfg,
     struct ifaddrs *ifaddr,
@@ -83,6 +63,8 @@ ifbsd_check_bridge(struct lldpd *cfg,
                .ifbic_len = sizeof(req),
                .ifbic_req = req
        };
+
+#if defined HOST_OS_FREEBSD
        struct ifdrv ifd = {
                .ifd_cmd = BRDGGIFS,
                .ifd_len = sizeof(bifc),
@@ -95,6 +77,16 @@ ifbsd_check_bridge(struct lldpd *cfg,
                    "%s is not a bridge", master->name);
                return;
        }
+#elif defined HOST_OS_OPENBSD
+       strlcpy(bifc.ifbic_name, master->name, sizeof(bifc.ifbic_name));
+       if (ioctl(cfg->g_sock, SIOCBRDGIFS, (caddr_t)&bifc) < 0) {
+               log_debug("interfaces",
+                   "%s is not a bridge", master->name);
+               return;
+       }
+#else
+# error Unsupported OS
+#endif
        if (bifc.ifbic_len >= sizeof(req)) {
                log_warnx("interfaces",
                    "%s is a bridge too big. Please, report the problem",
@@ -124,6 +116,13 @@ ifbsd_check_bond(struct lldpd *cfg,
     struct interfaces_device_list *interfaces,
     struct interfaces_device *master)
 {
+#if defined HOST_OS_OPENBSD
+/* OpenBSD is the same as FreeBSD, just lagg->trunk */
+# define lagg_reqport trunk_reqport
+# define lagg_reqall  trunk_reqall
+# define SIOCGLAGG SIOCGTRUNK
+# define LAGG_MAX_PORTS TRUNK_MAX_PORTS
+#endif
        struct lagg_reqport rpbuf[LAGG_MAX_PORTS];
        struct lagg_reqall ra = {
                .ra_size = sizeof(rpbuf),
@@ -246,10 +245,16 @@ ifbsd_extract_device(struct lldpd *cfg,
        /* Grab description */
        iface->alias = malloc(IFDESCRSIZE);
        if (iface->alias) {
+#ifdef HOST_OS_FREEBSD
                struct ifreq ifr = {
                        .ifr_buffer = { .buffer = iface->alias,
                                        .length = IFDESCRSIZE }
                };
+#else
+               struct ifreq ifr = {
+                       .ifr_data = (caddr_t)iface->alias
+               };
+#endif
                strlcpy(ifr.ifr_name, ifaddr->ifa_name, sizeof(ifr.ifr_name));
                if (ioctl(cfg->g_sock, SIOCGIFDESCR, (caddr_t)&ifr) < 0) {
                        free(iface->alias);
@@ -257,8 +262,7 @@ ifbsd_extract_device(struct lldpd *cfg,
                }
        }
 
-       if (ifbsd_check_driver(cfg, ifaddr, iface) == -1 ||
-           ifbsd_check_wireless(cfg, ifaddr, iface) == -1) {
+       if (ifbsd_check_wireless(cfg, ifaddr, iface) == -1) {
                interfaces_free_device(iface);
                return NULL;
        }
@@ -523,9 +527,14 @@ ifbsd_phys_init(struct lldpd *cfg,
                goto end;
        }
 
+#ifdef HOST_OS_FREEBSD
        /* We only want to receive incoming packets */
        enable = BPF_D_IN;
        if (ioctl(fd, BIOCSDIRECTION, (caddr_t)&enable) < 0) {
+#else
+       enable = BPF_DIRECTION_IN;
+       if (ioctl(fd, BIOCSDIRFILT, (caddr_t)&enable) < 0) {
+#endif
                log_warn("interfaces",
                    "unable to set packet direction for BPF filter on %s",
                    hardware->h_ifname);
index ab24486fbd36d2caf0f384069ad372c88d0ecccc..1af76f585116419768dcdc7b93adbc31d29d96b1 100644 (file)
 #ifndef _LLDP_TLV_H
 #define _LLDP_TLV_H
 
-/* Should be defined in net/ethertypes.h */
-#ifndef ETHERTYPE_LLDP
-#define ETHERTYPE_LLDP 0x88cc
-#endif
-
 #define LLDP_MULTICAST_ADDR    {                                               \
        0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e                                      \
 }
index b52ecedab38565c126dc7714f1e25ccd9b70795d..a3bcede9f3a48e81e7f2641bd7b70e90f063e48f 100644 (file)
 #include <sys/time.h>
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
-#include <net/ethernet.h>
+#include <netinet/if_ether.h>
 #include <pwd.h>
 #include <grp.h>
-#ifdef HOST_OS_FREEBSD
+#if defined HOST_OS_FREEBSD  || defined HOST_OS_OPENBSD
+# include <sys/param.h>
 # include <sys/sysctl.h>
 #endif
 
@@ -852,7 +853,7 @@ lldpd_update_localchassis(struct lldpd *cfg)
                        LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER;
                close(f);
        }
-#elif defined HOST_OS_FREEBSD
+#elif defined HOST_OS_FREEBSD || defined HOST_OS_OPENBSD
        int n, mib[4] = {
                CTL_NET,
                PF_INET,
@@ -867,6 +868,8 @@ lldpd_update_localchassis(struct lldpd *cfg)
                } else
                        LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER;
        }
+#else
+#error Unsupported OS
 #endif
        else log_debug("localchassis", "unable to check if forwarding is enabled");
 
index baf8d28b3c383b4f62c917b6562c1ce598f09a12..1a042623d5747b2a72f65e5dddc1ad4656c1b0a3 100644 (file)
@@ -34,7 +34,7 @@
 #include <string.h>
 #include <sys/queue.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
+#include <netinet/if_ether.h>
 #include <netinet/in.h>
 #include <sys/un.h>
 
index 65a60637d4909321faea973fb0d0d8365cf5f232..b63000d647692e8d26946047f072d33fd2a1854e 100644 (file)
@@ -42,7 +42,7 @@
 #ifdef HOST_OS_FREEBSD
 # include <net/if_dl.h>
 #endif
-#include <net/ethernet.h>
+#include <netinet/if_ether.h>
 
 /* Use resolv.h */
 #ifdef HAVE_SYS_TYPES_H
@@ -345,7 +345,7 @@ asroot_iface_init()
        must_write(remote, &rc, sizeof(rc));
        send_fd(remote, s);
        close(s);
-#elif defined HOST_OS_FREEBSD
+#elif defined HOST_OS_FREEBSD || defined HOST_OS_OPENBSD
        int fd = -1, rc = 0, n = 0;
        char dev[20];
        int ifindex;
@@ -391,6 +391,11 @@ asroot_iface_multicast()
        dlp->sdl_alen = ETHER_ADDR_LEN;
        dlp->sdl_slen = 0;
        must_read(remote, LLADDR(dlp), ETHER_ADDR_LEN);
+#elif defined HOST_OS_OPENBSD
+       struct sockaddr *sap = (struct sockaddr *)&ifr.ifr_addr;
+       sap->sa_len = sizeof(struct sockaddr);
+       sap->sa_family = AF_UNSPEC;
+       must_read(remote, sap->sa_data, ETHER_ADDR_LEN);
 #else
 #error Unsupported OS
 #endif
index 37e6e247806e07cfa174917148b8038a1d1f7bbf..1f65de933778aa2543ea53e8f8ef2320897910fd 100644 (file)
@@ -34,7 +34,7 @@
 # include <net/if.h>
 #endif
 
-#include <net/ethernet.h>
+#include <netinet/if_ether.h>
 #include <netinet/in.h>
 #include <sys/queue.h>