]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Mac OS X support.
authorVincent Bernat <bernat@luffy.cx>
Thu, 10 Jan 2013 19:23:57 +0000 (20:23 +0100)
committerVincent Bernat <bernat@luffy.cx>
Thu, 10 Jan 2013 19:23:57 +0000 (20:23 +0100)
This includes bond, VLAN and bridge support. Mac OS X is pretty
similar to FreeBSD except for bonding which is different. Bonding code
is stolen from ifconfig.c. Header files from XNU are
shipped because they are missing from Mac OS X developer tools.

Still missing:
 - integration into launchd
 - homebrew formula
 - DMI part (through ioreg)

16 files changed:
NEWS
README.md
configure.ac
include/osx/README.md [new file with mode: 0644]
include/osx/if_bond_var.h [new file with mode: 0644]
include/osx/if_bridgevar.h [new file with mode: 0644]
include/osx/if_vlan_var.h [new file with mode: 0644]
include/osx/lacp.h [new file with mode: 0644]
m4/os.m4
src/compat/Makefile.am
src/compat/empty.c [new file with mode: 0644]
src/daemon/Makefile.am
src/daemon/frame.h
src/daemon/interfaces-bsd.c
src/daemon/lldpd.c
src/daemon/priv.c

diff --git a/NEWS b/NEWS
index 5f4e8acc2b265c3fcd75821b5d0ea6f771f1774c..f5fd1f212b95f5a8786fdc9ad6bfaeeaa24c3366 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,7 @@
 lldpd (0.7.1)
   * Features
+    + Mac OS X support, sponsored by Xcloud, Mac cloud server hosting
+      provider. http://xcloud.me/
     + Upstart and systemd support.
     + Remove Unix socket when there is no process listening.
 
index 3b0a6d7f4b3d6d4b4a4140a235ee06aa70b1d340..18ce156e9d581e43c0ae4905207b067bb07570b5 100644 (file)
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ The following OS are supported:
  * GNU/Linux
  * NetBSD
  * OpenBSD
+ * Mac OS X
 
 Installation
 ------------
@@ -67,6 +68,41 @@ root, not `_lldpd`!). If you get fuzzy timestamps from syslog, copy
 line. If you don't want to run it as root, just install it setuid or
 setgid `_lldpd`.
 
+Installation (Mac OS X)
+-----------------------
+
+The same procedure as above applies for Mac OS X. However, you may
+want to install libevent from Homebrew, as well as Readline:
+
+    brew install libevent
+    brew install readline
+    ./configure CPPFLAGS="-I$(brew --prefix readline)/include" \
+                LDFLAGS="-L$(brew --prefix readline)/lib"
+    make
+    sudo make install
+
+You need to create the `_lldpd` user and group:
+
+    dscl . list /Users uid
+    dscl . list /Groups gid
+    # Find a free UID/GID, let's say 274
+    dscl . -create /Groups/_lldpd
+    dscl . -create /Groups/_lldpd PrimaryGroupID 274
+    dscl . -create /Groups/_lldpd Password "*"
+    dscl . -create /Groups/_lldpd RealName "lldpd privilege separation group"
+    dscl . -create /Users/_lldpd
+    dscl . -create /Users/_lldpd UserShell /usr/bin/false
+    dscl . -create /Users/_lldpd NFSHomeDirectory /var/run/lldpd
+    dscl . -create /Users/_lldpd PrimaryGroupID 274
+    dscl . -create /Users/_lldpd UniqueID 274
+    dscl . -create /Users/_lldpd Password "*"
+    dscl . -create /Users/_lldpd RealName "lldpd privilege separation user"
+
+Also create `/var/run/lldpd`:
+
+    mkdir -p /var/run/lldpd/etc
+    cp /etc/localtime /var/run/lldpd/etc/.
+
 Usage
 -----
 
index b55bd9a56f0697f32310811cf856e72ede1da05e..f07a16ae48402807b4810d83c25037e31b9a6cb2 100644 (file)
@@ -92,6 +92,11 @@ AC_FUNC_MALLOC
 AC_FUNC_REALLOC
 AC_REPLACE_FUNCS([strlcpy])
 AC_CHECK_FUNCS([setresuid setresgid])
+
+AC_SEARCH_LIBS([__res_init], resolv bind, AC_DEFINE([HAVE_RES_INIT], 1, [Define to indicate that res_init() exists]),
+AC_SEARCH_LIBS([res_9_init], resolv bind, AC_DEFINE([HAVE_RES_INIT], 1, [Define to indicate that res_init() exists]),
+AC_SEARCH_LIBS([res_init],   resolv bind, AC_DEFINE([HAVE_RES_INIT], 1, [Define to indicate that res_init() exists]))))
+
 AC_CACHE_SAVE
 
 ## Unit tests wich check
diff --git a/include/osx/README.md b/include/osx/README.md
new file mode 100644 (file)
index 0000000..316fbe5
--- /dev/null
@@ -0,0 +1,6 @@
+Those include headers have been stolen from `xnu-2050.18.24.tar.gz`
+and slightly modified. They should be shipped with the OS or the
+development tools but they are not. They are from Mac OS X 10.8.2 but
+should work with previous versions just fine.
+
+  http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/
diff --git a/include/osx/if_bond_var.h b/include/osx/if_bond_var.h
new file mode 100644 (file)
index 0000000..73f457e
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _NET_IF_BOND_VAR_H_
+#define        _NET_IF_BOND_VAR_H_
+
+#include <sys/types.h>
+
+#include <osx/lacp.h>
+
+#pragma pack(4)
+
+#define IF_BOND_OP_ADD_INTERFACE               1
+#define IF_BOND_OP_REMOVE_INTERFACE            2
+#define IF_BOND_OP_GET_STATUS                  3
+#define IF_BOND_OP_SET_VERBOSE                 4
+#define IF_BOND_OP_SET_MODE                    5
+
+#define IF_BOND_MODE_LACP                      0
+#define IF_BOND_MODE_STATIC                    1
+
+struct if_bond_partner_state {
+    lacp_system                ibps_system;
+    lacp_system_priority       ibps_system_priority;
+    lacp_key                   ibps_key;
+    lacp_port                  ibps_port;
+    lacp_port_priority         ibps_port_priority;
+    lacp_actor_partner_state   ibps_state;
+    u_char                     ibps_reserved1;
+};
+
+#define IF_BOND_STATUS_SELECTED_STATE_UNSELECTED       0
+#define IF_BOND_STATUS_SELECTED_STATE_SELECTED         1
+#define IF_BOND_STATUS_SELECTED_STATE_STANDBY          2
+
+struct if_bond_status {
+    char                       ibs_if_name[IFNAMSIZ];  /* interface name */
+    lacp_port_priority         ibs_port_priority;
+    lacp_actor_partner_state   ibs_state;
+    u_char                     ibs_selected_state;
+    struct if_bond_partner_state ibs_partner_state;
+    u_int32_t                  ibs_reserved[8];
+};
+
+#define IF_BOND_STATUS_REQ_VERSION     1
+
+struct if_bond_status_req {
+    int                ibsr_version;   /* version */
+    int                ibsr_total;     /* returned number of struct if_bond_status's */
+    int                ibsr_count;     /* number that will fit in ibsr_buffer */
+    union {                    /* buffer to hold if_bond_status's */
+       void *          ibsru_buffer;
+       u_int64_t       ibsru_buffer64;
+    } ibsr_ibsru;
+    lacp_key   ibsr_key;       /* returned */
+    u_int8_t   ibsr_mode;      /* returned (IF_BOND_MODE_{LACP, STATIC}) */
+    u_int8_t   ibsr_reserved0; /* for future use */
+    u_int32_t  ibsr_reserved[3];/* for future use */
+};
+#define ibsr_buffer    ibsr_ibsru.ibsru_buffer
+
+struct if_bond_req {
+    u_int32_t  ibr_op;                         /* operation */
+    union {
+       char    ibru_if_name[IFNAMSIZ];         /* interface name */
+       struct if_bond_status_req ibru_status;  /* status information */
+       int     ibru_int_val;
+    } ibr_ibru;
+};
+
+#pragma pack()
+
+#endif /* _NET_IF_BOND_VAR_H_ */
diff --git a/include/osx/if_bridgevar.h b/include/osx/if_bridgevar.h
new file mode 100644 (file)
index 0000000..cc7381f
--- /dev/null
@@ -0,0 +1,497 @@
+/*     $NetBSD: if_bridgevar.h,v 1.4 2003/07/08 07:13:50 itojun Exp $  */
+/*
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed for the NetBSD Project by
+ *     Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * OpenBSD: if_bridge.h,v 1.14 2001/03/22 03:48:29 jason Exp
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Data structure and control definitions for bridge interfaces.
+ */
+
+#ifndef _NET_IF_BRIDGEVAR_H_
+#define _NET_IF_BRIDGEVAR_H_
+
+#include <sys/queue.h>
+
+#include <net/if.h>
+
+/*
+ * Commands used in the SIOCSDRVSPEC ioctl.  Note the lookup of the
+ * bridge interface itself is keyed off the ifdrv structure.
+ */
+#define        BRDGADD                 0       /* add bridge member (ifbreq) */
+#define        BRDGDEL                 1       /* delete bridge member (ifbreq) */
+#define        BRDGGIFFLGS             2       /* get member if flags (ifbreq) */
+#define        BRDGSIFFLGS             3       /* set member if flags (ifbreq) */
+#define        BRDGSCACHE              4       /* set cache size (ifbrparam) */
+#define        BRDGGCACHE              5       /* get cache size (ifbrparam) */
+#define        BRDGGIFS                6       /* get member list (ifbifconf) */
+#define        BRDGRTS                 7       /* get address list (ifbaconf) */
+#define        BRDGSADDR               8       /* set static address (ifbareq) */
+#define        BRDGSTO                 9       /* set cache timeout (ifbrparam) */
+#define        BRDGGTO                 10      /* get cache timeout (ifbrparam) */
+#define        BRDGDADDR               11      /* delete address (ifbareq) */
+#define        BRDGFLUSH               12      /* flush address cache (ifbreq) */
+
+#define        BRDGGPRI                13      /* get priority (ifbrparam) */
+#define        BRDGSPRI                14      /* set priority (ifbrparam) */
+#define        BRDGGHT                 15      /* get hello time (ifbrparam) */
+#define        BRDGSHT                 16      /* set hello time (ifbrparam) */
+#define        BRDGGFD                 17      /* get forward delay (ifbrparam) */
+#define        BRDGSFD                 18      /* set forward delay (ifbrparam) */
+#define        BRDGGMA                 19      /* get max age (ifbrparam) */
+#define        BRDGSMA                 20      /* set max age (ifbrparam) */
+#define        BRDGSIFPRIO             21      /* set if priority (ifbreq) */
+#define        BRDGSIFCOST             22      /* set if path cost (ifbreq) */
+#define BRDGGFILT              23      /* get filter flags (ifbrparam) */
+#define BRDGSFILT          24  /* set filter flags (ifbrparam) */
+#define        BRDGPURGE               25      /* purge address cache for a particular interface (ifbreq) */
+#define        BRDGADDS                26      /* add bridge span member (ifbreq) */
+#define        BRDGDELS                27      /* delete bridge span member (ifbreq) */
+#define        BRDGPARAM               28      /* get bridge STP params (ifbropreq) */
+#define        BRDGGRTE                29      /* get cache drops (ifbrparam) */
+#define        BRDGGIFSSTP             30      /* get member STP params list (ifbpstpconf) */
+#define        BRDGSPROTO              31      /* set protocol (ifbrparam) */
+#define        BRDGSTXHC               32      /* set tx hold count (ifbrparam) */
+#define        BRDGSIFAMAX             33      /* set max interface addrs (ifbreq) */
+
+/*
+ * Generic bridge control request.
+ */
+#pragma pack(4)
+
+struct ifbreq {
+       char            ifbr_ifsname[IFNAMSIZ]; /* member if name */
+       uint32_t        ifbr_ifsflags;          /* member if flags */
+       uint32_t        ifbr_stpflags;          /* member if STP flags */
+       uint32_t        ifbr_path_cost;         /* member if STP cost */
+       uint8_t         ifbr_portno;            /* member if port number */
+       uint8_t         ifbr_priority;          /* member if STP priority */
+       uint8_t         ifbr_proto;             /* member if STP protocol */
+       uint8_t         ifbr_role;              /* member if STP role */
+       uint8_t         ifbr_state;             /* member if STP state */
+       uint32_t        ifbr_addrcnt;           /* member if addr number */
+       uint32_t        ifbr_addrmax;           /* member if addr max */
+       uint32_t        ifbr_addrexceeded;      /* member if addr violations */
+       uint8_t         pad[32];
+};
+
+#pragma pack()
+
+/* BRDGGIFFLAGS, BRDGSIFFLAGS */
+#define        IFBIF_LEARNING          0x0001  /* if can learn */
+#define        IFBIF_DISCOVER          0x0002  /* if sends packets w/ unknown dest. */
+#define        IFBIF_STP               0x0004  /* if participates in spanning tree */
+#define        IFBIF_SPAN              0x0008  /* if is a span port */
+#define        IFBIF_STICKY            0x0010  /* if learned addresses stick */
+#define        IFBIF_BSTP_EDGE         0x0020  /* member stp edge port */
+#define        IFBIF_BSTP_AUTOEDGE     0x0040  /* member stp autoedge enabled */
+#define        IFBIF_BSTP_PTP          0x0080  /* member stp point to point */
+#define        IFBIF_BSTP_AUTOPTP      0x0100  /* member stp autoptp enabled */
+#define        IFBIF_BSTP_ADMEDGE      0x0200  /* member stp admin edge enabled */
+#define        IFBIF_BSTP_ADMCOST      0x0400  /* member stp admin path cost */
+#define        IFBIF_PRIVATE           0x0800  /* if is a private segment */
+
+#define        IFBIFBITS       "\020\001LEARNING\002DISCOVER\003STP\004SPAN" \
+                       "\005STICKY\014PRIVATE\006EDGE\007AUTOEDGE\010PTP" \
+                       "\011AUTOPTP"
+#define        IFBIFMASK       ~(IFBIF_BSTP_EDGE|IFBIF_BSTP_AUTOEDGE|IFBIF_BSTP_PTP| \
+                       IFBIF_BSTP_AUTOPTP|IFBIF_BSTP_ADMEDGE| \
+                       IFBIF_BSTP_ADMCOST)     /* not saved */
+
+/* BRDGFLUSH */
+#define        IFBF_FLUSHDYN           0x00    /* flush learned addresses only */
+#define        IFBF_FLUSHALL           0x01    /* flush all addresses */
+
+/* BRDGSFILT */
+#define IFBF_FILT_USEIPF       0x00000001 /* run pfil hooks on the bridge
+interface */
+#define IFBF_FILT_MEMBER       0x00000002 /* run pfil hooks on the member
+interfaces */
+#define IFBF_FILT_ONLYIP       0x00000004 /* only pass IP[46] packets when
+pfil is enabled */
+#define IFBF_FILT_MASK         0x00000007 /* mask of valid values */
+
+
+/* APPLE MODIFICATION <jhw@apple.com>: Default is to pass non-IP packets. */
+#define        IFBF_FILT_DEFAULT       ( IFBF_FILT_USEIPF | IFBF_FILT_MEMBER )
+#if 0
+#define        IFBF_FILT_DEFAULT       (IFBF_FILT_USEIPF | \
+IFBF_FILT_MEMBER | \
+IFBF_FILT_ONLYIP)
+#endif
+
+/*
+ * Interface list structure.
+ */
+
+#pragma pack(4)
+
+#ifndef XNU_KERNEL_PRIVATE
+
+struct ifbifconf {
+       uint32_t        ifbic_len;      /* buffer size */
+       union {
+               caddr_t ifbicu_buf;
+               struct ifbreq *ifbicu_req;
+#define        ifbic_buf       ifbic_ifbicu.ifbicu_buf
+#define        ifbic_req       ifbic_ifbicu.ifbicu_req
+       } ifbic_ifbicu;
+};
+
+#else /* XNU_KERNEL_PRIVATE */
+
+struct ifbifconf32 {
+       uint32_t        ifbic_len;      /* buffer size */
+       union {
+               user32_addr_t   ifbicu_buf;
+               user32_addr_t   ifbicu_req;
+#define        ifbic_buf       ifbic_ifbicu.ifbicu_buf
+#define        ifbic_req       ifbic_ifbicu.ifbicu_req
+       } ifbic_ifbicu;
+};
+
+struct ifbifconf64 {
+       uint32_t        ifbic_len;      /* buffer size */
+       union {
+               user64_addr_t   ifbicu_buf;
+               user64_addr_t   ifbicu_req;
+       } ifbic_ifbicu;
+};
+#endif /* XNU_KERNEL_PRIVATE */
+
+#pragma pack()
+
+/*
+ * Bridge address request.
+ */
+
+#pragma pack(4)
+
+#ifndef XNU_KERNEL_PRIVATE
+
+struct ifbareq {
+       char            ifba_ifsname[IFNAMSIZ]; /* member if name */
+       unsigned long   ifba_expire;            /* address expire time */
+       uint8_t         ifba_flags;             /* address flags */
+       uint8_t         ifba_dst[ETHER_ADDR_LEN];/* destination address */
+       uint16_t        ifba_vlan;              /* vlan id */
+};
+
+#else /* XNU_KERNEL_PRIVATE */
+
+struct ifbareq32 {
+       char            ifba_ifsname[IFNAMSIZ]; /* member if name */
+       uint32_t        ifba_expire;            /* address expire time */
+       uint8_t         ifba_flags;             /* address flags */
+       uint8_t         ifba_dst[ETHER_ADDR_LEN];/* destination address */
+       uint16_t        ifba_vlan;              /* vlan id */
+};
+
+struct ifbareq64 {
+       char            ifba_ifsname[IFNAMSIZ]; /* member if name */
+       uint64_t        ifba_expire;            /* address expire time */
+       uint8_t         ifba_flags;             /* address flags */
+       uint8_t         ifba_dst[ETHER_ADDR_LEN];/* destination address */
+       uint16_t        ifba_vlan;              /* vlan id */
+};
+#endif /* XNU_KERNEL_PRIVATE */
+
+#pragma pack()
+
+#define        IFBAF_TYPEMASK  0x03    /* address type mask */
+#define        IFBAF_DYNAMIC   0x00    /* dynamically learned address */
+#define        IFBAF_STATIC    0x01    /* static address */
+#define        IFBAF_STICKY    0x02    /* sticky address */
+
+#define        IFBAFBITS       "\020\1STATIC\2STICKY"
+
+/*
+ * Address list structure.
+ */
+
+#pragma pack(4)
+
+#ifndef XNU_KERNEL_PRIVATE
+
+struct ifbaconf {
+       uint32_t        ifbac_len;      /* buffer size */
+       union {
+               caddr_t ifbacu_buf;
+               struct ifbareq *ifbacu_req;
+#define        ifbac_buf       ifbac_ifbacu.ifbacu_buf
+#define        ifbac_req       ifbac_ifbacu.ifbacu_req
+       } ifbac_ifbacu;
+};
+
+#else /* XNU_KERNEL_PRIVATE */
+
+struct ifbaconf32 {
+       uint32_t        ifbac_len;      /* buffer size */
+       union {
+               user32_addr_t   ifbacu_buf;
+               user32_addr_t   ifbacu_req;
+#define        ifbac_buf       ifbac_ifbacu.ifbacu_buf
+#define        ifbac_req       ifbac_ifbacu.ifbacu_req
+       } ifbac_ifbacu;
+};
+
+struct ifbaconf64 {
+       uint32_t        ifbac_len;      /* buffer size */
+       union {
+               user64_addr_t   ifbacu_buf;
+               user64_addr_t   ifbacu_req;
+       } ifbac_ifbacu;
+};
+#endif /* XNU_KERNEL_PRIVATE */
+
+#pragma pack()
+
+/*
+ * Bridge parameter structure.
+ */
+
+#pragma pack(4)
+
+struct ifbrparam {
+       union {
+               uint32_t ifbrpu_int32;
+               uint16_t ifbrpu_int16;
+               uint8_t ifbrpu_int8;
+       } ifbrp_ifbrpu;
+};
+
+#pragma pack()
+
+#define        ifbrp_csize     ifbrp_ifbrpu.ifbrpu_int32       /* cache size */
+#define        ifbrp_ctime     ifbrp_ifbrpu.ifbrpu_int32       /* cache time (sec) */
+#define        ifbrp_prio      ifbrp_ifbrpu.ifbrpu_int16       /* bridge priority */
+#define        ifbrp_proto     ifbrp_ifbrpu.ifbrpu_int8        /* bridge protocol */
+#define        ifbrp_txhc      ifbrp_ifbrpu.ifbrpu_int8        /* bpdu tx holdcount */
+#define        ifbrp_hellotime ifbrp_ifbrpu.ifbrpu_int8        /* hello time (sec) */
+#define        ifbrp_fwddelay  ifbrp_ifbrpu.ifbrpu_int8        /* fwd time (sec) */
+#define        ifbrp_maxage    ifbrp_ifbrpu.ifbrpu_int8        /* max age (sec) */
+#define        ifbrp_cexceeded ifbrp_ifbrpu.ifbrpu_int32       /* # of cache dropped
+                                                        * adresses */
+#define        ifbrp_filter    ifbrp_ifbrpu.ifbrpu_int32       /* filtering flags */
+
+/*
+ * Bridge current operational parameters structure.
+ */
+
+#pragma pack(4)
+
+#ifndef XNU_KERNEL_PRIVATE
+
+struct ifbropreq {
+       uint8_t         ifbop_holdcount;
+       uint8_t         ifbop_maxage;
+       uint8_t         ifbop_hellotime;
+       uint8_t         ifbop_fwddelay;
+       uint8_t         ifbop_protocol;
+       uint16_t        ifbop_priority;
+       uint16_t        ifbop_root_port;
+       uint32_t        ifbop_root_path_cost;
+       uint64_t        ifbop_bridgeid;
+       uint64_t        ifbop_designated_root;
+       uint64_t        ifbop_designated_bridge;
+       struct timeval  ifbop_last_tc_time;
+};
+
+#else /* XNU_KERNEL_PRIVATE */
+
+struct ifbropreq32 {
+       uint8_t         ifbop_holdcount;
+       uint8_t         ifbop_maxage;
+       uint8_t         ifbop_hellotime;
+       uint8_t         ifbop_fwddelay;
+       uint8_t         ifbop_protocol;
+       uint16_t        ifbop_priority;
+       uint16_t        ifbop_root_port;
+       uint32_t        ifbop_root_path_cost;
+       uint64_t        ifbop_bridgeid;
+       uint64_t        ifbop_designated_root;
+       uint64_t        ifbop_designated_bridge;
+       struct timeval  ifbop_last_tc_time;
+};
+
+struct ifbropreq64 {
+       uint8_t         ifbop_holdcount;
+       uint8_t         ifbop_maxage;
+       uint8_t         ifbop_hellotime;
+       uint8_t         ifbop_fwddelay;
+       uint8_t         ifbop_protocol;
+       uint16_t        ifbop_priority;
+       uint16_t        ifbop_root_port;
+       uint32_t        ifbop_root_path_cost;
+       uint64_t        ifbop_bridgeid;
+       uint64_t        ifbop_designated_root;
+       uint64_t        ifbop_designated_bridge;
+       struct timeval  ifbop_last_tc_time;
+};
+
+#endif
+
+#pragma pack()
+
+/*
+ * Bridge member operational STP params structure.
+ */
+
+#pragma pack(4)
+
+struct ifbpstpreq {
+       uint8_t         ifbp_portno;            /* bp STP port number */
+       uint32_t        ifbp_fwd_trans;         /* bp STP fwd transitions */
+       uint32_t        ifbp_design_cost;       /* bp STP designated cost */
+       uint32_t        ifbp_design_port;       /* bp STP designated port */
+       uint64_t        ifbp_design_bridge;     /* bp STP designated bridge */
+       uint64_t        ifbp_design_root;       /* bp STP designated root */
+};
+
+#pragma pack()
+
+/*
+ * Bridge STP ports list structure.
+ */
+
+#pragma pack(4)
+
+#ifndef XNU_KERNEL_PRIVATE
+
+struct ifbpstpconf {
+       uint32_t        ifbpstp_len;    /* buffer size */
+       union {
+               caddr_t ifbpstpu_buf;
+               struct ifbpstpreq *ifbpstpu_req;
+       } ifbpstp_ifbpstpu;
+#define        ifbpstp_buf     ifbpstp_ifbpstpu.ifbpstpu_buf
+#define        ifbpstp_req     ifbpstp_ifbpstpu.ifbpstpu_req
+};
+
+#else /* XNU_KERNEL_PRIVATE */
+
+struct ifbpstpconf32 {
+       uint32_t        ifbpstp_len;    /* buffer size */
+       union {
+               user32_addr_t   ifbpstpu_buf;
+               user32_addr_t   ifbpstpu_req;
+#define        ifbpstp_buf     ifbpstp_ifbpstpu.ifbpstpu_buf
+#define        ifbpstp_req     ifbpstp_ifbpstpu.ifbpstpu_req
+       } ifbpstp_ifbpstpu;
+};
+
+struct ifbpstpconf64 {
+       uint32_t        ifbpstp_len;    /* buffer size */
+       union {
+               user64_addr_t   ifbpstpu_buf;
+               user64_addr_t   ifbpstpu_req;
+       } ifbpstp_ifbpstpu;
+};
+
+#endif /* XNU_KERNEL_PRIVATE */
+
+#pragma pack()
+
+
+#ifdef XNU_KERNEL_PRIVATE
+
+extern u_int8_t        bstp_etheraddr[ETHER_ADDR_LEN];
+
+int    bridgeattach(int);
+
+#endif /* XNU_KERNEL_PRIVATE */
+#endif /* !_NET_IF_BRIDGEVAR_H_ */
diff --git a/include/osx/if_vlan_var.h b/include/osx/if_vlan_var.h
new file mode 100644 (file)
index 0000000..069a81d
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $FreeBSD: src/sys/net/if_vlan_var.h,v 1.16 2003/07/08 21:54:20 wpaul Exp $
+ */
+
+#ifndef _NET_IF_VLAN_VAR_H_
+#define        _NET_IF_VLAN_VAR_H_     1
+
+#define        ETHER_VLAN_ENCAP_LEN    4       /* len of 802.1Q VLAN encapsulation */
+struct ether_vlan_header {
+       u_char  evl_dhost[ETHER_ADDR_LEN];
+       u_char  evl_shost[ETHER_ADDR_LEN];
+       u_int16_t evl_encap_proto;
+       u_int16_t evl_tag;
+       u_int16_t evl_proto;
+};
+
+#define EVL_VLID_MASK  0x0FFF
+#define        EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK)
+#define        EVL_PRIOFTAG(tag) (((tag) >> 13) & 7)
+
+#if 0
+/* sysctl(3) tags, for compatibility purposes */
+#define        VLANCTL_PROTO   1
+#define        VLANCTL_MAX     2
+#endif
+
+/*
+ * Configuration structure for SIOCSETVLAN and SIOCGETVLAN ioctls.
+ */
+struct vlanreq {
+       char    vlr_parent[IFNAMSIZ];
+       u_short vlr_tag;
+};
+
+#ifdef KERNEL_PRIVATE
+int vlan_family_init(void) __attribute__((section("__TEXT, initcode")));
+#endif /* KERNEL_PRIVATE */
+#endif /* _NET_IF_VLAN_VAR_H_ */
diff --git a/include/osx/lacp.h b/include/osx/lacp.h
new file mode 100644 (file)
index 0000000..04c81c1
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+/*
+ * lacp.h
+ * - definitions for the Link Aggregation Control Protocol (LACP) and
+ *   the Link Aggregation Marker Protocol
+ */
+
+/* 
+ * Modification History
+ *
+ * May 14, 2004        Dieter Siegmund (dieter@apple.com)
+ * - created
+ */
+
+#ifndef _NET_LACP_H_
+#define        _NET_LACP_H_
+
+#include <sys/types.h>
+#include <string.h>
+
+/**
+ ** Link Aggregation Control Protocol (LACP) definitions
+ **/
+#define LACPDU_VERSION_1               1
+
+#define LACPDU_TLV_TYPE_TERMINATOR     0x00
+#define LACPDU_TLV_TYPE_ACTOR          0x01
+#define LACPDU_TLV_TYPE_PARTNER        0x02
+#define LACPDU_TLV_TYPE_COLLECTOR      0x03
+
+#define LACPDU_ACTOR_TLV_LENGTH        20
+#define LACPDU_PARTNER_TLV_LENGTH      20
+#define LACPDU_COLLECTOR_TLV_LENGTH    16
+
+typedef u_char lacp_actor_partner_state;
+typedef u_int16_t lacp_key;
+typedef u_int16_t lacp_system_priority, lacp_port_priority, lacp_port;
+typedef u_int16_t lacp_collector_max_delay;
+typedef struct {
+    u_char     system_id[6];
+} lacp_system, *lacp_system_ref;
+
+/*
+ * LACP Actor/Partner TLV 
+ */
+typedef struct lacp_actor_partner_tlv_s {
+    u_char     lap_tlv_type;           /* 0x01 or 0x02 */
+    u_char     lap_length;             /* 20 */
+    u_char     lap_system_priority[2];
+    u_char     lap_system[6];
+    u_char     lap_key[2];
+    u_char     lap_port_priority[2];
+    u_char     lap_port[2];
+    u_char     lap_state;
+    u_char     lap_reserved[3];
+} lacp_actor_partner_tlv, *lacp_actor_partner_tlv_ref;
+
+/*
+ * LACP Collector TLV
+ */
+typedef struct lacp_collector_tlv_s {
+    u_char     lac_tlv_type;           /* 0x03 */
+    u_char     lac_length;             /* 16 */
+    u_char     lac_max_delay[2];
+    u_char     lac_reserved[12];
+} lacp_collector_tlv, *lacp_collector_tlv_ref;
+
+
+/* 
+ * LACP Actor/Partner State bits
+ */
+#define LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY         0x01
+#define LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT          0x02
+#define LACP_ACTOR_PARTNER_STATE_AGGREGATION           0x04
+#define LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION       0x08
+#define LACP_ACTOR_PARTNER_STATE_COLLECTING            0x10
+#define LACP_ACTOR_PARTNER_STATE_DISTRIBUTING          0x20
+#define LACP_ACTOR_PARTNER_STATE_DEFAULTED             0x40
+#define LACP_ACTOR_PARTNER_STATE_EXPIRED               0x80
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_active_lacp(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_passive_lacp(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY);
+}
+
+static __inline__ int
+lacp_actor_partner_state_active_lacp(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_short_timeout(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_long_timeout(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT);
+}
+
+static __inline__ int
+lacp_actor_partner_state_short_timeout(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_aggregatable(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_AGGREGATION);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_individual(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_AGGREGATION);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_aggregatable(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_AGGREGATION) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_in_sync(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_out_of_sync(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION);
+}
+
+static __inline__ int
+lacp_actor_partner_state_in_sync(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_collecting(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_COLLECTING);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_not_collecting(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_COLLECTING);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_collecting(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_COLLECTING) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_distributing(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_DISTRIBUTING);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_not_distributing(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_DISTRIBUTING);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_distributing(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_DISTRIBUTING) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_defaulted(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_DEFAULTED);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_not_defaulted(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_DEFAULTED);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_defaulted(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_DEFAULTED) != 0);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_expired(lacp_actor_partner_state state)
+{
+    return (state | LACP_ACTOR_PARTNER_STATE_EXPIRED);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_set_not_expired(lacp_actor_partner_state state)
+{
+    return (state &= ~LACP_ACTOR_PARTNER_STATE_EXPIRED);
+}
+
+static __inline__ lacp_actor_partner_state
+lacp_actor_partner_state_expired(lacp_actor_partner_state state)
+{
+    return ((state & LACP_ACTOR_PARTNER_STATE_EXPIRED) != 0);
+}
+
+/*
+ * Function: lacp_uint16_set
+ * Purpose:
+ *   Set a field in a structure that's at least 16 bits to the given
+ *   value, putting it into network byte order
+ */
+static __inline__ void
+lacp_uint16_set(uint8_t * field, uint16_t value)
+{
+    uint16_t tmp_value = htons(value);
+    memcpy((void *)field, (void *)&tmp_value, sizeof(uint16_t));
+    return;
+}
+
+/*
+ * Function: lacp_uint16_get
+ * Purpose:
+ *   Get a field in a structure that's at least 16 bits, converting
+ *   to host byte order.
+ */
+static __inline__ uint16_t
+lacp_uint16_get(const uint8_t * field)
+{
+    uint16_t tmp_field;
+    memcpy((void *)&tmp_field, (void *)field, sizeof(uint16_t));
+    return (ntohs(tmp_field));
+}
+
+/*
+ * Function: lacp_uint32_set
+ * Purpose:
+ *   Set a field in a structure that's at least 32 bits to the given
+ *   value, putting it into network byte order
+ */
+static __inline__ void
+lacp_uint32_set(uint8_t * field, uint32_t value)
+{
+    uint32_t tmp_value = htonl(value);
+    memcpy((void *)field, (void *)&tmp_value, sizeof(uint32_t));
+    return;
+}
+
+/*
+ * Function: lacp_uint32_get
+ * Purpose:
+ *   Get a field in a structure that's at least 32 bits, converting
+ *   to host byte order.
+ */
+static __inline__ uint32_t
+lacp_uint32_get(const uint8_t * field)
+{
+    uint32_t tmp_field;
+    memcpy((void *)&tmp_field, (void *)field, sizeof(uint32_t));
+    return (ntohl(tmp_field));
+}
+
+/*
+ * LACP Actor/Partner TLV access functions
+ */
+static __inline__ void
+lacp_actor_partner_tlv_set_system_priority(lacp_actor_partner_tlv_ref tlv, 
+                                          lacp_system_priority system_priority)
+{
+    lacp_uint16_set(tlv->lap_system_priority, system_priority);
+    return;
+}
+
+static __inline__ lacp_system_priority
+lacp_actor_partner_tlv_get_system_priority(const lacp_actor_partner_tlv_ref tlv)
+{
+    return (lacp_system_priority)lacp_uint16_get(tlv->lap_system_priority);
+}
+
+static __inline__ void
+lacp_actor_partner_tlv_set_key(lacp_actor_partner_tlv_ref tlv, lacp_key key)
+{
+    lacp_uint16_set(tlv->lap_key, key);
+    return;
+}
+
+static __inline__ lacp_key
+lacp_actor_partner_tlv_get_key(const lacp_actor_partner_tlv_ref tlv)
+{
+    return (lacp_key)lacp_uint16_get(tlv->lap_key);
+}
+
+static __inline__ void
+lacp_actor_partner_tlv_set_port_priority(lacp_actor_partner_tlv_ref tlv, 
+                                        lacp_port_priority port_priority)
+{
+    lacp_uint16_set(tlv->lap_port_priority, port_priority);
+    return;
+}
+
+static __inline__ lacp_port_priority
+lacp_actor_partner_tlv_get_port_priority(const lacp_actor_partner_tlv_ref tlv)
+{
+    return (lacp_port_priority)lacp_uint16_get(tlv->lap_port_priority);
+}
+
+static __inline__ void
+lacp_actor_partner_tlv_set_port(lacp_actor_partner_tlv_ref tlv, lacp_port port)
+{
+    lacp_uint16_set(tlv->lap_port, port);
+    return;
+}
+
+static __inline__ lacp_port
+lacp_actor_partner_tlv_get_port(const lacp_actor_partner_tlv_ref tlv)
+{
+    return (lacp_port)lacp_uint16_get(tlv->lap_port);
+}
+
+/*
+ * LACP Collector TLV access functions
+ */
+static __inline__ void
+lacp_collector_tlv_set_max_delay(lacp_collector_tlv_ref tlv, 
+                                lacp_collector_max_delay delay)
+{
+    lacp_uint16_set(tlv->lac_max_delay, delay);
+    return;
+}
+
+static __inline__ lacp_collector_max_delay
+lacp_collector_tlv_get_max_delay(const lacp_collector_tlv_ref tlv)
+{
+    return (lacp_collector_max_delay)lacp_uint16_get(tlv->lac_max_delay);
+}
+
+typedef struct lacpdu_s {
+    u_char             la_subtype;
+    u_char             la_version;
+    u_char             la_actor_tlv[LACPDU_ACTOR_TLV_LENGTH];
+    u_char             la_partner_tlv[LACPDU_PARTNER_TLV_LENGTH];
+    u_char             la_collector_tlv[LACPDU_COLLECTOR_TLV_LENGTH];
+    u_char             la_terminator_type;
+    u_char             la_terminator_length;
+    u_char             la_reserved[50];
+} lacpdu, *lacpdu_ref;
+
+/* timer values in seconds */
+#define LACP_FAST_PERIODIC_TIME                1 
+#define LACP_SLOW_PERIODIC_TIME                30
+#define LACP_SHORT_TIMEOUT_TIME                3
+#define LACP_LONG_TIMEOUT_TIME         90
+#define LACP_CHURN_DETECTION_TIME      60
+#define LACP_AGGREGATE_WAIT_TIME       2
+
+/* packet rate per second */
+#define LACP_PACKET_RATE               3
+
+/**
+ ** Link Aggregation Marker Protocol definitions
+ **/
+#define LA_MARKER_PDU_VERSION_1                        1
+#define LA_MARKER_TLV_TYPE_TERMINATOR          0x00
+#define LA_MARKER_TLV_TYPE_MARKER              0x01
+#define LA_MARKER_TLV_TYPE_MARKER_RESPONSE     0x02
+
+#define LA_MARKER_TLV_LENGTH                   16
+#define LA_MARKER_RESPONSE_TLV_LENGTH          16
+
+typedef u_int32_t la_marker_transaction_id;
+
+typedef struct la_marker_pdu_s {
+    u_char             lm_subtype;             /* 0x02 */
+    u_char             lm_version;             /* 0x01 */
+    u_char             lm_marker_tlv_type;     /* 0x01 or 0x02 */
+    u_char             lm_marker_tlv_length;   /* 16 */
+    u_char             lm_requestor_port[2];
+    u_char             lm_requestor_system[6];
+    u_char             lm_requestor_transaction_id[4];
+    u_char             lm_pad[2];
+    u_char             lm_terminator_type;     /* 0x00 */
+    u_char             lm_terminator_length;   /* 0 */
+    u_char             lm_reserved[90];
+} la_marker_pdu, *la_marker_pdu_ref, 
+    la_marker_response_pdu, * la_marker_response_pdu_ref;
+
+static __inline__ void
+la_marker_pdu_set_requestor_port(la_marker_pdu_ref lmpdu, lacp_port port)
+{
+    lacp_uint16_set(lmpdu->lm_requestor_port, port);
+    return;
+}
+
+static __inline__ lacp_port
+la_marker_pdu_get_requestor_port(la_marker_pdu_ref lmpdu)
+{
+    return (lacp_port)lacp_uint16_get(lmpdu->lm_requestor_port);
+}
+
+static __inline__ void
+la_marker_pdu_set_requestor_transaction_id(la_marker_pdu_ref lmpdu, 
+                                          la_marker_transaction_id xid)
+{
+    lacp_uint32_set(lmpdu->lm_requestor_transaction_id, xid);
+    return;
+}
+
+static __inline__ la_marker_transaction_id
+la_marker_pdu_get_requestor_transaction_id(la_marker_pdu_ref lmpdu)
+{
+    return (la_marker_transaction_id)lacp_uint32_get(lmpdu->lm_requestor_transaction_id);
+}
+
+static __inline__ void
+la_marker_pdu_set_requestor_system(la_marker_pdu_ref lmpdu, lacp_system sys)
+{
+    *((lacp_system_ref)lmpdu->lm_requestor_system) = sys;
+    return;
+}
+
+static __inline__ lacp_system
+la_marker_pdu_get_requestor_system(la_marker_pdu_ref lmpdu)
+{
+    return (*(lacp_system_ref)(lmpdu->lm_requestor_system));
+}
+
+#endif /* _NET_LACP_H_ */
index 1732dccf5c1efa1b5faccd691e7136f9dad4a6a1..7947dc918cf3af1d09dc538885ad420e8a3e8624 100644 (file)
--- a/m4/os.m4
+++ b/m4/os.m4
@@ -10,7 +10,7 @@ AC_DEFUN([lldp_DEFINE_OS], [dnl
       AC_DEFINE_UNQUOTED(HOST_OS_$3, 1, [Host operating system is $2])
       ;;
   esac
-  AM_CONDITIONAL(HOST_OS_$3, test x$os = x$2)dnl
+  AM_CONDITIONAL(HOST_OS_$3, test x"$os" = x"$2")dnl
 ])
 
 AC_DEFUN([lldp_CHECK_OS], [
@@ -21,8 +21,9 @@ AC_DEFUN([lldp_CHECK_OS], [
   lldp_DEFINE_OS(freebsd*|kfreebsd*, FreeBSD, FREEBSD)
   lldp_DEFINE_OS(openbsd*, OpenBSD, OPENBSD)
   lldp_DEFINE_OS(netbsd*, NetBSD, NETBSD)
+  lldp_DEFINE_OS(darwin*, [Mac OS X], OSX)
 
-  if test x$os = x; then
+  if test x"$os" = x; then
      AC_MSG_RESULT(no)
      AC_MSG_ERROR([*** unsupported OS $host_os])
   fi
index 6bf15b994c052efa02de75aa83be563e89ed8c3a..4ab53f9e7c4606a7238ee1a62ab73bcb120f222d 100644 (file)
@@ -1,4 +1,4 @@
 noinst_LTLIBRARIES = libcompat.la
 
-libcompat_la_SOURCES = compat.h
+libcompat_la_SOURCES = compat.h empty.c
 libcompat_la_LIBADD  = @LTLIBOBJS@
diff --git a/src/compat/empty.c b/src/compat/empty.c
new file mode 100644 (file)
index 0000000..80587ae
--- /dev/null
@@ -0,0 +1,21 @@
+/* -*- mode: c; c-file-style: "openbsd" -*- */
+/*
+ * Copyright (c) 2013 Vincent Bernat <bernat@luffy.cx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Some versions of ar don't like to build a library from
+ * nothing. This happens on Mac OS X where we don't need any
+ * compatibility layer. So, we put a tiny variable. Just here. */
+static int __tiny_variable __attribute__((__unused__)) = 0;
index 8171133d3de9a8cc87e33a7a251aba2fa0dfc312..2f27b3b900de8dc0467635e74a132f8240f02f92 100644 (file)
@@ -42,6 +42,11 @@ liblldpd_la_SOURCES += \
        interfaces-bsd.c \
        dmi-dummy.c
 endif
+if HOST_OS_OSX
+liblldpd_la_SOURCES += \
+       interfaces-bsd.c \
+       dmi-dummy.c
+endif
 
 # Add SNMP support if needed
 if USE_SNMP
index 17470f97774cca75567cae940c1922929878c356..e7475a895cd9525928ac0aed0bb02eda4dfafc50 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef _FRAME_H
 #define _FRAME_H
 
-union {
+static union {
        uint8_t f_uint8;
        uint16_t f_uint16;
        uint32_t f_uint32;
index aeedf9e57ecc2c4beec3a450da4950bc41042d45..7e6d7c32e087e090f280067f091b4b697b3b051d 100644 (file)
 #include <net/if_media.h>
 #include <net/if_dl.h>
 #if defined HOST_OS_FREEBSD
-#include <net/if_vlan_var.h>
+# include <net/if_vlan_var.h>
 # include <net/if_bridgevar.h>
 # include <net/if_lagg.h>
 #elif defined HOST_OS_OPENBSD
-#include <net/if_vlan_var.h>
+# include <net/if_vlan_var.h>
 # include <net/if_bridge.h>
 # include <net/if_trunk.h>
 #elif defined HOST_OS_NETBSD
-#include <net/if_vlanvar.h>
+# include <net/if_vlanvar.h>
 # include <net/if_bridgevar.h>
 # include <net/agr/if_agrioctl.h>
+#elif defined HOST_OS_OSX
+# include <osx/if_vlan_var.h>
+# include <osx/if_bridgevar.h>
+# include <osx/if_bond_var.h>
 #endif
 
 #ifndef IFDESCRSIZE
@@ -70,7 +74,7 @@ ifbsd_check_bridge(struct lldpd *cfg,
                .ifbic_req = req
        };
 
-#if defined HOST_OS_FREEBSD || defined HOST_OS_NETBSD
+#if defined HOST_OS_FREEBSD || defined HOST_OS_NETBSD || defined HOST_OS_OSX
        struct ifdrv ifd = {
                .ifd_cmd = BRDGGIFS,
                .ifd_len = sizeof(bifc),
@@ -186,7 +190,7 @@ ifbsd_check_bond(struct lldpd *cfg,
                }
                return;
        }
-       for (int i = 0; i < apl->apl_nports; i++) {
+       for (int i = 0; i < apl->apl_nports; i++, api++) {
                struct interfaces_device *slave;
                slave = interfaces_nametointerface(interfaces,
                    api->api_ifname);
@@ -200,9 +204,62 @@ ifbsd_check_bond(struct lldpd *cfg,
                    "%s is enslaved to bond %s",
                    slave->name, master->name);
                slave->upper = master;
-               api++;
        }
        master->type |= IFACE_BOND_T;
+#elif defined HOST_OS_OSX
+       struct if_bond_req ibr = {
+               .ibr_op = IF_BOND_OP_GET_STATUS,
+               .ibr_ibru = {
+                       .ibru_status = { .ibsr_version = IF_BOND_STATUS_REQ_VERSION }
+               }
+       };
+       struct ifreq ifr = {
+               .ifr_data = (caddr_t)&ibr
+       };
+       strlcpy(ifr.ifr_name, master->name, sizeof(ifr.ifr_name));
+       if (ioctl(cfg->g_sock, SIOCGIFBOND, (caddr_t)&ifr) < 0) {
+               log_debug("interfaces",
+                   "%s is not an aggregate", master->name);
+               return;
+       }
+       master->type |= IFACE_BOND_T;
+       if (ibr.ibr_ibru.ibru_status.ibsr_total == 0) {
+               log_debug("interfaces", "no members for bond %s",
+                   master->name);
+               return;
+       }
+
+       struct if_bond_status_req *ibsr_p = &ibr.ibr_ibru.ibru_status;
+       ibsr_p->ibsr_buffer =
+           malloc(sizeof(struct if_bond_status)*ibsr_p->ibsr_total);
+       if (ibsr_p->ibsr_buffer == NULL) {
+               log_warnx("interfaces", "not enough memory to check bond members");
+               return;
+       }
+       ibsr_p->ibsr_count = ibsr_p->ibsr_total;
+       if (ioctl(cfg->g_sock, SIOCGIFBOND, (caddr_t)&ifr) < 0) {
+               log_warn("interfaces",
+                   "unable to get members for bond %s", master->name);
+               goto end;
+       }
+
+       struct if_bond_status *ibs_p = (struct if_bond_status *)ibsr_p->ibsr_buffer;
+       for (int i = 0; i < ibsr_p->ibsr_total; i++, ibs_p++) {
+               struct interfaces_device *slave;
+               slave = interfaces_nametointerface(interfaces,
+                   ibs_p->ibs_if_name);
+               if (slave == NULL) {
+                       log_warnx("interfaces",
+                           "%s should be enslaved to %s but we don't know %s",
+                           ibs_p->ibs_if_name, master->name, ibs_p->ibs_if_name);
+                       continue;
+               }
+               log_debug("interfaces", "%s is enslaved to bond %s",
+                   slave->name, master->name);
+               slave->upper = master;
+       }
+end:
+       free(ibsr_p->ibsr_buffer);
 #else
 # error Unsupported OS
 #endif
@@ -297,10 +354,10 @@ ifbsd_extract_device(struct lldpd *cfg,
                memcpy(iface->address, LLADDR(saddrdl), ETHER_ADDR_LEN);
 
        /* Grab description */
-#ifndef HOST_OS_NETBSD
+#if defined HOST_OS_FREEBSD || defined HOST_OS_OPENBSD
        iface->alias = malloc(IFDESCRSIZE);
        if (iface->alias) {
-#ifdef HOST_OS_FREEBSD
+#if defined HOST_OS_FREEBSD
                struct ifreq ifr = {
                        .ifr_buffer = { .buffer = iface->alias,
                                        .length = IFDESCRSIZE }
index 46ea049d15cb5f8285902ffb7a4bd8a86fb1f373..630c3e766fc23230f91162e76dddd40cdef0a364 100644 (file)
 #include <netinet/if_ether.h>
 #include <pwd.h>
 #include <grp.h>
-#if defined HOST_OS_FREEBSD  || defined HOST_OS_OPENBSD || defined HOST_OS_NETBSD
+#if defined HOST_OS_FREEBSD || \
+    defined HOST_OS_OPENBSD || \
+    defined HOST_OS_NETBSD  || \
+    defined HOST_OS_OSX
 # include <sys/param.h>
 # include <sys/sysctl.h>
 #endif
@@ -837,6 +840,35 @@ lldpd_med(struct lldpd_chassis *chassis)
 }
 #endif
 
+static int
+lldpd_forwarding_enabled(void)
+{
+       int rc = 0;
+#if defined HOST_OS_LINUX
+       int f;
+       char status;
+       if ((f = priv_open("/proc/sys/net/ipv4/ip_forward")) >= 0) {
+               if ((read(f, &status, 1) == 1) && (status == '1'))
+                       rc = 1;
+               close(f);
+       }
+#elif defined HOST_OS_FREEBSD || defined HOST_OS_OPENBSD || defined HOST_OS_NETBSD || defined HOST_OS_OSX
+       int n, mib[4] = {
+               CTL_NET,
+               PF_INET,
+               IPPROTO_IP,
+               IPCTL_FORWARDING
+       };
+       size_t len = sizeof(int);
+       if (sysctl(mib, 4, &n, &len, NULL, 0) != -1)
+               rc = (n == 1);
+#else
+#error Unsupported OS
+#endif
+       else log_debug("localchassis", "unable to check if forwarding is enabled");
+       return rc;
+}
+
 static void
 lldpd_update_localchassis(struct lldpd *cfg)
 {
@@ -876,36 +908,11 @@ lldpd_update_localchassis(struct lldpd *cfg)
         }
 
        /* Check forwarding */
-#if defined HOST_OS_LINUX
-       int f;
-       char status;
-       if ((f = priv_open("/proc/sys/net/ipv4/ip_forward")) >= 0) {
-               if ((read(f, &status, 1) == 1) && (status == '1')) {
-                       log_debug("localchassis", "forwarding is enabled, enable router capability");
-                       LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_ROUTER;
-               } else
-                       LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER;
-               close(f);
-       }
-#elif defined HOST_OS_FREEBSD || defined HOST_OS_OPENBSD || defined HOST_OS_NETBSD
-       int n, mib[4] = {
-               CTL_NET,
-               PF_INET,
-               IPPROTO_IP,
-               IPCTL_FORWARDING
-       };
-       size_t len = sizeof(int);
-       if (sysctl(mib, 4, &n, &len, NULL, 0) != -1) {
-               if (n == 1) {
-                       log_debug("localchassis", "forwarding is enabled, enable router capability");
-                       LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_ROUTER;
-               } 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");
+       if (lldpd_forwarding_enabled()) {
+               log_debug("localchassis", "forwarding is enabled, enable router capability");
+               LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_ROUTER;
+       } else
+               LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER;
 
 #ifdef ENABLE_LLDPMED
        if (LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_TELEPHONE)
@@ -1020,6 +1027,7 @@ static const struct intint filters[] = {
        { -1, 0 }
 };
 
+#ifndef HOST_OS_OSX
 /**
  * Tell if we have been started by upstart.
  */
@@ -1084,6 +1092,7 @@ lldpd_started_by_systemd()
        return 0;
 #endif
 }
+#endif
 
 int
 lldpd_main(int argc, char *argv[])
@@ -1274,7 +1283,8 @@ lldpd_main(int argc, char *argv[])
        /* Disable SIGPIPE */
        signal(SIGPIPE, SIG_IGN);
 
-       /* Daemonization, unless started by upstart or debug */
+       /* Daemonization, unless started by upstart, systemd or launchd or debug */
+#ifndef HOST_OS_OSX
        if (!lldpd_started_by_upstart() && !lldpd_started_by_systemd() &&
            !debug) {
                int pid;
@@ -1292,6 +1302,7 @@ lldpd_main(int argc, char *argv[])
                free(spid);
                close(pid);
        }
+#endif
 
        /* Try to read system information from /etc/os-release if possible.
           Fall back to lsb_release for compatibility. */
index 5f30ef91dfd4ec0af81cd510947555f30ded60ec..f5ae82bbe27757e6adc400fd9fa46ed4ae1f3fb5 100644 (file)
@@ -39,7 +39,7 @@
 #ifdef HOST_OS_LINUX
 # include <netpacket/packet.h> /* For sockaddr_ll */
 #endif
-#ifdef HOST_OS_FREEBSD
+#if defined HOST_OS_FREEBSD || HOST_OS_OSX
 # include <net/if_dl.h>
 #endif
 #include <netinet/if_ether.h>
@@ -217,7 +217,9 @@ asroot_gethostbyname()
                fatal("privsep", "failed to get system information");
        if ((hp = gethostbyname(un.nodename)) == NULL) {
                log_info("privsep", "unable to get system name");
+#ifdef HAVE_RES_INIT
                res_init();
+#endif
                 len = strlen(un.nodename);
                 must_write(remote, &len, sizeof(int));
                 must_write(remote, un.nodename, len + 1);
@@ -351,7 +353,8 @@ asroot_iface_init()
        close(s);
 #elif defined HOST_OS_FREEBSD || \
       defined HOST_OS_OPENBSD || \
-      defined HOST_OS_NETBSD
+      defined HOST_OS_NETBSD  || \
+      defined HOST_OS_OSX
        int fd = -1, rc = 0, n = 0;
        char dev[20];
        int ifindex;
@@ -387,7 +390,7 @@ asroot_iface_multicast()
        must_read(remote, ifr.ifr_name, IFNAMSIZ);
 #if defined HOST_OS_LINUX
        must_read(remote, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
-#elif defined HOST_OS_FREEBSD
+#elif defined HOST_OS_FREEBSD || defined HOST_OS_OSX
        /* Black magic from mtest.c */
        struct sockaddr_dl *dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
        dlp->sdl_len = sizeof(struct sockaddr_dl);