This commit was manufactured by cvs2svn to create branch 'RELENG_6'.
This commit is contained in:
parent
50c44d102c
commit
472436dd42
246
sys/compat/linux/linux_time.c
Normal file
246
sys/compat/linux/linux_time.c
Normal file
@ -0,0 +1,246 @@
|
||||
/* $NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Emmanuel Dreyfus.
|
||||
*
|
||||
* 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 the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#if 0
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include "opt_compat.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#ifdef COMPAT_LINUX32
|
||||
#include <machine/../linux32/linux.h>
|
||||
#include <machine/../linux32/linux32_proto.h>
|
||||
#else
|
||||
#include <machine/../linux/linux.h>
|
||||
#include <machine/../linux/linux_proto.h>
|
||||
#endif
|
||||
|
||||
static void native_to_linux_timespec(struct l_timespec *,
|
||||
struct timespec *);
|
||||
static int linux_to_native_timespec(struct timespec *,
|
||||
struct l_timespec *);
|
||||
static int linux_to_native_clockid(clockid_t *, clockid_t);
|
||||
|
||||
static void
|
||||
native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
|
||||
{
|
||||
ltp->tv_sec = ntp->tv_sec;
|
||||
ltp->tv_nsec = ntp->tv_nsec;
|
||||
}
|
||||
|
||||
static int
|
||||
linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
|
||||
{
|
||||
if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L)
|
||||
return (EINVAL);
|
||||
ntp->tv_sec = ltp->tv_sec;
|
||||
ntp->tv_nsec = ltp->tv_nsec;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
linux_to_native_clockid(clockid_t *n, clockid_t l)
|
||||
{
|
||||
switch (l) {
|
||||
case LINUX_CLOCK_REALTIME:
|
||||
*n = CLOCK_REALTIME;
|
||||
break;
|
||||
case LINUX_CLOCK_MONOTONIC:
|
||||
*n = CLOCK_MONOTONIC;
|
||||
break;
|
||||
case LINUX_CLOCK_PROCESS_CPUTIME_ID:
|
||||
case LINUX_CLOCK_THREAD_CPUTIME_ID:
|
||||
case LINUX_CLOCK_REALTIME_HR:
|
||||
case LINUX_CLOCK_MONOTONIC_HR:
|
||||
default:
|
||||
return (EINVAL);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
|
||||
{
|
||||
struct l_timespec lts;
|
||||
int error;
|
||||
clockid_t nwhich = 0; /* XXX: GCC */
|
||||
struct timespec tp;
|
||||
|
||||
error = linux_to_native_clockid(&nwhich, args->which);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_clock_gettime(td, nwhich, &tp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
native_to_linux_timespec(<s, &tp);
|
||||
|
||||
return (copyout(<s, args->tp, sizeof lts));
|
||||
}
|
||||
|
||||
int
|
||||
linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct l_timespec lts;
|
||||
int error;
|
||||
clockid_t nwhich = 0; /* XXX: GCC */
|
||||
|
||||
error = linux_to_native_clockid(&nwhich, args->which);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = copyin(args->tp, <s, sizeof lts);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = linux_to_native_timespec(&ts, <s);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
return (kern_clock_settime(td, nwhich, &ts));
|
||||
}
|
||||
|
||||
int
|
||||
linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct l_timespec lts;
|
||||
int error;
|
||||
clockid_t nwhich = 0; /* XXX: GCC */
|
||||
|
||||
if (args->tp == NULL)
|
||||
return (0);
|
||||
|
||||
error = linux_to_native_clockid(&nwhich, args->which);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_clock_getres(td, nwhich, &ts);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
native_to_linux_timespec(<s, &ts);
|
||||
|
||||
return (copyout(<s, args->tp, sizeof lts));
|
||||
}
|
||||
|
||||
int
|
||||
linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
|
||||
{
|
||||
struct timespec *rmtp;
|
||||
struct l_timespec lrqts, lrmts;
|
||||
struct timespec rqts, rmts;
|
||||
int error;
|
||||
|
||||
error = copyin(args->rqtp, &lrqts, sizeof lrqts);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (args->rmtp != NULL)
|
||||
rmtp = &rmts;
|
||||
else
|
||||
rmtp = NULL;
|
||||
|
||||
error = linux_to_native_timespec(&rqts, &lrqts);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_nanosleep(td, &rqts, rmtp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (args->rmtp != NULL) {
|
||||
native_to_linux_timespec(&lrmts, rmtp);
|
||||
error = copyout(&lrmts, args->rmtp, sizeof(lrmts));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args)
|
||||
{
|
||||
struct timespec *rmtp;
|
||||
struct l_timespec lrqts, lrmts;
|
||||
struct timespec rqts, rmts;
|
||||
int error;
|
||||
|
||||
if (args->flags != 0)
|
||||
return (EINVAL); /* XXX deal with TIMER_ABSTIME */
|
||||
|
||||
if (args->which != LINUX_CLOCK_REALTIME)
|
||||
return (EINVAL);
|
||||
|
||||
error = copyin(args->rqtp, &lrqts, sizeof lrqts);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (args->rmtp != NULL)
|
||||
rmtp = &rmts;
|
||||
else
|
||||
rmtp = NULL;
|
||||
|
||||
error = linux_to_native_timespec(&rqts, &lrqts);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_nanosleep(td, &rqts, rmtp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (args->rmtp != NULL) {
|
||||
native_to_linux_timespec(&lrmts, rmtp);
|
||||
error = copyout(&lrmts, args->rmtp, sizeof lrmts );
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
121
sys/contrib/dev/ath/public/wackelf.c
Normal file
121
sys/contrib/dev/ath/public/wackelf.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2006 Atheros Communications, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms 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 NO
|
||||
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
|
||||
* modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a
|
||||
* disclaimer similar to the Disclaimer below and any redistribution
|
||||
* must be conditioned upon including a substantially similar
|
||||
* Disclaimer requirement for further binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the
|
||||
* names of any contributors may be used to endorse or promote
|
||||
* product derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
|
||||
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR 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 DAMAGES.
|
||||
*
|
||||
* $Id: //depot/sw/branches/sam_hal/public/wackelf.c#3 $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Program to zap flags field in the ELF header of an object
|
||||
* file so that it appears to use VFP soft floating point.
|
||||
* This is done because there is no standard way to specify
|
||||
* this on the command line to gcc/binutils.
|
||||
*
|
||||
* Derived from code by Olivier Houchard <cognet@freebsd.org>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#define _LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||
#define _BIG_ENDIAN __BIG_ENDIAN
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define htobe16(x) __bswap_16((x))
|
||||
#define htobe32(x) __bswap_32((x))
|
||||
#define htole16(x) ((uint16_t)(x))
|
||||
#define htole32(x) ((uint32_t)(x))
|
||||
#else /* _BYTE_ORDER != _LITTLE_ENDIAN */
|
||||
#define htobe16(x) ((uint16_t)(x))
|
||||
#define htobe32(x) ((uint32_t)(x))
|
||||
#define htole16(x) __bswap_16((x))
|
||||
#define htole32(x) __bswap_32((x))
|
||||
#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
|
||||
#else
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int fd, endian, oflags;
|
||||
int format = 0x400; /* default to VFP */
|
||||
Elf32_Ehdr ehdr;
|
||||
|
||||
if (argc > 2) {
|
||||
if (strcmp(argv[1], "-fpa") == 0) {
|
||||
format = 0x200;
|
||||
argc--, argv++;
|
||||
} else if (strcmp(argv[1], "-vfp") == 0) {
|
||||
format = 0x400;
|
||||
argc--, argv++;
|
||||
} else if (strcmp(argv[1], "-none") == 0) {
|
||||
format = 0;
|
||||
argc--, argv++;
|
||||
}
|
||||
}
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s [-fpa|-vfp|-none] file\n", argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
fd = open(argv[1], O_RDWR);
|
||||
if (fd < 0)
|
||||
err(1, "could not open %s", argv[1]);
|
||||
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
|
||||
err(1, "could not read the ELF header");
|
||||
if (ehdr.e_machine == htole16(EM_ARM))
|
||||
endian = _LITTLE_ENDIAN;
|
||||
else if (ehdr.e_machine == htobe16(EM_ARM))
|
||||
endian = _BIG_ENDIAN;
|
||||
else
|
||||
errx(1, "not an ARM ELF object (machine 0x%x)", ehdr.e_machine);
|
||||
oflags = ehdr.e_flags;
|
||||
if (endian == _BIG_ENDIAN) {
|
||||
ehdr.e_flags &= ~htobe32(0x600); /* Remove FPA Soft float */
|
||||
ehdr.e_flags |= htobe32(format); /* VFP Soft Float */
|
||||
} else {
|
||||
ehdr.e_flags &= ~htole32(0x600); /* Remove FPA Soft float */
|
||||
ehdr.e_flags |= htole32(format); /* VFP Soft Float */
|
||||
}
|
||||
printf("%s: e_flags 0x%x => 0x%x\n", argv[1], oflags, ehdr.e_flags);
|
||||
if (lseek(fd, (off_t) 0, SEEK_SET) != 0)
|
||||
err(1, "lseek");
|
||||
if (write(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
|
||||
err(1, "yow, elf header write failed");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
2843
sys/dev/ral/rt2560.c
Normal file
2843
sys/dev/ral/rt2560.c
Normal file
File diff suppressed because it is too large
Load Diff
170
sys/dev/ral/rt2560var.h
Normal file
170
sys/dev/ral/rt2560var.h
Normal file
@ -0,0 +1,170 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006
|
||||
* Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and 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.
|
||||
*/
|
||||
|
||||
struct rt2560_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wr_ihdr;
|
||||
uint64_t wr_tsf;
|
||||
uint8_t wr_flags;
|
||||
uint8_t wr_rate;
|
||||
uint16_t wr_chan_freq;
|
||||
uint16_t wr_chan_flags;
|
||||
uint8_t wr_antenna;
|
||||
uint8_t wr_antsignal;
|
||||
};
|
||||
|
||||
#define RT2560_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
||||
|
||||
struct rt2560_tx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wt_ihdr;
|
||||
uint8_t wt_flags;
|
||||
uint8_t wt_rate;
|
||||
uint16_t wt_chan_freq;
|
||||
uint16_t wt_chan_flags;
|
||||
uint8_t wt_antenna;
|
||||
};
|
||||
|
||||
#define RT2560_TX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_ANTENNA))
|
||||
|
||||
struct rt2560_tx_data {
|
||||
bus_dmamap_t map;
|
||||
struct mbuf *m;
|
||||
struct ieee80211_node *ni;
|
||||
struct ral_rssdesc id;
|
||||
};
|
||||
|
||||
struct rt2560_tx_ring {
|
||||
bus_dma_tag_t desc_dmat;
|
||||
bus_dma_tag_t data_dmat;
|
||||
bus_dmamap_t desc_map;
|
||||
bus_addr_t physaddr;
|
||||
struct rt2560_tx_desc *desc;
|
||||
struct rt2560_tx_data *data;
|
||||
int count;
|
||||
int queued;
|
||||
int cur;
|
||||
int next;
|
||||
int cur_encrypt;
|
||||
int next_encrypt;
|
||||
};
|
||||
|
||||
struct rt2560_rx_data {
|
||||
bus_dmamap_t map;
|
||||
struct mbuf *m;
|
||||
int drop;
|
||||
};
|
||||
|
||||
struct rt2560_rx_ring {
|
||||
bus_dma_tag_t desc_dmat;
|
||||
bus_dma_tag_t data_dmat;
|
||||
bus_dmamap_t desc_map;
|
||||
bus_addr_t physaddr;
|
||||
struct rt2560_rx_desc *desc;
|
||||
struct rt2560_rx_data *data;
|
||||
int count;
|
||||
int cur;
|
||||
int next;
|
||||
int cur_decrypt;
|
||||
};
|
||||
|
||||
struct rt2560_node {
|
||||
struct ieee80211_node ni;
|
||||
struct ral_rssadapt rssadapt;
|
||||
};
|
||||
|
||||
struct rt2560_softc {
|
||||
struct ifnet *sc_ifp;
|
||||
struct ieee80211com sc_ic;
|
||||
int (*sc_newstate)(struct ieee80211com *,
|
||||
enum ieee80211_state, int);
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_st;
|
||||
bus_space_handle_t sc_sh;
|
||||
|
||||
struct mtx sc_mtx;
|
||||
|
||||
struct callout watchdog_ch;
|
||||
struct callout scan_ch;
|
||||
struct callout rssadapt_ch;
|
||||
|
||||
int sc_tx_timer;
|
||||
|
||||
uint32_t asic_rev;
|
||||
uint32_t eeprom_rev;
|
||||
uint8_t rf_rev;
|
||||
|
||||
struct rt2560_tx_ring txq;
|
||||
struct rt2560_tx_ring prioq;
|
||||
struct rt2560_tx_ring atimq;
|
||||
struct rt2560_tx_ring bcnq;
|
||||
struct rt2560_rx_ring rxq;
|
||||
|
||||
struct ieee80211_beacon_offsets sc_bo;
|
||||
|
||||
uint32_t rf_regs[4];
|
||||
uint8_t txpow[14];
|
||||
|
||||
struct {
|
||||
uint8_t reg;
|
||||
uint8_t val;
|
||||
} bbp_prom[16];
|
||||
|
||||
int led_mode;
|
||||
int hw_radio;
|
||||
int rx_ant;
|
||||
int tx_ant;
|
||||
int nb_ant;
|
||||
|
||||
int dwelltime;
|
||||
|
||||
struct bpf_if *sc_drvbpf;
|
||||
|
||||
union {
|
||||
struct rt2560_rx_radiotap_header th;
|
||||
uint8_t pad[64];
|
||||
} sc_rxtapu;
|
||||
#define sc_rxtap sc_rxtapu.th
|
||||
int sc_rxtap_len;
|
||||
|
||||
union {
|
||||
struct rt2560_tx_radiotap_header th;
|
||||
uint8_t pad[64];
|
||||
} sc_txtapu;
|
||||
#define sc_txtap sc_txtapu.th
|
||||
int sc_txtap_len;
|
||||
};
|
||||
|
||||
int rt2560_attach(device_t, int);
|
||||
int rt2560_detach(void *);
|
||||
void rt2560_shutdown(void *);
|
||||
void rt2560_suspend(void *);
|
||||
void rt2560_resume(void *);
|
||||
void rt2560_intr(void *);
|
||||
|
||||
#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
|
||||
#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
|
2901
sys/dev/ral/rt2661.c
Normal file
2901
sys/dev/ral/rt2661.c
Normal file
File diff suppressed because it is too large
Load Diff
172
sys/dev/ral/rt2661var.h
Normal file
172
sys/dev/ral/rt2661var.h
Normal file
@ -0,0 +1,172 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005
|
||||
* Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and 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.
|
||||
*/
|
||||
|
||||
struct rt2661_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wr_ihdr;
|
||||
uint64_t wr_tsf;
|
||||
uint8_t wr_flags;
|
||||
uint8_t wr_rate;
|
||||
uint16_t wr_chan_freq;
|
||||
uint16_t wr_chan_flags;
|
||||
uint8_t wr_antsignal;
|
||||
} __packed;
|
||||
|
||||
#define RT2661_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
||||
|
||||
struct rt2661_tx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wt_ihdr;
|
||||
uint8_t wt_flags;
|
||||
uint8_t wt_rate;
|
||||
uint16_t wt_chan_freq;
|
||||
uint16_t wt_chan_flags;
|
||||
} __packed;
|
||||
|
||||
#define RT2661_TX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL))
|
||||
|
||||
struct rt2661_tx_data {
|
||||
bus_dmamap_t map;
|
||||
struct mbuf *m;
|
||||
struct ieee80211_node *ni;
|
||||
struct ral_rssdesc id;
|
||||
};
|
||||
|
||||
struct rt2661_tx_ring {
|
||||
bus_dma_tag_t desc_dmat;
|
||||
bus_dma_tag_t data_dmat;
|
||||
bus_dmamap_t desc_map;
|
||||
bus_addr_t physaddr;
|
||||
struct rt2661_tx_desc *desc;
|
||||
struct rt2661_tx_data *data;
|
||||
int count;
|
||||
int queued;
|
||||
int cur;
|
||||
int next;
|
||||
int stat;
|
||||
};
|
||||
|
||||
struct rt2661_rx_data {
|
||||
bus_dmamap_t map;
|
||||
struct mbuf *m;
|
||||
};
|
||||
|
||||
struct rt2661_rx_ring {
|
||||
bus_dma_tag_t desc_dmat;
|
||||
bus_dma_tag_t data_dmat;
|
||||
bus_dmamap_t desc_map;
|
||||
bus_addr_t physaddr;
|
||||
struct rt2661_rx_desc *desc;
|
||||
struct rt2661_rx_data *data;
|
||||
int count;
|
||||
int cur;
|
||||
int next;
|
||||
};
|
||||
|
||||
struct rt2661_node {
|
||||
struct ieee80211_node ni;
|
||||
struct ral_rssadapt rssadapt;
|
||||
};
|
||||
|
||||
struct rt2661_softc {
|
||||
struct ifnet *sc_ifp;
|
||||
struct ieee80211com sc_ic;
|
||||
int (*sc_newstate)(struct ieee80211com *,
|
||||
enum ieee80211_state, int);
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_st;
|
||||
bus_space_handle_t sc_sh;
|
||||
|
||||
struct mtx sc_mtx;
|
||||
|
||||
struct callout watchdog_ch;
|
||||
struct callout scan_ch;
|
||||
struct callout rssadapt_ch;
|
||||
|
||||
int sc_tx_timer;
|
||||
|
||||
struct ieee80211_channel *sc_curchan;
|
||||
|
||||
uint8_t rf_rev;
|
||||
|
||||
uint8_t rfprog;
|
||||
uint8_t rffreq;
|
||||
|
||||
struct rt2661_tx_ring txq[4];
|
||||
struct rt2661_tx_ring mgtq;
|
||||
struct rt2661_rx_ring rxq;
|
||||
|
||||
uint32_t rf_regs[4];
|
||||
int8_t txpow[38];
|
||||
|
||||
struct {
|
||||
uint8_t reg;
|
||||
uint8_t val;
|
||||
} bbp_prom[16];
|
||||
|
||||
int hw_radio;
|
||||
int rx_ant;
|
||||
int tx_ant;
|
||||
int nb_ant;
|
||||
int ext_2ghz_lna;
|
||||
int ext_5ghz_lna;
|
||||
int rssi_2ghz_corr;
|
||||
int rssi_5ghz_corr;
|
||||
|
||||
uint8_t bbp18;
|
||||
uint8_t bbp21;
|
||||
uint8_t bbp22;
|
||||
uint8_t bbp16;
|
||||
uint8_t bbp17;
|
||||
uint8_t bbp64;
|
||||
|
||||
int dwelltime;
|
||||
|
||||
struct bpf_if *sc_drvbpf;
|
||||
|
||||
union {
|
||||
struct rt2661_rx_radiotap_header th;
|
||||
uint8_t pad[64];
|
||||
} sc_rxtapu;
|
||||
#define sc_rxtap sc_rxtapu.th
|
||||
int sc_rxtap_len;
|
||||
|
||||
union {
|
||||
struct rt2661_tx_radiotap_header th;
|
||||
uint8_t pad[64];
|
||||
} sc_txtapu;
|
||||
#define sc_txtap sc_txtapu.th
|
||||
int sc_txtap_len;
|
||||
};
|
||||
|
||||
int rt2661_attach(device_t, int);
|
||||
int rt2661_detach(void *);
|
||||
void rt2661_shutdown(void *);
|
||||
void rt2661_suspend(void *);
|
||||
void rt2661_resume(void *);
|
||||
void rt2661_intr(void *);
|
||||
|
||||
#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
|
||||
#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
|
183
sys/dev/sound/pci/envy24ht.h
Normal file
183
sys/dev/sound/pci/envy24ht.h
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
|
||||
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/* PCI device ID */
|
||||
#define PCIV_ENVY24 0x1412
|
||||
#define PCID_ENVY24HT 0x1724
|
||||
|
||||
#define PCIR_CCS 0x10 /* Controller I/O Base Address */
|
||||
#define ENVY24HT_PCIR_MT 0x14 /* Multi-Track I/O Base Address */
|
||||
|
||||
/* Controller Registers */
|
||||
|
||||
#define ENVY24HT_CCS_CTL 0x00 /* Control/Status Register */
|
||||
#define ENVY24HT_CCS_CTL_RESET 0x80 /* Entire Chip soft reset */
|
||||
|
||||
#define ENVY24HT_CCS_IMASK 0x01 /* Interrupt Mask Register */
|
||||
#define ENVY24HT_CCS_IMASK_PMT 0x10 /* Professional Multi-track */
|
||||
|
||||
#define ENVY24HT_CCS_I2CDEV 0x10 /* I2C Port Device Address Register */
|
||||
#define ENVY24HT_CCS_I2CDEV_ADDR 0xfe /* I2C device address */
|
||||
#define ENVY24HT_CCS_I2CDEV_ROM 0xa0 /* reserved for the external I2C E2PROM */
|
||||
#define ENVY24HT_CCS_I2CDEV_WR 0x01 /* write */
|
||||
#define ENVY24HT_CCS_I2CDEV_RD 0x00 /* read */
|
||||
|
||||
#define ENVY24HT_CCS_I2CADDR 0x11 /* I2C Port Byte Address Register */
|
||||
#define ENVY24HT_CCS_I2CDATA 0x12 /* I2C Port Read/Write Data Register */
|
||||
|
||||
#define ENVY24HT_CCS_I2CSTAT 0x13 /* I2C Port Control and Status Register */
|
||||
#define ENVY24HT_CCS_I2CSTAT_ROM 0x80 /* external E2PROM exists */
|
||||
#define ENVY24HT_CCS_I2CSTAT_BSY 0x01 /* I2C port read/write status busy */
|
||||
|
||||
#define ENVY24HT_CCS_SCFG 0x04 /* System Configuration Register */
|
||||
#define ENVY24HT_CCSM_SCFG_XIN2 0xc0 /* XIN2 Clock Source Configuration */
|
||||
/* 00: 24.576MHz(96kHz*256) */
|
||||
/* 01: 49.152MHz(192kHz*256) */
|
||||
/* 1x: Reserved */
|
||||
#define ENVY24HT_CCSM_SCFG_MPU 0x20 /* 0(not implemented)/1(1) MPU-401 UART */
|
||||
#define ENVY24HT_CCSM_SCFG_ADC 0x0c /* 1-2 stereo ADC connected, S/PDIF receiver connected */
|
||||
#define ENVY24HT_CCSM_SCFG_DAC 0x03 /* 1-4 stereo DAC connected */
|
||||
|
||||
#define ENVY24HT_CCS_ACL 0x05 /* AC-Link Configuration Register */
|
||||
#define ENVY24HT_CCSM_ACL_MTC 0x80 /* Multi-track converter type: 0:AC'97 1:I2S */
|
||||
#define ENVY24HT_CCSM_ACL_OMODE 0x02 /* AC 97 codec SDATA_OUT 0:split 1:packed */
|
||||
|
||||
#define ENVY24HT_CCS_I2S 0x06 /* I2S Converters Features Register */
|
||||
#define ENVY24HT_CCSM_I2S_VOL 0x80 /* I2S codec Volume and mute */
|
||||
#define ENVY24HT_CCSM_I2S_96KHZ 0x40 /* I2S converter 96kHz sampling rate support */
|
||||
#define ENVY24HT_CCSM_I2S_192KHZ 0x08 /* I2S converter 192kHz sampling rate support */
|
||||
#define ENVY24HT_CCSM_I2S_RES 0x30 /* Converter resolution */
|
||||
#define ENVY24HT_CCSM_I2S_16BIT 0x00 /* 16bit */
|
||||
#define ENVY24HT_CCSM_I2S_18BIT 0x10 /* 18bit */
|
||||
#define ENVY24HT_CCSM_I2S_20BIT 0x20 /* 20bit */
|
||||
#define ENVY24HT_CCSM_I2S_24BIT 0x30 /* 24bit */
|
||||
#define ENVY24HT_CCSM_I2S_ID 0x07 /* Other I2S IDs */
|
||||
|
||||
#define ENVY24HT_CCS_SPDIF 0x07 /* S/PDIF Configuration Register */
|
||||
#define ENVY24HT_CCSM_SPDIF_INT_EN 0x80 /* Enable integrated S/PDIF transmitter */
|
||||
#define ENVY24HT_CCSM_SPDIF_INT_OUT 0x40 /* Internal S/PDIF Out implemented */
|
||||
#define ENVY24HT_CCSM_SPDIF_ID 0x3c /* S/PDIF chip ID */
|
||||
#define ENVY24HT_CCSM_SPDIF_IN 0x02 /* S/PDIF Stereo In is present */
|
||||
#define ENVY24HT_CCSM_SPDIF_OUT 0x01 /* External S/PDIF Out implemented */
|
||||
|
||||
/* Professional Multi-Track Control Registers */
|
||||
|
||||
#define ENVY24HT_MT_INT_STAT 0x00 /* DMA Interrupt Mask and Status Register */
|
||||
#define ENVY24HT_MT_INT_RSTAT 0x02 /* Multi-track record interrupt status */
|
||||
#define ENVY24HT_MT_INT_PSTAT 0x01 /* Multi-track playback interrupt status */
|
||||
#define ENVY24HT_MT_INT_MASK 0x03
|
||||
#define ENVY24HT_MT_INT_RMASK 0x02 /* Multi-track record interrupt mask */
|
||||
#define ENVY24HT_MT_INT_PMASK 0x01 /* Multi-track playback interrupt mask */
|
||||
|
||||
#define ENVY24HT_MT_RATE 0x01 /* Sampling Rate Select Register */
|
||||
#define ENVY24HT_MT_RATE_SPDIF 0x10 /* S/PDIF input clock as the master */
|
||||
#define ENVY24HT_MT_RATE_48000 0x00
|
||||
#define ENVY24HT_MT_RATE_24000 0x01
|
||||
#define ENVY24HT_MT_RATE_12000 0x02
|
||||
#define ENVY24HT_MT_RATE_9600 0x03
|
||||
#define ENVY24HT_MT_RATE_32000 0x04
|
||||
#define ENVY24HT_MT_RATE_16000 0x05
|
||||
#define ENVY24HT_MT_RATE_8000 0x06
|
||||
#define ENVY24HT_MT_RATE_96000 0x07
|
||||
#define ENVY24HT_MT_RATE_64000 0x0f
|
||||
#define ENVY24HT_MT_RATE_44100 0x08
|
||||
#define ENVY24HT_MT_RATE_22050 0x09
|
||||
#define ENVY24HT_MT_RATE_11025 0x0a
|
||||
#define ENVY24HT_MT_RATE_88200 0x0b
|
||||
#define ENVY24HT_MT_RATE_MASK 0x0f
|
||||
|
||||
#define ENVY24HT_MT_PADDR 0x10 /* Playback DMA Current/Base Address Register */
|
||||
#define ENVY24HT_MT_PCNT 0x14 /* Playback DMA Current/Base Count Register */
|
||||
#define ENVY24HT_MT_PTERM 0x1C /* Playback Current/Base Terminal Count Register */
|
||||
|
||||
#define ENVY24HT_MT_PCTL 0x18 /* Global Playback and Record DMA Start/Stop Register */
|
||||
#define ENVY24HT_MT_PCTL_RSTART 0x02 /* 1: Record start; 0: Record stop */
|
||||
#define ENVY24HT_MT_PCTL_PSTART 0x01 /* 1: Playback start; 0: Playback stop */
|
||||
|
||||
#define ENVY24HT_MT_RADDR 0x20 /* Record DMA Current/Base Address Register */
|
||||
#define ENVY24HT_MT_RCNT 0x24 /* Record DMA Current/Base Count Register */
|
||||
#define ENVY24HT_MT_RTERM 0x26 /* Record Current/Base Terminal Count Register */
|
||||
|
||||
/*
|
||||
These map values are refferd from ALSA sound driver.
|
||||
*/
|
||||
/* ENVY24 configuration E2PROM map */
|
||||
#define ENVY24HT_E2PROM_SUBVENDOR 0x02
|
||||
#define ENVY24HT_E2PROM_SUBDEVICE 0x00
|
||||
#define ENVY24HT_E2PROM_SIZE 0x04
|
||||
#define ENVY24HT_E2PROM_VERSION 0x05
|
||||
#define ENVY24HT_E2PROM_SCFG 0x06
|
||||
#define ENVY24HT_E2PROM_ACL 0x07
|
||||
#define ENVY24HT_E2PROM_I2S 0x08
|
||||
#define ENVY24HT_E2PROM_SPDIF 0x09
|
||||
#define ENVY24HT_E2PROM_GPIOMASK 0x0d
|
||||
#define ENVY24HT_E2PROM_GPIOSTATE 0x10
|
||||
#define ENVY24HT_E2PROM_GPIODIR 0x0a
|
||||
|
||||
/* ENVY24 mixer channel defines */
|
||||
/*
|
||||
ENVY24 mixer has original line matrix. So, general mixer command is not
|
||||
able to use for this. If system has consumer AC'97 output, AC'97 line is
|
||||
used as master mixer, and it is able to control.
|
||||
*/
|
||||
#define ENVY24HT_CHAN_NUM 11 /* Play * 5 + Record * 5 + Mix * 1 */
|
||||
|
||||
#define ENVY24HT_CHAN_PLAY_DAC1 0
|
||||
#define ENVY24HT_CHAN_PLAY_DAC2 1
|
||||
#define ENVY24HT_CHAN_PLAY_DAC3 2
|
||||
#define ENVY24HT_CHAN_PLAY_DAC4 3
|
||||
#define ENVY24HT_CHAN_PLAY_SPDIF 4
|
||||
#define ENVY24HT_CHAN_REC_ADC1 5
|
||||
#define ENVY24HT_CHAN_REC_ADC2 6
|
||||
#define ENVY24HT_CHAN_REC_ADC3 7
|
||||
#define ENVY24HT_CHAN_REC_ADC4 8
|
||||
#define ENVY24HT_CHAN_REC_SPDIF 9
|
||||
#define ENVY24HT_CHAN_REC_MIX 10
|
||||
|
||||
#define ENVY24HT_MIX_MASK 0x3fd
|
||||
#define ENVY24HT_MIX_REC_MASK 0x3e0
|
||||
|
||||
/* volume value constants */
|
||||
#define ENVY24HT_VOL_MAX 0 /* 0db(negate) */
|
||||
#define ENVY24HT_VOL_MIN 96 /* -144db(negate) */
|
||||
#define ENVY24HT_VOL_MUTE 127 /* mute */
|
||||
|
||||
#define BUS_SPACE_MAXADDR_ENVY24 0x0fffffff /* Address space beyond 256MB is not
|
||||
supported */
|
||||
#define BUS_SPACE_MAXSIZE_ENVY24 0x3fffc /* 64k x 4byte(1dword) */
|
||||
|
||||
#define ENVY24HT_CCS_GPIO_HDATA 0x1E
|
||||
#define ENVY24HT_CCS_GPIO_LDATA 0x14
|
||||
#define ENVY24HT_CCS_GPIO_LMASK 0x16
|
||||
#define ENVY24HT_CCS_GPIO_HMASK 0x1F
|
||||
#define ENVY24HT_CCS_GPIO_CTLDIR 0x18
|
||||
|
589
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_addrs.c
Normal file
589
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_addrs.c
Normal file
@ -0,0 +1,589 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Shteryana Shopova <syrinx@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Bridge MIB implementation for SNMPd.
|
||||
* Bridge addresses.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_mib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <bsnmp/snmpmod.h>
|
||||
#include <bsnmp/snmp_mibII.h>
|
||||
|
||||
#include "bridge_tree.h"
|
||||
#include "bridge_snmp.h"
|
||||
|
||||
TAILQ_HEAD(tp_entries, tp_entry);
|
||||
|
||||
/*
|
||||
* Free the bridge address list.
|
||||
*/
|
||||
static void
|
||||
bridge_tpe_free(struct tp_entries *headp)
|
||||
{
|
||||
struct tp_entry *t;
|
||||
|
||||
while ((t = TAILQ_FIRST(headp)) != NULL) {
|
||||
TAILQ_REMOVE(headp, t, tp_e);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the bridge address entries from the address list,
|
||||
* for the specified bridge interface only.
|
||||
*/
|
||||
static void
|
||||
bridge_tpe_bif_free(struct tp_entries *headp,
|
||||
struct bridge_if *bif)
|
||||
{
|
||||
struct tp_entry *tp;
|
||||
|
||||
while (bif->f_tpa != NULL && bif->sysindex == bif->f_tpa->sysindex) {
|
||||
tp = TAILQ_NEXT(bif->f_tpa, tp_e);
|
||||
TAILQ_REMOVE(headp, bif->f_tpa, tp_e);
|
||||
free(bif->f_tpa);
|
||||
bif->f_tpa = tp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two mac addresses.
|
||||
* m1 < m2 : -1
|
||||
* m1 > m2 : +1
|
||||
* m1 = m2 : 0
|
||||
*/
|
||||
static int
|
||||
bridge_compare_macs(const uint8_t *m1, const uint8_t *m2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++) {
|
||||
if (m1[i] < m2[i])
|
||||
return (-1);
|
||||
if (m1[i] > m2[i])
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert an address entry in the bridge address TAILQ starting to search
|
||||
* for its place from the position of the first bridge address for the bridge
|
||||
* interface. Update the first bridge address if neccessary.
|
||||
*/
|
||||
static void
|
||||
bridge_addrs_insert_at(struct tp_entries *headp,
|
||||
struct tp_entry *ta, struct tp_entry **f_tpa)
|
||||
{
|
||||
struct tp_entry *t1;
|
||||
|
||||
assert(f_tpa != NULL);
|
||||
|
||||
for (t1 = *f_tpa;
|
||||
t1 != NULL && ta->sysindex == t1->sysindex;
|
||||
t1 = TAILQ_NEXT(t1, tp_e)) {
|
||||
if (bridge_compare_macs(ta->tp_addr, t1->tp_addr) < 0) {
|
||||
TAILQ_INSERT_BEFORE(t1, ta, tp_e);
|
||||
if (*f_tpa == t1)
|
||||
(*f_tpa) = ta;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (t1 == NULL)
|
||||
TAILQ_INSERT_TAIL(headp, ta, tp_e);
|
||||
else
|
||||
TAILQ_INSERT_BEFORE(t1, ta, tp_e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an address entry's possition in the address list
|
||||
* according to bridge interface name.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_find_pos(struct tp_entries *headp, uint32_t b_idx)
|
||||
{
|
||||
uint32_t t_idx;
|
||||
struct tp_entry *t1;
|
||||
|
||||
if ((t1 = TAILQ_FIRST(headp)) == NULL ||
|
||||
bridge_compare_sysidx(b_idx, t1->sysindex) < 0)
|
||||
return (NULL);
|
||||
|
||||
t_idx = t1->sysindex;
|
||||
|
||||
for (t1 = TAILQ_NEXT(t1, tp_e); t1 != NULL; t1 = TAILQ_NEXT(t1, tp_e)) {
|
||||
|
||||
if (t1->sysindex != t_idx) {
|
||||
if (bridge_compare_sysidx(b_idx, t1->sysindex) < 0)
|
||||
return (TAILQ_PREV(t1, tp_entries, tp_e));
|
||||
else
|
||||
t_idx = t1->sysindex;
|
||||
}
|
||||
}
|
||||
|
||||
if (t1 == NULL)
|
||||
t1 = TAILQ_LAST(headp, tp_entries);
|
||||
|
||||
return (t1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a bridge address in the bridge addresses list.
|
||||
*/
|
||||
static void
|
||||
bridge_addrs_bif_insert(struct tp_entries *headp, struct tp_entry *te,
|
||||
struct tp_entry **f_tpa)
|
||||
{
|
||||
struct tp_entry *temp;
|
||||
|
||||
if (*f_tpa != NULL)
|
||||
bridge_addrs_insert_at(headp, te, f_tpa);
|
||||
else {
|
||||
temp = bridge_addrs_find_pos(headp, te->sysindex);
|
||||
|
||||
if (temp == NULL)
|
||||
TAILQ_INSERT_HEAD(headp, te, tp_e);
|
||||
else
|
||||
TAILQ_INSERT_AFTER(headp, temp, te, tp_e);
|
||||
*f_tpa = te;
|
||||
}
|
||||
}
|
||||
|
||||
static struct tp_entries tp_entries = TAILQ_HEAD_INITIALIZER(tp_entries);
|
||||
static time_t address_list_age;
|
||||
|
||||
void
|
||||
bridge_addrs_update_listage(void)
|
||||
{
|
||||
address_list_age = time(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_addrs_fini(void)
|
||||
{
|
||||
bridge_tpe_free(&tp_entries);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_addrs_free(struct bridge_if *bif)
|
||||
{
|
||||
bridge_tpe_bif_free(&tp_entries, bif);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first address in the list.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_first(void)
|
||||
{
|
||||
return (TAILQ_FIRST(&tp_entries));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next address in the list.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_next(struct tp_entry *te)
|
||||
{
|
||||
return (TAILQ_NEXT(te, tp_e));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first address, learnt by the specified bridge interface.
|
||||
*/
|
||||
struct tp_entry *
|
||||
bridge_addrs_bif_first(struct bridge_if *bif)
|
||||
{
|
||||
return (bif->f_tpa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next address, learnt by the specified bridge interface.
|
||||
*/
|
||||
struct tp_entry *
|
||||
bridge_addrs_bif_next(struct tp_entry *te)
|
||||
{
|
||||
struct tp_entry *te_next;
|
||||
|
||||
if ((te_next = TAILQ_NEXT(te, tp_e)) == NULL ||
|
||||
te_next->sysindex != te->sysindex)
|
||||
return (NULL);
|
||||
|
||||
return (te_next);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a bridge address from the list.
|
||||
*/
|
||||
void
|
||||
bridge_addrs_remove(struct tp_entry *te, struct bridge_if *bif)
|
||||
{
|
||||
if (bif->f_tpa == te)
|
||||
bif->f_tpa = bridge_addrs_bif_next(te);
|
||||
|
||||
TAILQ_REMOVE(&tp_entries, te, tp_e);
|
||||
free(te);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate memory for a new bridge address and insert it in the list.
|
||||
*/
|
||||
struct tp_entry *
|
||||
bridge_new_addrs(uint8_t *mac, struct bridge_if *bif)
|
||||
{
|
||||
struct tp_entry *te;
|
||||
|
||||
if ((te = (struct tp_entry *) malloc(sizeof(*te))) == NULL) {
|
||||
syslog(LOG_ERR, "bridge new address: failed: %s",
|
||||
strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
bzero(te, sizeof(*te));
|
||||
|
||||
te->sysindex = bif->sysindex;
|
||||
bcopy(mac, te->tp_addr, ETHER_ADDR_LEN);
|
||||
bridge_addrs_bif_insert(&tp_entries, te, &(bif->f_tpa));
|
||||
|
||||
return (te);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a mac address, learnt on a bridge,
|
||||
* find the corrsponding TP entry for it.
|
||||
*/
|
||||
struct tp_entry *
|
||||
bridge_addrs_find(uint8_t *mac, struct bridge_if *bif)
|
||||
{
|
||||
struct tp_entry *te;
|
||||
|
||||
for (te = bif->f_tpa; te != NULL; te = TAILQ_NEXT(te, tp_e)) {
|
||||
if (te->sysindex != bif->sysindex) {
|
||||
te = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bridge_compare_macs(te->tp_addr, mac) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return (te);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_addrs_dump(struct bridge_if *bif)
|
||||
{
|
||||
struct tp_entry *te;
|
||||
|
||||
syslog(LOG_ERR, "Addresses count - %d", bif->num_addrs);
|
||||
for (te = bridge_addrs_bif_first(bif); te != NULL;
|
||||
te = bridge_addrs_bif_next(te)) {
|
||||
syslog(LOG_ERR, "address %x:%x:%x:%x:%x:%x on port %d.%d",
|
||||
te->tp_addr[0], te->tp_addr[1], te->tp_addr[2],
|
||||
te->tp_addr[3], te->tp_addr[4], te->tp_addr[5],
|
||||
te->sysindex, te->port_no);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC4188 specifics.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Construct the SNMP index from the address DST Mac.
|
||||
*/
|
||||
static void
|
||||
bridge_addrs_index_append(struct asn_oid *oid, uint sub,
|
||||
const struct tp_entry *te)
|
||||
{
|
||||
int i;
|
||||
|
||||
oid->len = sub + ETHER_ADDR_LEN + 1;
|
||||
oid->subs[sub] = ETHER_ADDR_LEN;
|
||||
|
||||
for (i = 1; i <= ETHER_ADDR_LEN; i++)
|
||||
oid->subs[sub + i] = te->tp_addr[i - 1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the address entry for the SNMP index from the default bridge only.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_get(const struct asn_oid *oid, uint sub,
|
||||
struct bridge_if *bif)
|
||||
{
|
||||
int i;
|
||||
uint8_t tp_addr[ETHER_ADDR_LEN];
|
||||
|
||||
if (oid->len - sub != ETHER_ADDR_LEN + 1 ||
|
||||
oid->subs[sub] != ETHER_ADDR_LEN)
|
||||
return (NULL);
|
||||
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++)
|
||||
tp_addr[i] = oid->subs[sub + i + 1];
|
||||
|
||||
return (bridge_addrs_find(tp_addr, bif));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next address entry for the SNMP index
|
||||
* from the default bridge only.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_getnext(const struct asn_oid *oid, uint sub,
|
||||
struct bridge_if *bif)
|
||||
{
|
||||
int i;
|
||||
uint8_t tp_addr[ETHER_ADDR_LEN];
|
||||
static struct tp_entry *te;
|
||||
|
||||
if (oid->len - sub == 0)
|
||||
return (bridge_addrs_bif_first(bif));
|
||||
|
||||
if (oid->len - sub != ETHER_ADDR_LEN + 1 ||
|
||||
oid->subs[sub] != ETHER_ADDR_LEN)
|
||||
return (NULL);
|
||||
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++)
|
||||
tp_addr[i] = oid->subs[sub + i + 1];
|
||||
|
||||
if ((te = bridge_addrs_find(tp_addr, bif)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (bridge_addrs_bif_next(te));
|
||||
}
|
||||
|
||||
int
|
||||
op_dot1d_tp_fdb(struct snmp_context *c __unused, struct snmp_value *val,
|
||||
uint sub, uint iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct bridge_if *bif;
|
||||
struct tp_entry *te;
|
||||
|
||||
if ((bif = bridge_get_default()) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
|
||||
if (time(NULL) - bif->addrs_age > bridge_get_data_maxage() &&
|
||||
bridge_update_addrs(bif) <= 0)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
|
||||
switch (op) {
|
||||
case SNMP_OP_GET:
|
||||
if ((te = bridge_addrs_get(&val->var, sub, bif)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
goto get;
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((te = bridge_addrs_getnext(&val->var, sub, bif)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
bridge_addrs_index_append(&val->var, sub, te);
|
||||
goto get;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
break;
|
||||
}
|
||||
abort();
|
||||
|
||||
get:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_dot1dTpFdbAddress:
|
||||
return (string_get(val, te->tp_addr, ETHER_ADDR_LEN));
|
||||
case LEAF_dot1dTpFdbPort :
|
||||
val->v.integer = te->port_no;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
case LEAF_dot1dTpFdbStatus:
|
||||
val->v.integer = te->status;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Private BEGEMOT-BRIDGE-MIB specifics.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Construct the SNMP index from the bridge interface name
|
||||
* and the address DST Mac.
|
||||
*/
|
||||
static int
|
||||
bridge_addrs_begemot_index_append(struct asn_oid *oid, uint sub,
|
||||
const struct tp_entry *te)
|
||||
{
|
||||
uint i, n_len;
|
||||
const char *b_name;
|
||||
|
||||
if ((b_name = bridge_if_find_name(te->sysindex)) == NULL)
|
||||
return (-1);
|
||||
|
||||
n_len = strlen(b_name);
|
||||
oid->len = sub++;
|
||||
oid->subs[oid->len++] = n_len;
|
||||
|
||||
for (i = 1; i <= n_len; i++)
|
||||
oid->subs[oid->len++] = b_name[i - 1];
|
||||
|
||||
oid->subs[oid->len++] = ETHER_ADDR_LEN;
|
||||
for (i = 1 ; i <= ETHER_ADDR_LEN; i++)
|
||||
oid->subs[oid->len++] = te->tp_addr[i - 1];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a bridge address entry by the bridge interface name
|
||||
* and the address DST Mac.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_begemot_get(const struct asn_oid *oid, uint sub)
|
||||
{
|
||||
uint i, n_len;
|
||||
uint8_t tp_addr[ETHER_ADDR_LEN];
|
||||
char bif_name[IFNAMSIZ];
|
||||
struct bridge_if *bif;
|
||||
|
||||
n_len = oid->subs[sub];
|
||||
if (oid->len - sub != n_len + ETHER_ADDR_LEN + 3 ||
|
||||
n_len >= IFNAMSIZ || oid->subs[sub + n_len + 1] != ETHER_ADDR_LEN)
|
||||
return (NULL);
|
||||
|
||||
for (i = 0; i < n_len; i++)
|
||||
bif_name[i] = oid->subs[n_len + i + 1];
|
||||
bif_name[i] = '\0';
|
||||
|
||||
for (i = 1; i <= ETHER_ADDR_LEN; i++)
|
||||
tp_addr[i - 1] = oid->subs[n_len + i + 1];
|
||||
|
||||
if ((bif = bridge_if_find_ifname(bif_name)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (bridge_addrs_find(tp_addr, bif));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next bridge address entry by the bridge interface name
|
||||
* and the address DST Mac.
|
||||
*/
|
||||
static struct tp_entry *
|
||||
bridge_addrs_begemot_getnext(const struct asn_oid *oid, uint sub)
|
||||
{
|
||||
uint i, n_len;
|
||||
uint8_t tp_addr[ETHER_ADDR_LEN];
|
||||
char bif_name[IFNAMSIZ];
|
||||
struct bridge_if *bif;
|
||||
struct tp_entry *tp;
|
||||
|
||||
if (oid->len - sub == 0)
|
||||
return (bridge_addrs_first());
|
||||
|
||||
n_len = oid->subs[sub];
|
||||
if (oid->len - sub != n_len + ETHER_ADDR_LEN + 2 ||
|
||||
n_len >= IFNAMSIZ || oid->subs[sub + n_len + 1] != ETHER_ADDR_LEN)
|
||||
return (NULL);
|
||||
|
||||
for (i = 1; i <= n_len; i++)
|
||||
bif_name[i - 1] = oid->subs[sub + i];
|
||||
|
||||
bif_name[i - 1] = '\0';
|
||||
|
||||
for (i = 1; i <= ETHER_ADDR_LEN; i++)
|
||||
tp_addr[i - 1] = oid->subs[sub + n_len + i + 1];
|
||||
|
||||
if ((bif = bridge_if_find_ifname(bif_name)) == NULL ||
|
||||
(tp = bridge_addrs_find(tp_addr, bif)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (bridge_addrs_next(tp));
|
||||
}
|
||||
|
||||
int
|
||||
op_begemot_tp_fdb(struct snmp_context *c __unused, struct snmp_value *val,
|
||||
uint sub, uint iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct tp_entry *te;
|
||||
|
||||
if (time(NULL) - address_list_age > bridge_get_data_maxage())
|
||||
bridge_update_all_addrs();
|
||||
|
||||
switch (op) {
|
||||
case SNMP_OP_GET:
|
||||
if ((te = bridge_addrs_begemot_get(&val->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
goto get;
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((te = bridge_addrs_begemot_getnext(&val->var,
|
||||
sub)) == NULL ||
|
||||
bridge_addrs_begemot_index_append(&val->var,
|
||||
sub, te) < 0)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
goto get;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
break;
|
||||
}
|
||||
abort();
|
||||
|
||||
get:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_begemotBridgeTpFdbAddress:
|
||||
return (string_get(val, te->tp_addr, ETHER_ADDR_LEN));
|
||||
case LEAF_begemotBridgeTpFdbPort:
|
||||
val->v.integer = te->port_no;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
case LEAF_begemotBridgeTpFdbStatus:
|
||||
val->v.integer = te->status;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
116
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_pf.c
Normal file
116
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_pf.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Shteryana Shopova <syrinx@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Bridge MIB implementation for SNMPd.
|
||||
* Bridge pfil controls.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_mib.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <bsnmp/snmpmod.h>
|
||||
#include <bsnmp/snmp_mibII.h>
|
||||
|
||||
#include "bridge_tree.h"
|
||||
#include "bridge_snmp.h"
|
||||
|
||||
static int
|
||||
val2snmp_truth(uint8_t val)
|
||||
{
|
||||
if (val == 0)
|
||||
return (2);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
snmp_truth2val(int32_t truth)
|
||||
{
|
||||
if (truth == 2)
|
||||
return (0);
|
||||
else if (truth == 1)
|
||||
return (1);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
op_begemot_bridge_pf(struct snmp_context *ctx, struct snmp_value *val,
|
||||
uint sub, uint iidx __unused, enum snmp_op op)
|
||||
{
|
||||
int k_val;
|
||||
|
||||
if (val->var.subs[sub - 1] > LEAF_begemotBridgeLayer2PfStatus)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
|
||||
switch (op) {
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
case SNMP_OP_ROLLBACK:
|
||||
bridge_do_pfctl(val->var.subs[sub - 1] - 1,
|
||||
op, &(ctx->scratch->int1));
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_COMMIT:
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_SET:
|
||||
ctx->scratch->int1 =
|
||||
bridge_get_pfval(val->var.subs[sub - 1]);
|
||||
|
||||
if ((k_val = snmp_truth2val(val->v.integer)) < 0)
|
||||
return (SNMP_ERR_BADVALUE);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_GET:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_begemotBridgePfilStatus:
|
||||
case LEAF_begemotBridgePfilMembers:
|
||||
case LEAF_begemotBridgePfilIpOnly:
|
||||
case LEAF_begemotBridgeLayer2PfStatus:
|
||||
if (bridge_do_pfctl(val->var.subs[sub - 1] - 1,
|
||||
op, &k_val) < 0)
|
||||
return (SNMP_ERR_GENERR);
|
||||
val->v.integer = val2snmp_truth(k_val);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
1490
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c
Normal file
1490
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c
Normal file
File diff suppressed because it is too large
Load Diff
338
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c
Normal file
338
usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Shteryana Shopova <syrinx@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Bridge MIB implementation for SNMPd.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_mib.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <bsnmp/snmpmod.h>
|
||||
#include <bsnmp/snmp_mibII.h>
|
||||
|
||||
#include "bridge_tree.h"
|
||||
#include "bridge_snmp.h"
|
||||
#include "bridge_oid.h"
|
||||
|
||||
static struct lmodule *bridge_module;
|
||||
|
||||
/* For the registration. */
|
||||
static const struct asn_oid oid_dot1Bridge = OIDX_dot1dBridge;
|
||||
/* The registration. */
|
||||
static uint reg_bridge;
|
||||
|
||||
/* Periodic timer for polling all bridges' data. */
|
||||
static void *bridge_data_timer;
|
||||
static void *bridge_tc_timer;
|
||||
|
||||
static int bridge_data_maxage = SNMP_BRIDGE_DATA_MAXAGE;
|
||||
static int bridge_poll_ticks = SNMP_BRIDGE_POLL_INTERVAL * 100;
|
||||
static int bridge_tc_poll_ticks = SNMP_BRIDGE_TC_POLL_INTERVAL * 100;
|
||||
|
||||
/*
|
||||
* Our default bridge, whose info will be visible under
|
||||
* the dot1dBridge subtree and functions to set/fetch it.
|
||||
*/
|
||||
static char bif_default_name[IFNAMSIZ] = "bridge0";
|
||||
static struct bridge_if *bif_default;
|
||||
|
||||
struct bridge_if *
|
||||
bridge_get_default(void)
|
||||
{
|
||||
struct mibif *ifp;
|
||||
|
||||
if (bif_default != NULL) {
|
||||
|
||||
/* Walk through the mibII interface list. */
|
||||
for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp))
|
||||
if (strcmp(ifp->name, bif_default->bif_name) == 0)
|
||||
break;
|
||||
|
||||
if (ifp == NULL)
|
||||
bif_default = NULL;
|
||||
}
|
||||
|
||||
return (bif_default);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_set_default(struct bridge_if *bif)
|
||||
{
|
||||
bif_default = bif;
|
||||
|
||||
syslog(LOG_ERR, "Set default bridge interface to: %s",
|
||||
bif == NULL ? "(none)" : bif->bif_name);
|
||||
}
|
||||
|
||||
const char *
|
||||
bridge_get_default_name(void)
|
||||
{
|
||||
return (bif_default_name);
|
||||
}
|
||||
|
||||
static int
|
||||
bridge_set_default_name(const char *bif_name, uint len)
|
||||
{
|
||||
struct bridge_if *bif;
|
||||
|
||||
if (len >= IFNAMSIZ)
|
||||
return (-1);
|
||||
|
||||
bcopy(bif_name, bif_default_name, len);
|
||||
bif_default_name[len] = '\0';
|
||||
|
||||
if ((bif = bridge_if_find_ifname(bif_default_name)) == NULL) {
|
||||
bif_default = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
bif_default = bif;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
bridge_get_data_maxage(void)
|
||||
{
|
||||
return (bridge_data_maxage);
|
||||
}
|
||||
|
||||
static void
|
||||
bridge_set_poll_ticks(int poll_ticks)
|
||||
{
|
||||
if (bridge_data_timer != NULL)
|
||||
timer_stop(bridge_data_timer);
|
||||
|
||||
bridge_poll_ticks = poll_ticks;
|
||||
bridge_data_timer = timer_start_repeat(bridge_poll_ticks,
|
||||
bridge_poll_ticks, bridge_update_all, NULL, bridge_module);
|
||||
}
|
||||
/*
|
||||
* The bridge module configuration via SNMP.
|
||||
*/
|
||||
static int
|
||||
bridge_default_name_save(struct snmp_context *ctx, const char *bridge_default)
|
||||
{
|
||||
if ((ctx->scratch->int1 = strlen(bridge_default)) >= IFNAMSIZ)
|
||||
return (-1);
|
||||
|
||||
if ((ctx->scratch->ptr1 = malloc(IFNAMSIZ)) == NULL)
|
||||
return (-1);
|
||||
|
||||
strncpy(ctx->scratch->ptr1, bridge_default, ctx->scratch->int1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
op_begemot_bridge_config(struct snmp_context *ctx, struct snmp_value *val,
|
||||
uint sub, uint iidx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
case SNMP_OP_GET:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_begemotBridgeDefaultBridgeIf:
|
||||
return (string_get(val, bridge_get_default_name(), -1));
|
||||
|
||||
case LEAF_begemotBridgeDataUpdate:
|
||||
val->v.integer = bridge_data_maxage;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case LEAF_begemotBridgeDataPoll:
|
||||
val->v.integer = bridge_poll_ticks / 100;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_SET:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_begemotBridgeDefaultBridgeIf:
|
||||
/*
|
||||
* Cannot use string_save() here - requires either
|
||||
* a fixed-sized or var-length string - not less
|
||||
* than or equal.
|
||||
*/
|
||||
if (bridge_default_name_save(ctx,
|
||||
bridge_get_default_name()) < 0)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
|
||||
if (bridge_set_default_name(val->v.octetstring.octets,
|
||||
val->v.octetstring.len) < 0)
|
||||
return (SNMP_ERR_BADVALUE);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case LEAF_begemotBridgeDataUpdate:
|
||||
if (val->v.integer < SNMP_BRIDGE_DATA_MAXAGE_MIN ||
|
||||
val->v.integer > SNMP_BRIDGE_DATA_MAXAGE_MAX)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
ctx->scratch->int1 = bridge_data_maxage;
|
||||
bridge_data_maxage = val->v.integer;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case LEAF_begemotBridgeDataPoll:
|
||||
if (val->v.integer < SNMP_BRIDGE_POLL_INTERVAL_MIN ||
|
||||
val->v.integer > SNMP_BRIDGE_POLL_INTERVAL_MAX)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
ctx->scratch->int1 = val->v.integer;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
abort();
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_begemotBridgeDefaultBridgeIf:
|
||||
bridge_set_default_name(ctx->scratch->ptr1,
|
||||
ctx->scratch->int1);
|
||||
free(ctx->scratch->ptr1);
|
||||
break;
|
||||
case LEAF_begemotBridgeDataUpdate:
|
||||
bridge_data_maxage = ctx->scratch->int1;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_COMMIT:
|
||||
switch (val->var.subs[sub - 1]) {
|
||||
case LEAF_begemotBridgeDefaultBridgeIf:
|
||||
free(ctx->scratch->ptr1);
|
||||
break;
|
||||
case LEAF_begemotBridgeDataPoll:
|
||||
bridge_set_poll_ticks(ctx->scratch->int1 * 100);
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Bridge mib module initialization hook.
|
||||
* Returns 0 on success, < 0 on error.
|
||||
*/
|
||||
static int
|
||||
bridge_init(struct lmodule * mod, int argc __unused, char *argv[] __unused)
|
||||
{
|
||||
bridge_module = mod;
|
||||
|
||||
if (bridge_kmod_load() < 0)
|
||||
return (-1);
|
||||
|
||||
if (bridge_ioctl_init() < 0)
|
||||
return (-1);
|
||||
|
||||
/* Register to get creation messages for bridge interfaces. */
|
||||
if (mib_register_newif(bridge_attach_newif, bridge_module)) {
|
||||
syslog(LOG_ERR, "Cannot register newif function: %s",
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bridge mib module finalization hook.
|
||||
*/
|
||||
static int
|
||||
bridge_fini(void)
|
||||
{
|
||||
mib_unregister_newif(bridge_module);
|
||||
or_unregister(reg_bridge);
|
||||
|
||||
if (bridge_data_timer != NULL) {
|
||||
timer_stop(bridge_data_timer);
|
||||
bridge_data_timer = NULL;
|
||||
}
|
||||
|
||||
if (bridge_tc_timer != NULL) {
|
||||
timer_stop(bridge_tc_timer);
|
||||
bridge_tc_timer = NULL;
|
||||
}
|
||||
|
||||
bridge_ifs_fini();
|
||||
bridge_ports_fini();
|
||||
bridge_addrs_fini();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bridge mib module start operation.
|
||||
*/
|
||||
static void
|
||||
bridge_start(void)
|
||||
{
|
||||
reg_bridge = or_register(&oid_dot1Bridge,
|
||||
"The IETF MIB for Bridges (RFC 4188).", bridge_module);
|
||||
|
||||
bridge_data_timer = timer_start_repeat(bridge_poll_ticks,
|
||||
bridge_poll_ticks, bridge_update_all, NULL, bridge_module);
|
||||
|
||||
bridge_tc_timer = timer_start_repeat(bridge_tc_poll_ticks,
|
||||
bridge_tc_poll_ticks, bridge_update_tc_time, NULL, bridge_module);
|
||||
}
|
||||
|
||||
static void
|
||||
bridge_dump(void)
|
||||
{
|
||||
struct bridge_if *bif;
|
||||
|
||||
if ((bif = bridge_get_default()) == NULL)
|
||||
syslog(LOG_ERR, "Dump: no default bridge interface");
|
||||
else
|
||||
syslog(LOG_ERR, "Dump: default bridge interface %s",
|
||||
bif->bif_name);
|
||||
|
||||
bridge_ifs_dump();
|
||||
bridge_pf_dump();
|
||||
}
|
||||
|
||||
const struct snmp_module config = {
|
||||
.comment = "This module implements the bridge mib (RFC 4188).",
|
||||
.init = bridge_init,
|
||||
.fini = bridge_fini,
|
||||
.start = bridge_start,
|
||||
.tree = bridge_ctree,
|
||||
.dump = bridge_dump,
|
||||
.tree_size = bridge_CTREE_SIZE,
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user