Import version 1.14 of bsnmp. This mainly consists of bug fixes

in the ASN.1 functions and comes with a test suite for these
functions.
This commit is contained in:
Hartmut Brandt 2020-03-31 17:50:32 +00:00
parent cf7f444550
commit d5efa260d9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/bsnmp/dist/; revision=359490
svn path=/vendor/1.14/; revision=359491; tag=vendor/bsnmp/1.14
54 changed files with 22092 additions and 16178 deletions

View File

@ -1,50 +0,0 @@
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/tags/RELENG_1_13/Makefile.in 2238 2018-06-27 14:58:50Z brandt_h $
#
SUBDIR= gensnmptree lib snmpd
ifeq "$(BUILD_MODULES)" "yes"
SUBDIR+= snmp_mibII snmp_ntp snmp_target snmp_usm snmp_vacm
endif
ifeq "$(HAVE_LIBSMI)" "yes"
SUBDIR += gensnmpdef
endif
PKGFILES=libbsnmp.pc
PKGFILESDIR= ${prefix}/libdata/pkgconfig
all:
+@for f in $(SUBDIR) ; do \
echo "==> $$f" ; \
if ! $(MAKE) -C $$f all ; then \
break ; \
fi ; \
done
install:
+@for f in $(SUBDIR) ; do \
echo "==> $$f" ; \
if ! $(SUBMAKE) -C $$f install ; then \
break ; \
fi ; \
done
@$(srcdir)/config/mkinstalldirs $(PKGFILESDIR)
for f in $(PKGFILES) ; do \
$(BSD_INSTALL_DATA) $(builddir)/$$f $(PKGFILESDIR) ; \
done
clean:
+@for f in $(SUBDIR) ; do \
echo "==> $$f" ; \
if ! $(SUBMAKE) -C $$f clean ; then \
break ; \
fi ; \
done
-rm -f $(PKGFILES)

View File

@ -1,5 +0,0 @@
Make the infrastructure:
libtoolize -c
aclocal
autoconf

View File

@ -1,11 +0,0 @@
# Copyright (c) 2004
# Hartmut Brandt
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/config/Makefile.build 1487 2008-12-23 19:03:33Z brandt_h $
#
all: build-prog build-lib build-man1 build-man3

View File

@ -1,129 +0,0 @@
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/config/Makefile.post 2117 2015-09-16 14:09:31Z brandt_h $
#
.SUFFIXES: .lo
.c.lo:
@test -d .deps || mkdir .deps >/dev/null 2>&1
$(LIBTOOL) --tag=CC --mode=compile $(CC) -c $(CFLAGS) -o $@ $<
$(LIBTOOL): $(LIBTOOL_DEPS)
$(SHELL) ../config.status --recheck
clean:
rm -rf *.o .libs .deps *.a *.la *.lo $(PROG) $(LIB) core $(PROG).core $(CLEANFILES)
DEPENDS=$(patsubst %.c,.deps/%.d, $(patsubst %.h,, $(SRCS)))
ifndef MANFILTER
MANFILTER=cat
endif
ifneq "$(MAN1)" ""
build-man1: $(MAN1:%.1=%.1out)
install-man1:
@$(srcdir)/../config/mkinstalldirs $(mandir)/man1
for f in $(MAN1) ; do \
$(BSD_INSTALL_MAN) $${f}out $(mandir)/man1/$${f} ; \
done
%.1out: %.1
cat $< | $(MANFILTER) >$@
else
build-man1:
install-man1:
endif
ifneq "$(MAN3)" ""
build-man3: $(MAN3:%.3=%.3out)
install-man3:
@$(srcdir)/../config/mkinstalldirs $(mandir)/man3
for f in $(MAN3) ; do \
$(BSD_INSTALL_MAN) $${f}out $(mandir)/man3/$${f} ; \
done
%.3out: %.3
cat $< | $(MANFILTER) >$@
else
build-man3:
install-man3:
endif
ifneq "$(DEFS)" ""
install-defs:
@$(srcdir)/../config/mkinstalldirs $(DEFSDIR)
$(BSD_INSTALL_DATA) $(DEFS:%=$(srcdir)/%) $(DEFSDIR)
DEFSDIR= ${datadir}/snmp/defs
else
install-defs:
endif
ifneq "$(INCS)" ""
INCDIR= $(includedir)/bsnmp
install-incs:
@$(srcdir)/../config/mkinstalldirs $(INCDIR)
for f in $(INCS) ; do \
if [ -r $(builddir)/$$f ] ; then \
$(BSD_INSTALL_DATA) $(builddir)/$$f $(INCDIR) ; \
else \
$(BSD_INSTALL_DATA) $(srcdir)/$$f $(INCDIR) ; \
fi ; \
done
else
install-incs:
endif
ifneq "$(BMIBS)" ""
BMIBSDIR= ${datadir}/snmp/mibs
install-mibs:
@$(srcdir)/../config/mkinstalldirs $(BMIBSDIR)
for f in $(BMIBS) ; do \
$(BSD_INSTALL_DATA) $(srcdir)/$$f $(BMIBSDIR) ; \
done
else
install-mibs:
endif
ifneq "$(PROG)" ""
build-prog: $(PROG)
install-prog:
@$(srcdir)/../config/mkinstalldirs $(bindir)
$(LIBTOOL) --mode=install $(BSD_INSTALL_PROGRAM) $(builddir)/$(PROG) $(bindir)/$(PROG)
else
build-prog:
install-prog:
endif
ifneq "$(LIB)" ""
build-lib: $(LIB)
install-lib:
@$(srcdir)/../config/mkinstalldirs $(libdir)
$(LIBTOOL) --mode=install $(BSD_INSTALL_DATA) $(LIB) $(libdir)
else
build-lib:
install-lib:
endif
install: install-prog install-lib install-incs install-man1 install-man3 install-defs install-mibs
-include /dev/null $(DEPENDS)

View File

@ -1,68 +0,0 @@
# Copyright (c) 2004-2005
# Hartmut Brandt.
# All rights reserved.
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/config/Makefile.pre 2117 2015-09-16 14:09:31Z brandt_h $
#
@SET_MAKE@
VPATH+= @srcdir@
srcdir= @srcdir@
top_builddir= @top_builddir@
builddir= @builddir@
prefix= @prefix@
exec_prefix= @exec_prefix@
bindir= @bindir@
sbindir= @sbindir@
libdir= @libdir@
includedir= @includedir@
mandir= @mandir@
datadir= @datadir@
datarootdir= @datarootdir@
INSTALL= @INSTALL@
INSTALL_PROGRAM= @INSTALL_PROGRAM@
INSTALL_DATA= @INSTALL_DATA@
INSTALL_SCRIPT= @INSTALL_SCRIPT@
ifndef BSD_INSTALL_MAN
BSD_INSTALL_MAN = ${INSTALL_DATA}
endif
ifndef BSD_INSTALL_DATA
BSD_INSTALL_DATA = ${INSTALL_DATA}
endif
ifndef BSD_INSTALL_PROGRAM
BSD_INSTALL_PROGRAM = ${INSTALL_PROGRAM}
endif
LIBTOOL= @LIBTOOL@
LIBTOOL_DEPS= @LIBTOOL_DEPS@
SHELL = @SHELL@
CC= @CC@
DEFINES=@DEFS@
CPPFLAGS= @CPPFLAGS@
CFLAGS= @CFLAGS@
LDFLAGS= @LDFLAGS@
LIBEV= @LIBEV@
LIBWRAP= @LIBWRAP@
LIBDL= @LIBDL@
# Assume a Posix-ish make that passes MAKEFLAGS in the environment.
SUBMAKE= $(MAKE) --no-print-directory
WARNS= @WARNS@
CFLAGS+= $(WARNS) -Wp,-MD,.deps/$(*F).d
CFLAGS+= $(DEFINES)
HAVE_LIBSMI=@HAVE_LIBSMI@
BUILD_MODULES=@BUILD_MODULES@

1433
config/config.guess vendored

File diff suppressed because it is too large Load Diff

1804
config/config.sub vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,527 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Begemot: bsnmp/trunk/config/mkinstalldirs 1487 2008-12-23 19:03:33Z brandt_h $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

View File

@ -1,202 +0,0 @@
#
# Copyright (c) 2004-2009
# Hartmut Brandt.
# All rights reserved.
# Copyright (c) 2003-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/tags/RELENG_1_13/configure.ac 2233 2018-06-25 17:17:57Z brandt_h $
#
AC_INIT([BSNMP], [1.0], [harti@freebsd.org], bsnmp)
AC_PREREQ(2.53)
AC_COPYRIGHT([Copyright (c)1996-2003 Fraunhofer Fokus. All rights reserved.])
AC_REVISION($Revision: 382 $)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR(config/install-sh)
AC_CONFIG_AUX_DIR(config)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
AC_PROG_CC
AC_PROG_CPP
AC_PROG_MAKE_SET
AC_PROG_INSTALL
LT_INIT
AC_SUBST(LIBTOOL_DEPS)
AC_SUBST(LIBTOOL)
#CFLAGS="${CFLAGS} -D_BSD_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE"
WARNS=" -Wsystem-headers -Werror -Wall -Wno-format-y2k -W \
-Wstrict-prototypes -Wmissing-prototypes \
-Wpointer-arith -Wreturn-type -Wcast-qual \
-Wwrite-strings -Wswitch -Wshadow -Wcast-align \
-Wbad-function-cast -Wchar-subscripts -Winline \
-Wnested-externs -Wredundant-decls -std=c99 \
-Wno-pointer-sign"
LIBDL=
BUILD_MODULES="yes"
case $host_os in
linux*)
WARNS+=" -Wno-cast-align -Wno-typedef-redefinition -Wno-builtin-requires-header"
LIBDL="-ldl"
BUILD_MODULES="no"
;;
esac
AC_SUBST(WARNS)
AC_SUBST(LIBDL)
AC_SUBST(BUILD_MODULES)
AC_ARG_WITH(libbegemot,
AC_HELP_STRING([--with-libbegemot],
[use libbegemot instead of libisc and set path to where the
includes and lib are found(default is NO, if no path specified default=/usr/local)]),
ac_cv_use_libbegemot=$withval, ac_cv_use_libbegemot=yes)
AC_CACHE_CHECK(whether to use libbegemot,
ac_cv_use_libbegemot, ac_cv_use_libbegemot=no)
if test $ac_cv_use_libbegemot == "yes" ; then
ac_cv_use_libbegemot="/usr/local"
fi
if test $ac_cv_use_libbegemot != "no" ; then
AC_DEFINE(USE_LIBBEGEMOT)
AC_SUBST(LIBEV, -lbegemot)
old_CPPFLAGS="$CPPFLAGS"
rpoll_path=""
CPPFLAGS="$old_CPPLFAGS -I$ac_cv_use_libbegemot/include"
AC_CHECK_HEADERS(rpoll.h, [rpoll_path="$ac_cv_use_libbegemot/include"],
[], [#include <sys/types.h>
])
if test -z "$rpoll_path" ; then
$as_unset ac_cv_header_rpoll_h
CPPFLAGS="$old_CPPLFAGS -I$ac_cv_use_libbegemot/include/libbegemot"
AC_CHECK_HEADERS(rpoll.h, [rpoll_path="$ac_cv_use_libbegemot/include/libbegemot"])
fi
if test -z "$rpoll_path" ; then
AC_MSG_FAILURE([cannot locate rpoll.h])
fi
CFLAGS="${CFLAGS} -I$rpoll_path"
LDFLAGS="${LDFLAGS} -L$ac_cv_use_libbegemot/lib"
AC_CHECK_LIB(begemot, poll_register, ,
[AC_ERROR([libbegemot not found])])
else
AC_SUBST(LIBEV, -lisc)
fi
AC_ARG_WITH(tcpwrappers,
AC_HELP_STRING([--with-tcpwrappers],
[use libwrap to control access]),
ac_cv_use_tcpwrappers=$withval, ac_cv_use_tcpwrappers=no)
if test $ac_cv_use_tcpwrappers != "no" ; then
AC_DEFINE(USE_TCPWRAPPERS)
AC_SUBST(LIBWRAP, -lwrap)
fi
LDFLAGS="${LDFLAGS} -L/usr/local/lib"
AC_CHECK_LIB(smi, smiGetNode, HAVE_LIBSMI=yes, HAVE_LIBSMI=no)
AC_SUBST(HAVE_LIBSMI)
# check for BSD's err.h
AC_CHECK_HEADERS([err.h])
# check for strlcpy
AC_CHECK_FUNCS(strlcpy)
# check for getaddrinfo
AC_CHECK_FUNCS(getaddrinfo)
# check for a usable tree.h
AC_CHECK_HEADER(sys/tree.h,
AC_DEFINE(HAVE_SYS_TREE_H))
# check whether we have posix stdint.h or at least inttypes.h
AC_CHECK_HEADER(stdint.h,
AC_DEFINE(HAVE_STDINT_H))
AC_CHECK_HEADER(inttypes.h,
[AC_DEFINE(HAVE_INTTYPES_H)
ac_have_inttypes_h=yes])
AC_CACHE_CHECK([how to print quads],
ac_cv_quad_fmt,
[if test "$ac_have_inttypes_h" = "yes" ; then
AC_EGREP_CPP(yes,
[
# include <inttypes.h>
# ifdef PRIu64
yes
# endif
],
ac_cv_quad_fmt=PRIu64,
AC_TRY_RUN(
[[
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
int
main()
{
char buf[100];
sprintf(buf, "%llx", 0x1234567887654321LLU);
exit((strcmp(buf, "1234567887654321") == 0) ? 0 : 1);
}
]],
ac_cv_quad_fmt='"ll"',
ac_cv_quad_fmt='"q"',
ac_cv_quad_fmt='"q"')
fi ]))
if test "$ac_cv_quad_fmt" = "PRIu64" ; then
AC_DEFINE(QUADFMT, PRIu64)
AC_DEFINE(QUADXFMT, PRIx64)
else
AC_DEFINE_UNQUOTED(QUADFMT, ${ac_cv_quad_fmt}"u")
AC_DEFINE_UNQUOTED(QUADXFMT, ${ac_cv_quad_fmt}"x")
fi
AC_CHECK_TYPES([u_int, u_char, u_long], [], [], [[#include <sys/types.h>]])
AC_CHECK_MEMBERS([struct sockaddr_un.sun_len, struct sockaddr_in.sin_len], [], [], [[#include <sys/socket.h>]])
AC_CONFIG_FILES([
Makefile:config/Makefile.pre:Makefile.in
gensnmpdef/Makefile:config/Makefile.pre:config/Makefile.build:gensnmpdef/Makefile.in:config/Makefile.post
gensnmptree/Makefile:config/Makefile.pre:config/Makefile.build:gensnmptree/Makefile.in:config/Makefile.post
lib/Makefile:config/Makefile.pre:config/Makefile.build:lib/Makefile.in:config/Makefile.post
snmpd/Makefile:config/Makefile.pre:config/Makefile.build:snmpd/Makefile.in:config/Makefile.post
libbsnmp.pc
])
case $host_os in
FreeBSD* | freebsd*)
AC_CONFIG_FILES([
snmp_mibII/Makefile:config/Makefile.pre:config/Makefile.build:snmp_mibII/Makefile.in:config/Makefile.post
snmp_ntp/Makefile:config/Makefile.pre:config/Makefile.build:snmp_ntp/Makefile.in:config/Makefile.post
snmp_target/Makefile:config/Makefile.pre:config/Makefile.build:snmp_target/Makefile.in:config/Makefile.post
snmp_usm/Makefile:config/Makefile.pre:config/Makefile.build:snmp_usm/Makefile.in:config/Makefile.post
snmp_vacm/Makefile:config/Makefile.pre:config/Makefile.build:snmp_vacm/Makefile.in:config/Makefile.post
])
;;
esac
AC_OUTPUT

View File

@ -1,19 +0,0 @@
# Copyright (c) 2004
# Hartmut Brandt
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/gensnmpdef/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
PROG= gensnmpdef
SRCS= gensnmpdef.c
MAN1= gensnmpdef.1
CFLAGS+= -I/usr/local/include
$(PROG): $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(SRCS:.c=.lo) -lsmi
CLEANFILES+= *.1out

View File

@ -1,19 +0,0 @@
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/gensnmptree/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
PROG= gensnmptree
SRCS= gensnmptree.c
MAN1= gensnmptree.1
CFLAGS+= -I$(srcdir)/../lib
$(PROG): $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -o $@ $(SRCS:.c=.lo)
CLEANFILES+= *.1out

View File

@ -2,7 +2,7 @@
.\" Copyright (c) 2001-2005
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
.\" All rights reserved.
.\" Copyright (c) 2006
.\" Copyright (c) 2006,2018
.\" Hartmut Brandt
.\" All rights reserved.
.\"
@ -31,7 +31,7 @@
.\"
.\" $Begemot: gensnmptree.1 383 2006-05-30 07:40:49Z brandt_h $
.\"
.Dd May 26, 2006
.Dd April 2, 2019
.Dt GENSNMPTREE 1
.Os
.Sh NAME
@ -39,7 +39,7 @@
.Nd "generate C and header files from a MIB description file"
.Sh SYNOPSIS
.Nm
.Op Fl dEehlt
.Op Fl dEeFfhlt
.Op Fl I Ar directory
.Op Fl i Ar infile
.Op Fl p Ar prefix
@ -99,6 +99,12 @@ is the length of the OID.
.It Va OID_ Ns Ar name
is the last component of the OID.
.El
.It Fl F
emit definitions for C-functions includeable in a C-file that do some basic
stuff on enums like value checking and conversion between value and strings.
.It Fl f
emit definitions for inline C-functions that do some basic
stuff on enums like value checking and conversion between value and strings.
.It Fl h
Print a short help page.
.It Fl I Ar directory

View File

@ -123,9 +123,40 @@ options:\n\
-i ifile read from the named file instead of stdin\n\
-l generate local include directives\n\
-p prefix prepend prefix to file and variable names\n\
-t generated a .def file\n\
-t generate a .def file\n\
";
/**
* Program operation.
*/
enum op {
/** generate the tree */
OP_GEN,
/** extract OIDs */
OP_EXTRACT,
/** print the parsed tree */
OP_TREE,
/** extract enums */
OP_ENUMS,
};
/**
* Which functions to create.
*/
enum gen_funcs {
/** none */
GEN_FUNCS_NONE,
/** functions for header files */
GEN_FUNCS_H,
/** functions for C files */
GEN_FUNCS_C,
};
/*
* A node in the OID tree
*/
@ -161,15 +192,18 @@ struct node {
uint32_t index; /* index for table entry */
char *func; /* function for tables */
struct node_list subs;
char *subtypes[SNMP_INDEXES_MAX];
} entry;
struct leaf {
enum snmp_syntax syntax; /* syntax for this leaf */
char *func; /* function name */
char *subtype; /* subtype */
} leaf;
struct column {
enum snmp_syntax syntax; /* syntax for this column */
char *subtype; /* subtype */
} column;
} u;
};
@ -213,7 +247,7 @@ xalloc(size_t size)
{
void *ptr;
if ((ptr = malloc(size)) == NULL)
if ((ptr = calloc(1, size)) == NULL)
err(1, "allocing %zu bytes", size);
return (ptr);
@ -709,12 +743,14 @@ make_type(const char *s)
* token.
*/
static u_int
parse_type(enum tok *tok, struct type *t, const char *vname)
parse_type(enum tok *tok, struct type *t, const char *vname, char **subtype)
{
u_int syntax;
struct enums *e;
syntax = val;
if (subtype != NULL)
*subtype = NULL;
if (*tok == TOK_ENUM || *tok == TOK_BITS) {
if (t == NULL && vname != NULL) {
@ -758,6 +794,8 @@ parse_type(enum tok *tok, struct type *t, const char *vname)
if ((*tok = gettoken()) == '|') {
if (gettoken() != TOK_STR)
report("subtype expected after '|'");
if (subtype != NULL)
*subtype = savetok();
*tok = gettoken();
}
}
@ -793,18 +831,21 @@ parse(enum tok tok)
if ((tok = gettoken()) == TOK_TYPE || tok == TOK_DEFTYPE ||
tok == TOK_ENUM || tok == TOK_BITS) {
/* LEAF or COLUM */
u_int syntax = parse_type(&tok, NULL, node->name);
char *subtype;
u_int syntax = parse_type(&tok, NULL, node->name, &subtype);
if (tok == TOK_STR) {
/* LEAF */
node->type = NODE_LEAF;
node->u.leaf.func = savetok();
node->u.leaf.syntax = syntax;
node->u.leaf.subtype = subtype;
tok = gettoken();
} else {
/* COLUMN */
node->type = NODE_COLUMN;
node->u.column.syntax = syntax;
node->u.column.subtype = subtype;
}
while (tok != ')') {
@ -824,9 +865,12 @@ parse(enum tok tok)
tok = gettoken();
while (tok == TOK_TYPE || tok == TOK_DEFTYPE ||
tok == TOK_ENUM || tok == TOK_BITS) {
u_int syntax = parse_type(&tok, NULL, node->name);
if (index_count++ == SNMP_INDEXES_MAX)
char *subtype;
u_int syntax = parse_type(&tok, NULL, node->name,
&subtype);
if (index_count == SNMP_INDEXES_MAX)
report("too many table indexes");
node->u.entry.subtypes[index_count++] = subtype;
node->u.entry.index |=
syntax << (SNMP_INDEX_SHIFT * index_count);
}
@ -881,7 +925,8 @@ parse_top(enum tok tok)
tok = gettoken();
t->is_enum = (tok == TOK_ENUM);
t->is_bits = (tok == TOK_BITS);
t->syntax = parse_type(&tok, t, NULL);
t->syntax = parse_type(&tok, t, NULL, NULL);
pushback(tok);
return (NULL);
@ -902,7 +947,7 @@ parse_top(enum tok tok)
* Generate the C-code table part for one node.
*/
static void
gen_node(FILE *fp, struct node *np, struct asn_oid *oid, u_int idx,
gen_node(FILE *fp, const struct node *np, struct asn_oid *oid, u_int idx,
const char *func)
{
u_int n;
@ -1007,7 +1052,7 @@ gen_node(FILE *fp, struct node *np, struct asn_oid *oid, u_int idx,
* Generate the header file with the function declarations.
*/
static void
gen_header(FILE *fp, struct node *np, u_int oidlen, const char *func)
gen_header(FILE *fp, const struct node *np, u_int oidlen, const char *func)
{
char f[MAXSTR + 4];
struct node *sub;
@ -1057,7 +1102,7 @@ gen_header(FILE *fp, struct node *np, u_int oidlen, const char *func)
* Generate the OID table.
*/
static void
gen_table(FILE *fp, struct node *node)
gen_table(FILE *fp, const struct node *node)
{
struct asn_oid oid;
@ -1116,6 +1161,8 @@ gen_tree(const struct node *np, int level)
case NODE_LEAF:
print_syntax(np->u.leaf.syntax);
if (np->u.leaf.subtype != NULL)
printf(" | %s", np->u.leaf.subtype);
printf(" %s%s%s)\n", np->u.leaf.func,
(np->flags & FL_GET) ? " GET" : "",
(np->flags & FL_SET) ? " SET" : "");
@ -1135,8 +1182,11 @@ gen_tree(const struct node *np, int level)
case NODE_ENTRY:
printf(" :");
for (i = 0; i < SNMP_INDEX_COUNT(np->u.entry.index); i++)
for (i = 0; i < SNMP_INDEX_COUNT(np->u.entry.index); i++) {
print_syntax(SNMP_INDEX(np->u.entry.index, i));
if (np->u.entry.subtypes[i] != NULL)
printf(" | %s", np->u.entry.subtypes[i]);
}
printf(" %s\n", np->u.entry.func);
TAILQ_FOREACH(sp, &np->u.entry.subs, link)
gen_tree(sp, level + 1);
@ -1145,6 +1195,8 @@ gen_tree(const struct node *np, int level)
case NODE_COLUMN:
print_syntax(np->u.column.syntax);
if (np->u.column.subtype != NULL)
printf(" | %s", np->u.column.subtype);
printf("%s%s)\n", (np->flags & FL_GET) ? " GET" : "",
(np->flags & FL_SET) ? " SET" : "");
break;
@ -1379,45 +1431,6 @@ unminus(FILE *fp, const char *s)
}
}
/**
* Generate a definition for the enum packed into a guard against multiple
* definitions.
*
* \param fp file to write definition to
* \param t type
*/
static void
gen_enum(FILE *fp, const struct type *t)
{
const struct enums *e;
long min = LONG_MAX;
fprintf(fp, "\n");
fprintf(fp, "#ifndef %s_defined__\n", t->name);
fprintf(fp, "#define %s_defined__\n", t->name);
fprintf(fp, "/*\n");
fprintf(fp, " * From %s:%u\n", t->from_fname, t->from_lno);
fprintf(fp, " */\n");
fprintf(fp, "enum %s {\n", t->name);
TAILQ_FOREACH(e, &t->enums, link) {
fprintf(fp, "\t%s_", t->name);
unminus(fp, e->name);
fprintf(fp, " = %ld,\n", e->value);
if (e->value < min)
min = e->value;
}
fprintf(fp, "};\n");
fprintf(fp, "#define STROFF_%s %ld\n", t->name, min);
fprintf(fp, "#define STRING_%s \\\n", t->name);
TAILQ_FOREACH(e, &t->enums, link) {
fprintf(fp, "\t[%ld] = \"%s_", e->value - min, t->name);
unminus(fp, e->name);
fprintf(fp, "\",\\\n");
}
fprintf(fp, "\n");
fprintf(fp, "#endif /* %s_defined__ */\n", t->name);
}
/**
* Generate helper functions for an enum.
*
@ -1482,6 +1495,54 @@ gen_enum_funcs(FILE *fp, const struct type *t, int ccode)
fprintf(fp, "}\n");
}
/**
* Generate a definition for the enum packed into a guard against multiple
* definitions.
*
* \param fp file to write definition to
* \param t type
* \param dof generate functions too
*/
static void
gen_enum(FILE *fp, const struct type *t, int dof)
{
const struct enums *e;
long min = LONG_MAX;
fprintf(fp, "\n");
fprintf(fp, "#ifndef %s_defined__\n", t->name);
fprintf(fp, "#define %s_defined__\n", t->name);
fprintf(fp, "/*\n");
fprintf(fp, " * From %s:%u\n", t->from_fname, t->from_lno);
fprintf(fp, " */\n");
fprintf(fp, "enum %s {\n", t->name);
TAILQ_FOREACH(e, &t->enums, link) {
fprintf(fp, "\t%s_", t->name);
unminus(fp, e->name);
fprintf(fp, " = %ld,\n", e->value);
if (e->value < min)
min = e->value;
}
fprintf(fp, "};\n");
fprintf(fp, "#define STROFF_%s %ld\n", t->name, min);
fprintf(fp, "#define STRING_%s \\\n", t->name);
TAILQ_FOREACH(e, &t->enums, link) {
fprintf(fp, "\t[%ld] = \"%s_", e->value - min, t->name);
unminus(fp, e->name);
fprintf(fp, "\",\\\n");
}
fprintf(fp, "\n");
if (dof) {
fprintf(fp, "#ifdef SNMPENUM_FUNCS\n");
fprintf(fp, "\n");
gen_enum_funcs(fp, t, 0);
fprintf(fp, "\n");
fprintf(fp, "#endif\n");
fprintf(fp, "\n");
}
fprintf(fp, "#endif /* %s_defined__ */\n", t->name);
}
/**
* Generate helper functions for an enum. This generates code for a c file.
*
@ -1519,13 +1580,13 @@ gen_all_enum_funcs(FILE *fp, int ccode)
}
static void
gen_enums(FILE *fp)
gen_enums(FILE *fp, int dof)
{
const struct type *t;
LIST_FOREACH(t, &types, link)
if (t->is_enum || t->is_bits)
gen_enum(fp, t);
gen_enum(fp, t, dof);
}
/**
@ -1545,9 +1606,7 @@ extract_enum(FILE *fp, const char *name, int gen_funcs)
LIST_FOREACH(t, &types, link)
if ((t->is_enum || t->is_bits) && strcmp(t->name, name) == 0) {
gen_enum(fp, t);
if (gen_funcs)
gen_enum_funcs(fp, t, 0);
gen_enum(fp, t, gen_funcs);
return (0);
}
return (-1);
@ -1566,11 +1625,8 @@ extract_all_enums(FILE *fp, int gen_funcs)
const struct type *t;
LIST_FOREACH(t, &types, link)
if (t->is_enum || t->is_bits) {
gen_enum(fp, t);
if (gen_funcs)
gen_enum_funcs(fp, t, 0);
}
if (t->is_enum || t->is_bits)
gen_enum(fp, t, gen_funcs);
}
/**
@ -1578,13 +1634,12 @@ extract_all_enums(FILE *fp, int gen_funcs)
*
* \param argc number of arguments
* \param argv arguments (enum names)
* \param gen_funcs_h generate functions into the header file
* \param gen_funcs_c generate a .c file with functions
* \param gen_funcs which functions to generate
*/
static void
make_enums(int argc, char *argv[], int gen_funcs_h, int gen_funcs_c)
make_enums(int argc, char *argv[], enum gen_funcs gen_funcs)
{
if (gen_funcs_c) {
if (gen_funcs == GEN_FUNCS_C) {
if (argc == 0)
gen_all_enum_funcs(stdout, 1);
else {
@ -1594,30 +1649,58 @@ make_enums(int argc, char *argv[], int gen_funcs_h, int gen_funcs_c)
}
} else {
if (argc == 0)
extract_all_enums(stdout, gen_funcs_h);
extract_all_enums(stdout, gen_funcs == GEN_FUNCS_H);
else {
for (int i = 0; i < argc; i++)
if (extract_enum(stdout, argv[i], gen_funcs_h))
if (extract_enum(stdout, argv[i],
gen_funcs == GEN_FUNCS_H))
errx(1, "enum not found: %s", argv[i]);
}
}
}
/**
* Produce the operation tables for the daemon or a module.
*
* \param root tree root
* \param gen_funcs generate enum funcs
*/
static void
make_table(const struct node *root, int gen_funcs)
{
FILE *fp;
char fname[MAXPATHLEN + 1];
sprintf(fname, "%stree.h", file_prefix);
if ((fp = fopen(fname, "w")) == NULL)
err(1, "%s: ", fname);
gen_header(fp, root, PREFIX_LEN, NULL);
fprintf(fp, "\n#ifdef SNMPTREE_TYPES\n");
gen_enums(fp, gen_funcs);
fprintf(fp, "\n#endif /* SNMPTREE_TYPES */\n\n");
fprintf(fp, "#define %sCTREE_SIZE %u\n", file_prefix, tree_size);
fprintf(fp, "extern const struct snmp_node %sctree[];\n", file_prefix);
fclose(fp);
sprintf(fname, "%stree.c", file_prefix);
if ((fp = fopen(fname, "w")) == NULL)
err(1, "%s: ", fname);
gen_table(fp, root);
fclose(fp);
}
int
main(int argc, char *argv[])
{
int do_extract = 0;
int do_tree = 0;
int do_enums = 0;
int gen_funcs_h = 0;
int gen_funcs_c = 0;
int opt;
struct node *root;
char fname[MAXPATHLEN + 1];
int tok;
FILE *fp;
enum op op = OP_GEN;
enum gen_funcs gen_funcs = GEN_FUNCS_NONE;
char *infile = NULL;
int opt;
while ((opt = getopt(argc, argv, "dEeFfhI:i:lp:t")) != EOF)
switch (opt) {
@ -1626,19 +1709,29 @@ main(int argc, char *argv[])
break;
case 'E':
do_enums = 1;
if (op != OP_GEN && op != OP_ENUMS)
errx(1, "-E conflicts with earlier options");
op = OP_ENUMS;
break;
case 'e':
do_extract = 1;
if (op != OP_GEN && op != OP_EXTRACT)
errx(1, "-e conflicts with earlier options");
op = OP_EXTRACT;
break;
case 'F':
gen_funcs_c = 1;
if (gen_funcs != GEN_FUNCS_NONE &&
gen_funcs != GEN_FUNCS_C)
errx(1, "-F conflicts with -f");
gen_funcs = GEN_FUNCS_C;
break;
case 'f':
gen_funcs_h = 1;
if (gen_funcs != GEN_FUNCS_NONE &&
gen_funcs != GEN_FUNCS_H)
errx(1, "-f conflicts with -F");
gen_funcs = GEN_FUNCS_H;
break;
case 'h':
@ -1665,73 +1758,61 @@ main(int argc, char *argv[])
break;
case 't':
do_tree = 1;
if (op != OP_GEN && op != OP_TREE)
errx(1, "-t conflicts with earlier options");
op = OP_TREE;
break;
}
if (do_extract + do_tree + do_enums > 1)
errx(1, "conflicting options -e/-t/-E");
if (!do_extract && !do_enums && argc != optind)
errx(1, "no arguments allowed");
if (do_extract && argc == optind)
errx(1, "no objects specified");
if ((gen_funcs_h || gen_funcs_c) && !do_enums)
errx(1, "-f and -F require -E");
if (gen_funcs_h && gen_funcs_c)
errx(1, "-f and -F are mutually exclusive");
argc -= optind;
argv += optind;
/* open input */
if (infile == NULL) {
input_new(stdin, NULL, "<stdin>");
} else {
FILE *fp;
if ((fp = fopen(infile, "r")) == NULL)
err(1, "%s", infile);
input_new(fp, NULL, infile);
}
root = parse_top(gettoken());
/* parse and check input */
struct node *root = parse_top(gettoken());
int tok;
while ((tok = gettoken()) != TOK_EOF)
merge(&root, parse_top(tok));
if (root)
check_tree(root);
if (do_extract) {
while (optind < argc) {
if (gen_extract(stdout, root, argv[optind]))
errx(1, "object not found: %s", argv[optind]);
optind++;
}
/* do what the user has requested */
switch (op) {
case OP_EXTRACT:
if (argc == 0)
errx(1, "-e requires arguments");
for (int i = 0; i < argc; i++)
if (gen_extract(stdout, root, argv[i]))
errx(1, "object not found: %s", argv[i]);
return (0);
}
if (do_enums) {
make_enums(argc - optind, argv + optind,
gen_funcs_h, gen_funcs_c);
case OP_ENUMS:
make_enums(argc, argv, gen_funcs);
return (0);
}
if (do_tree) {
case OP_TREE:
if (argc != 0)
errx(1, "-t allows no arguments");
gen_tree(root, 0);
return (0);
case OP_GEN:
if (argc != 0)
errx(1, "tree generation allows no arguments");
make_table(root, gen_funcs == GEN_FUNCS_H);
return (0);
}
sprintf(fname, "%stree.h", file_prefix);
if ((fp = fopen(fname, "w")) == NULL)
err(1, "%s: ", fname);
gen_header(fp, root, PREFIX_LEN, NULL);
fprintf(fp, "\n#ifdef SNMPTREE_TYPES\n");
gen_enums(fp);
fprintf(fp, "\n#endif /* SNMPTREE_TYPES */\n\n");
fprintf(fp, "#define %sCTREE_SIZE %u\n", file_prefix, tree_size);
fprintf(fp, "extern const struct snmp_node %sctree[];\n", file_prefix);
fclose(fp);
sprintf(fname, "%stree.c", file_prefix);
if ((fp = fopen(fname, "w")) == NULL)
err(1, "%s: ", fname);
gen_table(fp, root);
fclose(fp);
return (0);
}

View File

@ -1,34 +0,0 @@
# Copyright (c) 2003-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/lib/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
SRCS= asn1.c snmp.c snmpagent.c snmpclient.c support.c # snmptc.c
INCS= asn1.h snmp.h snmpagent.h snmpclient.h ${builddir}/snmptc.h
MAN3= asn1.3 bsnmplib.3 bsnmpclient.3 bsnmpagent.3
DEFS= tc.def
LIB= libbsnmp.la
SHLIB_MAJOR= 6
SHLIB_MINOR= 0
CFLAGS+= -I$(srcdir)
$(LIB): $(SRCS:.c=.lo) snmptc.h
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -o $@ $(SRCS:.c=.lo) -rpath $(libdir) -version-info $(SHLIB_MAJOR):$(SHLIB_MINOR)
snmptc.h : tc.def
( \
echo -n "/* autogenerated from tc.def; " ; \
ls -l -D "%F %T" $(srcdir)/tc.def | awk '{printf("%s %s",$$6,$$7)}' ; \
echo "*/"; \
echo "#ifndef snmptc_h_1529923773" ; \
echo "#define snmptc_h_1529923773" ; \
${top_builddir}/gensnmptree/gensnmptree -E -f <${srcdir}/tc.def ; \
echo "#endif" ; \
) >snmptc.h
CLEANFILES += snmptc.h *.3out

View File

@ -65,8 +65,8 @@ asn_get_header(struct asn_buf *b, u_char *type, asn_len_t *len)
return (ASN_ERR_EOBUF);
}
*type = *b->asn_cptr;
if ((*type & ASN_TYPE_MASK) > 0x30) {
asn_error(b, "types > 0x30 not supported (%u)",
if ((*type & ASN_TYPE_MASK) > 0x1e) {
asn_error(b, "tags > 0x1e not supported (%#x)",
*type & ASN_TYPE_MASK);
return (ASN_ERR_FAILED);
}
@ -100,6 +100,19 @@ asn_get_header(struct asn_buf *b, u_char *type, asn_len_t *len)
*len = *b->asn_cptr++;
b->asn_len--;
}
#ifdef BOGUS_CVE_2019_5610_FIX
/*
* This is the fix from CVE-2019-5610.
*
* This is the wrong place. Each of the asn functions should check
* that it has enough info for its own work.
*/
if (*len > b->asn_len) {
asn_error(b, "lenen %u exceeding asn_len %u", *len, b->asn_len);
return (ASN_ERR_EOBUF);
}
#endif
return (ASN_ERR_OK);
}
@ -142,7 +155,7 @@ asn_put_len(u_char *ptr, asn_len_t len)
/*
* Write a header (tag and length fields).
* Tags are restricted to one byte tags (value <= 0x30) and the
* Tags are restricted to one byte tags (value <= 0x1e) and the
* lenght field to 16-bit. All errors stop the encoding.
*/
enum asn_err
@ -151,8 +164,8 @@ asn_put_header(struct asn_buf *b, u_char type, asn_len_t len)
u_int lenlen;
/* tag field */
if ((type & ASN_TYPE_MASK) > 0x30) {
asn_error(NULL, "types > 0x30 not supported (%u)",
if ((type & ASN_TYPE_MASK) > 0x1e) {
asn_error(NULL, "types > 0x1e not supported (%#x)",
type & ASN_TYPE_MASK);
return (ASN_ERR_FAILED);
}
@ -246,9 +259,10 @@ asn_get_real_integer(struct asn_buf *b, asn_len_t len, int64_t *vp)
return (ASN_ERR_BADLEN);
}
err = ASN_ERR_OK;
if (len > 8)
if (len > 8) {
asn_error(b, "integer too long");
err = ASN_ERR_RANGE;
else if (len > 1 &&
} else if (len > 1 &&
((*b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) ||
(*b->asn_cptr == 0xff && (b->asn_cptr[1] & 0x80) == 0x80))) {
asn_error(b, "non-minimal integer");
@ -326,27 +340,35 @@ asn_put_real_integer(struct asn_buf *b, u_char type, int64_t ival)
static enum asn_err
asn_get_real_unsigned(struct asn_buf *b, asn_len_t len, uint64_t *vp)
{
enum asn_err err;
*vp = 0;
if (b->asn_len < len) {
asn_error(b, "truncated integer");
return (ASN_ERR_EOBUF);
}
if (len == 0) {
/* X.690: 8.3.1 */
asn_error(b, "zero-length integer");
*vp = 0;
return (ASN_ERR_BADLEN);
}
err = ASN_ERR_OK;
*vp = 0;
if ((*b->asn_cptr & 0x80) || (len == 9 && *b->asn_cptr != 0)) {
if (len > 1 && *b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) {
/* X.690: 8.3.2 */
asn_error(b, "non-minimal unsigned");
b->asn_cptr += len;
b->asn_len -= len;
return (ASN_ERR_BADLEN);
}
enum asn_err err = ASN_ERR_OK;
if ((*b->asn_cptr & 0x80) || len > 9 ||
(len == 9 && *b->asn_cptr != 0)) {
/* negative integer or too larger */
*vp = 0xffffffffffffffffULL;
err = ASN_ERR_RANGE;
} else if (len > 1 &&
*b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) {
asn_error(b, "non-minimal unsigned");
err = ASN_ERR_BADLEN;
asn_error(b, "unsigned too large or negative");
b->asn_cptr += len;
b->asn_len -= len;
return (ASN_ERR_RANGE);
}
while (len--) {
@ -400,11 +422,14 @@ asn_get_integer_raw(struct asn_buf *b, asn_len_t len, int32_t *vp)
enum asn_err ret;
if ((ret = asn_get_real_integer(b, len, &val)) == ASN_ERR_OK) {
if (len > 4)
if (len > 4) {
asn_error(b, "integer too long");
ret = ASN_ERR_BADLEN;
else if (val > INT32_MAX || val < INT32_MIN)
} else if (val > INT32_MAX || val < INT32_MIN) {
/* may not happen */
asn_error(b, "integer out of range");
ret = ASN_ERR_RANGE;
}
*vp = (int32_t)val;
}
return (ret);
@ -584,7 +609,7 @@ asn_get_objid_raw(struct asn_buf *b, asn_len_t len, struct asn_oid *oid)
return (ASN_ERR_EOBUF);
}
if (subid > (ASN_MAXID >> 7)) {
asn_error(b, "OBID subid too larger");
asn_error(b, "OID subid too larger");
err = ASN_ERR_RANGE;
}
subid = (subid << 7) | (*b->asn_cptr & 0x7f);
@ -640,7 +665,7 @@ asn_put_objid(struct asn_buf *b, const struct asn_oid *oid)
oidlen = 2;
} else if (oid->len == 1) {
/* illegal */
asn_error(b, "short oid");
asn_error(NULL, "short oid");
if (oid->subs[0] > 2)
asn_error(NULL, "oid[0] too large (%u)", oid->subs[0]);
err = ASN_ERR_RANGE;
@ -652,7 +677,8 @@ asn_put_objid(struct asn_buf *b, const struct asn_oid *oid)
err = ASN_ERR_RANGE;
}
if (oid->subs[0] > 2 ||
(oid->subs[0] < 2 && oid->subs[1] >= 40)) {
(oid->subs[0] < 2 && oid->subs[1] >= 40) ||
(oid->subs[0] == 2 && oid->subs[1] > ASN_MAXID - 2 * 40)) {
asn_error(NULL, "oid out of range (%u,%u)",
oid->subs[0], oid->subs[1]);
err = ASN_ERR_RANGE;
@ -809,10 +835,7 @@ asn_get_uint32_raw(struct asn_buf *b, asn_len_t len, uint32_t *vp)
enum asn_err err;
if ((err = asn_get_real_unsigned(b, len, &v)) == ASN_ERR_OK) {
if (len > 5) {
asn_error(b, "uint32 too long %u", len);
err = ASN_ERR_BADLEN;
} else if (v > UINT32_MAX) {
if (v > UINT32_MAX) {
asn_error(b, "uint32 too large %llu", v);
err = ASN_ERR_RANGE;
}

View File

@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $
.\"
.Dd December 31, 2016
.Dd March 31, 2020
.Dt BSNMPCLIENT 3
.Os
.Sh NAME
@ -177,7 +177,9 @@ If it is
a local stream socket is used.
For
.Dv SNMP_TRANS_UDP
a UDP socket is created.
a UDPv4 socket and for
.Dv SNMP_TRANS_UDP6
a UDPv6 socket is created.
It uses the
.Va chost
field as the path to the server's socket for local sockets.
@ -675,7 +677,12 @@ The syntax of a server specification is
.Pp
where
.Va trans
is the transport name (one of udp, stream or dgram),
is the transport name (one of
.Qq udp ,
.Qq udp6 ,
.Qq stream
or
.Qq dgram ) ,
.Va community
is the string to be used for both the read and the write community,
.Va server
@ -685,13 +692,51 @@ of a local socket, and
is the port in case of UDP transport.
The function returns 0 in the case of success and return -1 and sets
the error string in case of an error.
.Pp
The function
.Fn snmp_parse_serverr
fills the transport, the port number and the community strings with
reasonable default values when they are not specified.
The default transport
is
.Dv SNMP_TRANS_UDP .
If the host name contains a slash the default is modified to
.Dv SNMP_TRANS_LOC_DGRAM .
If the host name looks like a numeric IPv6 address the default is
.Dv SNMP_TRANS_UDP6 .
For numeric IPv6 addresses the transport name udp is automatically
translated as
.Dv SNMP_TRANS_UDP6 .
The default port number (for
.Dv udp
or
.Dv udp6 )
is
.Qq snmp .
The default read community is
.Qq public
and the default write community
.Qq private .
.Pp
.Fn snmp_parse_server
recognizes path names, host names and numerical IPv4 and IPv6 addresses.
A string consisting of digits and periods is assumed to be an IPv4 address
and must be parseable by
.Fn inet_aton 3 .
An IPv6 address is any string enclosed in square brackets.
It must be parseable with
.Fn gethostinfo 3 .
.Pp
The port number for
.Fn snmp_parse_server
can be specified numerically or symbolically.
It is ignored for local sockets.
.Sh DIAGNOSTICS
If an error occurs in any of the function an error indication as described
If an error occurs in any of the functions an error indication as described
above is returned.
Additionally the function sets a printable error string
in the
Additionally the function sets a printable error string in the
.Va error
filed of
field of
.Va snmp_client .
.Sh SEE ALSO
.Xr gensnmptree 1 ,

View File

@ -42,6 +42,9 @@
#include <sys/types.h>
#define BSNMP_MAJOR 1
#define BSNMP_MINOR 13
#define SNMP_COMMUNITY_MAXLEN 128
#define SNMP_MAX_BINDINGS 100
#define SNMP_CONTEXT_NAME_SIZ (32 + 1)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004-2005
* Copyright (c) 2004-2005,2018-2019
* Hartmut Brandt.
* All rights reserved.
* Copyright (c) 2001-2003
@ -34,11 +34,13 @@
*
* Support functions for SNMP clients.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <net/if.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@ -58,12 +60,16 @@
#include <err.h>
#endif
#include <arpa/inet.h>
#include "support.h"
#include "asn1.h"
#include "snmp.h"
#include "snmpclient.h"
#include "snmppriv.h"
#define DEBUG_PARSE 0
/* global context */
struct snmp_client snmp_client;
@ -474,7 +480,7 @@ table_check_response(struct tabwork *work, const struct snmp_pdu *resp)
if (snmp_client.version == SNMP_V1 &&
resp->error_status == SNMP_ERR_NOSUCHNAME &&
resp->error_index ==
(work->descr->last_change.len == 0) ? 1 : 2)
((work->descr->last_change.len == 0) ? 1 : 2))
/* EOT */
return (0);
/* Error */
@ -924,7 +930,8 @@ open_client_udp(const char *host, const char *port)
/* open connection */
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
hints.ai_family = snmp_client.trans == SNMP_TRANS_UDP ? AF_INET :
AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
error = getaddrinfo(snmp_client.chost, snmp_client.cport, &hints, &res0);
@ -1068,6 +1075,7 @@ snmp_open(const char *host, const char *port, const char *readcomm,
switch (snmp_client.trans) {
case SNMP_TRANS_UDP:
case SNMP_TRANS_UDP6:
if (open_client_udp(host, port) != 0)
return (-1);
break;
@ -1866,99 +1874,425 @@ snmp_client_set_port(struct snmp_client *cl, const char *p)
return (0);
}
/*
* parse a server specification
static const char *const trans_list[] = {
[SNMP_TRANS_UDP] = "udp::",
[SNMP_TRANS_LOC_DGRAM] = "dgram::",
[SNMP_TRANS_LOC_STREAM] = "stream::",
[SNMP_TRANS_UDP6] = "udp6::",
};
/**
* Try to get a transport identifier which is a leading alphanumeric string
* terminated by a double colon. The string may not be empty. The transport
* identifier is optional. Unknown transport identifiers are reject.
* Be careful: a double colon can also occur in a numeric IPv6 address.
*
* [trans::][community@][server][:port]
* \param sc client struct to set errors
* \param strp possible start of transport; updated to point to
* the next character to parse
*
* \return transport identifier
*/
static inline int
get_transp(struct snmp_client *sc, const char **strp)
{
const char *p;
size_t i;
for (i = 0; i < nitems(trans_list); i++) {
p = strstr(*strp, trans_list[i]);
if (p == *strp) {
*strp += strlen(trans_list[i]);
return ((int)i);
}
}
p = strstr(*strp, "::");
if (p == *strp) {
seterr(sc, "empty transport specifier");
return (-1);
}
if (p == NULL)
/* by default assume UDP */
return (SNMP_TRANS_UDP);
/* ignore :: after [ */
const char *ob = strchr(*strp, '[');
if (ob != NULL && p > ob)
/* by default assume UDP */
return (SNMP_TRANS_UDP);
seterr(sc, "unknown transport specifier '%.*s'", p - *strp, *strp);
return (-1);
}
/**
* Try to get community string. Eat everything up to the last @ (if there is
* any) but only if it is not longer than SNMP_COMMUNITY_MAXLEN. Empty
* community strings are legal.
*
* \param sc client struct to set errors
* \param strp possible start of community; updated to the point to
* the next character to parse
*
* \return end of community; equals *strp if there is none; NULL if there
* was an error
*/
static inline const char *
get_comm(struct snmp_client *sc, const char **strp)
{
const char *p = strrchr(*strp, '@');
if (p == NULL)
/* no community string */
return (*strp);
if (p - *strp > SNMP_COMMUNITY_MAXLEN) {
seterr(sc, "community string too long '%.*s'",
p - *strp, *strp);
return (NULL);
}
*strp = p + 1;
return (p);
}
/**
* Try to get an IPv6 address. This starts with an [ and should end with an ]
* and everything between should be not longer than INET6_ADDRSTRLEN and
* parseable by inet_pton().
*
* \param sc client struct to set errors
* \param strp possible start of IPv6 address (the '['); updated to point to
* the next character to parse (the one after the closing ']')
*
* \return end of address (equals *strp + 1 if there is none) or NULL
* on errors
*/
static inline const char *
get_ipv6(struct snmp_client *sc, const char **strp)
{
char str[INET6_ADDRSTRLEN + IF_NAMESIZE];
struct addrinfo hints, *res;
int error;
if (**strp != '[')
return (*strp + 1);
const char *p = *strp + 1;
while (*p != ']' ) {
if (*p == '\0') {
seterr(sc, "unterminated IPv6 address '%.*s'",
p - *strp, *strp);
return (NULL);
}
p++;
}
if (p - *strp > INET6_ADDRSTRLEN + IF_NAMESIZE) {
seterr(sc, "IPv6 address too long '%.*s'", p - *strp, *strp);
return (NULL);
}
strncpy(str, *strp + 1, p - (*strp + 1));
str[p - (*strp + 1)] = '\0';
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME | AI_NUMERICHOST;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
error = getaddrinfo(str, NULL, &hints, &res);
if (error != 0) {
seterr(sc, "%s: %s", str, gai_strerror(error));
return (NULL);
}
freeaddrinfo(res);
*strp = p + 1;
return (p);
}
/**
* Try to get an IPv4 address. This starts with a digit and consists of digits
* and dots, is not longer INET_ADDRSTRLEN and must be parseable by
* inet_aton().
*
* \param sc client struct to set errors
* \param strp possible start of IPv4 address; updated to point to the
* next character to parse
*
* \return end of address (equals *strp if there is none) or NULL
* on errors
*/
static inline const char *
get_ipv4(struct snmp_client *sc, const char **strp)
{
const char *p = *strp;
while (isascii(*p) && (isdigit(*p) || *p == '.'))
p++;
if (p - *strp > INET_ADDRSTRLEN) {
seterr(sc, "IPv4 address too long '%.*s'", p - *strp, *strp);
return (NULL);
}
if (*strp == p)
return *strp;
char str[INET_ADDRSTRLEN + 1];
strncpy(str, *strp, p - *strp);
str[p - *strp] = '\0';
struct in_addr addr;
if (inet_aton(str, &addr) != 1) {
seterr(sc, "illegal IPv4 address '%s'", str);
return (NULL);
}
*strp = p;
return (p);
}
/**
* Try to get a hostname. This includes everything up to but not including
* the last colon (if any). There is no length restriction.
*
* \param sc client struct to set errors
* \param strp possible start of hostname; updated to point to the next
* character to parse (the trailing NUL character or the last
* colon)
*
* \return end of address (equals *strp if there is none)
*/
static inline const char *
get_host(struct snmp_client *sc __unused, const char **strp)
{
const char *p = strrchr(*strp, ':');
if (p == NULL) {
*strp += strlen(*strp);
return (*strp);
}
*strp = p;
return (p);
}
/**
* Try to get a port number. This start with a colon and extends to the end
* of string. The port number must not be empty.
*
* \param sc client struct to set errors
* \param strp possible start of port specification; if this points to a
* colon there is a port specification
*
* \return end of port number (equals *strp if there is none); NULL
* if there is no port number
*/
static inline const char *
get_port(struct snmp_client *sc, const char **strp)
{
if (**strp != ':')
return (*strp + 1);
if ((*strp)[1] == '\0') {
seterr(sc, "empty port name");
return (NULL);
}
*strp += strlen(*strp);
return (*strp);
}
/**
* Save the string in the range given by two pointers.
*
* \param sc client struct to set errors
* \param s begin and end pointers
*
* \return freshly allocated copy of the string between s[0] and s[1]
*/
static inline char *
save_str(struct snmp_client *sc, const char *const s[2])
{
char *m;
if ((m = malloc(s[1] - s[0] + 1)) == NULL) {
seterr(sc, "%s: %s", __func__, strerror(errno));
return (NULL);
}
strncpy(m, s[0], s[1] - s[0]);
m[s[1] - s[0]] = '\0';
return (m);
}
/**
* Parse a server specification. All parts are optional:
*
* [<trans>::][<comm>@][<host-or-ip>][:<port>]
*
* The transport string consists of letters, digits or '_' and starts with
* a letter or digit. It is terminated by two colons and may not be empty.
*
* The community string is terminated by the last '@' and does not exceed
* SNMP_COMMUNITY_MAXLEN. It may be empty.
*
* The host or ip is either an IPv4 address (as parsed by inet_pton()), an
* IPv6 address in '[' and ']' and parseable by inet_aton() or a hostname
* terminated by the last colon or by the NUL character.
*
* The port number may be specified numerically or symbolically and starts
* with the last colon.
*
* The functions sets the chost, cport, trans, read_community and
* write_community fields on success and the error field on errors.
* The chost and cport fields are allocated by malloc(3), their previous
* content is deallocated by free(3).
*
* The function explicitly allows mismatches between the transport and
* the address type in order to support IPv4 in IPv6 addresses.
*
* \param sc client struct to fill
* \param str string to parse
*
* \return 0 on success and -1 on errors
*/
int
snmp_parse_server(struct snmp_client *sc, const char *str)
{
const char *p, *s = str;
const char *const orig = str;
/* look for a double colon */
for (p = s; *p != '\0'; p++) {
if (*p == '\\' && p[1] != '\0') {
p++;
continue;
}
if (*p == ':' && p[1] == ':')
break;
}
if (*p != '\0') {
if (p > s) {
if (p - s == 3 && strncmp(s, "udp", 3) == 0)
sc->trans = SNMP_TRANS_UDP;
else if (p - s == 6 && strncmp(s, "stream", 6) == 0)
sc->trans = SNMP_TRANS_LOC_STREAM;
else if (p - s == 5 && strncmp(s, "dgram", 5) == 0)
sc->trans = SNMP_TRANS_LOC_DGRAM;
else {
seterr(sc, "unknown SNMP transport '%.*s'",
(int)(p - s), s);
return (-1);
}
}
s = p + 2;
/* parse input */
int def_trans = 0, trans = get_transp(sc, &str);
if (trans < 0)
return (-1);
/* choose automatically */
if (orig == str)
def_trans = 1;
const char *const comm[2] = {
str,
get_comm(sc, &str),
};
if (comm[1] == NULL)
return (-1);
const char *const ipv6[2] = {
str + 1,
get_ipv6(sc, &str),
};
if (ipv6[1] == NULL)
return (-1);
const char *ipv4[2] = {
str,
str,
};
const char *host[2] = {
str,
str,
};
if (ipv6[0] == ipv6[1]) {
ipv4[1] = get_ipv4(sc, &str);
if (ipv4[0] == ipv4[1])
host[1] = get_host(sc, &str);
}
/* look for a @ */
for (p = s; *p != '\0'; p++) {
if (*p == '\\' && p[1] != '\0') {
p++;
continue;
}
if (*p == '@')
break;
const char *port[2] = {
str + 1,
get_port(sc, &str),
};
if (port[1] == NULL)
return (-1);
if (*str != '\0') {
seterr(sc, "junk at end of server specification '%s'", str);
return (-1);
}
if (*p != '\0') {
if (p - s > SNMP_COMMUNITY_MAXLEN) {
seterr(sc, "community string too long");
#if DEBUG_PARSE
printf("transp: %d (def=%d)\n", trans, def_trans);
printf("comm: %zu %zu\n", comm[0] - orig, comm[1] - orig);
printf("ipv6: %zu %zu\n", ipv6[0] - orig, ipv6[1] - orig);
printf("ipv4: %zu %zu\n", ipv4[0] - orig, ipv4[1] - orig);
printf("host: %zu %zu\n", host[0] - orig, host[1] - orig);
printf("port: %zu %zu\n", port[0] - orig, port[1] - orig);
#endif
/* analyse and allocate */
char *chost;
if (ipv6[0] != ipv6[1]) {
if ((chost = save_str(sc, ipv6)) == NULL)
return (-1);
}
strncpy(sc->read_community, s, p - s);
sc->read_community[p - s] = '\0';
strncpy(sc->write_community, s, p - s);
sc->write_community[p - s] = '\0';
s = p + 1;
}
/* look for a colon */
for (p = s; *p != '\0'; p++) {
if (*p == '\\' && p[1] != '\0') {
p++;
continue;
}
if (*p == ':')
break;
}
if (*p == ':') {
if (p > s) {
/* host:port */
free(sc->chost);
if ((sc->chost = malloc(p - s + 1)) == NULL) {
seterr(sc, "%s", strerror(errno));
return (-1);
}
strncpy(sc->chost, s, p - s);
sc->chost[p - s] = '\0';
}
/* port */
free(sc->cport);
if ((sc->cport = strdup(p + 1)) == NULL) {
seterr(sc, "%s", strerror(errno));
if (def_trans || trans == SNMP_TRANS_UDP)
/* assume the user meant udp6:: */
trans = SNMP_TRANS_UDP6;
} else if (ipv4[0] != ipv4[1]) {
if ((chost = save_str(sc, ipv4)) == NULL)
return (-1);
}
} else if (p > s) {
/* host */
free(sc->chost);
if ((sc->chost = strdup(s)) == NULL) {
seterr(sc, "%s", strerror(errno));
if (def_trans)
trans = SNMP_TRANS_UDP;
} else {
if ((chost = save_str(sc, host)) == NULL)
return (-1);
if (def_trans) {
/*
* Default transport is UDP unless the host contains
* a slash in which case we default to DGRAM.
*/
for (const char *p = host[0]; p < host[1]; p++)
if (*p == '/') {
trans = SNMP_TRANS_LOC_DGRAM;
break;
}
}
}
char *cport;
if (port[0] == port[1] && (
trans == SNMP_TRANS_UDP || trans == SNMP_TRANS_UDP6)) {
/* If port was not specified, use "snmp" name by default */
cport = strdup("snmp");
} else
cport = save_str(sc, port);
if (cport == NULL) {
free(chost);
return (-1);
}
/* commit */
sc->trans = trans;
/*
* If community string was specified and it is empty, overwrite it.
* If it was not specified, use default.
*/
if (comm[0] != comm[1] || strrchr(comm[0], '@') != NULL) {
strncpy(sc->read_community, comm[0], comm[1] - comm[0]);
sc->read_community[comm[1] - comm[0]] = '\0';
strncpy(sc->write_community, comm[0], comm[1] - comm[0]);
sc->write_community[comm[1] - comm[0]] = '\0';
}
free(sc->chost);
sc->chost = chost;
free(sc->cport);
sc->cport = cport;
#if DEBUG_PARSE
printf("Committed values:\n");
printf("trans: %d\n", sc->trans);
printf("comm: '%s'/'%s'\n", sc->read_community, sc->write_community);
printf("host: '%s'\n", sc->chost);
printf("port: '%s'\n", sc->cport);
#endif
return (0);
}

View File

@ -49,6 +49,7 @@
#define SNMP_TRANS_UDP 0
#define SNMP_TRANS_LOC_DGRAM 1
#define SNMP_TRANS_LOC_STREAM 2
#define SNMP_TRANS_UDP6 3
/* type of callback function for responses
* this callback function is responsible for free() any memory associated with

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: head/contrib/bsnmp/lib/snmpcrypto.c 310648 2016-12-27 23:32:54Z ngie $
* $FreeBSD: head/contrib/bsnmp/lib/snmpcrypto.c 339270 2018-10-09 21:28:26Z gjb $
*/
#include <sys/types.h>
#include <sys/socket.h>
@ -57,11 +57,11 @@
#define SNMP_AUTH_KEY_LOOPCNT 1048576
#define SNMP_AUTH_BUF_SIZE 72
#ifdef HAVE_LIBCRYPTO
static const uint8_t ipad = 0x36;
static const uint8_t opad = 0x5c;
#ifdef HAVE_LIBCRYPTO
static int32_t
snmp_digest_init(const struct snmp_user *user, EVP_MD_CTX *ctx,
const EVP_MD **dtype, uint32_t *keylen)
@ -94,9 +94,14 @@ snmp_pdu_calc_digest(const struct snmp_pdu *pdu, uint8_t *digest)
uint32_t i, keylen, olen;
int32_t err;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
EVP_MD_CTX *ctx;
err = snmp_digest_init(&pdu->user, &ctx, &dtype, &keylen);
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
return (SNMP_CODE_FAILED);
err = snmp_digest_init(&pdu->user, ctx, &dtype, &keylen);
if (err <= 0)
EVP_MD_CTX_free(ctx);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
@ -111,29 +116,29 @@ snmp_pdu_calc_digest(const struct snmp_pdu *pdu, uint8_t *digest)
key2[i] = extkey[i] ^ opad;
}
if (EVP_DigestUpdate(&ctx, key1, SNMP_EXTENDED_KEY_SIZ) != 1 ||
EVP_DigestUpdate(&ctx, pdu->outer_ptr, pdu->outer_len) != 1 ||
EVP_DigestFinal(&ctx, md, &olen) != 1)
if (EVP_DigestUpdate(ctx, key1, SNMP_EXTENDED_KEY_SIZ) != 1 ||
EVP_DigestUpdate(ctx, pdu->outer_ptr, pdu->outer_len) != 1 ||
EVP_DigestFinal(ctx, md, &olen) != 1)
goto failed;
if (EVP_DigestInit(&ctx, dtype) != 1 ||
EVP_DigestUpdate(&ctx, key2, SNMP_EXTENDED_KEY_SIZ) != 1 ||
EVP_DigestUpdate(&ctx, md, olen) != 1 ||
EVP_DigestFinal(&ctx, md, &olen) != 1)
if (EVP_DigestInit(ctx, dtype) != 1 ||
EVP_DigestUpdate(ctx, key2, SNMP_EXTENDED_KEY_SIZ) != 1 ||
EVP_DigestUpdate(ctx, md, olen) != 1 ||
EVP_DigestFinal(ctx, md, &olen) != 1)
goto failed;
if (olen < SNMP_USM_AUTH_SIZE) {
snmp_error("bad digest size - %d", olen);
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_BADDIGEST);
}
memcpy(digest, md, SNMP_USM_AUTH_SIZE);
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_OK);
failed:
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_BADDIGEST);
}
@ -176,7 +181,7 @@ snmp_pdu_encrypt(const struct snmp_pdu *pdu)
int32_t err, olen;
uint8_t iv[SNMP_PRIV_AES_IV_SIZ];
const EVP_CIPHER *ctype;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX *ctx;
err = snmp_pdu_cipher_init(pdu, pdu->scoped_len, &ctype, iv);
if (err < 0)
@ -184,18 +189,23 @@ snmp_pdu_encrypt(const struct snmp_pdu *pdu)
else if (err == 0)
return (SNMP_CODE_OK);
if (EVP_EncryptInit(&ctx, ctype, pdu->user.priv_key, iv) != 1)
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return (SNMP_CODE_FAILED);
if (EVP_EncryptInit(ctx, ctype, pdu->user.priv_key, iv) != 1)
goto failed;
if (EVP_EncryptUpdate(&ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
if (EVP_EncryptUpdate(ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
pdu->scoped_len) != 1 ||
EVP_EncryptFinal(&ctx, pdu->scoped_ptr + olen, &olen) != 1) {
EVP_CIPHER_CTX_cleanup(&ctx);
return (SNMP_CODE_FAILED);
}
EVP_EncryptFinal(ctx, pdu->scoped_ptr + olen, &olen) != 1)
goto failed;
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX_free(ctx);
return (SNMP_CODE_OK);
failed:
EVP_CIPHER_CTX_free(ctx);
return (SNMP_CODE_FAILED);
}
enum snmp_code
@ -204,7 +214,7 @@ snmp_pdu_decrypt(const struct snmp_pdu *pdu)
int32_t err, olen;
uint8_t iv[SNMP_PRIV_AES_IV_SIZ];
const EVP_CIPHER *ctype;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX *ctx;
err = snmp_pdu_cipher_init(pdu, pdu->scoped_len, &ctype, iv);
if (err < 0)
@ -212,19 +222,24 @@ snmp_pdu_decrypt(const struct snmp_pdu *pdu)
else if (err == 0)
return (SNMP_CODE_OK);
if (EVP_DecryptInit(&ctx, ctype, pdu->user.priv_key, iv) != 1 ||
EVP_CIPHER_CTX_set_padding(&ctx, 0) != 1)
return (SNMP_CODE_EDECRYPT);
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return (SNMP_CODE_FAILED);
if (EVP_DecryptInit(ctx, ctype, pdu->user.priv_key, iv) != 1 ||
EVP_CIPHER_CTX_set_padding(ctx, 0) != 1)
goto failed;
if (EVP_DecryptUpdate(&ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
if (EVP_DecryptUpdate(ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
pdu->scoped_len) != 1 ||
EVP_DecryptFinal(&ctx, pdu->scoped_ptr + olen, &olen) != 1) {
EVP_CIPHER_CTX_cleanup(&ctx);
return (SNMP_CODE_EDECRYPT);
}
EVP_DecryptFinal(ctx, pdu->scoped_ptr + olen, &olen) != 1)
goto failed;
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX_free(ctx);
return (SNMP_CODE_OK);
failed:
EVP_CIPHER_CTX_free(ctx);
return (SNMP_CODE_EDECRYPT);
}
/* [RFC 3414] - A.2. Password to Key Algorithm */
@ -234,13 +249,19 @@ snmp_passwd_to_keys(struct snmp_user *user, char *passwd)
int err, loop, i, pwdlen;
uint32_t keylen, olen;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
EVP_MD_CTX *ctx;
uint8_t authbuf[SNMP_AUTH_BUF_SIZE];
if (passwd == NULL || user == NULL)
return (SNMP_CODE_FAILED);
err = snmp_digest_init(user, &ctx, &dtype, &keylen);
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
return (SNMP_CODE_FAILED);
err = snmp_digest_init(user, ctx, &dtype, &keylen);
if (err <= 0)
EVP_MD_CTX_free(ctx);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
@ -252,18 +273,18 @@ snmp_passwd_to_keys(struct snmp_user *user, char *passwd)
for (loop = 0; loop < SNMP_AUTH_KEY_LOOPCNT; loop += i) {
for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++)
authbuf[i] = passwd[(loop + i) % pwdlen];
if (EVP_DigestUpdate(&ctx, authbuf, SNMP_EXTENDED_KEY_SIZ) != 1)
if (EVP_DigestUpdate(ctx, authbuf, SNMP_EXTENDED_KEY_SIZ) != 1)
goto failed;
}
if (EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1)
if (EVP_DigestFinal(ctx, user->auth_key, &olen) != 1)
goto failed;
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_OK);
failed:
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_BADDIGEST);
}
@ -274,16 +295,22 @@ snmp_get_local_keys(struct snmp_user *user, uint8_t *eid, uint32_t elen)
int err;
uint32_t keylen, olen;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
EVP_MD_CTX *ctx;
uint8_t authbuf[SNMP_AUTH_BUF_SIZE];
if (user == NULL || eid == NULL || elen > SNMP_ENGINE_ID_SIZ)
return (SNMP_CODE_FAILED);
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
return (SNMP_CODE_FAILED);
memset(user->priv_key, 0, sizeof(user->priv_key));
memset(authbuf, 0, sizeof(authbuf));
err = snmp_digest_init(user, &ctx, &dtype, &keylen);
err = snmp_digest_init(user, ctx, &dtype, &keylen);
if (err <= 0)
EVP_MD_CTX_free(ctx);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
@ -293,12 +320,12 @@ snmp_get_local_keys(struct snmp_user *user, uint8_t *eid, uint32_t elen)
memcpy(authbuf + keylen, eid, elen);
memcpy(authbuf + keylen + elen, user->auth_key, keylen);
if (EVP_DigestUpdate(&ctx, authbuf, 2 * keylen + elen) != 1 ||
EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1) {
EVP_MD_CTX_cleanup(&ctx);
if (EVP_DigestUpdate(ctx, authbuf, 2 * keylen + elen) != 1 ||
EVP_DigestFinal(ctx, user->auth_key, &olen) != 1) {
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_BADDIGEST);
}
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
if (user->priv_proto != SNMP_PRIV_NOPRIV)
memcpy(user->priv_key, user->auth_key, sizeof(user->priv_key));
@ -312,9 +339,15 @@ snmp_calc_keychange(struct snmp_user *user, uint8_t *keychange)
int32_t err, rvalue[SNMP_AUTH_HMACSHA_KEY_SIZ / 4];
uint32_t i, keylen, olen;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
EVP_MD_CTX *ctx;
err = snmp_digest_init(user, &ctx, &dtype, &keylen);
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
return (SNMP_CODE_FAILED);
err = snmp_digest_init(user, ctx, &dtype, &keylen);
if (err <= 0)
EVP_MD_CTX_free(ctx);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
@ -326,13 +359,13 @@ snmp_calc_keychange(struct snmp_user *user, uint8_t *keychange)
memcpy(keychange, user->auth_key, keylen);
memcpy(keychange + keylen, rvalue, keylen);
if (EVP_DigestUpdate(&ctx, keychange, 2 * keylen) != 1 ||
EVP_DigestFinal(&ctx, keychange, &olen) != 1) {
EVP_MD_CTX_cleanup(&ctx);
if (EVP_DigestUpdate(ctx, keychange, 2 * keylen) != 1 ||
EVP_DigestFinal(ctx, keychange, &olen) != 1) {
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_BADDIGEST);
}
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_free(ctx);
return (SNMP_CODE_OK);
}

View File

@ -46,3 +46,11 @@ typedef StorageType ENUM (
5 readOnly
)
typedef InetAddressType ENUM (
0 unknown
1 ipv4
2 ipv6
3 ipv4z
4 ipv6z
16 dns
)

View File

@ -1,12 +0,0 @@
# $Id: libbegemot.pc.in 31 2015-07-15 13:07:02Z kato_zo $
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
libdir=@libdir@
Name: libbegemot
Description: Library for storing the rpoll code
Version: 0.0.0
Requires:
Cflags: -I${includedir}
Libs: -L${libdir} -lbsnmp

View File

@ -1,48 +0,0 @@
# Copyright (c) 2004-2009,2018
# Hartmut Brandt
# All rights reserved.
# Copyright (c) 2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/snmp_mibII/Makefile.in 1492 2009-11-21 18:56:19Z brandt_h $
#
MOD= mibII
SRCS= ${MOD}_tree.c mibII.c mibII_begemot.c mibII_ifmib.c mibII_ifstack.c \
mibII_interfaces.c mibII_ip.c mibII_ipaddr.c mibII_nettomedia.c \
mibII_rcvaddr.c mibII_route.c mibII_tcp.c mibII_udp.c
INCS= snmp_${MOD}.h
DEFS= mibII_tree.def
MAN3= snmp_mibII.3
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${MIBSDIR}/%g'
XSYM= ipAddrTable ifTable ifRcvAddressEntry ifMIB ipMIB tcpMIB udpMIB \
ipForward ifIndex linkDown linkUp
BMIBS= BEGEMOT-IP-MIB.txt BEGEMOT-MIB2-MIB.txt
DEFS= mibII_tree.def
INCS= snmp_mibII.h
LIB= snmp_${MOD}.la
SHLIB_MAJOR= 3
SHLIB_MINOR= 0
CFLAGS+= -I$(srcdir) -I$(srcdir)/../lib -I$(builddir) -I$(srcdir)/../snmpd
CLEANFILES += ${MOD}_oid.h ${MOD}_tree.c ${MOD}_tree.h *.3out
# for bootstrapping
GENSNMPTREE= $(builddir)/../gensnmptree/gensnmptree -I${srcdir}/../lib
$(LIB): ${MOD}_oid.h ${MOD}_tree.h $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -module -o $@ $(SRCS:.c=.lo) -rpath $(libdir) -version-info $(SHLIB_MAJOR):$(SHLIB_MINOR)
${MOD}_oid.h: ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -e ${XSYM} >$@
${MOD}_tree.h ${MOD}_tree.c : ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -l -p ${MOD}_

View File

@ -411,7 +411,7 @@ mibif_reset_hc_timer(void)
hc_update_timer = NULL;
}
update_hc_counters(NULL);
if ((hc_update_timer = timer_start_repeat(ticks * 10, ticks * 10,
if ((hc_update_timer = timer_start_repeat(ticks, ticks,
update_hc_counters, NULL, module)) == NULL) {
syslog(LOG_ERR, "timer_start(%u): %m", ticks);
return;
@ -439,11 +439,15 @@ mibif_restart_mibII_poll_timer(void)
int
mib_fetch_ifmib(struct mibif *ifp)
{
static int kmib[2] = { -1, 0 }; /* for sysctl net.ifdescr_maxlen */
int name[6];
size_t kmiblen = nitems(kmib);
size_t len;
void *newmib;
struct ifmibdata oldmib = ifp->mib;
struct ifreq irr;
u_int alias_maxlen = MIBIF_ALIAS_SIZE_MAX;
if (fetch_generic_mib(ifp, &oldmib) == -1)
return (-1);
@ -515,18 +519,68 @@ mib_fetch_ifmib(struct mibif *ifp)
}
out:
/*
* Find sysctl mib for net.ifdescr_maxlen (one time).
* kmib[0] == -1 at first call to mib_fetch_ifmib().
* Then kmib[0] > 0 if we found sysctl mib for net.ifdescr_maxlen.
* Else, kmib[0] == 0 (unexpected error from a kernel).
*/
if (kmib[0] < 0 &&
sysctlnametomib("net.ifdescr_maxlen", kmib, &kmiblen) < 0) {
kmib[0] = 0;
syslog(LOG_WARNING, "sysctlnametomib net.ifdescr_maxlen: %m");
}
/*
* Fetch net.ifdescr_maxlen value every time to catch up with changes.
*/
len = sizeof(alias_maxlen);
if (kmib[0] > 0 && sysctl(kmib, 2, &alias_maxlen, &len, NULL, 0) < 0) {
/* unexpected error from the kernel, use default value */
alias_maxlen = MIBIF_ALIAS_SIZE_MAX;
syslog(LOG_WARNING, "sysctl net.ifdescr_maxlen: %m");
}
/*
* Kernel limit might be decreased after interfaces got
* their descriptions assigned. Try to obtain them anyway.
*/
if (alias_maxlen == 0)
alias_maxlen = MIBIF_ALIAS_SIZE_MAX;
/*
* Allocate maximum memory for a buffer and later reallocate
* to free extra memory.
*/
if ((ifp->alias = malloc(alias_maxlen)) == NULL) {
syslog(LOG_WARNING, "malloc(%d) failed: %m", (int)alias_maxlen);
goto fin;
}
strlcpy(irr.ifr_name, ifp->name, sizeof(irr.ifr_name));
irr.ifr_buffer.buffer = MIBIF_PRIV(ifp)->alias;
irr.ifr_buffer.length = sizeof(MIBIF_PRIV(ifp)->alias);
irr.ifr_buffer.buffer = ifp->alias;
irr.ifr_buffer.length = alias_maxlen;
if (ioctl(mib_netsock, SIOCGIFDESCR, &irr) == -1) {
MIBIF_PRIV(ifp)->alias[0] = 0;
free(ifp->alias);
ifp->alias = NULL;
if (errno != ENOMSG)
syslog(LOG_WARNING, "SIOCGIFDESCR (%s): %m", ifp->name);
} else if (irr.ifr_buffer.buffer == NULL) {
MIBIF_PRIV(ifp)->alias[0] = 0;
free(ifp->alias);
ifp->alias = NULL;
syslog(LOG_WARNING, "SIOCGIFDESCR (%s): too long (%zu)",
ifp->name, irr.ifr_buffer.length);
} else {
ifp->alias_size = strnlen(ifp->alias, alias_maxlen) + 1;
if (ifp->alias_size > MIBIF_ALIAS_SIZE)
ifp->alias_size = MIBIF_ALIAS_SIZE;
if (ifp->alias_size < alias_maxlen)
ifp->alias = realloc(ifp->alias, ifp->alias_size);
}
fin:
ifp->mibtick = get_ticks();
return (0);
}
@ -706,6 +760,10 @@ mibif_free(struct mibif *ifp)
mibif_reset_hc_timer();
}
if (ifp->alias != NULL) {
free(ifp->alias);
ifp->alias = NULL;
}
free(ifp->private);
ifp->private = NULL;
free(ifp->physaddr);
@ -1772,8 +1830,7 @@ mibII_loading(const struct lmodule *mod, int loaded)
mib_unregister_newif(mod);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
extern const struct snmp_module config;
const struct snmp_module config = {
"This module implements the interface and ip groups.",
mibII_init,
@ -1787,7 +1844,6 @@ const struct snmp_module config = {
mibII_CTREE_SIZE,
mibII_loading
};
#pragma GCC diagnostic push
/*
* Should have a list of these attached to each interface.

View File

@ -57,8 +57,9 @@
#include "snmp_mibII.h"
#include "mibII_tree.h"
/* maximum size of the interface alias */
/* maximum size of interface alias unless overridden with net.ifdescr_maxlen */
#define MIBIF_ALIAS_SIZE (64 + 1)
#define MIBIF_ALIAS_SIZE_MAX 1024
/*
* Interface list and flags.
@ -80,9 +81,6 @@ struct mibif_private {
uint64_t hc_opackets;
uint64_t hc_imcasts;
uint64_t hc_ipackets;
/* this should be made public */
char alias[MIBIF_ALIAS_SIZE];
};
#define MIBIF_PRIV(IFP) ((struct mibif_private *)((IFP)->private))

View File

@ -373,11 +373,6 @@ op_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
switch (op) {
again:
if (op != SNMP_OP_GETNEXT)
return (SNMP_ERR_NOSUCHNAME);
/* FALLTHROUGH */
case SNMP_OP_GETNEXT:
if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
return (SNMP_ERR_NOSUCHNAME);
@ -460,52 +455,36 @@ op_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
break;
case LEAF_ifHCInOctets:
if (!(ifp->flags & MIBIF_HIGHSPEED))
goto again;
value->v.counter64 = MIBIF_PRIV(ifp)->hc_inoctets;
break;
case LEAF_ifHCInUcastPkts:
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
goto again;
value->v.counter64 = MIBIF_PRIV(ifp)->hc_ipackets -
MIBIF_PRIV(ifp)->hc_imcasts;
break;
case LEAF_ifHCInMulticastPkts:
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
goto again;
value->v.counter64 = MIBIF_PRIV(ifp)->hc_imcasts;
break;
case LEAF_ifHCInBroadcastPkts:
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
goto again;
value->v.counter64 = 0;
break;
case LEAF_ifHCOutOctets:
if (!(ifp->flags & MIBIF_HIGHSPEED))
goto again;
value->v.counter64 = MIBIF_PRIV(ifp)->hc_outoctets;
break;
case LEAF_ifHCOutUcastPkts:
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
goto again;
value->v.counter64 = MIBIF_PRIV(ifp)->hc_opackets -
MIBIF_PRIV(ifp)->hc_omcasts;
break;
case LEAF_ifHCOutMulticastPkts:
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
goto again;
value->v.counter64 = MIBIF_PRIV(ifp)->hc_omcasts;
break;
case LEAF_ifHCOutBroadcastPkts:
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
goto again;
value->v.counter64 = 0;
break;
@ -528,7 +507,7 @@ op_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
break;
case LEAF_ifAlias:
ret = string_get(value, MIBIF_PRIV(ifp)->alias, -1);
ret = string_get(value, ifp->alias, ifp->alias_size - 1);
break;
case LEAF_ifCounterDiscontinuityTime:

View File

@ -80,6 +80,9 @@ struct mibif {
/* to be set by ifType specific modules. This is ifSpecific. */
struct asn_oid spec_oid;
char *alias;
size_t alias_size;
/* private data - don't touch */
void *private;
};

View File

@ -1,38 +0,0 @@
# Copyright (c) 2005
# Hartmut Brandt.
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/snmp_ntp/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
MOD= ntp
SRCS= ${MOD}_tree.c snmp_ntp.c
DEFS= ntp_tree.def
BMIBS= BEGEMOT-NTP-MIB.txt NTP-MIB.txt NTP-PROXY-MIB.txt
# MAN3= snmp_ntp.3
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${MIBSDIR}/%g'
XSYM= ntpMIB
LIB= snmp_${MOD}.la
SHLIB_MAJOR= 3
SHLIB_MINOR= 0
CFLAGS+= -I$(srcdir) -I$(srcdir)/../lib -I$(builddir) -I$(srcdir)/../snmpd
CLEANFILES += ${MOD}_oid.h ${MOD}_tree.c ${MOD}_tree.h
# for bootstrapping
GENSNMPTREE= $(builddir)/../gensnmptree/gensnmptree -I${srcdir}/../lib
$(LIB): ${MOD}_oid.h ${MOD}_tree.h $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -module -o $@ $(SRCS:.c=.lo) -rpath $(libdir) -version-info $(SHLIB_MAJOR):$(SHLIB_MINOR)
${MOD}_oid.h: ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -e ${XSYM} >$@
${MOD}_tree.h ${MOD}_tree.c : ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -l -p ${MOD}_

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005
* Copyright (c) 2005,2018
* Hartmut Brandt.
* All rights reserved.
*
@ -53,6 +53,8 @@
#include "support.h"
#include "snmpmod.h"
#define SNMPTREE_TYPES
#include "ntp_tree.h"
#include "ntp_oid.h"

View File

@ -1,38 +0,0 @@
# Copyright (c) 2018
# Hartmut Brandt.
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/snmp_ntp/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
MOD= target
SRCS= ${MOD}_tree.c target_snmp.c
DEFS= ${MOD}_tree.def
BMIBS=
MAN3= snmp_target.3
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${MIBSDIR}/%g'
XSYM= snmpTargetMIB snmpNotificationMIB snmpUDPDomain snmpNotifyType
LIB= snmp_${MOD}.la
SHLIB_MAJOR= 6
SHLIB_MINOR= 0
CFLAGS+= -I$(srcdir) -I$(srcdir)/../lib -I$(builddir) -I$(top_builddir) -I$(srcdir)/../snmpd
CLEANFILES += ${MOD}_oid.h ${MOD}_tree.c ${MOD}_tree.h *.3out
# for bootstrapping
GENSNMPTREE= $(builddir)/../gensnmptree/gensnmptree -I${srcdir}/../lib
$(LIB): ${MOD}_oid.h ${MOD}_tree.h $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -module -o $@ $(SRCS:.c=.lo) -rpath $(libdir) -version-info $(SHLIB_MAJOR):$(SHLIB_MINOR)
${MOD}_oid.h: ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -e ${XSYM} >$@
${MOD}_tree.h ${MOD}_tree.c : ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -l -p ${MOD}_

View File

@ -42,7 +42,6 @@
#include "asn1.h"
#include "snmp.h"
#include "snmpmod.h"
#include "lib/snmptc.h"
#define SNMPTREE_TYPES
#include "target_tree.h"
@ -828,9 +827,10 @@ target_dump(void)
/* XXX: dump the module stats & list of mgmt targets */
}
const char target_comment[] = \
static const char target_comment[] = \
"This module implements SNMP Management Target MIB Module defined in RFC 3413.";
extern const struct snmp_module config;
const struct snmp_module config = {
.comment = target_comment,
.init = target_init,

View File

@ -1,40 +0,0 @@
# Copyright (c) 2018
# Hartmut Brandt.
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/snmp_ntp/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
MOD= usm
SRCS= ${MOD}_tree.c usm_snmp.c
DEFS= ${MOD}_tree.def
BMIBS=
MAN3= snmp_usm.3
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${MIBSDIR}/%g'
XSYM= snmpUsmMIB usmNoAuthProtocol usmHMACMD5AuthProtocol \
usmHMACSHAAuthProtocol usmNoPrivProtocol usmDESPrivProtocol \
usmAesCfb128Protocol usmUserSecurityName
LIB= snmp_${MOD}.la
SHLIB_MAJOR= 6
SHLIB_MINOR= 0
CFLAGS+= -I$(srcdir) -I$(srcdir)/../lib -I$(builddir) -I$(top_builddir) -I$(srcdir)/../snmpd
CLEANFILES += ${MOD}_oid.h ${MOD}_tree.c ${MOD}_tree.h *.3out
# for bootstrapping
GENSNMPTREE= $(builddir)/../gensnmptree/gensnmptree -I${srcdir}/../lib
$(LIB): ${MOD}_oid.h ${MOD}_tree.h $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -module -o $@ $(SRCS:.c=.lo) -rpath $(libdir) -version-info $(SHLIB_MAJOR):$(SHLIB_MINOR)
${MOD}_oid.h: ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -e ${XSYM} >$@
${MOD}_tree.h ${MOD}_tree.c : ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -l -p ${MOD}_

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2010 The FreeBSD Foundation
* Copyright (c) 2010,2018 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Shteryana Sotirova Shopova under
@ -42,9 +42,8 @@
#include "asn1.h"
#include "snmp.h"
#include "snmpmod.h"
#include "lib/snmptc.h"
#define SNMP_TREETYPES
#define SNMPTREE_TYPES
#include "usm_tree.h"
#include "usm_oid.h"
@ -606,9 +605,10 @@ usm_dump(void)
privstr[uuser->suser.priv_proto]);
}
const char usm_comment[] = \
static const char usm_comment[] =
"This module implements SNMP User-based Security Model defined in RFC 3414.";
extern const struct snmp_module config;
const struct snmp_module config = {
.comment = usm_comment,
.init = usm_init,

View File

@ -1,38 +0,0 @@
# Copyright (c) 2018
# Hartmut Brandt.
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/snmp_ntp/Makefile.in 1487 2008-12-23 19:03:33Z brandt_h $
#
MOD= vacm
SRCS= ${MOD}_tree.c vacm_snmp.c
DEFS= ${MOD}_tree.def
BMIBS=
MAN3= snmp_vacm.3
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${MIBSDIR}/%g'
XSYM= snmpVacmMIB vacmAccessContextMatch
LIB= snmp_${MOD}.la
SHLIB_MAJOR= 6
SHLIB_MINOR= 0
CFLAGS+= -I$(srcdir) -I$(srcdir)/../lib -I$(builddir) -I$(top_builddir) -I$(srcdir)/../snmpd
CLEANFILES += ${MOD}_oid.h ${MOD}_tree.c ${MOD}_tree.h *.3out
# for bootstrapping
GENSNMPTREE= $(builddir)/../gensnmptree/gensnmptree -I${srcdir}/../lib
$(LIB): ${MOD}_oid.h ${MOD}_tree.h $(SRCS:.c=.lo)
$(LIBTOOL) --mode=link $(CC) $(LDLAGS) -module -o $@ $(SRCS:.c=.lo) -rpath $(libdir) -version-info $(SHLIB_MAJOR):$(SHLIB_MINOR)
${MOD}_oid.h: ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -e ${XSYM} >$@
${MOD}_tree.h ${MOD}_tree.c : ${MOD}_tree.def
${GENSNMPTREE} <${srcdir}/${MOD}_tree.def -l -p ${MOD}_

View File

@ -42,7 +42,6 @@
#include "asn1.h"
#include "snmp.h"
#include "snmpmod.h"
#include "lib/snmptc.h"
#define SNMPTREE_TYPES
#include "vacm_tree.h"
@ -1014,9 +1013,10 @@ vacm_dump(void)
"excluded":"included");
}
const char vacm_comment[] = \
static const char vacm_comment[] =
"This module implements SNMP View-based Access Control Model defined in RFC 3415.";
extern const struct snmp_module config;
const struct snmp_module config = {
.comment = vacm_comment,
.init = vacm_init,

View File

@ -3,6 +3,10 @@
-- Fraunhofer Institute for Open Communication Systems (FhG Fokus).
-- All rights reserved.
--
-- Copyright (c) 2018
-- Hartmut Brandt.
-- All rights reserved.
--
-- Author: Harti Brandt <harti@freebsd.org>
--
-- Redistribution and use in source and binary forms, with or without
@ -34,17 +38,17 @@ BEGEMOT-SNMPD-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, OBJECT-IDENTITY, Counter32,
Unsigned32, IpAddress
Integer32, Unsigned32, IpAddress
FROM SNMPv2-SMI
TEXTUAL-CONVENTION, TruthValue, RowStatus
FROM SNMPv2-TC
MODULE-COMPLIANCE, OBJECT-GROUP
FROM SNMPv2-CONF
InetAddressType, InetAddress, InetPortNumber
FROM INET-ADDRESS-MIB
begemot
FROM BEGEMOT-MIB;
begemotSnmpd MODULE-IDENTITY
LAST-UPDATED "201801190000Z"
LAST-UPDATED "201808080000Z"
ORGANIZATION "Fraunhofer FOKUS, CATS"
CONTACT-INFO
" Hartmut Brandt
@ -59,6 +63,9 @@ begemotSnmpd MODULE-IDENTITY
E-mail: harti@freebsd.org"
DESCRIPTION
"The MIB module for the Begemot SNMP daemon."
REVISION "201808080000Z"
DESCRIPTION
"Add the begemotSnmpdTransInetTable."
::= { begemot 1 }
begemotSnmpdObjects OBJECT IDENTIFIER ::= { begemotSnmpd 1 }
@ -93,7 +100,7 @@ begemotSnmpdAgentFreeBSD OBJECT-IDENTITY
begemotSnmpdConfig OBJECT IDENTIFIER ::= { begemotSnmpdObjects 1 }
begemotSnmpdTransmitBuffer OBJECT-TYPE
SYNTAX INTEGER (484..65535)
SYNTAX Integer32 (484..65535)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
@ -103,7 +110,7 @@ begemotSnmpdTransmitBuffer OBJECT-TYPE
::= { begemotSnmpdConfig 1 }
begemotSnmpdReceiveBuffer OBJECT-TYPE
SYNTAX INTEGER (484..65535)
SYNTAX Integer32 (484..65535)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
@ -181,7 +188,7 @@ begemotTrapSinkAddr OBJECT-TYPE
::= { begemotTrapSinkEntry 1 }
begemotTrapSinkPort OBJECT-TYPE
SYNTAX INTEGER (1..65535)
SYNTAX Integer32 (1..65535)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
@ -203,7 +210,7 @@ begemotTrapSinkStatus OBJECT-TYPE
begemotSnmpdPortTable OBJECT-TYPE
SYNTAX SEQUENCE OF BegemotSnmpdPortEntry
MAX-ACCESS not-accessible
STATUS current
STATUS deprecated
DESCRIPTION
"A table with descriptions of UDP ports to listen on
for SNMP messages."
@ -212,7 +219,7 @@ begemotSnmpdPortTable OBJECT-TYPE
begemotSnmpdPortEntry OBJECT-TYPE
SYNTAX BegemotSnmpdPortEntry
MAX-ACCESS not-accessible
STATUS current
STATUS deprecated
DESCRIPTION
"An entry in the table with descriptions of UDP ports to
listen on for SNMP messages."
@ -228,15 +235,15 @@ BegemotSnmpdPortEntry ::= SEQUENCE {
begemotSnmpdPortAddress OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS not-accessible
STATUS current
STATUS deprecated
DESCRIPTION
"The IP address to bind to."
::= { begemotSnmpdPortEntry 1 }
begemotSnmpdPortPort OBJECT-TYPE
SYNTAX INTEGER (1..65535)
SYNTAX Integer32 (1..65535)
MAX-ACCESS not-accessible
STATUS current
STATUS deprecated
DESCRIPTION
"The UDP port to listen on for SNMP messages."
::= { begemotSnmpdPortEntry 2 }
@ -244,7 +251,7 @@ begemotSnmpdPortPort OBJECT-TYPE
begemotSnmpdPortStatus OBJECT-TYPE
SYNTAX INTEGER { valid(1), invalid(2) }
MAX-ACCESS read-create
STATUS current
STATUS deprecated
DESCRIPTION
"Set status to 1 to create entry, set it to 2 to delete it."
::= { begemotSnmpdPortEntry 3 }
@ -275,7 +282,7 @@ BegemotSnmpdCommunityEntry ::= SEQUENCE {
begemotSnmpdCommunityIndex Unsigned32,
begemotSnmpdCommunityString OCTET STRING,
begemotSnmpdCommunityDescr OCTET STRING,
begemotSnmpdCommunityPermission INTEGER
begemotSnmpdCommunityPermission Unsigned32
}
begemotSnmpdCommunityModule OBJECT-TYPE
@ -312,7 +319,7 @@ begemotSnmpdCommunityDescr OBJECT-TYPE
::= { begemotSnmpdCommunityEntry 4 }
begemotSnmpdCommunityPermission OBJECT-TYPE
SYNTAX INTEGER (1..4294967295)
SYNTAX Unsigned32 (1..4294967295)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
@ -449,7 +456,7 @@ begemotSnmpdDebugSnmpTrace OBJECT-TYPE
::= { begemotSnmpdDebug 2 }
begemotSnmpdDebugSyslogPri OBJECT-TYPE
SYNTAX INTEGER (0..8)
SYNTAX Integer32 (0..8)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
@ -570,10 +577,115 @@ begemotSnmpdTransportOid OBJECT-TYPE
"A pointer to the group with the transport-dependend stuff."
::= { begemotSnmpdTransportEntry 3 }
-- ----------------------------------------------------------------------
--
-- Internet port table.
--
BegemotSnmpdTransportProto ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION
"A value that represents the type of protocol to be used for
listening on a socket. The following protocols are currently
used:
udp(1) Use UDP for IPv4 and IPv6 sockets."
SYNTAX INTEGER {
udp(1)
}
begemotSnmpdTransInetTable OBJECT-TYPE
SYNTAX SEQUENCE OF BegemotSnmpdTransInetEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"This table contains all the ports the daemon should listen on.
Entries can be created at initialization time via the config
file or at run time via a SET. One row can map to several open
sockets in the case of InetAddressType::dns rows. These rows
open one socket for each address returned by getaddrinfo(3).
for SNMP messages."
::= { begemotSnmpdObjects 11 }
begemotSnmpdTransInetEntry OBJECT-TYPE
SYNTAX BegemotSnmpdTransInetEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A row of the internet port table. Each row may map to one or
more listening sockets."
INDEX {
begemotSnmpdTransInetAddressType,
begemotSnmpdTransInetAddress,
begemotSnmpdTransInetPort,
begemotSnmpdTransInetProto
}
::= { begemotSnmpdTransInetTable 1 }
BegemotSnmpdTransInetEntry ::= SEQUENCE {
begemotSnmpdTransInetAddressType InetAddressType,
begemotSnmpdTransInetAddress InetAddress,
begemotSnmpdTransInetPort InetPortNumber,
begemotSnmpdTransInetProto BegemotSnmpdTransportProto,
begemotSnmpdTransInetStatus RowStatus
}
begemotSnmpdTransInetAddressType OBJECT-TYPE
SYNTAX InetAddressType
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The type of the address. Only ipv4, ipv6, ipv6z and dns are
supported."
::= { begemotSnmpdTransInetEntry 1 }
begemotSnmpdTransInetAddress OBJECT-TYPE
SYNTAX InetAddress (SIZE (0..64))
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The address. For ipv4 addresses the length must be 4, ipv6
addresses have a length of 16 and ipv6z addresses a length of
20 where the last four bytes are the interface index in big
endian format. dns addresses may be of zero-length in which case
getaddrinfo() generates INADDR_ANY and its IPv6 equivalent. dns
addresses will open a socket for all addresses returned by
getaddrinfo()."
::= { begemotSnmpdTransInetEntry 2 }
begemotSnmpdTransInetPort OBJECT-TYPE
SYNTAX InetPortNumber (1..65535)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The port to listen on for SNMP messages."
::= { begemotSnmpdTransInetEntry 3 }
begemotSnmpdTransInetProto OBJECT-TYPE
SYNTAX BegemotSnmpdTransportProto
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The protocol to use. Currently only the value udp(1) is supported."
::= { begemotSnmpdTransInetEntry 4 }
begemotSnmpdTransInetStatus OBJECT-TYPE
SYNTAX RowStatus
MAX-ACCESS read-create
STATUS current
DESCRIPTION
"The status of the conceptual row. A row may be created using
createAndGo(4) or createAndWait(5). An inactive row can be
activated writing active(1) and an active row can be inactivated
by writing notInService(2). Finally active or inactive rows can be
deleted by writing the value destroy(6). The value of this field
will never read as notReady(3)."
::= { begemotSnmpdTransInetEntry 5 }
--
-- XXX These should go into their own MIB
--
begemotSnmpdTransUdp OBJECT IDENTIFIER ::= { begemotSnmpdTransportMappings 2 }
begemotSnmpdTransLsock OBJECT IDENTIFIER ::= { begemotSnmpdTransportMappings 3 }
begemotSnmpdTransInet OBJECT IDENTIFIER ::= { begemotSnmpdTransportMappings 4 }
END

View File

@ -1,45 +0,0 @@
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# $Begemot: bsnmp/trunk/snmpd/Makefile.in 2117 2015-09-16 14:09:31Z brandt_h $
#
PROG= bsnmpd
SRCS= tree.c main.c action.c config.c export.c trap.c
SRCS+= trans_udp.c trans_lsock.c
MAN1= bsnmpd.1
MAN3= snmpmod.3
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${MIBSDIR}/%g'
XSYM= snmpMIB begemotSnmpdModuleTable begemotSnmpd begemotTrapSinkTable \
sysUpTime snmpTrapOID coldStart authenticationFailure \
begemotSnmpdLocalPortTable begemotSnmpdTransUdp begemotSnmpdTransLsock \
freeBSDVersion freeBSD
BMIBS= FOKUS-MIB.txt BEGEMOT-MIB.txt BEGEMOT-SNMPD.txt
DEFS= tree.def
INCS= snmpmod.h
CFLAGS+= -I$(builddir)/. -I${srcdir} -I${srcdir}/../lib
LDFLAGS+= $(LIBDL) -export-dynamic
$(PROG): $(SRCS:.c=.lo) oid.h tree.h
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(SRCS:.c=.lo) \
$(builddir)/../lib/libbsnmp.la $(LIBEV) $(LIBWRAP)
CLEANFILES += tree.c tree.h oid.h *.3out *.1out
GENSNMPTREE= $(builddir)/../gensnmptree/gensnmptree -I${srcdir}/../lib
tree.c tree.h: tree.def ../gensnmptree/gensnmptree
${GENSNMPTREE} -l <${srcdir}/tree.def
oid.h: tree.def ../gensnmptree/gensnmptree
${GENSNMPTREE} <${srcdir}/tree.def -e ${XSYM} >$@
$(SRCS:.c=.lo): oid.h

View File

@ -65,6 +65,8 @@
#include "tree.h"
#include "oid.h"
#include "trans_inet.h"
#define PATH_PID "/var/run/%s.pid"
#define PATH_CONFIG "/etc/%s.config"
#define PATH_ENGINE "/var/%s.engine"
@ -765,13 +767,13 @@ trans_insert_port(struct transport *t, struct tport *port)
{
struct tport *p;
port->transport = t;
TAILQ_FOREACH(p, &t->table, link) {
if (asn_compare_oid(&p->index, &port->index) > 0) {
TAILQ_INSERT_BEFORE(p, port, link);
return;
}
}
port->transport = t;
TAILQ_INSERT_TAIL(&t->table, port, link);
}
@ -1038,7 +1040,7 @@ snmpd_input(struct port_input *pi, struct tport *tport)
ssize_t ret, slen;
int32_t vi;
#ifdef USE_TCPWRAPPERS
char client[16];
char client[INET6_ADDRSTRLEN];
#endif
ret = tport->transport->vtab->recv(tport, pi);
@ -1184,8 +1186,12 @@ snmpd_input(struct port_input *pi, struct tport *tport)
sndbuf, &sndlen, "SNMP", ierr, vi, NULL);
if (ferr == SNMPD_INPUT_OK) {
slen = tport->transport->vtab->send(tport, sndbuf, sndlen,
pi->peer, pi->peerlen);
if (tport->transport->vtab->send != NULL)
slen = tport->transport->vtab->send(tport, sndbuf,
sndlen, pi->peer, pi->peerlen);
else
slen = tport->transport->vtab->send2(tport, sndbuf,
sndlen, pi);
if (slen == -1)
syslog(LOG_ERR, "send*: %m");
else if ((size_t)slen != sndlen)
@ -1201,7 +1207,8 @@ snmpd_input(struct port_input *pi, struct tport *tport)
}
/*
* Send a PDU to a given port
* Send a PDU to a given port. If this is a multi-socket port, use the
* first socket.
*/
void
snmp_send_port(void *targ, const struct asn_oid *port, struct snmp_pdu *pdu,
@ -1224,7 +1231,10 @@ snmp_send_port(void *targ, const struct asn_oid *port, struct snmp_pdu *pdu,
snmp_output(pdu, sndbuf, &sndlen, "SNMP PROXY");
len = trans->vtab->send(tp, sndbuf, sndlen, addr, addrlen);
if (trans->vtab->send != NULL)
len = trans->vtab->send(tp, sndbuf, sndlen, addr, addrlen);
else
len = trans->vtab->send2(tp, sndbuf, sndlen, NULL);
if (len == -1)
syslog(LOG_ERR, "sendto: %m");
@ -1238,16 +1248,37 @@ snmp_send_port(void *targ, const struct asn_oid *port, struct snmp_pdu *pdu,
/*
* Close an input source
*
* \param pi input instance
*/
void
snmpd_input_close(struct port_input *pi)
{
if (pi->id != NULL)
if (pi->id != NULL) {
fd_deselect(pi->id);
if (pi->fd >= 0)
pi->id = NULL;
}
if (pi->fd >= 0) {
(void)close(pi->fd);
if (pi->buf != NULL)
pi->fd = -1;
}
if (pi->buf != NULL) {
free(pi->buf);
pi->buf = NULL;
}
}
/*
* Initialize an input source.
*
* \param pi input instance
*/
void
snmpd_input_init(struct port_input *pi)
{
pi->id = NULL;
pi->fd = -1;
pi->buf = NULL;
}
/*
@ -1584,9 +1615,7 @@ main(int argc, char *argv[])
progargs = argv;
nprogargs = argc;
srandomdev();
snmp_serial_no = random();
snmp_serial_no = arc4random();
#ifdef USE_TCPWRAPPERS
/*
@ -1633,6 +1662,8 @@ main(int argc, char *argv[])
syslog(LOG_WARNING, "cannot start UDP transport");
if (lsock_trans.start() != SNMP_ERR_NOERROR)
syslog(LOG_WARNING, "cannot start LSOCK transport");
if (inet_trans.start() != SNMP_ERR_NOERROR)
syslog(LOG_WARNING, "cannot start INET transport");
#ifdef USE_LIBBEGEMOT
if (debug.evdebug > 0)

View File

@ -28,7 +28,7 @@
#
# $Begemot: bsnmp/snmpd/snmpd.config,v 1.16 2006/02/14 09:04:20 brandt_h Exp $
#
# Example configuration file.
# Example configuration file for testing.
#
#
@ -38,46 +38,80 @@ host := foo.bar.com
location := "Room 200"
contact := "sysmeister@bar.com"
system := 1 # FreeBSD
traphost := noc.bar.com
traphost := localhost
trapport := 162
read := "public"
# Uncomment the line below that sets the community string
# to enable write access.
write := "geheim"
write := "geheim" # take care - this allows writing
trap := "mytrap"
securityModelSNMPv1 := 1
securityModelSNMPv2c := 2
noAuthNoPriv := 1
#
# Configuration
#
%snmpd
begemotSnmpdDebugDumpPdus = 2
begemotSnmpdDebugSyslogPri = 7
begemotSnmpdDebugSnmpTrace = 0
#
# Set the read and write communities.
# Set community strings.
#
# The default value of the community strings is NULL (note, that this is
# different from the empty string). This disables both read and write access.
# To enable read access only the read community string must be set. Setting
# the write community string enables both read and write access with that
# string.
# Each community string has a permission attached to it - 1 for read only
# and 2 for read/write. Default is 1. Community strings must be unique.
#
# Be sure to understand the security implications of SNMPv2 - the community
# strings are readable on the wire!
#
begemotSnmpdCommunityString.0.1 = $(read)
# begemotSnmpdCommunityString.0.2 = $(write)
# begemotSnmpdCommunityString.0.3 = "otherPublic"
begemotSnmpdCommunityPermission.0.1 = 1
#begemotSnmpdCommunityString.0.2 = $(write)
#begemotSnmpdCommunityPermission.0.2 = 2
#begemotSnmpdCommunityString.0.3 = "otherPublic"
begemotSnmpdCommunityDisable = 1
# open standard SNMP ports
begemotSnmpdPortStatus.[$(host)].161 = 1
begemotSnmpdPortStatus.127.0.0.1.161 = 1
# 0.0.0.0:161
begemotSnmpdTransInetStatus.1.4.0.0.0.0.161.1 = 4
# test the port table; IPv4 address
# 127.0.0.1:10161
begemotSnmpdTransInetStatus.1.4.127.0.0.1.10161.1 = 4
# test the port table; IPv6 address
# ::1:10162
begemotSnmpdTransInetStatus.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.10162.1 = 4
# :::10163
begemotSnmpdTransInetStatus.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.10163.1 = 4
# fe80::1%1:10164 - requires inet fe80::1%em0/64
begemotSnmpdTransInetStatus.4.20.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.1.10164.1 = 4
# fe80::1%2:10164 - requires inet fe80::1%em1/64
begemotSnmpdTransInetStatus.4.20.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.2.10164.1 = 4
# fe80::1:10170 - should fail (no scope index)
# begemotSnmpdTransInetStatus.2.16.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.10170.1 = 4
# fe80::1%0:10170 - should fail (default scope index for link local address)
# begemotSnmpdTransInetStatus.4.20.254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.0.10170.1 = 4
# test the port table; DNS address
# :10165 UDPv4 and UDPv6
begemotSnmpdTransInetStatus.16.0.10165.1 = 4
# 127.0.0.1:10166
# ::1:10166
begemotSnmpdTransInetStatus.16."localhost".10166.1 = 4
# ::1:10167
begemotSnmpdTransInetStatus.16."localhost6".10167.1 = 4
# fe80::1%em0:10168 - requires inet fe80::$em0/64
begemotSnmpdTransInetStatus.16."fe80::1%em0".10168.1 = 4
# fe80::1%em1:10169 - requires inet fe80::$em1/64
begemotSnmpdTransInetStatus.16."fe80::1%em1".10169.1 = 4
# open a unix domain socket
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
# begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
# begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
# send traps to the traphost
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
@ -93,12 +127,57 @@ snmpEnableAuthenTraps = 2
#
# Load MIB-2 module
#
#begemotSnmpdModulePath."mibII" = "../snmp_mibII/.libs/snmp_mibII.so"
begemotSnmpdModulePath."mibII" = "/usr/local/lib/snmp_mibII.so"
#
# SNMPv3 notification targets
#
#begemotSnmpdModulePath."target" = "../snmp_target/.libs/snmp_target.so"
begemotSnmpdModulePath."target" = "/usr/local/lib/snmp_target.so"
#
# SNMPv3 user-based security module
#
#begemotSnmpdModulePath."usm" = "../snmp_usm/.libs/snmp_usm.so"
begemotSnmpdModulePath."usm" = "/usr/local/lib/snmp_usm.so"
#
# SNMPv3 view-based access control module
#
#begemotSnmpdModulePath."vacm" = "../snmp_vacm/.libs/snmp_vacm.so"
begemotSnmpdModulePath."vacm" = "/usr/local/lib/snmp_vacm.so"
#
# Netgraph module
#
begemotSnmpdModulePath."netgraph" = "/usr/local/lib/snmp_netgraph.so"
# begemotSnmpdModulePath."netgraph" = "/usr/local/lib/snmp_netgraph.so"
# %netgraph
# begemotNgControlNodeName = "snmpd"
%vacm
internetoid := 1.3.6.1
internetoidlen := 4
vacmSecurityToGroupStatus.$(securityModelSNMPv1).$(read) = 4
vacmGroupName.$(securityModelSNMPv1).$(read) = $(read)
vacmSecurityToGroupStatus.$(securityModelSNMPv2c).$(read) = 4
vacmGroupName.$(securityModelSNMPv2c).$(read) = $(read)
vacmSecurityToGroupStatus.$(securityModelSNMPv2c).$(write) = 4
vacmGroupName.$(securityModelSNMPv2c).$(write) = $(write)
vacmViewTreeFamilyStatus."internet".$(internetoidlen).$(internetoid) = 4
vacmAccessStatus.$(read)."".$(securityModelSNMPv1).$(noAuthNoPriv) = 4
vacmAccessReadViewName.$(read)."".$(securityModelSNMPv1).$(noAuthNoPriv) = "internet"
vacmAccessStatus.$(write)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = 4
vacmAccessStatus.$(read)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = 4
vacmAccessReadViewName.$(write)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet"
vacmAccessReadViewName.$(read)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet"
vacmAccessWriteViewName.$(write)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet"
vacmAccessWriteViewName.$(read)."".$(securityModelSNMPv2c).$(noAuthNoPriv) = "internet"
%netgraph
begemotNgControlNodeName = "snmpd"

View File

@ -174,7 +174,7 @@ TAILQ_HEAD(tport_list, tport);
int snmpd_input(struct port_input *, struct tport *);
void snmpd_input_close(struct port_input *);
void snmpd_input_init(struct port_input *);
/*
* Transport domain
@ -194,6 +194,10 @@ struct transport_def {
ssize_t (*send)(struct tport *, const u_char *, size_t,
const struct sockaddr *, size_t);
ssize_t (*recv)(struct tport *, struct port_input *);
/** send via a multi-socket port */
ssize_t (*send2)(struct tport *, const u_char *, size_t,
struct port_input *);
};
struct transport {
struct asn_oid index; /* transport table index */

View File

@ -56,6 +56,48 @@
* ordering can be done either on an integer/unsigned field, an asn_oid
* or an ordering function.
*/
/*
* First set of macros is used when the link is embedded into sub-struct
* and links these sub-structs. The sub-struct must be the first field.
*
* The list is a list of the subfield types.
*/
#define INSERT_OBJECT_OID_LINK_INDEX_TYPE(PTR, LIST, LINK, INDEX, SUBF) do {\
typedef __typeof ((PTR)->SUBF) _subf_type; \
_subf_type *_lelem; \
\
TAILQ_FOREACH(_lelem, (LIST), LINK) \
if (asn_compare_oid(&_lelem->INDEX, &(PTR)->SUBF.INDEX) > 0)\
break; \
if (_lelem == NULL) \
TAILQ_INSERT_TAIL((LIST), &(PTR)->SUBF, LINK); \
else \
TAILQ_INSERT_BEFORE(_lelem, &(PTR)->SUBF, LINK); \
} while (0)
#define NEXT_OBJECT_OID_LINK_INDEX_TYPE(LIST, OID, SUB, LINK, INDEX, TYPE) ({\
__typeof (TAILQ_FIRST((LIST))) _lelem; \
\
TAILQ_FOREACH(_lelem, (LIST), LINK) \
if (index_compare(OID, SUB, &_lelem->INDEX) < 0) \
break; \
(TYPE *)(_lelem); \
})
#define FIND_OBJECT_OID_LINK_INDEX_TYPE(LIST, OID, SUB, LINK, INDEX, TYPE) ({\
__typeof (TAILQ_FIRST((LIST))) _lelem; \
\
TAILQ_FOREACH(_lelem, (LIST), LINK) \
if (index_compare(OID, SUB, &_lelem->INDEX) == 0) \
break; \
(TYPE *)(_lelem); \
})
/*
* This set of macros allows specification of the link and index name.
* The index is an OID.
*/
#define INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \
__typeof (PTR) _lelem; \
\

1341
snmpd/trans_inet.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*-
* Copyright (c) 2018 The FreeBSD Foundation
* All rights reserved.
/*
* Copyright (c) 2018
* Hartmut Brandt.
* All rights reserved.
*
* Author: Harti Brandt <harti@freebsd.org>
*
@ -24,42 +25,14 @@
* 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.
*
* $Id$
*/
#ifndef snmptc_h_1529923773
#define snmptc_h_1529923773
#ifndef trans_inet_h_1530971397
#define trans_inet_h_1530971397
@tc@
/**
* Check whether a row status is ok.
*
* \param s row status
*
* \return true if value is ok, false otherwise
*/
static inline int
isok_RowStatus(enum RowStatus s)
{
return s >= RowStatus_active && s <= RowStatus_destroy;
}
/**
* Make string out of a row status.
*
* \param s row status
*
* \return string version; if the value is not a legal status
* return "RowStatus???"
*/
static inline const char *
tostr_RowStatus(enum RowStatus s)
{
static const char *vals[] = { STRING_RowStatus };
if (isok_RowStatus(s))
return vals[(int)s - STROFF_RowStatus];
return ("RowStatus???");
}
/* transport declaration */
extern const struct transport_def inet_trans;
#endif

View File

@ -70,7 +70,8 @@ const struct transport_def lsock_trans = {
lsock_close_port,
lsock_init_port,
lsock_send,
lsock_recv
lsock_recv,
NULL
};
static struct transport *my_trans;

View File

@ -67,7 +67,8 @@ const struct transport_def udp_trans = {
udp_close_port,
udp_init_port,
udp_send,
udp_recv
udp_recv,
NULL
};
static struct transport *my_trans;

View File

@ -53,8 +53,9 @@
#include <arpa/inet.h>
#include "snmpmod.h"
#include "../lib/snmptc.h"
#include "snmpd.h"
#define SNMPTREE_TYPES
#include "tree.h"
#include "oid.h"
@ -725,8 +726,7 @@ target_activate_address(struct target_address *addrs)
sa.sin_addr.s_addr = htonl((addrs->address[0] << 24) |
(addrs->address[1] << 16) | (addrs->address[2] << 8) |
(addrs->address[3] << 0));
sa.sin_port = htons(addrs->address[4]) << 8 |
htons(addrs->address[5]) << 0;
sa.sin_port = htons(addrs->address[4] << 8 | addrs->address[5]);
if (connect(addrs->socket, (struct sockaddr *)&sa, sa.sin_len) == -1) {
syslog(LOG_ERR, "connect(%s,%u): %m",

View File

@ -3,6 +3,10 @@
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Copyright (c) 2018
# Hartmut Brandt.
# All rights reserved.
#
# Author: Harti Brandt <harti@freebsd.org>
#
# Redistribution and use in source and binary forms, with or without
@ -33,6 +37,10 @@
include "tc.def"
typedef BegemotSnmpdTransportProto ENUM (
1 udp
)
(1 internet
(2 mgmt
(1 mibII
@ -172,13 +180,24 @@ include "tc.def"
))
(2 begemotSnmpdTransUdp OID op_transport_dummy)
(3 begemotSnmpdTransLsock OID op_transport_dummy)
(4 begemotSnmpdTransInet OID op_transport_dummy)
)
(11 begemotSnmpdTransInetTable
(1 begemotSnmpdTransInetEntry : INTEGER OCTETSTRING INTEGER INTEGER op_snmp_trans_inet
(1 begemotSnmpdTransInetAddressType InetAddressType)
(2 begemotSnmpdTransInetAddress OCTETSTRING)
(3 begemotSnmpdTransInetPort INTEGER)
(4 begemotSnmpdTransInetProto BegemotSnmpdTransportProto)
(5 begemotSnmpdTransInetStatus RowStatus GET SET)
))
)
(2 begemotSnmpdDefs
(1 begemotSnmpdAgent
(1 begemotSnmpdAgentFreeBSD OID op_dummy)
)
)
(3 begemotSnmpdCompliance)
)
))
)

1041
tests/asn1.cc Normal file

File diff suppressed because it is too large Load Diff

17597
tests/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

317
tests/constbuf.h Normal file
View File

@ -0,0 +1,317 @@
/**
* Copyright (c) 2019-2020 Hartmut Brandt.
*
* 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.
*/
#ifndef constbuf_h_1578777513
#define constbuf_h_1578777513
#include <array>
#include <cassert>
#include <cstdint>
#if !defined(HAVE_EXPR_IN_ARRAY_SIZE) && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>= 9 || (__GNUC__ == 9 && __GNUC_MINOR__ >= 1))))
#define HAVE_EXPR_IN_ARRAY_SIZE 1
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template"
#endif
#ifndef HAVE_EXPR_IN_ARRAY_SIZE
#include <vector>
#endif
namespace test {
namespace detail {
enum class Constbuf_mode {
BIN,
COMMENT,
HEX,
CHECK,
GOTO,
};
template<typename A>
constexpr bool
count_comment(A c, Constbuf_mode &mode)
{
if (c == '\n')
mode = Constbuf_mode::BIN;
return false;
}
template<typename A>
constexpr bool
count_hex(A c, Constbuf_mode &mode, std::size_t &bits)
{
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F')) {
if (bits % 4 != 0)
throw "unaligned hex digit";
bits += 4;
return false;
}
if (c == ':')
return false;
mode = Constbuf_mode::BIN;
return true;
}
template<typename A, typename U>
constexpr bool
handle_hex(A c, Constbuf_mode &mode, std::size_t &bit, U &n)
{
if (c >= '0' && c <= '9') {
n[bit / 8] |= ((c - '0') << 4) >> (bit % 8);
bit += 4;
return false;
}
if (c >= 'a' && c <= 'f') {
n[bit / 8] |= ((c - 'a' + 10) << 4) >> (bit % 8);
bit += 4;
return false;
}
if (c >= 'A' && c <= 'F') {
n[bit / 8] |= ((c - 'A' + 10) << 4) >> (bit % 8);
bit += 4;
return false;
}
if (c == ':')
return false;
mode = Constbuf_mode::BIN;
return true;
}
template<typename A>
constexpr bool
count_check(A c, Constbuf_mode &mode, std::size_t &)
{
if (c >= '0' && c <= '9')
return false;
mode = Constbuf_mode::BIN;
return true;
}
template<typename A>
constexpr bool
handle_check(A c, Constbuf_mode &mode, std::size_t &bits, std::size_t &addr)
{
if (c >= '0' && c <= '9') {
addr = 10 * addr + c - '0';
return false;
}
if (bits % 8 != 0 || bits / 8 != addr)
throw "address check failed";
mode = Constbuf_mode::BIN;
return true;
}
template<typename A>
constexpr bool
count_goto(A c, Constbuf_mode &mode, std::size_t &bits, std::size_t &addr)
{
if (c >= '0' && c <= '9') {
addr = 10 * addr + c - '0';
return false;
}
if (8 * addr < bits)
throw "cannot go backwards";
bits = 8 * addr;
mode = Constbuf_mode::BIN;
return true;
}
template<typename A>
constexpr bool
count_bin(A c, Constbuf_mode &mode, std::size_t &bits, std::size_t &addr)
{
if (c == ' ' || c == '\t' || c == '\n')
/* just ignore */
return false;
if (c == ';') {
mode = Constbuf_mode::COMMENT;
return false;
}
if (c == 'x' || c == 'X') {
mode = Constbuf_mode::HEX;
return false;
}
if (c == '!') {
mode = Constbuf_mode::CHECK;
return false;
}
if (c == '@') {
mode = Constbuf_mode::GOTO;
addr = 0;
return false;
}
if (c == '0' || c == '1' || c == '.') {
bits++;
return false;
}
throw "bad character";
}
template<typename A, typename U>
constexpr bool
handle_bin(A c, Constbuf_mode &mode, std::size_t &bit, std::size_t &addr, U &n)
{
if (c == ' ' || c == '\t' || c == '\n')
/* just ignore */
return false;
if (c == ';') {
mode = Constbuf_mode::COMMENT;
return false;
}
if (c == 'x' || c == 'X') {
mode = Constbuf_mode::HEX;
return false;
}
if (c == '!') {
mode = Constbuf_mode::CHECK;
addr = 0;
return false;
}
if (c == '@') {
mode = Constbuf_mode::GOTO;
addr = 0;
return false;
}
if (c == '0' || c == '.') {
bit++;
return false;
}
if (c == '1') {
n[bit / 8] |= 0x80 >> (bit % 8);
bit++;
return false;
}
throw "bad character";
}
/**
* Count the bits in the test buffer. For a syntax see below.
*
* \tparam A buffer base character type
* \tparam a characters
*
* \return number of bits required
*/
template<typename A, A ...a>
constexpr std::size_t
count_bits()
{
std::size_t bits {0};
std::size_t addr {0};
auto mode = Constbuf_mode::BIN;
for (auto c : {a...}) {
for (bool again = true; again; again = false) {
switch (mode) {
case Constbuf_mode::COMMENT:
again = count_comment(c, mode);
break;
case Constbuf_mode::CHECK:
again = count_check(c, mode, bits);
break;
case Constbuf_mode::GOTO:
again = count_goto(c, mode, bits, addr);
break;
case Constbuf_mode::HEX:
again = count_hex(c, mode, bits);
break;
case Constbuf_mode::BIN:
again = count_bin(c, mode, bits, addr);
break;
}
}
}
return bits;
}
}
template<typename A, A ...a>
#ifdef HAVE_EXPR_IN_ARRAY_SIZE
constexpr auto
#else
auto
#endif
constbuf()
{
#ifdef HAVE_EXPR_IN_ARRAY_SIZE
std::array<uint8_t, (detail::count_bits<A, a...>() + 7) / 8> n {};
#else
std::vector<uint8_t> n((detail::count_bits<A, a...>() + 7) / 8);
#endif
using namespace detail;
std::size_t bit {0};
std::size_t addr {0};
auto mode = Constbuf_mode::BIN;
for (auto c : {a...}) {
for (bool again = true; again; again = false) {
switch (mode) {
case Constbuf_mode::COMMENT:
again = count_comment(c, mode);
break;
case Constbuf_mode::CHECK:
again = handle_check(c, mode, bit, addr);
break;
case Constbuf_mode::GOTO:
again = count_goto(c, mode, bit, addr);
break;
case Constbuf_mode::HEX:
again = handle_hex(c, mode, bit, n);
break;
case Constbuf_mode::BIN:
again = handle_bin(c, mode, bit, addr, n);
break;
}
}
}
return n;
}
inline namespace literals {
inline namespace cbuf_literals {
#ifdef HAVE_EXPR_IN_ARRAY_SIZE
template<typename A, A ...a>
constexpr auto
#else
template<typename A, A ...a>
auto
#endif
operator ""_cbuf()
{
return test::constbuf<A, a...>();
}
} /* namespace cbuf_literals */
} /* namespace literals */
} /* namespace test */
#endif

2
tests/main.cc Normal file
View File

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

529
tests/snmp_parse_server.cc Normal file
View File

@ -0,0 +1,529 @@
#include <iostream>
#include <string>
extern "C" {
#include "asn1.h"
#include "snmp.h"
#include "snmpclient.h"
};
#include "catch.hpp"
using namespace std::string_literals;
static inline int
try_parse(struct snmp_client *sc, const char *str)
{
const int r = snmp_parse_server(sc, str);
if (false && r != 0)
std::cout << "snmp_parse_server: " << sc->error << "\n";
return r;
}
TEST_CASE("snmp_parse_server: empty string", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
REQUIRE(try_parse(&sc, "") == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == ""s);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
TEST_CASE("snmp_parse_server: hostname only", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("simple name without special characters") {
const auto str = "somehost"s;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == str);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("complex host name without special characters") {
const auto str = "some.host.domain"s;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == str);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("complex host name with special characters") {
const auto str = "some-mul.host-32.domain."s;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == str);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("relative path name") {
const auto str = "foo/bar"s;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_LOC_DGRAM);
REQUIRE(sc.chost == str);
REQUIRE(sc.cport == ""s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("absolute path name") {
const auto str = "/foo/bar"s;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_LOC_DGRAM);
REQUIRE(sc.chost == str);
REQUIRE(sc.cport == ""s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
}
TEST_CASE("snmp_parse_server: ipv6 address only", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("in6_addr_any") {
const auto host = "::"s;
const auto str = "[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("localhost") {
const auto host = "::1"s;
const auto str = "[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("link local address") {
const auto host = "fc00:0:12::1"s;
const auto str = "[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("illegal address (bad character)") {
const auto host = "fc00:0:1x::1"s;
const auto str = "[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == host + ": Name does not resolve");
}
SECTION("illegal address (two double colons)") {
const auto host = "fc00::0:12::1"s;
const auto str = "[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == host + ": Name does not resolve");
}
SECTION("illegal address (two many colons)") {
const auto host = "1:2:3:4:5:6:7:8:9"s;
const auto str = "[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == host + ": Name does not resolve");
}
SECTION("ipv6 address and junk") {
const auto host = "::"s;
const auto str = "[" + host + "]" + "xxx";
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == "junk at end of server specification 'xxx'"s);
}
}
TEST_CASE("snmp_parse_server: hostname and port", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("simple name and numeric port") {
const auto host = "somehost"s;
const auto port = "10007"s;
const auto str = host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("simple name and string port") {
const auto host = "somehost"s;
const auto port = "telnet"s;
const auto str = host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("name with embedded colon and numeric port") {
const auto host = "somehost:foo"s;
const auto port = "10007"s;
const auto str = host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("FQDN with embedded colon and numeric port") {
const auto host = "bla.blub:foo.baz."s;
const auto port = "10007"s;
const auto str = host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("simple name and empty port") {
const auto host = "somehost"s;
const auto port = ""s;
const auto str = host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == "empty port name"s);
}
}
TEST_CASE("snmp_parse_server: ipv6 and port", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("ANY address and numeric port") {
const auto host = "::"s;
const auto port = "10007"s;
const auto str = "[" + host + "]:" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("localhost address and string port") {
const auto host = "::1"s;
const auto port = "snmp"s;
const auto str = "[" + host + "]:" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("some address name and empty port") {
const auto host = "fc00:00:01::2:3"s;
const auto port = ""s;
const auto str = "[" + host + "]:" + port;
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == "empty port name"s);
}
}
TEST_CASE("snmp_parse_server: IPv4 address only", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("single octet address") {
const auto host = "127"s;
const auto str = host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("two octet address") {
const auto host = "127.1"s;
const auto str = host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("three octet address") {
const auto host = "127.23.1"s;
const auto str = host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("four octet address") {
const auto host = "127.18.23.1"s;
const auto str = host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("four octet octal address") {
const auto host = "0300.077.0377.01"s;
const auto str = host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("four octet hex address") {
const auto host = "x80.x12.xff.x1"s;
const auto str = host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
}
TEST_CASE("snmp_parse_server: transport and hostname", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("udp and host") {
const auto trans = "udp"s;
const auto host = "somehost"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("udp and ipv4 address") {
const auto trans = "udp"s;
const auto host = "240.0.1.2"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("udp6 and host") {
const auto trans = "udp6"s;
const auto host = "somehost"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("udp6 and ipv6 address") {
const auto trans = "udp6"s;
const auto host = "fec0:0:2::17"s;
const auto str = trans + "::[" + host + "]";
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("dgram and host") {
const auto trans = "dgram"s;
const auto host = "somehost"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_LOC_DGRAM);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == ""s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("stream and host") {
const auto trans = "stream"s;
const auto host = "somehost"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_LOC_STREAM);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == ""s);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("unknown transport and host") {
const auto trans = "foo"s;
const auto host = "somehost"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == "unknown transport specifier '" + trans + "'");
}
SECTION("empty transport and host") {
const auto trans = ""s;
const auto host = "somehost"s;
const auto str = trans + "::" + host;
REQUIRE(try_parse(&sc, str.c_str()) == -1);
REQUIRE(sc.error == "empty transport specifier"s);
}
}
TEST_CASE("snmp_parse_server: transport, host and port", "[snmp_parse_server]") {
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("udp, host and port") {
const auto trans = "udp"s;
const auto host = "somehost"s;
const auto port = "ssh"s;
const auto str = trans + "::" + host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("udp, host with colon and port") {
const auto trans = "udp"s;
const auto host = "somehost:foo"s;
const auto port = "ssh"s;
const auto str = trans + "::" + host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("udp and port") {
const auto trans = "udp"s;
const auto host = ""s;
const auto port = "ssh"s;
const auto str = trans + "::" + host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
SECTION("udp6, ipv6 and port") {
const auto trans = "udp6"s;
const auto host = "::1:2"s;
const auto port = "ssh"s;
const auto str = trans + "::[" + host + "]:" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == "public"s);
REQUIRE(sc.write_community == "private"s);
}
}
TEST_CASE("snmp_parse_server: community and host", "[snmp_parse_server]")
{
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("community and host") {
const auto comm = "public"s;
const auto host = "server.com"s;
const auto str = comm + "@" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == comm);
REQUIRE(sc.write_community == comm);
}
SECTION("community with @ and host") {
const auto comm = "public@bla"s;
const auto host = "server.com"s;
const auto str = comm + "@" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == comm);
REQUIRE(sc.write_community == comm);
}
SECTION("empty community and host") {
const auto comm = ""s;
const auto host = "server.com"s;
const auto str = comm + "@" + host;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == "snmp"s);
REQUIRE(sc.read_community == comm);
REQUIRE(sc.write_community == comm);
}
}
TEST_CASE("snmp_parse_server: transport, community, host and port", "[snmp_parse_server]")
{
struct snmp_client sc;
snmp_client_init(&sc);
SECTION("transport, community, host and numeric port") {
const auto trans = "udp6"s;
const auto comm = "public"s;
const auto host = "server.com"s;
const auto port = "65000"s;
const auto str = trans + "::" + comm + "@" + host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == comm);
REQUIRE(sc.write_community == comm);
}
SECTION("transport, community, ipv4 and symbolic port") {
const auto trans = "udp6"s;
const auto comm = "public"s;
const auto host = "127.1"s;
const auto port = "ftp"s;
const auto str = trans + "::" + comm + "@" + host + ":" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == comm);
REQUIRE(sc.write_community == comm);
}
SECTION("transport, community, ipv6 and symbolic port") {
const auto trans = "udp"s;
const auto comm = "public"s;
const auto host = "fe80::1:2"s;
const auto port = "ftp"s;
const auto str = trans + "::" + comm + "@[" + host + "]:" + port;
REQUIRE(try_parse(&sc, str.c_str()) == 0);
REQUIRE(sc.trans == SNMP_TRANS_UDP6);
REQUIRE(sc.chost == host);
REQUIRE(sc.cport == port);
REQUIRE(sc.read_community == comm);
REQUIRE(sc.write_community == comm);
}
}