From: Vincent Bernat Date: Thu, 10 Jan 2013 19:23:57 +0000 (+0100) Subject: Mac OS X support. X-Git-Tag: 0.7.1~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e66b7f34ca14a04dd53b52adcd701be9c0e892c1;p=thirdparty%2Flldpd.git Mac OS X support. 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) --- diff --git a/NEWS b/NEWS index 5f4e8acc..f5fd1f21 100644 --- 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. diff --git a/README.md b/README.md index 3b0a6d7f..18ce156e 100644 --- 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 ----- diff --git a/configure.ac b/configure.ac index b55bd9a5..f07a16ae 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 00000000..316fbe5e --- /dev/null +++ b/include/osx/README.md @@ -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 index 00000000..73f457ec --- /dev/null +++ b/include/osx/if_bond_var.h @@ -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 + +#include + +#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 index 00000000..cc7381f8 --- /dev/null +++ b/include/osx/if_bridgevar.h @@ -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 + +#include + +/* + * 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 : 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 index 00000000..069a81d9 --- /dev/null +++ b/include/osx/if_vlan_var.h @@ -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 index 00000000..04c81c16 --- /dev/null +++ b/include/osx/lacp.h @@ -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 +#include + +/** + ** 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_ */ diff --git a/m4/os.m4 b/m4/os.m4 index 1732dccf..7947dc91 100644 --- 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 diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am index 6bf15b99..4ab53f9e 100644 --- a/src/compat/Makefile.am +++ b/src/compat/Makefile.am @@ -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 index 00000000..80587aea --- /dev/null +++ b/src/compat/empty.c @@ -0,0 +1,21 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2013 Vincent Bernat + * + * 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; diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 8171133d..2f27b3b9 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -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 diff --git a/src/daemon/frame.h b/src/daemon/frame.h index 17470f97..e7475a89 100644 --- a/src/daemon/frame.h +++ b/src/daemon/frame.h @@ -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; diff --git a/src/daemon/interfaces-bsd.c b/src/daemon/interfaces-bsd.c index aeedf9e5..7e6d7c32 100644 --- a/src/daemon/interfaces-bsd.c +++ b/src/daemon/interfaces-bsd.c @@ -28,17 +28,21 @@ #include #include #if defined HOST_OS_FREEBSD -#include +# include # include # include #elif defined HOST_OS_OPENBSD -#include +# include # include # include #elif defined HOST_OS_NETBSD -#include +# include # include # include +#elif defined HOST_OS_OSX +# include +# include +# include #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 } diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 46ea049d..630c3e76 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -37,7 +37,10 @@ #include #include #include -#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 # include #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. */ diff --git a/src/daemon/priv.c b/src/daemon/priv.c index 5f30ef91..f5ae82bb 100644 --- a/src/daemon/priv.c +++ b/src/daemon/priv.c @@ -39,7 +39,7 @@ #ifdef HOST_OS_LINUX # include /* For sockaddr_ll */ #endif -#ifdef HOST_OS_FREEBSD +#if defined HOST_OS_FREEBSD || HOST_OS_OSX # include #endif #include @@ -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);