summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-12-09 22:01:15 +0000
committerdim <dim@FreeBSD.org>2010-12-09 22:01:15 +0000
commita3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9 (patch)
tree5f0a24f71baa3176c75a20a51a9e20a22c75426c /usr.sbin
parentad01c620333d05c430d583ee40647e396be1ab91 (diff)
parent12dd9eb8e940c48f9fc30dbc137071b4fe5caead (diff)
downloadFreeBSD-src-a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9.zip
FreeBSD-src-a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9.tar.gz
Sync: merge r216133 through r216338 from ^/head.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile.amd643
-rw-r--r--usr.sbin/ac/ac.c2
-rw-r--r--usr.sbin/boot0cfg/boot0cfg.c2
-rw-r--r--usr.sbin/bsnmpd/Makefile3
-rw-r--r--usr.sbin/bsnmpd/bsnmpd/Makefile8
-rw-r--r--usr.sbin/bsnmpd/modules/Makefile2
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c1
-rwxr-xr-xusr.sbin/bsnmpd/modules/snmp_usm/Makefile22
-rwxr-xr-xusr.sbin/bsnmpd/modules/snmp_vacm/Makefile20
-rw-r--r--usr.sbin/bsnmpd/tools/Makefile7
-rw-r--r--usr.sbin/bsnmpd/tools/Makefile.inc13
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/Makefile28
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1401
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c1275
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/Makefile14
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c971
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c1018
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c1287
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h95
-rwxr-xr-xusr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c2121
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h331
-rw-r--r--usr.sbin/config/SMM.doc/0.t88
-rw-r--r--usr.sbin/config/SMM.doc/1.t61
-rw-r--r--usr.sbin/config/SMM.doc/2.t188
-rw-r--r--usr.sbin/config/SMM.doc/3.t299
-rw-r--r--usr.sbin/config/SMM.doc/4.t442
-rw-r--r--usr.sbin/config/SMM.doc/5.t271
-rw-r--r--usr.sbin/config/SMM.doc/6.t233
-rw-r--r--usr.sbin/config/SMM.doc/a.t162
-rw-r--r--usr.sbin/config/SMM.doc/b.t137
-rw-r--r--usr.sbin/config/SMM.doc/c.t109
-rw-r--r--usr.sbin/config/SMM.doc/d.t272
-rw-r--r--usr.sbin/config/SMM.doc/e.t114
-rw-r--r--usr.sbin/config/SMM.doc/spell.ok305
-rw-r--r--usr.sbin/cxgbtool/cxgbtool.c3
-rw-r--r--usr.sbin/extattrctl/extattrctl.c6
-rw-r--r--usr.sbin/fifolog/lib/fifolog_write.h6
-rw-r--r--usr.sbin/fifolog/lib/fifolog_write_poll.c290
-rw-r--r--usr.sbin/fwcontrol/fwcontrol.c1
-rw-r--r--usr.sbin/lpr/Makefile2
-rw-r--r--usr.sbin/lpr/SMM.doc/0.t68
-rw-r--r--usr.sbin/lpr/SMM.doc/1.t77
-rw-r--r--usr.sbin/lpr/SMM.doc/2.t141
-rw-r--r--usr.sbin/lpr/SMM.doc/3.t73
-rw-r--r--usr.sbin/lpr/SMM.doc/4.t206
-rw-r--r--usr.sbin/lpr/SMM.doc/5.t116
-rw-r--r--usr.sbin/lpr/SMM.doc/6.t94
-rw-r--r--usr.sbin/lpr/SMM.doc/7.t226
-rw-r--r--usr.sbin/lpr/SMM.doc/Makefile12
-rw-r--r--usr.sbin/lpr/SMM.doc/spell.ok70
-rw-r--r--usr.sbin/rarpd/rarpd.c4
-rw-r--r--usr.sbin/sysinstall/dist.c5
-rw-r--r--usr.sbin/sysinstall/install.c2
-rw-r--r--usr.sbin/timed/SMM.doc/timed/Makefile12
-rw-r--r--usr.sbin/timed/SMM.doc/timed/date53
-rw-r--r--usr.sbin/timed/SMM.doc/timed/loop54
-rw-r--r--usr.sbin/timed/SMM.doc/timed/spell.ok34
-rw-r--r--usr.sbin/timed/SMM.doc/timed/time53
-rw-r--r--usr.sbin/timed/SMM.doc/timed/timed.ms462
-rw-r--r--usr.sbin/timed/SMM.doc/timed/unused53
-rw-r--r--usr.sbin/timed/SMM.doc/timedop/Makefile8
-rw-r--r--usr.sbin/timed/SMM.doc/timedop/timed.ms279
-rw-r--r--usr.sbin/traceroute/Makefile2
-rw-r--r--usr.sbin/traceroute6/Makefile2
-rw-r--r--usr.sbin/traceroute6/traceroute6.c27
-rw-r--r--usr.sbin/usbdevs/Makefile7
-rw-r--r--usr.sbin/usbdevs/usbdevs.870
-rw-r--r--usr.sbin/usbdevs/usbdevs.c233
-rw-r--r--usr.sbin/usbdump/usbdump.c2
69 files changed, 7794 insertions, 5264 deletions
diff --git a/usr.sbin/Makefile.amd64 b/usr.sbin/Makefile.amd64
index 61f94c4..232831b 100644
--- a/usr.sbin/Makefile.amd64
+++ b/usr.sbin/Makefile.amd64
@@ -27,4 +27,7 @@ SUBDIR+= ndiscvt
.endif
SUBDIR+= sicontrol
SUBDIR+= spkrtest
+.if ${MK_SYSINSTALL} != "no"
+SUBDIR+= sade
+.endif
SUBDIR+= zzz
diff --git a/usr.sbin/ac/ac.c b/usr.sbin/ac/ac.c
index c584cd4..5dc8271 100644
--- a/usr.sbin/ac/ac.c
+++ b/usr.sbin/ac/ac.c
@@ -584,7 +584,7 @@ ac(const char *file)
if (!(Flags & AC_W))
usht.ut_tv.tv_sec = time(NULL);
else
- usht.ut_tv.tv_sec = ut_timecopy;;
+ usht.ut_tv.tv_sec = ut_timecopy;
usht.ut_type = SHUTDOWN_TIME;
if (Flags & AC_D) {
diff --git a/usr.sbin/boot0cfg/boot0cfg.c b/usr.sbin/boot0cfg/boot0cfg.c
index fe2c755..cd3bfe2 100644
--- a/usr.sbin/boot0cfg/boot0cfg.c
+++ b/usr.sbin/boot0cfg/boot0cfg.c
@@ -356,8 +356,6 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
if (n != mbr_size)
errx(1, "%s: short write", fname);
return;
- } else {
- err(1, "write_mbr: %s", fname);
}
/*
diff --git a/usr.sbin/bsnmpd/Makefile b/usr.sbin/bsnmpd/Makefile
index c948108..632753d 100644
--- a/usr.sbin/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/Makefile
@@ -2,6 +2,7 @@
SUBDIR= gensnmptree \
bsnmpd \
- modules
+ modules \
+ tools
.include <bsd.subdir.mk>
diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile b/usr.sbin/bsnmpd/bsnmpd/Makefile
index e74f675..f7e9b23 100644
--- a/usr.sbin/bsnmpd/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/bsnmpd/Makefile
@@ -2,6 +2,8 @@
#
# Author: Harti Brandt <harti@freebsd.org>
+.include <bsd.own.mk>
+
CONTRIB=${.CURDIR}/../../../contrib/bsnmp
.PATH: ${CONTRIB}/snmpd
@@ -11,7 +13,7 @@ SRCS+= oid.h tree.c tree.h
XSYM= snmpMIB begemotSnmpdModuleTable begemotSnmpd begemotTrapSinkTable \
sysUpTime snmpTrapOID coldStart authenticationFailure \
begemotSnmpdTransUdp begemotSnmpdTransLsock begemotSnmpdLocalPortTable \
- freeBSDVersion
+ freeBSD freeBSDVersion
CLEANFILES= oid.h tree.c tree.h
MAN= bsnmpd.1 snmpmod.3
NO_WERROR=
@@ -31,6 +33,10 @@ LDADD= -lbegemot -lbsnmp -lwrap
LDFLAGS= -export-dynamic
+.if ${MK_OPENSSL} != "no"
+CFLAGS+= -DHAVE_LIBCRYPTO
+.endif
+
oid.h: tree.def Makefile
gensnmptree -e ${XSYM} < ${.ALLSRC:M*.def} > ${.TARGET}
diff --git a/usr.sbin/bsnmpd/modules/Makefile b/usr.sbin/bsnmpd/modules/Makefile
index c2b7360..f7deb77 100644
--- a/usr.sbin/bsnmpd/modules/Makefile
+++ b/usr.sbin/bsnmpd/modules/Makefile
@@ -13,6 +13,8 @@ SUBDIR= ${_snmp_atm} \
snmp_hostres \
snmp_mibII \
snmp_pf \
+ snmp_usm \
+ snmp_vacm \
snmp_wlan
.if ${MK_NETGRAPH_SUPPORT} != "no"
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
index c7178f3..bc4bc35 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -26,6 +26,7 @@
* $FreeBSD$
*/
+#include <sys/queue.h>
#include <bsnmp/snmpmod.h>
#include <net/pfvar.h>
diff --git a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile
new file mode 100755
index 0000000..4ae818a
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+#
+# Author: Shteryana Shopova <syrinx@freebsd.org>
+
+CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp
+.PATH: ${CONTRIB}/snmp_usm
+
+MOD= usm
+SRCS= usm_snmp.c
+XSYM= snmpUsmMIB usmNoAuthProtocol usmHMACMD5AuthProtocol \
+ usmHMACSHAAuthProtocol usmNoPrivProtocol usmDESPrivProtocol \
+ usmAesCfb128Protocol usmUserSecurityName
+
+MAN= snmp_usm.3
+
+CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -DSNMPTREE_TYPES
+CFLAGS+= -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY -DHAVE_SYS_TREE_H
+
+DEFS= ${MOD}_tree.def
+BMIBS=
+
+.include <bsd.snmpmod.mk>
diff --git a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile
new file mode 100755
index 0000000..1be8d62
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile
@@ -0,0 +1,20 @@
+# $FreeBSD$
+#
+# Author: Shteryana Shopova <syrinx@freebsd.org>
+
+CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp
+.PATH: ${CONTRIB}/snmp_vacm
+
+MOD= vacm
+SRCS= vacm_snmp.c
+XSYM= snmpVacmMIB
+
+MAN= snmp_vacm.3
+
+CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -DSNMPTREE_TYPES
+CFLAGS+= -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY -DHAVE_SYS_TREE_H
+
+DEFS= ${MOD}_tree.def
+BMIBS=
+
+.include <bsd.snmpmod.mk>
diff --git a/usr.sbin/bsnmpd/tools/Makefile b/usr.sbin/bsnmpd/tools/Makefile
new file mode 100644
index 0000000..3ffc01e
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+# Author: Shteryana Shopova <syrinx@FreeBSD.org>
+
+SUBDIR= libbsnmptools \
+ bsnmptools
+
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/bsnmpd/tools/Makefile.inc b/usr.sbin/bsnmpd/tools/Makefile.inc
new file mode 100644
index 0000000..e08fe26
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/Makefile.inc
@@ -0,0 +1,13 @@
+# $FreeBSD$
+# Author: Shteryana Shopova <syrinx@FreeBSD.org>
+
+BINDIR?= /usr/bin
+
+CFLAGS+= -I. -I${.CURDIR}
+
+.if exists(${.OBJDIR}/../libbsnmptools)
+LIBBSNMPTOOLSDIR= ${.OBJDIR}/../libbsnmptools
+.else
+LIBBSNMPTOOLSDIR= ${.CURDIR}/../libbsnmptools
+.endif
+LIBBSNMPTOOLS= ${LIBBSNMPTOOLSDIR}/libbsnmptools.a
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile
new file mode 100644
index 0000000..94a1cea
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile
@@ -0,0 +1,28 @@
+# $FreeBSD$
+# Author: Shteryana Shopova <syrinx@FreeBSD.org>
+
+.include <bsd.own.mk>
+
+.PATH: ${.CURDIR}
+
+PROG= bsnmpget
+
+DPADD+= ${LIBBSNMP} ${LIBBSNMPTOOLS}
+LDADD+= -lbsnmp -lbsnmptools
+CFLAGS+= -I${.CURDIR}/../libbsnmptools
+LDFLAGS+= -L${LIBBSNMPTOOLSDIR}
+
+.if ${MK_OPENSSL} != "no"
+DPADD+= ${LIBCRYPTO}
+LDADD+= -lcrypto
+.endif
+
+LINKS= ${BINDIR}/bsnmpget ${BINDIR}/bsnmpwalk
+LINKS+= ${BINDIR}/bsnmpget ${BINDIR}/bsnmpset
+
+MAN= bsnmpget.1
+
+MLINKS= bsnmpget.1 bsnmpwalk.1
+MLINKS+= bsnmpget.1 bsnmpset.1
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1 b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
new file mode 100644
index 0000000..aa3f911
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
@@ -0,0 +1,401 @@
+.\"
+.\" Copyright (c) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" Portions of this documentation were written by Shteryana Sotirova Shopova
+.\" under sponsorship from the FreeBSD Foundation.
+.\"
+.\" Copyright (c) 2005-2007 The FreeBSD Project.
+.\" All rights reserved.
+.\"
+.\" Author: Shteryana Shopova <syrinx@FreeBSD.org>
+.\"
+.\" 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 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 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 17, 2007
+.Dt BSNMPGET 1
+.Os
+.Sh NAME
+.Nm bsnmpget ,
+.Nm bsnmpwalk ,
+.Nm bsnmpset
+.Nd "simple tools for querying SNMP agents"
+.Sh SYNOPSIS
+.Nm
+.Op Fl aDdehnK
+.Op Fl A Ar options
+.Op Fl b Ar buffersize
+.Op Fl C Ar options
+.Op Fl I Ar options
+.Op Fl i Ar filelist
+.Op Fl l Ar filename
+.Op Fl M Ar max-repetitions
+.Op Fl N Ar non-repeaters
+.Op Fl o Ar output
+.Op Fl P Ar options
+.Op Fl p Ar pdu
+.Op Fl r Ar retries
+.Op Fl s Ar [trans::][community@][server][:port]
+.Op Fl t Ar timeout
+.Op Fl U Ar options
+.Op Fl v Ar version
+.Op Ar OID ...
+.Pp
+.Nm bsnmpwalk
+.Op Fl dhnK
+.Op Fl A Ar options
+.Op Fl b Ar buffersize
+.Op Fl C Ar options
+.Op Fl I Ar options
+.Op Fl i Ar filelist
+.Op Fl l Ar filename
+.Op Fl o Ar output
+.Op Fl P Ar options
+.Op Fl r Ar retries
+.Op Fl s Ar [trans::][community@][server][:port]
+.Op Fl t Ar timeout
+.Op Fl U Ar options
+.Op Fl v Ar version
+.Op Ar OID ...
+.Pp
+.Nm bsnmpset
+.Op Fl adehnK
+.Op Fl A Ar options
+.Op Fl b Ar buffersize
+.Op Fl C Ar options
+.Op Fl I Ar options
+.Op Fl i Ar filelist
+.Op Fl l Ar filename
+.Op Fl o Ar output
+.Op Fl P Ar options
+.Op Fl r Ar retries
+.Op Fl s Ar [trans::][community@][server][:port]
+.Op Fl t Ar timeout
+.Op Fl U Ar options
+.Op Fl v Ar version
+.Ar OID Ns = Ar syntax Ns : Ns Ar value
+.Op Ar OID Ns = Ar syntax Ns : Ns Ar value ...
+.Sh DESCRIPTION
+.Nm ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+are simple tools for retrieving management information from and setting
+management information to a Simple Network Managment Protocol (SNMP) agent.
+.Pp
+Depending on the options
+.Nm bsnmpget
+constructs either a SMNP GetRequest, GetNextRequest
+or a GetBulkRequest packet, fills in the object identifiers (OIDs) of the
+objects whose values will be retrived, waits for a response and prints it if
+received successfully.
+.Pp
+.Nm Bsnmpwalk
+queries an agent with SMNP GetNextRequest packets,
+asking for values of OID instances that are a part of the object subtree
+rooted at the provided OIDs.
+.Pp
+.Nm Bsnmpset
+constructs a SMNP SetRequest packet, fills in the OIDs (object identifiers),
+syntaxes and values of the objects whose values are to be set and waits for a
+responce from server.
+.Sh OPTIONS
+.Pp
+The options are as follows (not all apply to all three programs):
+.Bl -tag -width ".It Fl D Ar options"
+.It Fl A Ar options
+Authentication options to use with SNMPv3 PDUs
+.Bl -tag -width
+.It Cm proto=[md5|sha]
+The protocol to use when calculating the PDU message digest.
+.It Cm key=authkey
+A binary localized authentication key to use when calculating the PDU message
+digest.
+.El
+.Pp
+By default SNMPv3 PDUs are sent unauthenticated.
+.It Fl a
+Skip any sanity checks when adding OIDs to a Protocol Data Unit (PDU):
+ingore syntax/access type, allow adding of non-leaf objects for GetPdu and
+read-only objects to a SetPDU.
+.It Fl b Ar buffersize
+Tune the size of buffers used to send and receive packets.
+The default size is 10000 bytes which should be enough unless an agent sends
+a really large octetstring.
+The maximum allowed length is 65535 according to the Structure of Management
+Information (SMIv2).
+.It Fl C Ar options
+The context to query with SNMPv3 PDUs.
+.Bl -tag -width
+.It Cm context=name
+The context name. Default is "" (empty).
+.It Cm context-engine=engine-id
+The SNMP Engine ID of the context to query with SNMPv3 PDUs, represented as
+binary octet string. By default, this is set to the Engine ID of the SNMP agent.
+.El
+.It Fl D
+Perform SNMP USM Engine Discovery, rather than sending a request for the value
+of a specific object.
+.It Fl d
+Turn on debugging.
+This option will cause the packets sent and received to be dumped to the
+terminal.
+.It Fl e
+Retry on error.
+If an error is returned in the response PDU, resend the request removing the
+variable that caused the error until a valid response is received.
+This is only usefull for a GetRequest- and a GetNextRequest-PDU.
+.It Fl h
+Print a short help text with default values for various options.
+.It Fl I Ar options
+Load each MIB description file from the given list to translate symbolic
+object names to their numerical representation and vice versa.
+Use the other options to obtain a non-default behaviour:
+.Bl -tag -width
+.It Cm cut=OID
+Specifies the initial OID that was cut by
+.Xr gensnmpdef 1
+when producing the MIB description file.
+The default value is .iso(1).org(3).dod(6) which is what should have been
+used for all the files installed under /usr/share/snmp/defs/ .
+Use this only if you generated your own files, providing a '-c' option to
+.Xr gensnmpdef 1 .
+.It Cm path=filedir
+The directory where files in the list will be searched.
+The default is
+.Pa /usr/share/snmp/defs/ .
+.It Cm file=filelist
+A comma separated list of files to which the two options above will apply.
+.El
+.Pp
+The file suboption has to come after the other suboptions so that their
+non-default values will be applied to the list of files.
+The order of the other suboptions before each file suboption can be random.
+Suboptions may be separated either by commas or by spaces.
+If using spaces make sure the entire option string is one argument, for
+example using quotes.
+.It Fl i Ar filelist
+List of MIB description files produced by
+.Xr gensnmpdef 1 which
+.Nm bsnmpget ,
+.Nm bsnmpwalk
+or
+.Nm bsnmpset
+will search to translate numerical OIDs to their symbolic object names.
+Multiple files can be provided either giving this option multiple times
+or a comma separated list of file names.
+If a filename begins with a letter the default directory,
+/usr/share/snmp/defs/ ,
+will be searched.
+.It Fl K
+Calculate and display the localized authentication and privacy keys
+corresponding to a plain text password. The password is obtain via the
+environment. Additionally, if one or more OIDs are specified, the calculated
+keys are used when processing the SNMPv3 requests.
+.It Fl l Ar filename
+The path of the posix local (unix domain) socket if local
+transport is used.
+.It Fl M Ar max-repetitions
+The value for the max-repetitions field in a GetBulk PDU.
+Default is 1.
+.It Fl N Ar non-repeaters
+The value for the non-repeaters field in a GetBulk PDU.
+Default is 0.
+.It Fl n
+Only use numerical representations for input and output OIDs and do not
+try to resolve symbolic object names.
+Note that
+.Nm bsnmpget ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+will print numerical OIDs anyway if the corresponding string representation
+is not found in the MIB description files.
+.It Fl o Ar [quiet|short|verbose]
+The format used to print the received response.
+Quiet only prints values, short (default) prints an abbreviated OID
+representation and the value.
+In addition to the short output verbose prints the type before the value.
+.It Fl P Ar options
+Privacy options to use with SNMPv3 PDUs
+.Bl -tag -width
+.It Cm proto=[aes|des]
+The protocol to use when encypting/decrypting SNMPv3 PDU data.
+.It Cm key=privkey
+A binary localized privacy key to use when encypting/decrypting SNMPv3 PDU data.
+.El
+.Pp
+By default plain text SNMPv3 PDUs are sent.
+.It Fl p Ar [get|getnext|getbulk]
+The PDU type to send by
+.Nm bsmpget .
+Default is get.
+.It Fl r Ar retries
+Number of resends of request packets before giving up if the agent does
+not respond after the first try.
+Default is 3.
+.It Fl s Ar [trans::] Ns Ar [community@] Ns Ar [server] Ns Ar [:port]
+Each of the server specification components is optional but at least one
+has to be provided if '-s' option is used.
+The server specification is constructed in the following manner:
+.Bl -tag -width
+.It Cm trans::
+Transport type may be one of udp, stream or dgram.
+If this option is not provided an udp inet/inet6 socket will be used, which
+is the most common.
+Stream stands for a posix local stream socket and a posix local datagram
+socket will be used if dgram is specified.
+.It Cm community@
+Specify an SNMP community string to be used when sending packets.
+If the option is skipped the default "public" will be used for
+.Nm
+and
+.Nm bsnmpwalk
+and the default "private" community string will be used for
+.Nm bsnmpset .
+.It Cm server
+This might be either the IP address or the hostname where the agent is
+listening.
+The default is 'localhost'.
+.It Cm port
+The destination port to send the requests to.
+This is useful if the SNMP agent listens on a non-default port.
+Default is given by the 'snmp' entry in /etc/services, port 161.
+.El
+.It Fl t Ar timeout
+Number of seconds before resending a request packet if the agent does
+not respond.
+The default value is 3 seconds.
+.It Fl U Ar options
+User credentials when sending SNMPv3 PDUs.
+.Bl -tag -width
+.It Cm engine=id
+The Engine ID of the SNMP agent represented as a binary octet string.
+.It Cm engine-boots=value
+The value of the snmpEngineBoots of the SNMP agent.
+.It Cm engine-time=value
+The value of the snmpEngineTime of the SNMP agent.
+.Pp
+If any of the above is not specified, SNMP USM Engine Discovery is attempted.
+This is also the default behavior.
+.It Cm name=username
+The USM user name to include in the SNMPv3 PDUs. By default, the user name is
+obtain via the environment
+.El
+.It Fl v Ar version
+The SNMP protocol version to use when sending requests. SNMP versions 1, 2 and
+3 are supported.
+If no version option is provided
+.Nm bsnmpget ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+will use version 2.
+Note that GetBulkRequest-PDUs were introduced in SNMPv2 thus setting the
+version to 1 is incompatiable with sending a GetBulk PDU.
+.It OID
+The object identifier whose value to retrive.
+At least one OID should be provided for
+.Nm bsnmpget
+to be able to send a request.
+.Pp
+For
+.Nm bsnmpwalk
+this is the root object identifier of the subtree whose values are to be
+retrived.
+If no OID is provided
+.Nm bsnmpwalk
+will walk the mib2 subtree rooted
+at .iso(1).org(3).dod(6).internet(1).mgmt(2).mib2(1) .
+.Pp
+Any of the formats used to print a single variable
+is valid as input OID:
+.Bl -tag -width
+.It 1.3.6.1.2.1.25.1.1.0
+.It sysDescr
+.It ifPhysAddress.1
+.It ifRcvAddressStatus.2.6.255.255.255.255.255.255
+.It ifRcvAddressType[2,ff:ff:ff:ff:ff:ff]
+.It ifRcvAddressStatus[Integer:1,OctetString:ff:ff:ff:ff:ff:ff]
+(requires '-o verbose' option)
+.El
+.Pp
+Square brackets are used to denote an entry's indexes.
+When used in an input OID, the square brackets may have to be
+escaped or the OID has to be quoted to protect it from the shell.
+Note there is no difference between ifName.1 and "ifName[1]".
+.It OID Ns = Ns Ar [syntax Ns :] Ns Ar value
+The object identifier with its syntax type and value that is to be set.
+At least one such string OID=[syntax:]value should be provided to
+.Nm bsnmpset
+to be able to send a request.
+.Bl -tag -width
+.It Cm OID
+OID may be input as a string, a string followed by a random number of integers
+(suboids) separated by dots, a sequence of integers separated by dots - that is
+if '-n' options is used - and in such case a syntax is required for every value,
+or a string followed by square brackets (used to denote an entry's indexes) and
+corresponding indexes.
+Any of formats used to print a single variable by
+.Nm bsnmpset is
+valid for inpit OID as well:
+.Bl -tag -width
+.It 1.3.6.1.2.1.25.1.1.0=TimeTicks:537615486
+.It sysLocation=OctetString:"@ Home" (with '-o verbose' option)
+.It sysLocation.0="@ Home"
+.It 1.3.6.1.2.1.2.2.1.6.1=OctetString:ffffffffffff
+.It ifPhysAddress.1="00:02:b3:1d:1c:a3"
+.It ifRcvAddressStatus.1.6.255.255.255.255.255.255=1
+.It "ifRcvAddressStatus[Integer:1,OctetString:ff:ff:ff:ff:ff:ff]=Integer:1"
+(with '-o verbose' option)
+.El
+.It Cm syntax
+where syntax string is one of :
+Integer, OctetString, OID, IpAddress, Counter32, Gauge, TimeTicks, Counter64.
+.It Cm value
+The value to be set - IP address in form of u.u.u.u - for example
+1.3.1.6.1.2.0=IpAddress:192.168.0.1, strings require inverted-commas if they
+contain any special characters or spaces, all other numeric types don't.
+.El
+.Sh ENVIRONMENT
+.Nm ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+use the following environment variables:
+.Bl -tag -width SNMPAUTH
+.It Ev SNMPAUTH
+Specifies a default SNMP USM authentication protocol.
+.It Ev SNMPPRIV
+Specifies a default SNMP USM privacy protocol.
+.It Ev SNMPUSER
+Specifies a default SNMP USM user name.
+.It Ev SNMPPASSWD
+Specifies the SNMP USM plain text password to use when calculating localized
+authentication and privacy keys. If this variable exists in the environment,
+SMNPv3 is the default version to use for outgoing requests.
+.Sh SEE ALSO
+.Xr gensnmpdef 1
+.Sh AUTHORS
+.An Shteryana Shopova Aq syrinx@FreeBSD.org
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
new file mode 100644
index 0000000..c05a05a
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
@@ -0,0 +1,1275 @@
+/*-
+ * Copyright (c) 2005-2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * Bsnmpget and bsnmpwalk are simple tools for querying SNMP agents,
+ * bsnmpset can be used to set MIB objects in an agent.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include <bsnmp/snmpclient.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+static const char *program_name = NULL;
+static enum program_e {
+ BSNMPGET,
+ BSNMPWALK,
+ BSNMPSET
+} program;
+
+/* *****************************************************************************
+ * Common bsnmptools functions.
+ */
+static void
+usage(void)
+{
+ fprintf(stderr,
+"Usage:\n"
+"%s %s [-A options] [-b buffersize] [-C options] [-I options]\n"
+"\t[-i filelist] [-l filename]%s [-o output] [-P options]\n"
+"\t%s[-r retries] [-s [trans::][community@][server][:port]]\n"
+"\t[-t timeout] [-U options] [-v version]%s\n",
+ program_name,
+ (program == BSNMPGET) ? "[-aDdehnK]" :
+ (program == BSNMPWALK) ? "[-dhnK]" :
+ (program == BSNMPSET) ? "[-adehnK]" :
+ "",
+ (program == BSNMPGET) ? " [-M max-repetitions] [-N non-repeaters]" : "",
+ (program == BSNMPGET) ? "[-p pdu] " : "",
+ (program == BSNMPGET) ? " OID [OID ...]" :
+ (program == BSNMPWALK || program == BSNMPSET) ? " [OID ...]" :
+ ""
+ );
+}
+
+static int32_t
+parse_max_repetitions(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ uint32_t v;
+
+ assert(opt_arg != NULL);
+
+ v = strtoul(opt_arg, (void *) NULL, 10);
+
+ if (v > SNMP_MAX_BINDINGS) {
+ warnx("Max repetitions value greater than %d maximum allowed.",
+ SNMP_MAX_BINDINGS);
+ return (-1);
+ }
+
+ SET_MAXREP(snmptoolctx, v);
+ return (2);
+}
+
+static int32_t
+parse_non_repeaters(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ uint32_t v;
+
+ assert(opt_arg != NULL);
+
+ v = strtoul(opt_arg, (void *) NULL, 10);
+
+ if (v > SNMP_MAX_BINDINGS) {
+ warnx("Non repeaters value greater than %d maximum allowed.",
+ SNMP_MAX_BINDINGS);
+ return (-1);
+ }
+
+ SET_NONREP(snmptoolctx, v);
+ return (2);
+}
+
+static int32_t
+parse_pdu_type(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (strcasecmp(opt_arg, "getbulk") == 0)
+ SET_PDUTYPE(snmptoolctx, SNMP_PDU_GETBULK);
+ else if (strcasecmp(opt_arg, "getnext") == 0)
+ SET_PDUTYPE(snmptoolctx, SNMP_PDU_GETNEXT);
+ else if (strcasecmp(opt_arg, "get") == 0)
+ SET_PDUTYPE(snmptoolctx, SNMP_PDU_GET);
+ else {
+ warnx("PDU type '%s' not supported.", opt_arg);
+ return (-1);
+ }
+
+ return (2);
+}
+
+static int32_t
+snmptool_parse_options(struct snmp_toolinfo *snmptoolctx, int argc, char **argv)
+{
+ int32_t count, optnum = 0;
+ int ch;
+ const char *opts;
+
+ switch (program) {
+ case BSNMPWALK:
+ opts = "dhnKA:b:C:I:i:l:o:P:r:s:t:U:v:";
+ break;
+ case BSNMPGET:
+ opts = "aDdehnKA:b:C:I:i:l:M:N:o:P:p:r:s:t:U:v:";
+ break;
+ case BSNMPSET:
+ opts = "adehnKA:b:C:I:i:l:o:P:r:s:t:U:v:";
+ break;
+ default:
+ return (-1);
+ }
+
+ while ((ch = getopt(argc, argv, opts)) != EOF) {
+ switch (ch) {
+ case 'A':
+ count = parse_authentication(snmptoolctx, optarg);
+ break;
+ case 'a':
+ count = parse_skip_access(snmptoolctx);
+ break;
+ case 'b':
+ count = parse_buflen(optarg);
+ break;
+ case 'D':
+ count = parse_discovery(snmptoolctx);
+ break;
+ case 'd':
+ count = parse_debug();
+ break;
+ case 'e':
+ count = parse_errors(snmptoolctx);
+ break;
+ case 'h':
+ usage();
+ return (-2);
+ case 'C':
+ count = parse_context(snmptoolctx, optarg);
+ break;
+ case 'I':
+ count = parse_include(snmptoolctx, optarg);
+ break;
+ case 'i':
+ count = parse_file(snmptoolctx, optarg);
+ break;
+ case 'K':
+ count = parse_local_key(snmptoolctx);
+ break;
+ case 'l':
+ count = parse_local_path(optarg);
+ break;
+ case 'M':
+ count = parse_max_repetitions(snmptoolctx, optarg);
+ break;
+ case 'N':
+ count = parse_non_repeaters(snmptoolctx, optarg);
+ break;
+ case 'n':
+ count = parse_num_oids(snmptoolctx);
+ break;
+ case 'o':
+ count = parse_output(snmptoolctx, optarg);
+ break;
+ case 'P':
+ count = parse_privacy(snmptoolctx, optarg);
+ break;
+ case 'p':
+ count = parse_pdu_type(snmptoolctx, optarg);
+ break;
+ case 'r':
+ count = parse_retry(optarg);
+ break;
+ case 's':
+ count = parse_server(optarg);
+ break;
+ case 't':
+ count = parse_timeout(optarg);
+ break;
+ case 'U':
+ count = parse_user_security(snmptoolctx, optarg);
+ break;
+ case 'v':
+ count = parse_version(optarg);
+ break;
+ case '?':
+ default:
+ usage();
+ return (-1);
+ }
+ if (count < 0)
+ return (-1);
+ optnum += count;
+ }
+
+ return (optnum);
+}
+
+/*
+ * Read user input OID - one of following formats:
+ * 1) 1.2.1.1.2.1.0 - that is if option numeric was giveni;
+ * 2) string - in such case append .0 to the asn_oid subs;
+ * 3) string.1 - no additional proccessing required in such case.
+ */
+static char *
+snmptools_parse_stroid(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ char string[MAXSTR], *str;
+ int32_t i = 0;
+ struct asn_oid in_oid;
+
+ str = argv;
+
+ if (*str == '.')
+ str++;
+
+ while (isalpha(*str) || *str == '_' || (i != 0 && isdigit(*str))) {
+ str++;
+ i++;
+ }
+
+ if (i <= 0 || i >= MAXSTR)
+ return (NULL);
+
+ memset(&in_oid, 0, sizeof(struct asn_oid));
+ if ((str = snmp_parse_suboid((argv + i), &in_oid)) == NULL) {
+ warnx("Invalid OID - %s", argv);
+ return (NULL);
+ }
+
+ strlcpy(string, argv, i + 1);
+ if (snmp_lookup_oidall(snmptoolctx, obj, string) < 0) {
+ warnx("No entry for %s in mapping lists", string);
+ return (NULL);
+ }
+
+ /* If OID given on command line append it. */
+ if (in_oid.len > 0)
+ asn_append_oid(&(obj->val.var), &in_oid);
+ else if (*str == '[') {
+ if ((str = snmp_parse_index(snmptoolctx, str + 1, obj)) == NULL)
+ return (NULL);
+ } else if (obj->val.syntax > 0 && GET_PDUTYPE(snmptoolctx) ==
+ SNMP_PDU_GET) {
+ if (snmp_suboid_append(&(obj->val.var), (asn_subid_t) 0) < 0)
+ return (NULL);
+ }
+
+ return (str);
+}
+
+static int32_t
+snmptools_parse_oid(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ if (argv == NULL)
+ return (-1);
+
+ if (ISSET_NUMERIC(snmptoolctx)) {
+ if (snmp_parse_numoid(argv, &(obj->val.var)) < 0)
+ return (-1);
+ } else {
+ if (snmptools_parse_stroid(snmptoolctx, obj, argv) == NULL &&
+ snmp_parse_numoid(argv, &(obj->val.var)) < 0)
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+snmptool_add_vbind(struct snmp_pdu *pdu, struct snmp_object *obj)
+{
+ if (obj->error > 0)
+ return (0);
+
+ asn_append_oid(&(pdu->bindings[pdu->nbindings].var), &(obj->val.var));
+ pdu->nbindings++;
+
+ return (pdu->nbindings);
+}
+
+/* *****************************************************************************
+ * bsnmpget private functions.
+ */
+static int32_t
+snmpget_verify_vbind(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu,
+ struct snmp_object *obj)
+{
+ if (pdu->version == SNMP_V1 && obj->val.syntax ==
+ SNMP_SYNTAX_COUNTER64) {
+ warnx("64-bit counters are not supported in SNMPv1 PDU");
+ return (-1);
+ }
+
+ if (ISSET_NUMERIC(snmptoolctx) || pdu->type == SNMP_PDU_GETNEXT ||
+ pdu->type == SNMP_PDU_GETBULK)
+ return (1);
+
+ if (pdu->type == SNMP_PDU_GET && obj->val.syntax == SNMP_SYNTAX_NULL) {
+ warnx("Only leaf object values can be added to GET PDU");
+ return (-1);
+ }
+
+ return (1);
+}
+
+/*
+ * In case of a getbulk PDU, the error_status and error_index fields are used by
+ * libbsnmp to hold the values of the non-repeaters and max-repetitions fields
+ * that are present only in the getbulk - so before sending the PDU make sure
+ * these have correct values as well.
+ */
+static void
+snmpget_fix_getbulk(struct snmp_pdu *pdu, uint32_t max_rep, uint32_t non_rep)
+{
+ assert(pdu != NULL);
+
+ if (pdu->nbindings < non_rep)
+ pdu->error_status = pdu->nbindings;
+ else
+ pdu->error_status = non_rep;
+
+ if (max_rep > 0)
+ pdu->error_index = max_rep;
+ else
+ pdu->error_index = 1;
+}
+
+static int
+snmptool_get(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_pdu req, resp;
+
+ snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx));
+
+ while ((snmp_pdu_add_bindings(snmptoolctx, snmpget_verify_vbind,
+ snmptool_add_vbind, &req, SNMP_MAX_BINDINGS)) > 0) {
+
+ if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK)
+ snmpget_fix_getbulk(&req, GET_MAXREP(snmptoolctx),
+ GET_NONREP(snmptoolctx));
+
+ if (snmp_dialog(&req, &resp) == -1) {
+ warnx("Snmp dialog - %s", strerror(errno));
+ break;
+ }
+
+ if (snmp_parse_resp(&resp, &req) >= 0) {
+ snmp_output_resp(snmptoolctx, &resp);
+ break;
+ }
+
+ snmp_output_err_resp(snmptoolctx, &resp);
+ if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK ||
+ !ISSET_RETRY(snmptoolctx))
+ break;
+
+ /*
+ * Loop through the object list and set object->error to the
+ * varbinding that caused the error.
+ */
+ if (snmp_object_seterror(snmptoolctx,
+ &(resp.bindings[resp.error_index - 1]),
+ resp.error_status) <= 0)
+ break;
+
+ fprintf(stderr, "Retrying...\n");
+ snmp_pdu_free(&resp);
+ snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx));
+ }
+
+ snmp_pdu_free(&resp);
+
+ return (0);
+}
+
+
+/* *****************************************************************************
+ * bsnmpwalk private functions.
+ */
+/* The default tree to walk. */
+static const struct asn_oid snmp_mibII_OID = {
+ 6 , { 1, 3, 6, 1, 2, 1 }
+};
+
+static int32_t
+snmpwalk_add_default(struct snmp_toolinfo *snmptoolctx __unused,
+ struct snmp_object *obj, char *string __unused)
+{
+ asn_append_oid(&(obj->val.var), &snmp_mibII_OID);
+ return (1);
+}
+
+/*
+ * Prepare the next GetNext/Get PDU to send.
+ */
+static void
+snmpwalk_nextpdu_create(uint32_t op, struct asn_oid *var, struct snmp_pdu *pdu)
+{
+ snmp_pdu_create(pdu, op);
+ asn_append_oid(&(pdu->bindings[0].var), var);
+ pdu->nbindings = 1;
+}
+
+static int
+snmptool_walk(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_pdu req, resp;
+ struct asn_oid root; /* Keep the inital oid. */
+ int32_t outputs, rc;
+
+ snmp_pdu_create(&req, SNMP_PDU_GETNEXT);
+
+ while ((rc = snmp_pdu_add_bindings(snmptoolctx, NULL,
+ snmptool_add_vbind, &req, 1)) > 0) {
+
+ /* Remember the root where the walk started from. */
+ memset(&root, 0, sizeof(struct asn_oid));
+ asn_append_oid(&root, &(req.bindings[0].var));
+
+ outputs = 0;
+ while (snmp_dialog(&req, &resp) >= 0) {
+ if ((snmp_parse_resp(&resp, &req)) < 0) {
+ snmp_output_err_resp(snmptoolctx, &resp);
+ snmp_pdu_free(&resp);
+ outputs = -1;
+ break;
+ }
+
+ if (!(asn_is_suboid(&root, &(resp.bindings[0].var)))) {
+ snmp_pdu_free(&resp);
+ break;
+ }
+
+ if (snmp_output_resp(snmptoolctx, &resp)!= 0) {
+ snmp_pdu_free(&resp);
+ outputs = -1;
+ break;
+ }
+ outputs++;
+ snmp_pdu_free(&resp);
+
+ snmpwalk_nextpdu_create(SNMP_PDU_GETNEXT,
+ &(resp.bindings[0].var), &req);
+ }
+
+ /* Just in case our root was a leaf. */
+ if (outputs == 0) {
+ snmpwalk_nextpdu_create(SNMP_PDU_GET, &root, &req);
+ if (snmp_dialog(&req, &resp) == SNMP_CODE_OK) {
+ if (snmp_parse_resp(&resp,&req) < 0)
+ snmp_output_err_resp(snmptoolctx, &resp);
+ else
+ snmp_output_resp(snmptoolctx, &(resp));
+
+ snmp_pdu_free(&resp);
+ } else
+ warnx("Snmp dialog - %s", strerror(errno));
+ }
+
+ if (snmp_object_remove(snmptoolctx, &root) < 0) {
+ warnx("snmp_object_remove");
+ break;
+ }
+
+ snmp_pdu_create(&req, SNMP_PDU_GETNEXT);
+ }
+
+ if (rc == 0)
+ return (0);
+ else
+ return (1);
+}
+
+/* *****************************************************************************
+ * bsnmpset private functions.
+ */
+
+static int32_t
+parse_oid_numeric(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ int32_t saved_errno;
+ asn_subid_t suboid;
+
+ do {
+ saved_errno = errno;
+ errno = 0;
+ suboid = strtoul(val, &endptr, 10);
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val,
+ strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+ errno = saved_errno;
+ if ((asn_subid_t) suboid > ASN_MAXID) {
+ warnx("Suboid %u > ASN_MAXID", suboid);
+ return (-1);
+ }
+ if (snmp_suboid_append(&(value->v.oid), suboid) < 0)
+ return (-1);
+ val = endptr + 1;
+ } while (*endptr == '.');
+
+ if (*endptr != '\0')
+ warnx("OID value %s not supported", val);
+
+ value->syntax = SNMP_SYNTAX_OID;
+ return (0);
+}
+
+/*
+ * Allow OID leaf in both forms:
+ * 1) 1.3.6.1.2... -> in such case call directly the function reading raw OIDs;
+ * 2) begemotSnmpdAgentFreeBSD -> lookup the ASN OID corresponding to that.
+ */
+static int32_t
+parse_oid_string(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_value *value, char *string)
+{
+ struct snmp_object obj;
+
+ if (isdigit(string[0]))
+ return (parse_oid_numeric(value, string));
+
+ memset(&obj, 0, sizeof(struct snmp_object));
+ if (snmp_lookup_enumoid(snmptoolctx, &obj, string) < 0) {
+ warnx("Unknown OID enum string - %s", string);
+ return (-1);
+ }
+
+ asn_append_oid(&(value->v.oid), &(obj.val.var));
+ return (1);
+}
+
+static int32_t
+parse_ip(struct snmp_value * value, char * val)
+{
+ uint32_t v;
+ int32_t i;
+ char *endptr, *str;
+
+ str = val;
+ for (i = 0; i < 4; i++) {
+ v = strtoul(str, &endptr, 10);
+ if (v > 0xff)
+ return (-1);
+ if (*endptr != '.' && *endptr != '\0' && i != 3)
+ break;
+ str = endptr + 1;
+ value->v.ipaddress[i] = (uint8_t) v;
+ }
+
+ value->syntax = SNMP_SYNTAX_IPADDRESS;
+ return (0);
+}
+
+static int32_t
+parse_int(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ int32_t v, saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtol(val, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ value->syntax = SNMP_SYNTAX_INTEGER;
+ value->v.integer = v;
+ errno = saved_errno;
+
+ return (0);
+}
+
+static int32_t
+parse_int_string(struct snmp_object *object, char *val)
+{
+ int32_t v;
+
+ if (isdigit(val[0]))
+ return ((parse_int(&(object->val), val)));
+
+ if (object->info == NULL) {
+ warnx("Unknown enumerated integer type - %s", val);
+ return (-1);
+ }
+ if ((v = enum_number_lookup(object->info->snmp_enum, val)) < 0)
+ warnx("Unknown enumerated integer type - %s", val);
+
+ object->val.v.integer = v;
+ return (1);
+}
+
+/*
+ * Here syntax may be one of SNMP_SYNTAX_COUNTER, SNMP_SYNTAX_GAUGE,
+ * SNMP_SYNTAX_TIMETICKS.
+ */
+static int32_t
+parse_uint(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ uint32_t v = 0;
+ int32_t saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(val, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ value->v.uint32 = v;
+ errno = saved_errno;
+
+ return (0);
+}
+
+static int32_t
+parse_ticks(struct snmp_value *value, char *val)
+{
+ if (parse_uint(value, val) < 0)
+ return (-1);
+
+ value->syntax = SNMP_SYNTAX_TIMETICKS;
+ return (0);
+}
+
+static int32_t
+parse_gauge(struct snmp_value *value, char *val)
+{
+ if (parse_uint(value, val) < 0)
+ return (-1);
+
+ value->syntax = SNMP_SYNTAX_GAUGE;
+ return (0);
+}
+
+static int32_t
+parse_counter(struct snmp_value *value, char *val)
+{
+ if (parse_uint(value, val) < 0)
+ return (-1);
+
+ value->syntax = SNMP_SYNTAX_COUNTER;
+ return (0);
+}
+
+static int32_t
+parse_uint64(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ int32_t saved_errno;
+ uint64_t v;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(val, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ value->syntax = SNMP_SYNTAX_COUNTER64;
+ value->v.counter64 = v;
+ errno = saved_errno;
+
+ return (0);
+}
+
+static int32_t
+parse_syntax_val(struct snmp_value *value, enum snmp_syntax syntax, char *val)
+{
+ switch (syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (parse_int(value, val));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (parse_ip(value, val));
+ case SNMP_SYNTAX_COUNTER:
+ return (parse_counter(value, val));
+ case SNMP_SYNTAX_GAUGE:
+ return (parse_gauge(value, val));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (parse_ticks(value, val));
+ case SNMP_SYNTAX_COUNTER64:
+ return (parse_uint64(value, val));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_tc2oct(SNMP_STRING, value, val));
+ case SNMP_SYNTAX_OID:
+ return (parse_oid_numeric(value, val));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (-1);
+}
+
+/*
+ * Parse a command line argument of type OID=syntax:value and fill in whatever
+ * fields can be derived from the input into snmp_value structure. Reads numeric
+ * OIDs.
+ */
+static int32_t
+parse_pair_numoid_val(char *str, struct snmp_value *snmp_val)
+{
+ int32_t cnt;
+ char *ptr;
+ enum snmp_syntax syntax;
+ char oid_str[ASN_OIDSTRLEN];
+
+ ptr = str;
+ for (cnt = 0; cnt < ASN_OIDSTRLEN; cnt++)
+ if (ptr[cnt] == '=')
+ break;
+
+ if (cnt >= ASN_OIDSTRLEN) {
+ warnx("OID too long - %s", str);
+ return (-1);
+ }
+ strlcpy(oid_str, ptr, (size_t) (cnt + 1));
+
+ ptr = str + cnt + 1;
+ for (cnt = 0; cnt < MAX_CMD_SYNTAX_LEN; cnt++)
+ if(ptr[cnt] == ':')
+ break;
+
+ if (cnt >= MAX_CMD_SYNTAX_LEN) {
+ warnx("Unknown syntax in OID - %s", str);
+ return (-1);
+ }
+
+ if ((syntax = parse_syntax(ptr)) <= SNMP_SYNTAX_NULL) {
+ warnx("Unknown syntax in OID - %s", ptr);
+ return (-1);
+ }
+
+ ptr = ptr + cnt + 1;
+ for (cnt = 0; cnt < MAX_OCTSTRING_LEN; cnt++)
+ if (ptr[cnt] == '\0')
+ break;
+
+ if (ptr[cnt] != '\0') {
+ warnx("Value string too long - %s",ptr);
+ return (-1);
+ }
+
+ /*
+ * Here try parsing the OIDs and syntaxes and then check values - have
+ * to know syntax to check value boundaries.
+ */
+ if (snmp_parse_numoid(oid_str, &(snmp_val->var)) < 0) {
+ warnx("Error parsing OID %s",oid_str);
+ return (-1);
+ }
+
+ if (parse_syntax_val(snmp_val, syntax, ptr) < 0)
+ return (-1);
+
+ return (1);
+}
+
+/* XXX-BZ aruments should be swapped. */
+static int32_t
+parse_syntax_strval(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct snmp_object *object)
+{
+ uint32_t len;
+ enum snmp_syntax syn;
+
+ /*
+ * Syntax string here not required - still may be present.
+ */
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) {
+ for (len = 0 ; *(str + len) != ':'; len++) {
+ if (*(str + len) == '\0') {
+ warnx("Syntax missing in value - %s", str);
+ return (-1);
+ }
+ }
+ if ((syn = parse_syntax(str)) <= SNMP_SYNTAX_NULL) {
+ warnx("Unknown syntax in - %s", str);
+ return (-1);
+ }
+ if (syn != object->val.syntax) {
+ if (!ISSET_ERRIGNORE(snmptoolctx)) {
+ warnx("Bad syntax in - %s", str);
+ return (-1);
+ } else
+ object->val.syntax = syn;
+ }
+ len++;
+ } else
+ len = 0;
+
+ switch (object->val.syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (parse_int_string(object, str + len));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (parse_ip(&(object->val), str + len));
+ case SNMP_SYNTAX_COUNTER:
+ return (parse_counter(&(object->val), str + len));
+ case SNMP_SYNTAX_GAUGE:
+ return (parse_gauge(&(object->val), str + len));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (parse_ticks(&(object->val), str + len));
+ case SNMP_SYNTAX_COUNTER64:
+ return (parse_uint64(&(object->val), str + len));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_tc2oct(object->info->tc, &(object->val),
+ str + len));
+ case SNMP_SYNTAX_OID:
+ return (parse_oid_string(snmptoolctx, &(object->val),
+ str + len));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (-1);
+}
+
+static int32_t
+parse_pair_stroid_val(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ char *ptr;
+
+ if ((ptr = snmptools_parse_stroid(snmptoolctx, obj, argv)) == NULL)
+ return (-1);
+
+ if (*ptr != '=') {
+ warnx("Value to set expected after OID");
+ return (-1);
+ }
+
+ if (parse_syntax_strval(snmptoolctx, ptr + 1, obj) < 0)
+ return (-1);
+
+ return (1);
+}
+
+
+static int32_t
+snmpset_parse_oid(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ if (argv == NULL)
+ return (-1);
+
+ if (ISSET_NUMERIC(snmptoolctx)) {
+ if (parse_pair_numoid_val(argv, &(obj->val)) < 0)
+ return (-1);
+ } else {
+ if (parse_pair_stroid_val(snmptoolctx, obj, argv) < 0)
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+add_ip_syntax(struct snmp_value *dst, struct snmp_value *src)
+{
+ int8_t i;
+
+ dst->syntax = SNMP_SYNTAX_IPADDRESS;
+ for (i = 0; i < 4; i++)
+ dst->v.ipaddress[i] = src->v.ipaddress[i];
+
+ return (1);
+}
+
+static int32_t
+add_octstring_syntax(struct snmp_value *dst, struct snmp_value *src)
+{
+ if (src->v.octetstring.len > ASN_MAXOCTETSTRING) {
+ warnx("OctetString len too big - %u",src->v.octetstring.len);
+ return (-1);
+ }
+
+ if ((dst->v.octetstring.octets = malloc(src->v.octetstring.len)) ==
+ NULL) {
+ syslog(LOG_ERR, "malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+
+ memcpy(dst->v.octetstring.octets, src->v.octetstring.octets,
+ src->v.octetstring.len);
+ dst->syntax = SNMP_SYNTAX_OCTETSTRING;
+ dst->v.octetstring.len = src->v.octetstring.len;
+
+ return(0);
+}
+
+static int32_t
+add_oid_syntax(struct snmp_value *dst, struct snmp_value *src)
+{
+ asn_append_oid(&(dst->v.oid), &(src->v.oid));
+ dst->syntax = SNMP_SYNTAX_OID;
+ return (0);
+}
+
+/*
+ * Check syntax - if one of SNMP_SYNTAX_NULL, SNMP_SYNTAX_NOSUCHOBJECT,
+ * SNMP_SYNTAX_NOSUCHINSTANCE, SNMP_SYNTAX_ENDOFMIBVIEW or anything not known -
+ * return error.
+ */
+static int32_t
+snmpset_add_value(struct snmp_value *dst, struct snmp_value *src)
+{
+ if (dst == NULL || src == NULL)
+ return (-1);
+
+ switch (src->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ dst->v.integer = src->v.integer;
+ dst->syntax = SNMP_SYNTAX_INTEGER;
+ break;
+ case SNMP_SYNTAX_TIMETICKS:
+ dst->v.uint32 = src->v.uint32;
+ dst->syntax = SNMP_SYNTAX_TIMETICKS;
+ break;
+ case SNMP_SYNTAX_GAUGE:
+ dst->v.uint32 = src->v.uint32;
+ dst->syntax = SNMP_SYNTAX_GAUGE;
+ break;
+ case SNMP_SYNTAX_COUNTER:
+ dst->v.uint32 = src->v.uint32;
+ dst->syntax = SNMP_SYNTAX_COUNTER;
+ break;
+ case SNMP_SYNTAX_COUNTER64:
+ dst->v.counter64 = src->v.counter64;
+ dst->syntax = SNMP_SYNTAX_COUNTER64;
+ break;
+ case SNMP_SYNTAX_IPADDRESS:
+ add_ip_syntax(dst, src);
+ break;
+ case SNMP_SYNTAX_OCTETSTRING:
+ add_octstring_syntax(dst, src);
+ break;
+ case SNMP_SYNTAX_OID:
+ add_oid_syntax(dst, src);
+ break;
+ default:
+ warnx("Unknown syntax %d", src->syntax);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int32_t
+snmpset_verify_vbind(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu,
+ struct snmp_object *obj)
+{
+ if (pdu->version == SNMP_V1 && obj->val.syntax ==
+ SNMP_SYNTAX_COUNTER64) {
+ warnx("64-bit counters are not supported in SNMPv1 PDU");
+ return (-1);
+ }
+
+ if (ISSET_NUMERIC(snmptoolctx) || ISSET_ERRIGNORE(snmptoolctx))
+ return (1);
+
+ if (obj->info->access < SNMP_ACCESS_SET) {
+ warnx("Object %s not accessible for set - try 'bsnmpset -a'",
+ obj->info->string);
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+snmpset_add_vbind(struct snmp_pdu *pdu, struct snmp_object *obj)
+{
+ if (pdu->nbindings > SNMP_MAX_BINDINGS) {
+ warnx("Too many OIDs for one PDU");
+ return (-1);
+ }
+
+ if (obj->error > 0)
+ return (0);
+
+ if (snmpset_add_value(&(pdu->bindings[pdu->nbindings]), &(obj->val))
+ < 0)
+ return (-1);
+
+ asn_append_oid(&(pdu->bindings[pdu->nbindings].var), &(obj->val.var));
+ pdu->nbindings++;
+
+ return (pdu->nbindings);
+}
+
+static int
+snmptool_set(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_pdu req, resp;
+
+ snmp_pdu_create(&req, SNMP_PDU_SET);
+
+ while ((snmp_pdu_add_bindings(snmptoolctx, snmpset_verify_vbind,
+ snmpset_add_vbind, &req, SNMP_MAX_BINDINGS)) > 0) {
+ if (snmp_dialog(&req, &resp)) {
+ warnx("Snmp dialog - %s", strerror(errno));
+ break;
+ }
+
+ if (snmp_pdu_check(&req, &resp) > 0) {
+ if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET)
+ snmp_output_resp(snmptoolctx, &resp);
+ break;
+ }
+
+ snmp_output_err_resp(snmptoolctx, &resp);
+ if (!ISSET_RETRY(snmptoolctx))
+ break;
+
+ if (snmp_object_seterror(snmptoolctx,
+ &(resp.bindings[resp.error_index - 1]),
+ resp.error_status) <= 0)
+ break;
+
+ fprintf(stderr, "Retrying...\n");
+ snmp_pdu_free(&req);
+ snmp_pdu_free(&resp);
+ snmp_pdu_create(&req, SNMP_PDU_SET);
+ }
+
+ snmp_pdu_free(&resp);
+
+ return (0);
+}
+
+/* *****************************************************************************
+ * main
+ */
+/*
+ * According to command line options prepare SNMP Get | GetNext | GetBulk PDU.
+ * Wait for a responce and print it.
+ */
+/*
+ * Do a 'snmp walk' - according to command line options request for values
+ * lexicographically subsequent and subrooted at a common node. Send a GetNext
+ * PDU requesting the value for each next variable and print the responce. Stop
+ * when a Responce PDU is received that contains the value of a variable not
+ * subrooted at the variable the walk started.
+ */
+int
+main(int argc, char ** argv)
+{
+ struct snmp_toolinfo snmptoolctx;
+ int32_t oid_cnt, last_oid, opt_num;
+ int rc = 0;
+
+ /* Make sure program_name is set and valid. */
+ if (*argv == NULL)
+ program_name = "snmptool";
+ else {
+ program_name = strrchr(*argv, '/');
+ if (program_name != NULL)
+ program_name++;
+ else
+ program_name = *argv;
+ }
+
+ if (program_name == NULL) {
+ fprintf(stderr, "Error: No program name?\n");
+ exit (1);
+ } else if (strcmp(program_name, "bsnmpget") == 0)
+ program = BSNMPGET;
+ else if (strcmp(program_name, "bsnmpwalk") == 0)
+ program = BSNMPWALK;
+ else if (strcmp(program_name, "bsnmpset") == 0)
+ program = BSNMPSET;
+ else {
+ fprintf(stderr, "Unknown snmp tool name '%s'.\n", program_name);
+ exit (1);
+ }
+
+ /* Initialize. */
+ if (snmptool_init(&snmptoolctx) < 0)
+ exit (1);
+
+ if ((opt_num = snmptool_parse_options(&snmptoolctx, argc, argv)) < 0) {
+ snmp_tool_freeall(&snmptoolctx);
+ /* On -h (help) exit without error. */
+ if (opt_num == -2)
+ exit(0);
+ else
+ exit(1);
+ }
+
+ oid_cnt = argc - opt_num - 1;
+ if (oid_cnt == 0) {
+ switch (program) {
+ case BSNMPGET:
+ if (!ISSET_EDISCOVER(&snmptoolctx) &&
+ !ISSET_LOCALKEY(&snmptoolctx)) {
+ fprintf(stderr, "No OID given.\n");
+ usage();
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ break;
+
+ case BSNMPWALK:
+ if (snmp_object_add(&snmptoolctx, snmpwalk_add_default,
+ NULL) < 0) {
+ fprintf(stderr,
+ "Error setting default subtree.\n");
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ break;
+
+ case BSNMPSET:
+ fprintf(stderr, "No OID given.\n");
+ usage();
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ }
+
+ if (snmp_import_all(&snmptoolctx) < 0) {
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+
+ /* A simple sanity check - can not send GETBULK when using SNMPv1. */
+ if (program == BSNMPGET && snmp_client.version == SNMP_V1 &&
+ GET_PDUTYPE(&snmptoolctx) == SNMP_PDU_GETBULK) {
+ fprintf(stderr, "Cannot send GETBULK PDU with SNMPv1.\n");
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+
+ for (last_oid = argc - 1; oid_cnt > 0; last_oid--, oid_cnt--) {
+ if ((snmp_object_add(&snmptoolctx, (program == BSNMPSET) ?
+ snmpset_parse_oid : snmptools_parse_oid,
+ argv[last_oid])) < 0) {
+ fprintf(stderr, "Error parsing OID string '%s'.\n",
+ argv[last_oid]);
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ }
+
+ if (snmp_open(NULL, NULL, NULL, NULL)) {
+ warnx("Failed to open snmp session: %s.", strerror(errno));
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+
+ if (snmp_client.version == SNMP_V3 && snmp_client.engine.engine_len == 0)
+ SET_EDISCOVER(&snmptoolctx);
+
+ if (ISSET_EDISCOVER(&snmptoolctx) &&
+ snmp_discover_engine(snmptoolctx.passwd) < 0) {
+ warnx("Unknown SNMP Engine ID: %s.", strerror(errno));
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (GET_OUTPUT(&snmptoolctx) == OUTPUT_VERBOSE ||
+ ISSET_EDISCOVER(&snmptoolctx))
+ snmp_output_engine();
+
+ if (snmp_client.version == SNMP_V3 && ISSET_LOCALKEY(&snmptoolctx) &&
+ !ISSET_EDISCOVER(&snmptoolctx)) {
+ if (snmp_passwd_to_keys(&snmp_client.user,
+ snmptoolctx.passwd) != SNMP_CODE_OK ||
+ snmp_get_local_keys(&snmp_client.user,
+ snmp_client.engine.engine_id,
+ snmp_client.engine.engine_len) != SNMP_CODE_OK) {
+ warnx("Failed to get keys: %s.", strerror(errno));
+ rc = 1;
+ goto cleanup;
+ }
+ }
+
+ if (GET_OUTPUT(&snmptoolctx) == OUTPUT_VERBOSE ||
+ ISSET_EDISCOVER(&snmptoolctx))
+ snmp_output_keys();
+
+ if (ISSET_EDISCOVER(&snmptoolctx) && snmptoolctx.objects == 0)
+ goto cleanup;
+
+ switch (program) {
+ case BSNMPGET:
+ rc = snmptool_get(&snmptoolctx);
+ break;
+ case BSNMPWALK:
+ rc = snmptool_walk(&snmptoolctx);
+ break;
+ case BSNMPSET:
+ rc = snmptool_set(&snmptoolctx);
+ break;
+ }
+
+
+cleanup:
+ snmp_tool_freeall(&snmptoolctx);
+ snmp_close();
+
+ exit(rc);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile b/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile
new file mode 100644
index 0000000..f2b71b6
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile
@@ -0,0 +1,14 @@
+#
+# $FreeBSD$
+#
+
+.PATH: ${.CURDIR}
+
+LIB= bsnmptools
+#INTERNALLIB=
+SRCS= bsnmpimport.c bsnmpmap.c bsnmptools.c bsnmptc.c
+CFLAGS+= -g -Wall -Werror
+
+SHLIB_MAJOR= 0
+
+.include <bsd.lib.mk>
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c
new file mode 100644
index 0000000..b92532f
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c
@@ -0,0 +1,971 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Read file containing table description - reuse magic from gensnmptree.c.
+ * Hopefully one day most of the code here will be part of libbsnmp and
+ * this duplication won't be necessary.
+ *
+ * Syntax is:
+ * ---------
+ * file := top | top file
+ *
+ * top := tree | typedef | include
+ *
+ * tree := head elements ')'
+ *
+ * entry := head ':' index STRING elements ')'
+ *
+ * leaf := head type STRING ACCESS ')'
+ *
+ * column := head type ACCESS ')'
+ *
+ * type := BASETYPE | BASETYPE '|' subtype | enum | bits
+ *
+ * subtype := STRING
+ *
+ * enum := ENUM '(' value ')'
+ *
+ * bits := BITS '(' value ')'
+ *
+ * value := INT STRING | INT STRING value
+ *
+ * head := '(' INT STRING
+ *
+ * elements := EMPTY | elements element
+ *
+ * element := tree | leaf | column
+ *
+ * index := type | index type
+ *
+ * typedef := 'typedef' STRING type
+ *
+ * include := 'include' filespec
+ *
+ * filespec := '"' STRING '"' | '<' STRING '>'
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include <bsnmp/snmpagent.h> /* SNMP_INDEXES_MAX */
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+enum snmp_tbl_entry {
+ ENTRY_NONE = 0,
+ ENTRY_INDEX,
+ ENTRY_DATA
+};
+
+enum {
+ FL_GET = 0x01,
+ FL_SET = 0x02,
+};
+
+/************************************************************
+ *
+ * Allocate memory and panic just in the case...
+ */
+static void *
+xalloc(size_t size)
+{
+ void *ptr;
+
+ if ((ptr = malloc(size)) == NULL)
+ err(1, "allocing %zu bytes", size);
+
+ return (ptr);
+}
+
+static char *
+savestr(const char *s)
+{
+ if (s == NULL)
+ return (NULL);
+
+ return (strcpy(xalloc(strlen(s) + 1), s));
+}
+
+/************************************************************
+ *
+ * Input stack
+ */
+struct input {
+ FILE *fp;
+ uint32_t lno;
+ char *fname;
+ char *path;
+ LIST_ENTRY(input) link;
+};
+
+LIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
+struct input *input = NULL;
+int32_t pbchar = -1;
+
+#define MAX_PATHS 100
+
+static const char *paths[MAX_PATHS + 1] = {
+ "/usr/share/snmp/defs",
+ "/usr/local/share/snmp/defs",
+ NULL
+};
+
+static void
+input_new(FILE *fp, const char *path, const char *fname)
+{
+ struct input *ip;
+
+ ip = xalloc(sizeof(*ip));
+ ip->fp = fp;
+ ip->lno = 1;
+ ip->fname = savestr(fname);
+ ip->path = savestr(path);
+ LIST_INSERT_HEAD(&inputs, ip, link);
+
+ input = ip;
+}
+
+static void
+input_close(void)
+{
+ if (input == NULL)
+ return;
+
+ fclose(input->fp);
+ free(input->fname);
+ free(input->path);
+ LIST_REMOVE(input, link);
+ free(input);
+
+ input = LIST_FIRST(&inputs);
+}
+
+static FILE *
+tryopen(const char *path, const char *fname)
+{
+ char *fn;
+ FILE *fp;
+
+ if (path == NULL)
+ fn = savestr(fname);
+ else {
+ fn = xalloc(strlen(path) + strlen(fname) + 2);
+ sprintf(fn, "%s/%s", path, fname);
+ }
+ fp = fopen(fn, "r");
+ free(fn);
+ return (fp);
+}
+
+static int32_t
+input_fopen(const char *fname)
+{
+ FILE *fp;
+ u_int p;
+
+ if (fname[0] == '/' || fname[0] == '.' || fname[0] == '~') {
+ if ((fp = tryopen(NULL, fname)) != NULL) {
+ input_new(fp, NULL, fname);
+ return (0);
+ }
+
+ } else {
+
+ for (p = 0; paths[p] != NULL; p++)
+ if ((fp = tryopen(paths[p], fname)) != NULL) {
+ input_new(fp, paths[p], fname);
+ return (0);
+ }
+ }
+
+ warnx("cannot open '%s'", fname);
+ return (-1);
+}
+
+static int32_t
+tgetc(void)
+{
+ int c;
+
+ if (pbchar != -1) {
+ c = pbchar;
+ pbchar = -1;
+ return (c);
+ }
+
+ for (;;) {
+ if (input == NULL)
+ return (EOF);
+
+ if ((c = getc(input->fp)) != EOF)
+ return (c);
+
+ input_close();
+ }
+}
+
+static int32_t
+tungetc(int c)
+{
+
+ if (pbchar != -1)
+ return (-1);
+
+ pbchar = c;
+ return (1);
+}
+
+/************************************************************
+ *
+ * Parsing input
+ */
+enum tok {
+ TOK_EOF = 0200, /* end-of-file seen */
+ TOK_NUM, /* number */
+ TOK_STR, /* string */
+ TOK_ACCESS, /* access operator */
+ TOK_TYPE, /* type operator */
+ TOK_ENUM, /* enum token (kind of a type) */
+ TOK_TYPEDEF, /* typedef directive */
+ TOK_DEFTYPE, /* defined type */
+ TOK_INCLUDE, /* include directive */
+ TOK_FILENAME, /* filename ("foo.bar" or <foo.bar>) */
+ TOK_BITS, /* bits token (kind of a type) */
+ TOK_ERR /* unexpected char - exit */
+};
+
+static const struct {
+ const char *str;
+ enum tok tok;
+ uint32_t val;
+} keywords[] = {
+ { "GET", TOK_ACCESS, FL_GET },
+ { "SET", TOK_ACCESS, FL_SET },
+ { "NULL", TOK_TYPE, SNMP_SYNTAX_NULL },
+ { "INTEGER", TOK_TYPE, SNMP_SYNTAX_INTEGER },
+ { "INTEGER32", TOK_TYPE, SNMP_SYNTAX_INTEGER },
+ { "UNSIGNED32", TOK_TYPE, SNMP_SYNTAX_GAUGE },
+ { "OCTETSTRING", TOK_TYPE, SNMP_SYNTAX_OCTETSTRING },
+ { "IPADDRESS", TOK_TYPE, SNMP_SYNTAX_IPADDRESS },
+ { "OID", TOK_TYPE, SNMP_SYNTAX_OID },
+ { "TIMETICKS", TOK_TYPE, SNMP_SYNTAX_TIMETICKS },
+ { "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
+ { "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
+ { "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
+ { "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
+ { "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
+ { "typedef", TOK_TYPEDEF, 0 },
+ { "include", TOK_INCLUDE, 0 },
+ { NULL, 0, 0 }
+};
+
+struct {
+ /* Current OID type, regarding table membership. */
+ enum snmp_tbl_entry tbl_type;
+ /* A pointer to a structure in table list to add to its members. */
+ struct snmp_index_entry *table_idx;
+} table_data;
+
+struct asn_oid current_oid;
+char nexttok[MAXSTR];
+u_long val; /* integer values */
+int32_t all_cond; /* all conditions are true */
+int32_t saved_token = -1;
+
+/* Prepare the global data before parsing a new file. */
+static void
+snmp_import_init(struct asn_oid *append)
+{
+ memset(&table_data, 0, sizeof(table_data));
+ memset(&current_oid, 0, sizeof(struct asn_oid));
+ memset(nexttok, 0, MAXSTR);
+
+ if (append != NULL)
+ asn_append_oid(&current_oid, append);
+
+ all_cond = 0;
+ val = 0;
+ saved_token = -1;
+}
+
+static int32_t
+gettoken(struct snmp_toolinfo *snmptoolctx)
+{
+ int c;
+ struct enum_type *t;
+
+ if (saved_token != -1) {
+ c = saved_token;
+ saved_token = -1;
+ return (c);
+ }
+
+ again:
+ /*
+ * Skip any whitespace before the next token.
+ */
+ while ((c = tgetc()) != EOF) {
+ if (c == '\n')
+ input->lno++;
+ if (!isspace(c))
+ break;
+ }
+ if (c == EOF)
+ return (TOK_EOF);
+
+ if (!isascii(c)) {
+ warnx("unexpected character %#2x", (u_int) c);
+ return (TOK_ERR);
+ }
+
+ /*
+ * Skip comments.
+ */
+ if (c == '#') {
+ while ((c = tgetc()) != EOF) {
+ if (c == '\n') {
+ input->lno++;
+ goto again;
+ }
+ }
+ warnx("unexpected EOF in comment");
+ return (TOK_ERR);
+ }
+
+ /*
+ * Single character tokens.
+ */
+ if (strchr("():|", c) != NULL)
+ return (c);
+
+ if (c == '"' || c == '<') {
+ int32_t end = c;
+ size_t n = 0;
+
+ val = 1;
+ if (c == '<') {
+ val = 0;
+ end = '>';
+ }
+
+ while ((c = tgetc()) != EOF) {
+ if (c == end)
+ break;
+ if (n == sizeof(nexttok) - 1) {
+ nexttok[n++] = '\0';
+ warnx("filename too long '%s...'", nexttok);
+ return (TOK_ERR);
+ }
+ nexttok[n++] = c;
+ }
+ nexttok[n++] = '\0';
+ return (TOK_FILENAME);
+ }
+
+ /*
+ * Sort out numbers.
+ */
+ if (isdigit(c)) {
+ size_t n = 0;
+ nexttok[n++] = c;
+ while ((c = tgetc()) != EOF) {
+ if (!isdigit(c)) {
+ if (tungetc(c) < 0)
+ return (TOK_ERR);
+ break;
+ }
+ if (n == sizeof(nexttok) - 1) {
+ nexttok[n++] = '\0';
+ warnx("number too long '%s...'", nexttok);
+ return (TOK_ERR);
+ }
+ nexttok[n++] = c;
+ }
+ nexttok[n++] = '\0';
+ sscanf(nexttok, "%lu", &val);
+ return (TOK_NUM);
+ }
+
+ /*
+ * So that has to be a string.
+ */
+ if (isalpha(c) || c == '_' || c == '-') {
+ size_t n = 0;
+ nexttok[n++] = c;
+ while ((c = tgetc()) != EOF) {
+ if (!isalnum(c) && c != '_' && c != '-') {
+ if (tungetc (c) < 0)
+ return (TOK_ERR);
+ break;
+ }
+ if (n == sizeof(nexttok) - 1) {
+ nexttok[n++] = '\0';
+ warnx("string too long '%s...'", nexttok);
+ return (TOK_ERR);
+ }
+ nexttok[n++] = c;
+ }
+ nexttok[n++] = '\0';
+
+ /*
+ * Keywords.
+ */
+ for (c = 0; keywords[c].str != NULL; c++)
+ if (strcmp(keywords[c].str, nexttok) == 0) {
+ val = keywords[c].val;
+ return (keywords[c].tok);
+ }
+
+ if ((t = snmp_enumtc_lookup(snmptoolctx, nexttok)) != NULL) {
+ val = t->syntax;
+ return (TOK_DEFTYPE);
+ }
+
+ return (TOK_STR);
+ }
+
+ if (isprint(c))
+ warnx("%u: unexpected character '%c'", input->lno, c);
+ else
+ warnx("%u: unexpected character 0x%02x", input->lno, (u_int) c);
+
+ return (TOK_ERR);
+}
+
+/*
+ * Update table information.
+ */
+static struct snmp_index_entry *
+snmp_import_update_table(enum snmp_tbl_entry te, struct snmp_index_entry *tbl)
+{
+ switch (te) {
+ case ENTRY_NONE:
+ if (table_data.tbl_type == ENTRY_NONE)
+ return (NULL);
+ if (table_data.tbl_type == ENTRY_INDEX)
+ table_data.table_idx = NULL;
+ table_data.tbl_type--;
+ return (NULL);
+
+ case ENTRY_INDEX:
+ if (tbl == NULL)
+ warnx("No table_index to add!!!");
+ table_data.table_idx = tbl;
+ table_data.tbl_type = ENTRY_INDEX;
+ return (tbl);
+
+ case ENTRY_DATA:
+ if (table_data.tbl_type == ENTRY_INDEX) {
+ table_data.tbl_type = ENTRY_DATA;
+ return (table_data.table_idx);
+ }
+ return (NULL);
+
+ default:
+ /* NOTREACHED */
+ warnx("Unknown table entry type!!!");
+ break;
+ }
+
+ return (NULL);
+}
+
+static int32_t
+parse_enum(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ struct enum_pairs *enums)
+{
+ while ((*tok = gettoken(snmptoolctx)) == TOK_STR) {
+ if (enum_pair_insert(enums, val, nexttok) < 0)
+ return (-1);
+ if ((*tok = gettoken(snmptoolctx)) != TOK_NUM)
+ break;
+ }
+
+ if (*tok != ')') {
+ warnx("')' at end of enums");
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+parse_subtype(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ enum snmp_tc *tc)
+{
+ if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
+ warnx("subtype expected after '|'");
+ return (-1);
+ }
+
+ *tc = snmp_get_tc(nexttok);
+ *tok = gettoken(snmptoolctx);
+
+ return (1);
+}
+
+static int32_t
+parse_type(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ enum snmp_tc *tc, struct enum_pairs **snmp_enum)
+{
+ int32_t syntax, mem;
+
+ syntax = val;
+ *tc = 0;
+
+ if (*tok == TOK_ENUM || *tok == TOK_BITS) {
+ if (*snmp_enum == NULL) {
+ if ((*snmp_enum = enum_pairs_init()) == NULL)
+ return (-1);
+ mem = 1;
+ *tc = SNMP_TC_OWN;
+ } else
+ mem = 0;
+
+ if (gettoken(snmptoolctx) != '(') {
+ warnx("'(' expected after ENUM/BITS");
+ return (-1);
+ }
+
+ if ((*tok = gettoken(snmptoolctx)) != TOK_NUM) {
+ warnx("need value for ENUM//BITS");
+ if (mem == 1) {
+ free(*snmp_enum);
+ *snmp_enum = NULL;
+ }
+ return (-1);
+ }
+
+ if (parse_enum(snmptoolctx, tok, *snmp_enum) < 0) {
+ enum_pairs_free(*snmp_enum);
+ *snmp_enum = NULL;
+ return (-1);
+ }
+
+ *tok = gettoken(snmptoolctx);
+
+ } else if (*tok == TOK_DEFTYPE) {
+ struct enum_type *t;
+
+ *tc = 0;
+ t = snmp_enumtc_lookup(snmptoolctx, nexttok);
+ if (t != NULL)
+ *snmp_enum = t->snmp_enum;
+
+ *tok = gettoken(snmptoolctx);
+
+ } else {
+ if ((*tok = gettoken(snmptoolctx)) == '|') {
+ if (parse_subtype(snmptoolctx, tok, tc) < 0)
+ return (-1);
+ }
+ }
+
+ return (syntax);
+}
+
+static int32_t
+snmp_import_head(struct snmp_toolinfo *snmptoolctx)
+{
+ enum tok tok;
+
+ if ((tok = gettoken(snmptoolctx)) == '(')
+ tok = gettoken(snmptoolctx);
+
+ if (tok != TOK_NUM || val > ASN_MAXID ) {
+ warnx("Suboid expected - line %d", input->lno);
+ return (-1);
+ }
+
+ if (gettoken(snmptoolctx) != TOK_STR) {
+ warnx("Node name expected at line %d", input->lno);
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+snmp_import_table(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *obj)
+{
+ int32_t i;
+ enum snmp_tc tc;
+ enum tok tok;
+ struct snmp_index_entry *entry;
+
+ if ((entry = malloc(sizeof(struct snmp_index_entry))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(entry, 0, sizeof(struct snmp_index_entry));
+ STAILQ_INIT(&(entry->index_list));
+
+ for (i = 0, tok = gettoken(snmptoolctx); i < SNMP_INDEXES_MAX; i++) {
+ int32_t syntax;
+ struct enum_pairs *enums = NULL;
+
+ if (tok != TOK_TYPE && tok != TOK_DEFTYPE && tok != TOK_ENUM &&
+ tok != TOK_BITS)
+ break;
+
+ if ((syntax = parse_type(snmptoolctx, &tok, &tc, &enums)) < 0) {
+ enum_pairs_free(enums);
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ }
+
+ if (snmp_syntax_insert(&(entry->index_list), enums, syntax,
+ tc) < 0) {
+ snmp_index_listfree(&(entry->index_list));
+ enum_pairs_free(enums);
+ free(entry);
+ return (-1);
+ }
+ }
+
+ if (i == 0 || i > SNMP_INDEXES_MAX) {
+ warnx("Bad number of indexes at line %d", input->lno);
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ }
+
+ if (tok != TOK_STR) {
+ warnx("String expected after indexes at line %d", input->lno);
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ }
+
+ entry->string = obj->string;
+ entry->strlen = obj->strlen;
+ asn_append_oid(&(entry->var), &(obj->var));
+
+ if ((i = snmp_table_insert(snmptoolctx, entry)) < 0) {
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ } else if (i == 0) {
+ /* Same entry already present in lists. */
+ free(entry->string);
+ free(entry);
+ }
+
+ (void) snmp_import_update_table(ENTRY_INDEX, entry);
+
+ return (1);
+}
+
+/*
+ * Read everything after the syntax type that is certainly a leaf OID info.
+ */
+static int32_t
+snmp_import_leaf(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ struct snmp_oid2str *oid2str)
+{
+ int32_t i, syntax;
+
+ if ((syntax = parse_type(snmptoolctx, tok, &(oid2str->tc), &(oid2str->snmp_enum)))
+ < 0)
+ return(-1);
+
+ oid2str->syntax = syntax;
+ /*
+ * That is the name of the function, corresponding to the entry.
+ * It is used by bsnmpd, but is not interesting for us.
+ */
+ if (*tok == TOK_STR)
+ *tok = gettoken(snmptoolctx);
+
+ for (i = 0; i < SNMP_ACCESS_GETSET && *tok == TOK_ACCESS; i++) {
+ oid2str->access |= (uint32_t) val;
+ *tok = gettoken(snmptoolctx);
+ }
+
+ if (*tok != ')') {
+ warnx("')' expected at end of line %d", input->lno);
+ return (-1);
+ }
+
+ oid2str->table_idx = snmp_import_update_table(ENTRY_DATA, NULL);
+
+ if ((i = snmp_leaf_insert(snmptoolctx, oid2str)) < 0) {
+ warnx("Error adding leaf %s to list", oid2str->string);
+ return (-1);
+ }
+
+ /*
+ * Same entry is already present in the mapping lists and
+ * the new one was not inserted.
+ */
+ if (i == 0) {
+ free(oid2str->string);
+ free(oid2str);
+ }
+
+ (void) snmp_import_update_table(ENTRY_NONE, NULL);
+
+ return (1);
+}
+
+static int32_t
+snmp_import_object(struct snmp_toolinfo *snmptoolctx)
+{
+ char *string;
+ int i;
+ enum tok tok;
+ struct snmp_oid2str *oid2str;
+
+ if (snmp_import_head(snmptoolctx) < 0)
+ return (-1);
+
+ if ((oid2str = malloc(sizeof(struct snmp_oid2str))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ if ((string = malloc(strlen(nexttok) + 1)) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ free(oid2str);
+ return (-1);
+ }
+
+ memset(oid2str, 0, sizeof(struct snmp_oid2str));
+ strlcpy(string, nexttok, strlen(nexttok) + 1);
+ oid2str->string = string;
+ oid2str->strlen = strlen(nexttok);
+
+ asn_append_oid(&(oid2str->var), &(current_oid));
+ if (snmp_suboid_append(&(oid2str->var), (asn_subid_t) val) < 0)
+ goto error;
+
+ /*
+ * Prepared the entry - now figure out where to insert it.
+ * After the object we have following options:
+ * 1) new line, blank, ) - then it is an enum oid -> snmp_enumlist;
+ * 2) new line , ( - nonleaf oid -> snmp_nodelist;
+ * 2) ':' - table entry - a variable length SYNTAX_TYPE (one or more)
+ * may follow and second string must end line -> snmp_tablelist;
+ * 3) OID , string ) - this is a trap entry or a leaf -> snmp_oidlist;
+ * 4) SYNTAX_TYPE, string (not always), get/set modifier - always last
+ * and )- this is definitely a leaf.
+ */
+
+ switch (tok = gettoken(snmptoolctx)) {
+ case ')':
+ if ((i = snmp_enum_insert(snmptoolctx, oid2str)) < 0)
+ goto error;
+ if (i == 0) {
+ free(oid2str->string);
+ free(oid2str);
+ }
+ return (1);
+
+ case '(':
+ if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
+ goto error;
+
+ /*
+ * Ignore the error for nodes since the .def files currently
+ * contain different strings for 1.3.6.1.2.1 - mibII. Only make
+ * sure the memory is freed and don't complain.
+ */
+ if ((i = snmp_node_insert(snmptoolctx, oid2str)) <= 0) {
+ free(string);
+ free(oid2str);
+ }
+ return (snmp_import_object(snmptoolctx));
+
+ case ':':
+ if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
+ goto error;
+ if (snmp_import_table(snmptoolctx, oid2str) < 0)
+ goto error;
+ /*
+ * A different table entry type was malloced and the data is
+ * contained there.
+ */
+ free(oid2str);
+ return (1);
+
+ case TOK_TYPE:
+ /* FALLTHROUGH */
+ case TOK_DEFTYPE:
+ /* FALLTHROUGH */
+ case TOK_ENUM:
+ /* FALLTHROUGH */
+ case TOK_BITS:
+ if (snmp_import_leaf(snmptoolctx, &tok, oid2str) < 0)
+ goto error;
+ return (1);
+
+ default:
+ warnx("Unexpected token at line %d - %s", input->lno,
+ input->fname);
+ break;
+ }
+
+error:
+ snmp_mapping_entryfree(oid2str);
+
+ return (-1);
+}
+
+static int32_t
+snmp_import_tree(struct snmp_toolinfo *snmptoolctx, enum tok *tok)
+{
+ while (*tok != TOK_EOF) {
+ switch (*tok) {
+ case TOK_ERR:
+ return (-1);
+ case '(':
+ if (snmp_import_object(snmptoolctx) < 0)
+ return (-1);
+ break;
+ case ')':
+ if (snmp_suboid_pop(&current_oid) < 0)
+ return (-1);
+ (void) snmp_import_update_table(ENTRY_NONE, NULL);
+ break;
+ default:
+ /* Anything else here would be illegal. */
+ return (-1);
+ }
+ *tok = gettoken(snmptoolctx);
+ }
+
+ return (0);
+}
+
+static int32_t
+snmp_import_top(struct snmp_toolinfo *snmptoolctx, enum tok *tok)
+{
+ enum snmp_tc tc;
+ struct enum_type *t;
+
+ if (*tok == '(')
+ return (snmp_import_tree(snmptoolctx, tok));
+
+ if (*tok == TOK_TYPEDEF) {
+ if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
+ warnx("type name expected after typedef - %s",
+ input->fname);
+ return (-1);
+ }
+
+ t = snmp_enumtc_init(nexttok);
+
+ *tok = gettoken(snmptoolctx);
+ t->is_enum = (*tok == TOK_ENUM);
+ t->is_bits = (*tok == TOK_BITS);
+ t->syntax = parse_type(snmptoolctx, tok, &tc, &(t->snmp_enum));
+ snmp_enumtc_insert(snmptoolctx, t);
+
+ return (1);
+ }
+
+ if (*tok == TOK_INCLUDE) {
+ int i;
+
+ *tok = gettoken(snmptoolctx);
+ if (*tok != TOK_FILENAME) {
+ warnx("filename expected in include directive - %s",
+ nexttok);
+ return (-1);
+ }
+
+ if (( i = add_filename(snmptoolctx, nexttok, NULL, 1)) == 0) {
+ *tok = gettoken(snmptoolctx);
+ return (1);
+ }
+
+ if (i == -1)
+ return (-1);
+
+ input_fopen(nexttok);
+ *tok = gettoken(snmptoolctx);
+ return (1);
+ }
+
+ warnx("'(' or 'typedef' expected - %s", nexttok);
+ return (-1);
+}
+
+static int32_t
+snmp_import(struct snmp_toolinfo *snmptoolctx)
+{
+ int i;
+ enum tok tok;
+
+ tok = gettoken(snmptoolctx);
+
+ do
+ i = snmp_import_top(snmptoolctx, &tok);
+ while (i > 0);
+
+ return (i);
+}
+
+/*
+ * Read a .def file and import oid<->string mapping.
+ * Mappings are inserted into a global structure containing list for each OID
+ * syntax type.
+ */
+int32_t
+snmp_import_file(struct snmp_toolinfo *snmptoolctx, struct fname *file)
+{
+ int idx;
+
+ snmp_import_init(&(file->cut));
+ input_fopen(file->name);
+ if ((idx = snmp_import(snmptoolctx)) < 0)
+ warnx("Failed to read mappings from file %s", file->name);
+
+ input_close();
+
+ return (idx);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c
new file mode 100644
index 0000000..a6d14a2
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c
@@ -0,0 +1,1018 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+extern int _bsnmptools_debug;
+#define DEBUG if (_bsnmptools_debug) fprintf
+
+/* Allocate memory and initialize list. */
+struct snmp_mappings *
+snmp_mapping_init(void)
+{
+ struct snmp_mappings *m;
+
+ if ((m = malloc(sizeof(struct snmp_mappings))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (NULL);
+ }
+
+ memset(m, 0, sizeof(struct snmp_mappings));
+ return (m);
+}
+
+#define snmp_nodelist mappings->nodelist
+#define snmp_intlist mappings->intlist
+#define snmp_octlist mappings->octlist
+#define snmp_oidlist mappings->oidlist
+#define snmp_iplist mappings->iplist
+#define snmp_ticklist mappings->ticklist
+#define snmp_cntlist mappings->cntlist
+#define snmp_gaugelist mappings->gaugelist
+#define snmp_cnt64list mappings->cnt64list
+#define snmp_enumlist mappings->enumlist
+#define snmp_tablelist mappings->tablelist
+#define snmp_tclist mappings->tclist
+
+void
+enum_pairs_free(struct enum_pairs *headp)
+{
+ struct enum_pair *e;
+
+ if (headp == NULL)
+ return;
+
+ while ((e = STAILQ_FIRST(headp)) != NULL) {
+ STAILQ_REMOVE_HEAD(headp, link);
+
+ if (e->enum_str)
+ free(e->enum_str);
+ free(e);
+ }
+
+ free(headp);
+}
+
+void
+snmp_mapping_entryfree(struct snmp_oid2str *entry)
+{
+ if (entry->string)
+ free(entry->string);
+
+ if (entry->tc == SNMP_TC_OWN)
+ enum_pairs_free(entry->snmp_enum);
+
+ free(entry);
+}
+
+static void
+snmp_mapping_listfree(struct snmp_mapping *headp)
+{
+ struct snmp_oid2str *p;
+
+ while ((p = SLIST_FIRST(headp)) != NULL) {
+ SLIST_REMOVE_HEAD(headp, link);
+
+ if (p->string)
+ free(p->string);
+
+ if (p->tc == SNMP_TC_OWN)
+ enum_pairs_free(p->snmp_enum);
+ free(p);
+ }
+
+ SLIST_INIT(headp);
+}
+
+void
+snmp_index_listfree(struct snmp_idxlist *headp)
+{
+ struct index *i;
+
+ while ((i = STAILQ_FIRST(headp)) != NULL) {
+ STAILQ_REMOVE_HEAD(headp, link);
+ if (i->tc == SNMP_TC_OWN)
+ enum_pairs_free(i->snmp_enum);
+ free(i);
+ }
+
+ STAILQ_INIT(headp);
+}
+
+static void
+snmp_mapping_table_listfree(struct snmp_table_index *headp)
+{
+ struct snmp_index_entry *t;
+
+ while ((t = SLIST_FIRST(headp)) != NULL) {
+ SLIST_REMOVE_HEAD(headp, link);
+
+ if (t->string)
+ free(t->string);
+
+ snmp_index_listfree(&(t->index_list));
+ free(t);
+ }
+}
+
+static void
+snmp_enumtc_listfree(struct snmp_enum_tc *headp)
+{
+ struct enum_type *t;
+
+ while ((t = SLIST_FIRST(headp)) != NULL) {
+ SLIST_REMOVE_HEAD(headp, link);
+
+ if (t->name)
+ free(t->name);
+ enum_pairs_free(t->snmp_enum);
+ free(t);
+ }
+}
+
+int
+snmp_mapping_free(struct snmp_toolinfo *snmptoolctx)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return (-1);
+
+ snmp_mapping_listfree(&snmptoolctx->snmp_nodelist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_intlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_octlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_oidlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_iplist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_ticklist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_cntlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_gaugelist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_cnt64list);
+ snmp_mapping_listfree(&snmptoolctx->snmp_enumlist);
+ snmp_mapping_table_listfree(&snmptoolctx->snmp_tablelist);
+ snmp_enumtc_listfree(&snmptoolctx->snmp_tclist);
+ free(snmptoolctx->mappings);
+
+ return (0);
+}
+
+static void
+snmp_dump_enumpairs(struct enum_pairs *headp)
+{
+ struct enum_pair *entry;
+
+ if (headp == NULL)
+ return;
+
+ fprintf(stderr,"enums: ");
+ STAILQ_FOREACH(entry, headp, link)
+ fprintf(stderr,"%d - %s, ", entry->enum_val,
+ (entry->enum_str == NULL)?"NULL":entry->enum_str);
+
+ fprintf(stderr,"; ");
+}
+
+void
+snmp_dump_oid2str(struct snmp_oid2str *entry)
+{
+ char buf[ASN_OIDSTRLEN];
+
+ if (entry != NULL) {
+ memset(buf, 0, sizeof(buf));
+ asn_oid2str_r(&(entry->var), buf);
+ DEBUG(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
+ entry->syntax, entry->access, entry->strlen);
+ snmp_dump_enumpairs(entry->snmp_enum);
+ DEBUG(stderr,"%s \n", (entry->table_idx == NULL)?"No table":
+ entry->table_idx->string);
+ }
+}
+
+static void
+snmp_dump_indexlist(struct snmp_idxlist *headp)
+{
+ struct index *entry;
+
+ if (headp == NULL)
+ return;
+
+ STAILQ_FOREACH(entry, headp, link) {
+ fprintf(stderr,"%d, ", entry->syntax);
+ snmp_dump_enumpairs(entry->snmp_enum);
+ }
+
+ fprintf(stderr,"\n");
+}
+
+/* Initialize the enum pairs list of a oid2str entry. */
+struct enum_pairs *
+enum_pairs_init(void)
+{
+ struct enum_pairs *snmp_enum;
+
+ if ((snmp_enum = malloc(sizeof(struct enum_pairs))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (NULL);
+ }
+
+ STAILQ_INIT(snmp_enum);
+ return (snmp_enum);
+}
+
+/*
+ * Given a number and string, allocate memory for a (int, string) pair and add
+ * it to the given oid2str mapping entry's enum pairs list.
+ */
+int32_t
+enum_pair_insert(struct enum_pairs *headp, int32_t enum_val, char *enum_str)
+{
+ struct enum_pair *e_new;
+
+ if ((e_new = malloc(sizeof(struct enum_pair))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(e_new, 0, sizeof(struct enum_pair));
+
+ if ((e_new->enum_str = malloc(strlen(enum_str) + 1)) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ free(e_new);
+ return (-1);
+ }
+
+ e_new->enum_val = enum_val;
+ strlcpy(e_new->enum_str, enum_str, strlen(enum_str) + 1);
+ STAILQ_INSERT_TAIL(headp, e_new, link);
+
+ return (1);
+
+}
+
+/*
+ * Insert an entry in a list - entries are lexicographicaly order by asn_oid.
+ * Returns 1 on success, -1 if list is not initialized, 0 if a matching oid already
+ * exists. Error cheking is left to calling function.
+ */
+static int
+snmp_mapping_insert(struct snmp_mapping *headp, struct snmp_oid2str *entry)
+{
+ int32_t rc;
+ struct snmp_oid2str *temp, *prev;
+
+ if (entry == NULL)
+ return(-1);
+
+ if ((prev = SLIST_FIRST(headp)) == NULL ||
+ asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
+ SLIST_INSERT_HEAD(headp, entry, link);
+ return (1);
+ } else
+ rc = -1; /* Make the compiler happy. */
+
+ SLIST_FOREACH(temp, headp, link) {
+ if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
+ break;
+ prev = temp;
+ rc = -1;
+ }
+
+ switch (rc) {
+ case 0:
+ /* Ops, matching OIDs - hope the rest info also matches. */
+ if (strncmp(temp->string, entry->string, entry->strlen)) {
+ syslog(LOG_INFO, "Matching OIDs with different string "
+ "mappings: old - %s, new - %s", temp->string,
+ entry->string);
+ return (-1);
+ }
+ /*
+ * Ok, we have that already.
+ * As long as the strings match - don't complain.
+ */
+ return (0);
+
+ case 1:
+ SLIST_INSERT_AFTER(temp, entry, link);
+ break;
+
+ case -1:
+ SLIST_INSERT_AFTER(prev, entry, link);
+ break;
+
+ default:
+ /* NOTREACHED */
+ return (-1);
+ }
+
+ return (1);
+}
+
+int32_t
+snmp_node_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_nodelist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_int_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_intlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_oct_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_octlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_oid_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_oidlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_ip_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_iplist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_tick_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_ticklist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_cnt_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_cntlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_gauge_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_gaugelist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_cnt64_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_cnt64list,entry));
+
+ return (-1);
+}
+
+int32_t
+snmp_enum_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_enumlist,entry));
+
+ return (-1);
+}
+
+int32_t
+snmp_leaf_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ switch (entry->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_int_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_oct_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_OID:
+ return (snmp_oid_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_ip_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_COUNTER:
+ return (snmp_cnt_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_GAUGE:
+ return (snmp_gauge_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_tick_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_cnt64_insert(snmptoolctx, entry));
+ default:
+ break;
+ }
+
+ return (-1);
+}
+
+static int32_t
+snmp_index_insert(struct snmp_idxlist *headp, struct index *idx)
+{
+ if (headp == NULL || index == NULL)
+ return (-1);
+
+ STAILQ_INSERT_TAIL(headp, idx, link);
+ return (1);
+}
+
+int32_t
+snmp_syntax_insert(struct snmp_idxlist *headp, struct enum_pairs *enums,
+ enum snmp_syntax syntax, enum snmp_tc tc)
+{
+ struct index *idx;
+
+ if ((idx = malloc(sizeof(struct index))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(idx, 0, sizeof(struct index));
+
+ if (snmp_index_insert(headp, idx) < 0) {
+ free(idx);
+ return (-1);
+ }
+
+ idx->syntax = syntax;
+ idx->snmp_enum = enums;
+ idx->tc = tc;
+
+ return (1);
+}
+
+int32_t
+snmp_table_insert(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_index_entry *entry)
+{
+ int32_t rc;
+ struct snmp_index_entry *temp, *prev;
+
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL ||
+ entry == NULL)
+ return(-1);
+
+ if ((prev = SLIST_FIRST(&snmptoolctx->snmp_tablelist)) == NULL ||
+ asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
+ SLIST_INSERT_HEAD(&snmptoolctx->snmp_tablelist, entry, link);
+ return (1);
+ } else
+ rc = -1; /* Make the compiler happy. */
+
+ SLIST_FOREACH(temp, &snmptoolctx->snmp_tablelist, link) {
+ if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
+ break;
+ prev = temp;
+ rc = -1;
+ }
+
+ switch (rc) {
+ case 0:
+ /* Ops, matching OIDs - hope the rest info also matches. */
+ if (strncmp(temp->string, entry->string, entry->strlen)) {
+ syslog(LOG_INFO, "Matching OIDs with different string "
+ "mapping - old - %s, new - %s", temp->string,
+ entry->string);
+ return (-1);
+ }
+ return(0);
+
+ case 1:
+ SLIST_INSERT_AFTER(temp, entry, link);
+ break;
+
+ case -1:
+ SLIST_INSERT_AFTER(prev, entry, link);
+ break;
+
+ default:
+ /* NOTREACHED */
+ return (-1);
+ }
+
+ return (1);
+}
+
+struct enum_type *
+snmp_enumtc_init(char *name)
+{
+ struct enum_type *enum_tc;
+
+ if ((enum_tc = malloc(sizeof(struct enum_type))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (NULL);
+ }
+
+ memset(enum_tc, 0, sizeof(struct enum_type));
+ if ((enum_tc->name = malloc(strlen(name) + 1)) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ free(enum_tc);
+ return (NULL);
+ }
+ strlcpy(enum_tc->name, name, strlen(name) + 1);
+
+ return (enum_tc);
+}
+
+void
+snmp_enumtc_free(struct enum_type *tc)
+{
+ if (tc->name)
+ free(tc->name);
+ if (tc->snmp_enum)
+ enum_pairs_free(tc->snmp_enum);
+ free(tc);
+}
+
+void
+snmp_enumtc_insert(struct snmp_toolinfo *snmptoolctx, struct enum_type *entry)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return; /* XXX no error handling? */
+
+ SLIST_INSERT_HEAD(&snmptoolctx->snmp_tclist, entry, link);
+}
+
+struct enum_type *
+snmp_enumtc_lookup(struct snmp_toolinfo *snmptoolctx, char *name)
+{
+ struct enum_type *temp;
+
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return (NULL);
+
+ SLIST_FOREACH(temp, &snmptoolctx->snmp_tclist, link) {
+ if (strcmp(temp->name, name) == 0)
+ return (temp);
+ }
+ return (NULL);
+}
+
+static void
+snmp_mapping_dumplist(struct snmp_mapping *headp)
+{
+ char buf[ASN_OIDSTRLEN];
+ struct snmp_oid2str *entry;
+
+ if (headp == NULL)
+ return;
+
+ SLIST_FOREACH(entry,headp,link) {
+ memset(buf, 0, sizeof(buf));
+ asn_oid2str_r(&(entry->var), buf);
+ fprintf(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
+ entry->syntax, entry->access ,entry->strlen);
+ fprintf(stderr," - %s \n", (entry->table_idx == NULL)?
+ "No table":entry->table_idx->string);
+ }
+}
+
+static void
+snmp_mapping_dumptable(struct snmp_table_index *headp)
+{
+ char buf[ASN_OIDSTRLEN];
+ struct snmp_index_entry *entry;
+
+ if (headp == NULL)
+ return;
+
+ SLIST_FOREACH(entry, headp, link) {
+ memset(buf, 0, sizeof(buf));
+ asn_oid2str_r(&(entry->var), buf);
+ fprintf(stderr,"%s - %s - %d - ", buf, entry->string,
+ entry->strlen);
+ snmp_dump_indexlist(&(entry->index_list));
+ }
+}
+
+void
+snmp_mapping_dump(struct snmp_toolinfo *snmptoolctx /* int bits */)
+{
+ if (!_bsnmptools_debug)
+ return;
+
+ if (snmptoolctx == NULL) {
+ fprintf(stderr,"No snmptool context!\n");
+ return;
+ }
+
+ if (snmptoolctx->mappings == NULL) {
+ fprintf(stderr,"No mappings!\n");
+ return;
+ }
+
+ fprintf(stderr,"snmp_nodelist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_nodelist);
+
+ fprintf(stderr,"snmp_intlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_intlist);
+
+ fprintf(stderr,"snmp_octlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_octlist);
+
+ fprintf(stderr,"snmp_oidlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_oidlist);
+
+ fprintf(stderr,"snmp_iplist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_iplist);
+
+ fprintf(stderr,"snmp_ticklist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_ticklist);
+
+ fprintf(stderr,"snmp_cntlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_cntlist);
+
+ fprintf(stderr,"snmp_gaugelist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_gaugelist);
+
+ fprintf(stderr,"snmp_cnt64list:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_cnt64list);
+
+ fprintf(stderr,"snmp_enumlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_enumlist);
+
+ fprintf(stderr,"snmp_tablelist:\n");
+ snmp_mapping_dumptable(&snmptoolctx->snmp_tablelist);
+}
+
+char *
+enum_string_lookup(struct enum_pairs *headp, int32_t enum_val)
+{
+ struct enum_pair *temp;
+
+ if (headp == NULL)
+ return (NULL);
+
+ STAILQ_FOREACH(temp, headp, link) {
+ if (temp->enum_val == enum_val)
+ return (temp->enum_str);
+ }
+
+ return (NULL);
+}
+
+int32_t
+enum_number_lookup(struct enum_pairs *headp, char *e_str)
+{
+ struct enum_pair *tmp;
+
+ if (headp == NULL)
+ return (-1);
+
+ STAILQ_FOREACH(tmp, headp, link)
+ if (strncmp(tmp->enum_str, e_str, strlen(tmp->enum_str)) == 0)
+ return (tmp->enum_val);
+
+ return (-1);
+}
+
+static int32_t
+snmp_lookuplist_string(struct snmp_mapping *headp, struct snmp_object *s)
+{
+ struct snmp_oid2str *temp;
+
+ if (headp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp, headp, link)
+ if (asn_compare_oid(&(temp->var), &(s->val.var)) == 0)
+ break;
+
+ if ((s->info = temp) == NULL)
+ return (-1);
+
+ return (1);
+}
+
+/* provided an asn_oid find the corresponding string for it */
+static int32_t
+snmp_lookup_leaf(struct snmp_mapping *headp, struct snmp_object *s)
+{
+ struct snmp_oid2str *temp;
+
+ if (headp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp,headp,link) {
+ if ((asn_compare_oid(&(temp->var), &(s->val.var)) == 0) ||
+ (asn_is_suboid(&(temp->var), &(s->val.var)))) {
+ s->info = temp;
+ return (1);
+ }
+ }
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_leafstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ switch (s->val.syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s));
+ case SNMP_SYNTAX_OID:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s));
+ case SNMP_SYNTAX_COUNTER:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s));
+ case SNMP_SYNTAX_GAUGE:
+ return (snmp_lookup_leaf(
+ &snmptoolctx->snmp_gaugelist, s));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_lookup_leaf(
+ &snmptoolctx->snmp_ticklist, s));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_lookup_leaf(
+ &snmptoolctx->snmp_cnt64list, s));
+ case SNMP_SYNTAX_NOSUCHOBJECT:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_NOSUCHINSTANCE:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_ENDOFMIBVIEW:
+ return (snmp_lookup_allstring(snmptoolctx, s));
+ default:
+ warnx("Unknown syntax - %d", s->val.syntax);
+ break;
+ }
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_enumstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s));
+}
+
+int32_t
+snmp_lookup_oidstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookuplist_string(&snmptoolctx->snmp_oidlist, s));
+}
+
+int32_t
+snmp_lookup_nodestring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s));
+}
+
+int32_t
+snmp_lookup_allstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return (-1);
+
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_gaugelist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_ticklist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_cnt64list, s) > 0)
+ return (1);
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
+ return (1);
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
+ return (1);
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_nonleaf_string(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *s)
+{
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
+ return (1);
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
+ return (1);
+
+ return (-1);
+}
+
+static int32_t
+snmp_lookup_oidlist(struct snmp_mapping *hp, struct snmp_object *s, char *oid)
+{
+ struct snmp_oid2str *temp;
+
+ if (hp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp, hp, link) {
+ if (temp->strlen != strlen(oid))
+ continue;
+
+ if (strncmp(temp->string, oid, temp->strlen))
+ continue;
+
+ s->val.syntax = temp->syntax;
+ s->info = temp;
+ asn_append_oid(&(s->val.var), &(temp->var));
+ return (1);
+ }
+
+ return (-1);
+}
+
+static int32_t
+snmp_lookup_tablelist(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_table_index *headp, struct snmp_object *s, char *oid)
+{
+ struct snmp_index_entry *temp;
+
+ if (snmptoolctx == NULL || headp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp, headp, link) {
+ if (temp->strlen != strlen(oid))
+ continue;
+
+ if (strncmp(temp->string, oid, temp->strlen))
+ continue;
+
+ /*
+ * Another hack here - if we were given a table name
+ * return the corresponding pointer to it's entry.
+ * That should not change the reponce we'll get.
+ */
+ s->val.syntax = SNMP_SYNTAX_NULL;
+ asn_append_oid(&(s->val.var), &(temp->var));
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_nodelist, s) > 0)
+ return (1);
+ else
+ return (-1);
+ }
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_oidall(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
+ char *oid)
+{
+ if (snmptoolctx == NULL || s == NULL || oid == NULL)
+ return (-1);
+
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_tablelist(snmptoolctx, &snmptoolctx->snmp_tablelist,
+ s, oid) > 0)
+ return (1);
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_enumoid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
+ char *oid)
+{
+ if (snmptoolctx == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_enumlist, s, oid));
+}
+
+int32_t
+snmp_lookup_oid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
+ char *oid)
+{
+ if (snmptoolctx == NULL || s == NULL)
+ return (-1);
+
+ switch (s->val.syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist,
+ s, oid));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist,
+ s, oid));
+ case SNMP_SYNTAX_OID:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist,
+ s, oid));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist,
+ s, oid));
+ case SNMP_SYNTAX_COUNTER:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist,
+ s, oid));
+ case SNMP_SYNTAX_GAUGE:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist,
+ s, oid));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist,
+ s, oid));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list,
+ s, oid));
+ case SNMP_SYNTAX_NULL:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist,
+ s, oid));
+ default:
+ warnx("Unknown syntax - %d", s->val.syntax);
+ break;
+ }
+
+ return (-1);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c
new file mode 100644
index 0000000..dc22c69
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c
@@ -0,0 +1,1287 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * Textual conventions for OctetStrings
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+/* OctetString, DisplayString */
+static char *snmp_oct2str(uint32_t, char *, char *);
+static char *snmp_str2asn_oid(char *, struct asn_oid *);
+static int parse_octetstring(struct snmp_value *, char *);
+
+/* DateAndTime */
+static char *snmp_octstr2date(uint32_t, char *, char *);
+static char *snmp_date2asn_oid(char * , struct asn_oid *);
+static int parse_dateandtime(struct snmp_value *, char *);
+
+/* PhysAddress */
+static char *snmp_oct2physAddr(uint32_t, char *, char *);
+static char *snmp_addr2asn_oid(char *, struct asn_oid *);
+static int parse_physaddress(struct snmp_value *, char *);
+
+/* NTPTimeStamp */
+static char *snmp_oct2ntp_ts(uint32_t, char *, char *);
+static char *snmp_ntp_ts2asn_oid(char *, struct asn_oid *);
+static int parse_ntp_ts(struct snmp_value *, char *);
+
+/* BridgeId */
+static char *snmp_oct2bridgeid(uint32_t, char *, char *);
+static char *snmp_bridgeid2oct(char *, struct asn_oid *);
+static int parse_bridge_id(struct snmp_value *, char *);
+
+/* BridgePortId */
+static char *snmp_oct2bport_id(uint32_t, char *, char *);
+static char *snmp_bport_id2oct(char *, struct asn_oid *);
+static int parse_bport_id(struct snmp_value *, char *);
+
+/* InetAddress */
+static char *snmp_oct2inetaddr(uint32_t len, char *octets, char *buf);
+static char *snmp_inetaddr2oct(char *str, struct asn_oid *oid);
+static int32_t parse_inetaddr(struct snmp_value *value, char *string);
+
+static char *snmp_oct2bits(uint32_t len, char *octets, char *buf);
+static char *snmp_bits2oct(char *str, struct asn_oid *oid);
+static int32_t parse_bits(struct snmp_value *value, char *string);
+
+struct snmp_text_conv {
+ enum snmp_tc tc;
+ const char *tc_str;
+ int32_t len;
+ snmp_oct2tc_f oct2tc;
+ snmp_tc2oid_f tc2oid;
+ snmp_tc2oct_f tc2oct;
+} text_convs[] = {
+ { SNMP_STRING, "OctetString", SNMP_VAR_STRSZ,
+ snmp_oct2str, snmp_str2asn_oid, parse_octetstring },
+
+ { SNMP_DISPLAYSTRING, "DisplayString" , SNMP_VAR_STRSZ,
+ snmp_oct2str, snmp_str2asn_oid, parse_octetstring },
+
+ { SNMP_DATEANDTIME, "DateAndTime", SNMP_DATETIME_STRSZ,
+ snmp_octstr2date, snmp_date2asn_oid, parse_dateandtime },
+
+ { SNMP_PHYSADDR, "PhysAddress", SNMP_PHYSADDR_STRSZ,
+ snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
+
+ { SNMP_ATMESI, "AtmESI", SNMP_PHYSADDR_STRSZ,
+ snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
+
+ { SNMP_NTP_TIMESTAMP, "NTPTimeStamp", SNMP_NTP_TS_STRSZ,
+ snmp_oct2ntp_ts, snmp_ntp_ts2asn_oid, parse_ntp_ts },
+
+ { SNMP_MACADDRESS, "MacAddress", SNMP_PHYSADDR_STRSZ,
+ snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
+
+ { SNMP_BRIDGE_ID, "BridgeId", SNMP_BRIDGEID_STRSZ,
+ snmp_oct2bridgeid, snmp_bridgeid2oct, parse_bridge_id },
+
+ { SNMP_BPORT_ID, "BridgePortId", SNMP_BPORT_STRSZ,
+ snmp_oct2bport_id, snmp_bport_id2oct, parse_bport_id },
+
+ { SNMP_INETADDRESS, "InetAddress", SNMP_INADDRS_STRSZ,
+ snmp_oct2inetaddr, snmp_inetaddr2oct, parse_inetaddr },
+
+ { SNMP_TC_OWN, "BITS", SNMP_VAR_STRSZ,
+ snmp_oct2bits, snmp_bits2oct, parse_bits },
+
+ { SNMP_UNKNOWN, "Unknown", SNMP_VAR_STRSZ, snmp_oct2str,
+ snmp_str2asn_oid, parse_octetstring } /* keep last */
+};
+
+/* Common API */
+enum snmp_tc
+snmp_get_tc(char *str)
+{
+ int i;
+ for (i = 0; i < SNMP_UNKNOWN; i++) {
+ if (!strncmp(text_convs[i].tc_str, str,
+ strlen(text_convs[i].tc_str)))
+ return (text_convs[i].tc);
+ }
+
+ return (SNMP_STRING);
+}
+
+char *
+snmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets)
+{
+ uint32_t tc_len;
+ char * buf;
+
+ if (tc < 0 || tc > SNMP_UNKNOWN)
+ tc = SNMP_UNKNOWN;
+
+ if (text_convs[tc].len > 0)
+ tc_len = text_convs[tc].len;
+ else
+ tc_len = 2 * len + 3;
+
+ if ((buf = malloc(tc_len)) == NULL ) {
+ syslog(LOG_ERR, "malloc failed - %s", strerror(errno));
+ return (NULL);
+ }
+
+ memset(buf, 0, tc_len);
+ if (text_convs[tc].oct2tc(len, octets, buf) == NULL) {
+ free(buf);
+ return (NULL);
+ }
+
+ return (buf);
+}
+
+char *
+snmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid)
+{
+ if (tc < 0 || tc > SNMP_UNKNOWN)
+ tc = SNMP_UNKNOWN;
+
+ return (text_convs[tc].tc2oid(str, oid));
+}
+
+int32_t
+snmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string)
+{
+ if (tc < 0 || tc > SNMP_UNKNOWN)
+ tc = SNMP_UNKNOWN;
+
+ return (text_convs[tc].tc2oct(value, string));
+}
+
+/*****************************************************
+* Basic OctetString type.
+*/
+static char *
+snmp_oct2str(uint32_t len, char *octets, char *buf)
+{
+ uint8_t binary = 0;
+ uint32_t i;
+ char *ptr;
+
+ if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL)
+ return (NULL);
+
+ for (ptr = buf, i = 0; i < len; i++)
+ if (!isprint(octets[i])) {
+ binary = 1;
+ buf += sprintf(buf, "0x");
+ break;
+ }
+
+ for (ptr = buf, i = 0; i < len; i++)
+ if (!binary)
+ ptr += sprintf(ptr, "%c", octets[i]);
+ else
+ ptr += sprintf(ptr, "%2.2x", (u_char)octets[i]);
+
+ return (buf);
+}
+
+static char *
+snmp_str2asn_oid(char *str, struct asn_oid *oid)
+{
+ uint32_t i, len = 0;
+
+ /*
+ * OctetStrings are allowed max length of ASN_MAXOCTETSTRING,
+ * but trying to index an entry with such a long OctetString
+ * will fail anyway.
+ */
+ for (len = 0; len < ASN_MAXOIDLEN; len++) {
+ if (strchr(",]", *(str + len)) != NULL)
+ break;
+ }
+
+ if (len >= ASN_MAXOIDLEN)
+ return (NULL);
+
+ if (snmp_suboid_append(oid, (asn_subid_t) len) < 0)
+ return (NULL);
+
+ for (i = 0; i < len; i++)
+ if (snmp_suboid_append(oid, (asn_subid_t) *(str + i)) < 0)
+ return (NULL);
+
+ return (str + len);
+}
+
+static int32_t
+parse_octetstring(struct snmp_value *value, char *val)
+{
+ size_t len;
+
+ if ((len = strlen(val)) >= MAX_OCTSTRING_LEN) {
+ warnx("Octetstring too long - %d is max allowed",
+ MAX_OCTSTRING_LEN - 1);
+ return (-1);
+ }
+
+ value->v.octetstring.len = len;
+
+ if((value->v.octetstring.octets = malloc(len)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memcpy(value->v.octetstring.octets, val, len);
+ value->syntax = SNMP_SYNTAX_OCTETSTRING;
+
+ return (0);
+}
+
+/*************************************************************
+ * DateAndTime
+ *************************************************************
+ * rfc 2579 specification:
+ * DateAndTime ::= TEXTUAL-CONVENTION
+ * DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
+ * STATUS current
+ * DESCRIPTION
+ * "A date-time specification.
+ *
+ * field octets contents range
+ * ----- ------ -------- -----
+ * 1 1-2 year* 0..65536
+ * 2 3 month 1..12
+ * 3 4 day 1..31
+ * 4 5 hour 0..23
+ * 5 6 minutes 0..59
+ * 6 7 seconds 0..60
+ * (use 60 for leap-second)
+ * 7 8 deci-seconds 0..9
+ * 8 9 direction from UTC '+' / '-'
+ * 9 10 hours from UTC* 0..13
+ * 10 11 minutes from UTC 0..59
+ *
+ * * Notes:
+ * - the value of year is in network-byte order
+ * - daylight saving time in New Zealand is +13
+ *
+ * For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
+ * displayed as:
+ *
+ * 1992-5-26,13:30:15.0,-4:0
+ */
+static char *
+snmp_octstr2date(uint32_t len, char *octets, char *buf)
+{
+ int year;
+ char *ptr;
+
+ if (len != SNMP_DATETIME_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+ year = (octets[0] << 8);
+ year += (octets[1]);
+
+ ptr = buf;
+ ptr += sprintf(ptr, "%4.4d-%.2d-%.2d, ", year, octets[2],octets[3]);
+ ptr += sprintf(ptr, "%2.2d:%2.2d:%2.2d.%.2d, ", octets[4],octets[5],
+ octets[6],octets[7]);
+ ptr += sprintf(ptr, "%c%.2d:%.2d", octets[8],octets[9],octets[10]);
+
+ return (buf);
+}
+
+static char *
+snmp_date2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v;
+ int32_t saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_DATETIME_OCTETS) < 0)
+ return (NULL);
+
+ /* Read 'YYYY-' and write it in two subs. */
+ ptr = str;
+ saved_errno = errno;
+ errno = 0;
+ v = strtoul(ptr, &endptr, 10);
+ if (v > 0xffff)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '-')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) ((v & 0xff00) >> 8)) < 0)
+ return (NULL);
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0)
+ return (NULL);
+
+ /* 'MM-' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '-')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'DD,' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '-')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'HH:' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ':')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'MM:' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ':')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'SS.' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '.')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'M(mseconds),' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ',')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'UTC' - optional */
+ ptr = endptr + 1;
+ if (*ptr == 'U' && *(ptr + 1) == 'T' && *(ptr + 1) == 'C')
+ ptr += 3;
+
+ /* '+/-' */
+ if (*ptr == '-' || *ptr == '+') {
+ if (snmp_suboid_append(oid, (asn_subid_t) (*ptr)) < 0)
+ return (NULL);
+ } else
+ goto error1;
+
+ /* 'HH:' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ':')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'MM' - last one - ignore endptr here. */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+
+ error:
+ errno = saved_errno;
+ error1:
+ warnx("Date value %s not supported", str);
+ return (NULL);
+}
+
+/* Read a DateAndTime string eg. 1992-5-26,13:30:15.0,-4:0. */
+static int32_t
+parse_dateandtime(struct snmp_value *sv, char *val)
+{
+ char *endptr;
+ uint32_t v;
+ uint8_t date[SNMP_DATETIME_OCTETS];
+
+ /* 'YYYY-' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 0xffff || *endptr != '-')
+ goto error;
+ date[0] = ((v & 0xff00) >> 8);
+ date[1] = (v & 0xff);
+ val = endptr + 1;
+
+ /* 'MM-' */
+ v = strtoul(val, &endptr, 10);
+ if (v == 0 || v > 12 || *endptr != '-')
+ goto error;
+ date[2] = v;
+ val = endptr + 1;
+
+ /* 'DD,' */
+ v = strtoul(val, &endptr, 10);
+ if (v == 0 || v > 31 || *endptr != ',')
+ goto error;
+ date[3] = v;
+ val = endptr + 1;
+
+ /* 'HH:' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 23 || *endptr != ':')
+ goto error;
+ date[4] = v;
+ val = endptr + 1;
+
+ /* 'MM:' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 59 || *endptr != ':')
+ goto error;
+ date[5] = v;
+ val = endptr + 1;
+
+ /* 'SS.' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 60 || *endptr != '.')
+ goto error;
+ date[6] = v;
+ val = endptr + 1;
+
+ /* '(deci-)s,' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 9 || *endptr != ',')
+ goto error;
+ date[7] = v;
+ val = endptr + 1;
+
+ /* offset - '+/-' */
+ if (*val != '-' && *val != '+')
+ goto error;
+ date[8] = (uint8_t) *val;
+ val = endptr + 1;
+
+ /* 'HH:' - offset from UTC */
+ v = strtoul(val, &endptr, 10);
+ if (v > 13 || *endptr != ':')
+ goto error;
+ date[9] = v;
+ val = endptr + 1;
+
+ /* 'MM'\0'' offset from UTC */
+ v = strtoul(val, &endptr, 10);
+ if (v > 59 || *endptr != '\0')
+ goto error;
+ date[10] = v;
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_DATETIME_OCTETS)) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_DATETIME_OCTETS;
+ memcpy(sv->v.octetstring.octets, date, SNMP_DATETIME_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+
+ error:
+ warnx("Date value %s not supported", val);
+ return (-1);
+}
+
+/**************************************************************
+ * PhysAddress
+ */
+static char *
+snmp_oct2physAddr(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+ uint32_t i;
+
+ if (len != SNMP_PHYSADDR_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+
+ ptr = buf;
+ ptr += sprintf(ptr, "%2.2x", octets[0]);
+ for (i = 1; i < 6; i++)
+ ptr += sprintf(ptr, ":%2.2x", octets[i]);
+
+ return (buf);
+}
+
+static char *
+snmp_addr2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v, i;
+ int saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_PHYSADDR_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ for (i = 0; i < 5; i++) {
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (*endptr != ':') {
+ warnx("Failed adding oid - %s",str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+ ptr = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_physaddress(struct snmp_value *sv, char *val)
+{
+ char *endptr;
+ int32_t i;
+ uint32_t v;
+ uint8_t phys_addr[SNMP_PHYSADDR_OCTETS];
+
+ for (i = 0; i < 5; i++) {
+ v = strtoul(val, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ }
+ if(*endptr != ':') {
+ warnx("Failed reading octet - %s", val);
+ return (-1);
+ }
+ phys_addr[i] = v;
+ val = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ v = strtoul(val, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ }
+ phys_addr[5] = v;
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_PHYSADDR_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_PHYSADDR_OCTETS;
+ memcpy(sv->v.octetstring.octets, phys_addr, SNMP_PHYSADDR_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+
+/**************************************************************
+ * NTPTimeStamp
+ **************************************************************
+ * NTP MIB, Revision 0.2, 7/25/97:
+ * NTPTimeStamp ::= TEXTUAL-CONVENTION
+ * DISPLAY-HINT "4x.4x"
+ * STATUS current
+ * DESCRIPTION
+ * ""
+ * SYNTAX OCTET STRING (SIZE(8))
+ */
+static char *
+snmp_oct2ntp_ts(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+ uint32_t i;
+
+ if (len != SNMP_NTP_TS_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+
+ ptr = buf;
+ i = octets[0] * 1000 + octets[1] * 100 + octets[2] * 10 + octets[3];
+ ptr += sprintf(ptr, "%4.4d", i);
+ i = octets[4] * 1000 + octets[5] * 100 + octets[6] * 10 + octets[7];
+ ptr += sprintf(ptr, ".%4.4d", i);
+
+ return (buf);
+}
+
+static char *
+snmp_ntp_ts2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v, i, d;
+ struct asn_oid suboid;
+ int saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_NTP_TS_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ warnx("Integer value %s not supported", str);
+ errno = saved_errno;
+ return (NULL);
+ } else
+ errno = saved_errno;
+
+ if (*endptr != '.') {
+ warnx("Failed adding oid - %s",str);
+ return (NULL);
+ }
+
+ memset(&suboid, 0, sizeof(struct asn_oid));
+ suboid.len = SNMP_NTP_TS_OCTETS;
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ suboid.subs[i] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ warnx("Integer value %s not supported", str);
+ errno = saved_errno;
+ return (NULL);
+ } else
+ errno = saved_errno;
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ suboid.subs[i + 4] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+
+ asn_append_oid(oid, &suboid);
+ return (endptr);
+}
+
+static int32_t
+parse_ntp_ts(struct snmp_value *sv, char *val)
+{
+ char *endptr;
+ int32_t i, d, saved_errno;
+ uint32_t v;
+ uint8_t ntp_ts[SNMP_NTP_TS_OCTETS];
+
+ saved_errno = errno;
+ v = strtoul(val, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ saved_errno = errno;
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ } else
+ saved_errno = errno;
+
+ if (*endptr != '.') {
+ warnx("Failed reading octet - %s", val);
+ return (-1);
+ }
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ ntp_ts[i] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+ val = endptr + 1;
+
+ saved_errno = errno;
+ v = strtoul(val, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ saved_errno = errno;
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ } else
+ saved_errno = errno;
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ ntp_ts[i + 4] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_NTP_TS_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_NTP_TS_OCTETS;
+ memcpy(sv->v.octetstring.octets, ntp_ts, SNMP_NTP_TS_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+
+/**************************************************************
+ * BridgeId
+ **************************************************************
+ * BRIDGE-MIB, REVISION "200509190000Z"
+ * BridgeId ::= TEXTUAL-CONVENTION
+ * STATUS current
+ * DESCRIPTION
+ * "The Bridge-Identifier, as used in the Spanning Tree
+ * Protocol, to uniquely identify a bridge. Its first two
+ * octets (in network byte order) contain a priority value,
+ * and its last 6 octets contain the MAC address used to
+ * refer to a bridge in a unique fashion (typically, the
+ * numerically smallest MAC address of all ports on the
+ * bridge)."
+ * SYNTAX OCTET STRING (SIZE (8))
+ */
+static char *
+snmp_oct2bridgeid(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+ uint32_t i, priority;
+
+ if (len != SNMP_BRIDGEID_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+ ptr = buf;
+
+ priority = octets[0] << 8;
+ priority += octets[1];
+ if (priority > SNMP_MAX_BRIDGE_PRIORITY) {
+ warnx("Invalid bridge priority %d", priority);
+ return (NULL);
+ } else
+ ptr += sprintf(ptr, "%d.", octets[0]);
+
+ ptr += sprintf(ptr, "%2.2x", octets[2]);
+
+ for (i = 1; i < 6; i++)
+ ptr += sprintf(ptr, ":%2.2x", octets[i + 2]);
+
+ return (buf);
+}
+
+static char *
+snmp_bridgeid2oct(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v, i;
+ int32_t saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BRIDGEID_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ /* Read the priority. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ errno = 0;
+
+ if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge priority value %d", v);
+ return (NULL);
+ }
+
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff00)) < 0)
+ return (NULL);
+
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0)
+ return (NULL);
+
+ ptr = endptr + 1;
+ for (i = 0; i < 5; i++) {
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (*endptr != ':') {
+ warnx("Failed adding oid - %s",str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+ ptr = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_bridge_id(struct snmp_value *sv, char *string)
+{
+ char *ptr, *endptr;
+ int32_t i, saved_errno;
+ uint32_t v;
+ uint8_t bridge_id[SNMP_BRIDGEID_OCTETS];
+
+ ptr = string;
+ /* Read the priority. */
+ saved_errno = errno;
+ errno = 0;
+ v = strtoul(string, &endptr, 10);
+ errno = saved_errno;
+
+ if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge priority value %d", v);
+ return (-1);
+ }
+
+ bridge_id[0] = (v & 0xff00);
+ bridge_id[1] = (v & 0xff);
+
+ string = endptr + 1;
+
+ for (i = 0; i < 5; i++) {
+ v = strtoul(string, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", string);
+ return (-1);
+ }
+ if(*endptr != ':') {
+ warnx("Failed reading octet - %s", string);
+ return (-1);
+ }
+ bridge_id[i + 2] = v;
+ string = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ v = strtoul(string, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", string);
+ return (-1);
+ }
+ bridge_id[7] = v;
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_BRIDGEID_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_BRIDGEID_OCTETS;
+ memcpy(sv->v.octetstring.octets, bridge_id, SNMP_BRIDGEID_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+
+/**************************************************************
+ * BridgePortId
+ **************************************************************
+ * BEGEMOT-BRIDGE-MIB, LAST-UPDATED "200608100000Z"
+ * BridgePortId ::= TEXTUAL-CONVENTION
+ * DISPLAY-HINT "1x.1x"
+ * STATUS current
+ * DESCRIPTION
+ * "A port identifier that contains a bridge port's STP priority
+ * in the first octet and the port number in the second octet."
+ * SYNTAX OCTET STRING (SIZE(2))
+ */
+static char *
+snmp_oct2bport_id(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+
+ if (len != SNMP_BPORT_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+ ptr = buf;
+
+ ptr += sprintf(ptr, "%d.", octets[0]);
+ ptr += sprintf(ptr, "%d", octets[1]);
+
+ return (buf);
+}
+
+static char *
+snmp_bport_id2oct(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v;
+ int saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BPORT_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ /* Read the priority. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ errno = 0;
+
+ if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge port priority value %d", v);
+ return (NULL);
+ }
+
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+
+ if (v > 0xff) {
+ warnx("Bad port number - %d", v);
+ return (NULL);
+ }
+
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_bport_id(struct snmp_value *value, char *string)
+{
+ char *ptr, *endptr;
+ int saved_errno;
+ uint32_t v;
+ uint8_t bport_id[SNMP_BPORT_OCTETS];
+
+ ptr = string;
+ /* Read the priority. */
+ saved_errno = errno;
+ errno = 0;
+ v = strtoul(string, &endptr, 10);
+ errno = saved_errno;
+
+ if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge port priority value %d", v);
+ return (-1);
+ }
+
+ bport_id[0] = v;
+
+ string = endptr + 1;
+ v = strtoul(string, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Bad port number - %d", v);
+ return (-1);
+ }
+
+ bport_id[1] = v;
+
+ if ((value->v.octetstring.octets = malloc(SNMP_BPORT_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ value->v.octetstring.len = SNMP_BPORT_OCTETS;
+ memcpy(value->v.octetstring.octets, bport_id, SNMP_BPORT_OCTETS);
+ value->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+/**************************************************************
+ * InetAddress
+ **************************************************************
+ * INET-ADDRESS-MIB, REVISION "200502040000Z"
+ * InetAddress ::= TEXTUAL-CONVENTION
+ * STATUS current
+ * DESCRIPTION
+ * "Denotes a generic Internet address.
+ *
+ * An InetAddress value is always interpreted within the context
+ * of an InetAddressType value. Every usage of the InetAddress
+ * textual convention is required to specify the InetAddressType
+ * object that provides the context. It is suggested that the
+ * InetAddressType object be logically registered before the
+ * object(s) that use the InetAddress textual convention, if
+ * they appear in the same logical row.
+ *
+ * The value of an InetAddress object must always be
+ * consistent with the value of the associated InetAddressType
+ * object. Attempts to set an InetAddress object to a value
+ * inconsistent with the associated InetAddressType
+ * must fail with an inconsistentValue error.
+ *
+ * When this textual convention is used as the syntax of an
+ * index object, there may be issues with the limit of 128
+ * sub-identifiers specified in SMIv2, STD 58. In this case,
+ * the object definition MUST include a 'SIZE' clause to
+ * limit the number of potential instance sub-identifiers;
+ * otherwise the applicable constraints MUST be stated in
+ * the appropriate conceptual row DESCRIPTION clauses, or
+ * in the surrounding documentation if there is no single
+ * DESCRIPTION clause that is appropriate."
+ * SYNTAX OCTET STRING (SIZE (0..255))
+ **************************************************************
+ * TODO: FIXME!!! syrinx: Since we do not support checking the
+ * consistency of a varbinding based on the value of a previous
+ * one, try to guess the type of address based on the
+ * OctetString SIZE - 4 for IPv4, 16 for IPv6, others currently
+ * not supported.
+ */
+static char *
+snmp_oct2inetaddr(uint32_t len, char *octets, char *buf)
+{
+ int af;
+ void *ip;
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+
+ if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL)
+ return (NULL);
+
+ switch (len) {
+ /* XXX: FIXME - IPv4*/
+ case 4:
+ memcpy(&ipv4.s_addr, octets, sizeof(ipv4.s_addr));
+ af = AF_INET;
+ ip = &ipv4;
+ break;
+
+ /* XXX: FIXME - IPv4*/
+ case 16:
+ memcpy(ipv6.s6_addr, octets, sizeof(ipv6.s6_addr));
+ af = AF_INET6;
+ ip = &ipv6;
+ break;
+
+ default:
+ return (NULL);
+ }
+
+ if (inet_ntop(af, ip, buf, SNMP_INADDRS_STRSZ) == NULL) {
+ warnx("inet_ntop failed - %s", strerror(errno));
+ return (NULL);
+ }
+
+ return (buf);
+}
+
+static char *
+snmp_inetaddr2oct(char *str, struct asn_oid *oid)
+{
+ return (NULL);
+}
+
+static int32_t
+parse_inetaddr(struct snmp_value *value, char *string)
+{
+ return (-1);
+}
+
+/**************************************************************
+ * SNMP BITS type - XXX: FIXME
+ **************************************************************/
+static char *
+snmp_oct2bits(uint32_t len, char *octets, char *buf)
+{
+ int i, bits;
+ uint64_t value;
+
+ if (len > sizeof(value) || octets == NULL || buf == NULL)
+ return (NULL);
+
+ for (i = len, value = 0, bits = 0; i > 0; i--, bits += 8)
+ value += octets[i] << bits;
+
+ buf[0]= '\0';
+ sprintf(buf, "0x%llx.",(long long unsigned) value);
+
+ return (buf);
+}
+
+static char *
+snmp_bits2oct(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ int i, size, bits, saved_errno;
+ uint64_t v, mask = 0xFF00000000000000;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(str, &endptr, 16);
+ if (errno != 0) {
+ warnx("Bad BITS value %s - %s", str, strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+
+ bits = 8;
+ /* Determine length - up to 8 octets supported so far. */
+ for (size = sizeof(v); size > 0; size--) {
+ if ((v & mask) != 0)
+ break;
+ mask = mask >> bits;
+ }
+
+ if (size == 0)
+ size = 1;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) size) < 0)
+ return (NULL);
+
+ for (i = 0, bits = 0; i < size; i++, bits += 8)
+ if (snmp_suboid_append(oid,
+ (asn_subid_t)((v & mask) >> bits)) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_bits(struct snmp_value *value, char *string)
+{
+ char *endptr;
+ int i, size, bits, saved_errno;
+ uint64_t v, mask = 0xFF00000000000000;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(string, &endptr, 16);
+
+ if (errno != 0) {
+ warnx("Bad BITS value %s - %s", string, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ bits = 8;
+ /* Determine length - up to 8 octets supported so far. */
+ for (size = sizeof(v); size > 0; size--) {
+ if ((v & mask) != 0)
+ break;
+ mask = mask >> bits;
+ }
+
+ if (size == 0)
+ size = 1;
+
+ if ((value->v.octetstring.octets = malloc(size)) == NULL) {
+ syslog(LOG_ERR, "malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ value->v.octetstring.len = size;
+ for (i = 0, bits = 0; i < size; i++, bits += 8)
+ value->v.octetstring.octets[i] = (v & mask) >> bits;
+ value->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h
new file mode 100644
index 0000000..fd06676
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * Textual conventions for snmp
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BSNMP_TEXT_CONV_H_
+#define _BSNMP_TEXT_CONV_H_
+
+/* Variable display length string. */
+#define SNMP_VAR_STRSZ -1
+
+/*
+ * 11 bytes - octets that represent DateAndTime Textual convention
+ * and the size of string used to diplay that.
+ */
+#define SNMP_DATETIME_OCTETS 11
+#define SNMP_DATETIME_STRSZ 32
+
+/*
+ * 6 bytes - octets that represent PhysAddress Textual convention
+ * and the size of string used to diplay that.
+ */
+#define SNMP_PHYSADDR_OCTETS 6
+#define SNMP_PHYSADDR_STRSZ 19
+
+/* NTPTimeStamp. */
+#define SNMP_NTP_TS_OCTETS 8
+#define SNMP_NTP_TS_STRSZ 10
+
+/* BridgeId. */
+#define SNMP_BRIDGEID_OCTETS 8
+#define SNMP_BRIDGEID_STRSZ 25
+#define SNMP_MAX_BRIDGE_PRIORITY 65535
+
+/* BridgePortId. */
+#define SNMP_BPORT_OCTETS 2
+#define SNMP_BPORT_STRSZ 7
+#define SNMP_MAX_BPORT_PRIORITY 255
+
+/* InetAddress. */
+#define SNMP_INADDRS_STRSZ INET6_ADDRSTRLEN
+
+enum snmp_tc {
+ SNMP_STRING = 0,
+ SNMP_DISPLAYSTRING = 1,
+ SNMP_DATEANDTIME = 2,
+ SNMP_PHYSADDR = 3,
+ SNMP_ATMESI = 4,
+ SNMP_NTP_TIMESTAMP = 5,
+ SNMP_MACADDRESS = 6,
+ SNMP_BRIDGE_ID = 7,
+ SNMP_BPORT_ID = 8,
+ SNMP_INETADDRESS = 9,
+ SNMP_TC_OWN = 10,
+ SNMP_UNKNOWN, /* keep last */
+};
+
+typedef char * (*snmp_oct2tc_f) (uint32_t len, char *octs, char *buf);
+typedef char * (*snmp_tc2oid_f) (char *str, struct asn_oid *oid);
+typedef int32_t (*snmp_tc2oct_f) (struct snmp_value *value, char *string);
+
+enum snmp_tc snmp_get_tc(char *str);
+char *snmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets);
+char *snmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid);
+int32_t snmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string);
+
+#endif /* _BSNMP_TEXT_CONV_H_ */
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
new file mode 100755
index 0000000..dbaac5b
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -0,0 +1,2121 @@
+/*-
+ * Copyright (c) 2005-2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * Helper functions for snmp client tools
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include <bsnmp/snmpclient.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+/* Internal varibale to turn on library debugging for testing and to
+ * find bugs. It is not exported via the header file.
+ * XXX should we cover it by some #ifdef BSNMPTOOLS_DEBUG? */
+int _bsnmptools_debug = 0;
+
+/* Default files to import mapping from if none explicitly provided. */
+#define bsnmpd_defs "/usr/share/snmp/defs/tree.def"
+#define mibII_defs "/usr/share/snmp/defs/mibII_tree.def"
+
+/*
+ * The .iso.org.dod oid that has to be prepended to every OID when requesting
+ * a value.
+ */
+const struct asn_oid IsoOrgDod_OID = {
+ 3, { 1, 3, 6 }
+};
+
+
+#define SNMP_ERR_UNKNOWN 0
+
+/*
+ * An array of error strings corresponding to error definitions from libbsnmp.
+ */
+static const struct {
+ const char *str;
+ int32_t error;
+} error_strings[] = {
+ { "Unknown", SNMP_ERR_UNKNOWN },
+ { "Too big ", SNMP_ERR_TOOBIG },
+ { "No such Name", SNMP_ERR_NOSUCHNAME },
+ { "Bad Value", SNMP_ERR_BADVALUE },
+ { "Readonly", SNMP_ERR_READONLY },
+ { "General error", SNMP_ERR_GENERR },
+ { "No access", SNMP_ERR_NO_ACCESS },
+ { "Wrong type", SNMP_ERR_WRONG_TYPE },
+ { "Wrong lenght", SNMP_ERR_WRONG_LENGTH },
+ { "Wrong encoding", SNMP_ERR_WRONG_ENCODING },
+ { "Wrong value", SNMP_ERR_WRONG_VALUE },
+ { "No creation", SNMP_ERR_NO_CREATION },
+ { "Inconsistent value", SNMP_ERR_INCONS_VALUE },
+ { "Resource unavailable", SNMP_ERR_RES_UNAVAIL },
+ { "Commit failed", SNMP_ERR_COMMIT_FAILED },
+ { "Undo failed", SNMP_ERR_UNDO_FAILED },
+ { "Authorization error", SNMP_ERR_AUTH_ERR },
+ { "Not writable", SNMP_ERR_NOT_WRITEABLE },
+ { "Inconsistent name", SNMP_ERR_INCONS_NAME },
+ { NULL, 0 }
+};
+
+/* This one and any following are exceptions. */
+#define SNMP_SYNTAX_UNKNOWN SNMP_SYNTAX_NOSUCHOBJECT
+
+static const struct {
+ const char *str;
+ enum snmp_syntax stx;
+} syntax_strings[] = {
+ { "Null", SNMP_SYNTAX_NULL },
+ { "Integer", SNMP_SYNTAX_INTEGER },
+ { "OctetString", SNMP_SYNTAX_OCTETSTRING },
+ { "OID", SNMP_SYNTAX_OID },
+ { "IpAddress", SNMP_SYNTAX_IPADDRESS },
+ { "Counter32", SNMP_SYNTAX_COUNTER },
+ { "Gauge", SNMP_SYNTAX_GAUGE },
+ { "TimeTicks", SNMP_SYNTAX_TIMETICKS },
+ { "Counter64", SNMP_SYNTAX_COUNTER64 },
+ { "Unknown", SNMP_SYNTAX_UNKNOWN },
+};
+
+int
+snmptool_init(struct snmp_toolinfo *snmptoolctx)
+{
+ char *str;
+ size_t slen;
+
+ memset(snmptoolctx, 0, sizeof(struct snmp_toolinfo));
+ snmptoolctx->objects = 0;
+ snmptoolctx->mappings = NULL;
+ snmptoolctx->flags = SNMP_PDU_GET; /* XXX */
+ SLIST_INIT(&snmptoolctx->filelist);
+ snmp_client_init(&snmp_client);
+
+ if (add_filename(snmptoolctx, bsnmpd_defs, &IsoOrgDod_OID, 0) < 0)
+ warnx("Error adding file %s to list", bsnmpd_defs);
+
+ if (add_filename(snmptoolctx, mibII_defs, &IsoOrgDod_OID, 0) < 0)
+ warnx("Error adding file %s to list", mibII_defs);
+
+ /* Read the environment */
+ if ((str = getenv("SNMPAUTH")) != NULL) {
+ slen = strlen(str);
+ if (slen == strlen("md5") && strcasecmp(str, "md5") == 0)
+ snmp_client.user.auth_proto = SNMP_AUTH_HMAC_MD5;
+ else if (slen == strlen("sha")&& strcasecmp(str, "sha") == 0)
+ snmp_client.user.auth_proto = SNMP_AUTH_HMAC_SHA;
+ else if (slen != 0)
+ warnx("Bad authentication type - %s in SNMPAUTH", str);
+ }
+
+ if ((str = getenv("SNMPPRIV")) != NULL) {
+ slen = strlen(str);
+ if (slen == strlen("des") && strcasecmp(str, "des") == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_DES;
+ else if (slen == strlen("aes")&& strcasecmp(str, "aes") == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_AES;
+ else if (slen != 0)
+ warnx("Bad privacy type - %s in SNMPPRIV", str);
+ }
+
+ if ((str = getenv("SNMPUSER")) != NULL) {
+ if ((slen = strlen(str)) > sizeof(snmp_client.user.sec_name)) {
+ warnx("Username too long - %s in SNMPUSER", str);
+ return (-1);
+ }
+ if (slen > 0) {
+ strlcpy(snmp_client.user.sec_name, str,
+ sizeof(snmp_client.user.sec_name));
+ snmp_client.version = SNMP_V3;
+ }
+ }
+
+ if ((str = getenv("SNMPPASSWD")) != NULL) {
+ if ((slen = strlen(str)) > MAXSTR)
+ slen = MAXSTR - 1;
+ if ((snmptoolctx->passwd = malloc(slen + 1)) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+ if (slen > 0)
+ strlcpy(snmptoolctx->passwd, str, slen + 1);
+ }
+
+ return (0);
+}
+
+#define OBJECT_IDX_LIST(o) o->info->table_idx->index_list
+
+/*
+ * Walk through the file list and import string<->oid mappings from each file.
+ */
+int32_t
+snmp_import_all(struct snmp_toolinfo *snmptoolctx)
+{
+ int32_t fc;
+ struct fname *tmp;
+
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ if (ISSET_NUMERIC(snmptoolctx))
+ return (0);
+
+ if ((snmptoolctx->mappings = snmp_mapping_init()) == NULL)
+ return (-1);
+
+ fc = 0;
+ if (SLIST_EMPTY(&snmptoolctx->filelist)) {
+ warnx("No files to read OID <-> string conversions from");
+ return (-1);
+ } else {
+ SLIST_FOREACH(tmp, &snmptoolctx->filelist, link) {
+ if (tmp->done)
+ continue;
+ if (snmp_import_file(snmptoolctx, tmp) < 0) {
+ fc = -1;
+ break;
+ }
+ fc++;
+ }
+ }
+
+ snmp_mapping_dump(snmptoolctx);
+ return (fc);
+}
+
+/*
+ * Add a filename to the file list - the initail idea of keeping a list with all
+ * files to read OIDs from was that an application might want to have loaded in
+ * memory the OIDs from a single file only and when done with them read the OIDs
+ * from another file. This is not used yet but might be a good idea at some
+ * point. Size argument is number of bytes in string including trailing '\0',
+ * not string lenght.
+ */
+int32_t
+add_filename(struct snmp_toolinfo *snmptoolctx, const char *filename,
+ const struct asn_oid *cut, int32_t done)
+{
+ char *fstring;
+ struct fname *entry;
+
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ /* Make sure file was not in list. */
+ SLIST_FOREACH(entry, &snmptoolctx->filelist, link) {
+ if (strncmp(entry->name, filename, strlen(entry->name)) == 0)
+ return (0);
+ }
+
+ if ((fstring = malloc(strlen(filename) + 1)) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+
+ if ((entry = malloc(sizeof(struct fname))) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ free(fstring);
+ return (-1);
+ }
+
+ memset(entry, 0, sizeof(struct fname));
+
+ if (cut != NULL)
+ asn_append_oid(&(entry->cut), cut);
+ strlcpy(fstring, filename, strlen(filename) + 1);
+ entry->name = fstring;
+ entry->done = done;
+ SLIST_INSERT_HEAD(&snmptoolctx->filelist, entry, link);
+
+ return (1);
+}
+
+void
+free_filelist(struct snmp_toolinfo *snmptoolctx)
+{
+ struct fname *f;
+
+ if (snmptoolctx == NULL)
+ return; /* XXX error handling */
+
+ while ((f = SLIST_FIRST(&snmptoolctx->filelist)) != NULL) {
+ SLIST_REMOVE_HEAD(&snmptoolctx->filelist, link);
+ if (f->name)
+ free(f->name);
+ free(f);
+ }
+}
+
+static char
+isvalid_fchar(char c, int pos)
+{
+ if (isalpha(c)|| c == '/'|| c == '_' || c == '.' || c == '~' ||
+ (pos != 0 && isdigit(c))){
+ return (c);
+ }
+
+ if (c == '\0')
+ return (0);
+
+ if (!isascii(c) || !isprint(c))
+ warnx("Unexpected character %#2x", (u_int) c);
+ else
+ warnx("Illegal character '%c'", c);
+
+ return (-1);
+}
+
+/*
+ * Re-implement getsubopt from scratch, because the second argument is broken
+ * and will not compile with WARNS=5.
+ * Copied from src/contrib/bsnmp/snmpd/main.c.
+ */
+static int
+getsubopt1(char **arg, const char *const *options, char **valp, char **optp)
+{
+ static const char *const delim = ",\t ";
+ u_int i;
+ char *ptr;
+
+ *optp = NULL;
+
+ /* Skip leading junk. */
+ for (ptr = *arg; *ptr != '\0'; ptr++)
+ if (strchr(delim, *ptr) == NULL)
+ break;
+ if (*ptr == '\0') {
+ *arg = ptr;
+ return (-1);
+ }
+ *optp = ptr;
+
+ /* Find the end of the option. */
+ while (*++ptr != '\0')
+ if (strchr(delim, *ptr) != NULL || *ptr == '=')
+ break;
+
+ if (*ptr != '\0') {
+ if (*ptr == '=') {
+ *ptr++ = '\0';
+ *valp = ptr;
+ while (*ptr != '\0' && strchr(delim, *ptr) == NULL)
+ ptr++;
+ if (*ptr != '\0')
+ *ptr++ = '\0';
+ } else
+ *ptr++ = '\0';
+ }
+
+ *arg = ptr;
+
+ for (i = 0; *options != NULL; options++, i++)
+ if (strcmp(*optp, *options) == 0)
+ return (i);
+ return (-1);
+}
+
+static int32_t
+parse_path(char *value)
+{
+ int32_t i, len;
+
+ if (value == NULL)
+ return (-1);
+
+ for (len = 0; len < MAXPATHLEN; len++) {
+ i = isvalid_fchar(*(value + len), len) ;
+
+ if (i == 0)
+ break;
+ else if (i < 0)
+ return (-1);
+ }
+
+ if (len >= MAXPATHLEN || value[len] != '\0') {
+ warnx("Bad pathname - '%s'", value);
+ return (-1);
+ }
+
+ return (len);
+}
+
+static int32_t
+parse_flist(struct snmp_toolinfo *snmptoolctx, char *value, char *path,
+ const struct asn_oid *cut)
+{
+ int32_t namelen;
+ char filename[MAXPATHLEN + 1];
+
+ if (value == NULL)
+ return (-1);
+
+ do {
+ memset(filename, 0, MAXPATHLEN + 1);
+
+ if (isalpha(*value) && (path == NULL || path[0] == '\0')) {
+ strlcpy(filename, SNMP_DEFS_DIR, MAXPATHLEN + 1);
+ namelen = strlen(SNMP_DEFS_DIR);
+ } else if (path != NULL){
+ strlcpy(filename, path, MAXPATHLEN + 1);
+ namelen = strlen(path);
+ } else
+ namelen = 0;
+
+ for ( ; namelen < MAXPATHLEN; value++) {
+ if (isvalid_fchar(*value, namelen) > 0) {
+ filename[namelen++] = *value;
+ continue;
+ }
+
+ if (*value == ',' )
+ value++;
+ else if (*value == '\0')
+ ;
+ else {
+ if (!isascii(*value) || !isprint(*value))
+ warnx("Unexpected character %#2x in"
+ " filename", (u_int) *value);
+ else
+ warnx("Illegal character '%c' in"
+ " filename", *value);
+ return (-1);
+ }
+
+ filename[namelen]='\0';
+ break;
+ }
+
+ if ((namelen == MAXPATHLEN) && (filename[MAXPATHLEN] != '\0')) {
+ warnx("Filename %s too long", filename);
+ return (-1);
+ }
+
+ if (add_filename(snmptoolctx, filename, cut, 0) < 0) {
+ warnx("Error adding file %s to list", filename);
+ return (-1);
+ }
+ } while (*value != '\0');
+
+ return(1);
+}
+
+static int32_t
+parse_ascii(char *ascii, uint8_t *binstr, size_t binlen)
+{
+ int32_t alen, count, saved_errno, i;
+ uint32_t val;
+ char dptr[3];
+
+ /* Filter 0x at the beggining */
+ if ((alen = strlen(ascii)) > 2 && ascii[0] == '0' && ascii[1] == 'x')
+ i = 2;
+ else
+ i = 0;
+
+ saved_errno = errno;
+ errno = 0;
+ for (count = 0; i < alen; i += 2) {
+ /* XXX: consider strlen(ascii) % 2 != 0 */
+ dptr[0] = ascii[i];
+ dptr[1] = ascii[i + 1];
+ dptr[2] = '\0';
+ if ((val = strtoul(dptr, NULL, 16)) > 0xFF || errno != 0) {
+ errno = saved_errno;
+ return (-1);
+ }
+ binstr[count] = (uint8_t) val;
+ if (++count >= binlen) {
+ warnx("Key %s too long - truncating to %zu octest",
+ ascii, binlen);
+ break;
+ }
+ }
+
+ return (count);
+}
+
+/*
+ * Functions to parse common input options for client tools and fill in the
+ * snmp_client structure.
+ */
+int32_t
+parse_authentication(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt;
+ char *val, *option;
+ const char *const subopts[] = {
+ "proto",
+ "key",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'proto' requires an argument");
+ return (-1);
+ }
+ if (strlen(val) != 3) {
+ warnx("Unknown auth protocol - %s", val);
+ return (-1);
+ }
+ if (strncasecmp("md5", val, strlen("md5")) == 0)
+ snmp_client.user.auth_proto =
+ SNMP_AUTH_HMAC_MD5;
+ else if (strncasecmp("sha", val, strlen("sha")) == 0)
+ snmp_client.user.auth_proto =
+ SNMP_AUTH_HMAC_SHA;
+ else {
+ warnx("Unknown auth protocol - %s", val);
+ return (-1);
+ }
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'key' requires an argument");
+ return (-1);
+ }
+ if (parse_ascii(val, snmp_client.user.auth_key,
+ SNMP_AUTH_KEY_SIZ) < 0) {
+ warnx("Bad authentication key- %s", val);
+ return (-1);
+ }
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_privacy(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt;
+ char *val, *option;
+ const char *const subopts[] = {
+ "proto",
+ "key",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'proto' requires an argument");
+ return (-1);
+ }
+ if (strlen(val) != 3) {
+ warnx("Unknown privacy protocol - %s", val);
+ return (-1);
+ }
+ if (strncasecmp("aes", val, strlen("aes")) == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_AES;
+ else if (strncasecmp("des", val, strlen("des")) == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_DES;
+ else {
+ warnx("Unknown privacy protocol - %s", val);
+ return (-1);
+ }
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'key' requires an argument");
+ return (-1);
+ }
+ if (parse_ascii(val, snmp_client.user.priv_key,
+ SNMP_PRIV_KEY_SIZ) < 0) {
+ warnx("Bad privacy key- %s", val);
+ return (-1);
+ }
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_context(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt;
+ char *val, *option;
+ const char *const subopts[] = {
+ "context",
+ "context-engine",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'context' - no argument");
+ return (-1);
+ }
+ strlcpy(snmp_client.cname, val, SNMP_CONTEXT_NAME_SIZ);
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'context-engine' - no argument");
+ return (-1);
+ }
+ if ((snmp_client.clen = parse_ascii(val,
+ snmp_client.cengine, SNMP_ENGINE_ID_SIZ)) < 0) {
+ warnx("Bad EngineID - %s", val);
+ return (-1);
+ }
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_user_security(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt, saved_errno;
+ char *val, *option;
+ const char *const subopts[] = {
+ "engine",
+ "engine-boots",
+ "engine-time",
+ "name",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'engine' - no argument");
+ return (-1);
+ }
+ snmp_client.engine.engine_len = parse_ascii(val,
+ snmp_client.engine.engine_id, SNMP_ENGINE_ID_SIZ);
+ if (snmp_client.engine.engine_len < 0) {
+ warnx("Bad EngineID - %s", val);
+ return (-1);
+ }
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'engine-boots' - no argument");
+ return (-1);
+ }
+ saved_errno = errno;
+ errno = 0;
+ snmp_client.engine.engine_boots = strtoul(val, NULL, 10);
+ if (errno != 0) {
+ warnx("Bad 'engine-boots' value %s - %s", val,
+ strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+ errno = saved_errno;
+ break;
+ case 2:
+ if (val == NULL) {
+ warnx("Suboption 'engine-time' - no argument");
+ return (-1);
+ }
+ saved_errno = errno;
+ errno = 0;
+ snmp_client.engine.engine_time = strtoul(val, NULL, 10);
+ if (errno != 0) {
+ warnx("Bad 'engine-time' value %s - %s", val,
+ strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+ errno = saved_errno;
+ break;
+ case 3:
+ strlcpy(snmp_client.user.sec_name, val,
+ SNMP_ADM_STR32_SIZ);
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_file(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (parse_flist(snmptoolctx, opt_arg, NULL, &IsoOrgDod_OID) < 0)
+ return (-1);
+
+ return (2);
+}
+
+int32_t
+parse_include(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ char path[MAXPATHLEN + 1];
+ int32_t cut_dflt, len, subopt;
+ struct asn_oid cut;
+ char *val, *option;
+ const char *const subopts[] = {
+ "cut",
+ "path",
+ "file",
+ NULL
+ };
+
+#define INC_CUT 0
+#define INC_PATH 1
+#define INC_LIST 2
+
+ assert(opt_arg != NULL);
+
+ /* if (opt == 'i')
+ free_filelist(snmptoolctx, ); */
+ /*
+ * This function should be called only after getopt(3) - otherwise if
+ * no previous validation of opt_arg strlen() may not return what is
+ * expected.
+ */
+
+ path[0] = '\0';
+ memset(&cut, 0, sizeof(struct asn_oid));
+ cut_dflt = -1;
+
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case INC_CUT:
+ if (val == NULL) {
+ warnx("Suboption 'cut' requires an argument");
+ return (-1);
+ } else {
+ if (snmp_parse_numoid(val, &cut) < 0)
+ return (-1);
+ }
+ cut_dflt = 1;
+ break;
+
+ case INC_PATH:
+ if ((len = parse_path(val)) < 0)
+ return (-1);
+ strlcpy(path, val, len + 1);
+ break;
+
+ case INC_LIST:
+ if (val == NULL)
+ return (-1);
+ if (cut_dflt == -1)
+ len = parse_flist(snmptoolctx, val, path, &IsoOrgDod_OID);
+ else
+ len = parse_flist(snmptoolctx, val, path, &cut);
+ if (len < 0)
+ return (-1);
+ break;
+
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ }
+
+ /* XXX: Fix me - returning two is wrong here */
+ return (2);
+}
+
+int32_t
+parse_server(char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (snmp_parse_server(&snmp_client, opt_arg) < 0)
+ return (-1);
+
+ if (snmp_client.trans > SNMP_TRANS_UDP && snmp_client.chost == NULL) {
+ if ((snmp_client.chost = malloc(strlen(SNMP_DEFAULT_LOCAL + 1)))
+ == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+ strcpy(snmp_client.chost, SNMP_DEFAULT_LOCAL);
+ }
+
+ return (2);
+}
+
+int32_t
+parse_timeout(char *opt_arg)
+{
+ int32_t v, saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtol(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx( "Error parsing timeout value - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ snmp_client.timeout.tv_sec = v;
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_retry(char *opt_arg)
+{
+ uint32_t v;
+ int32_t saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx("Error parsing retries count - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ snmp_client.retries = v;
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_version(char *opt_arg)
+{
+ uint32_t v;
+ int32_t saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx("Error parsing version - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ switch (v) {
+ case 1:
+ snmp_client.version = SNMP_V1;
+ break;
+ case 2:
+ snmp_client.version = SNMP_V2c;
+ break;
+ case 3:
+ snmp_client.version = SNMP_V3;
+ break;
+ default:
+ warnx("Unsupported SNMP version - %u", v);
+ errno = saved_errno;
+ return (-1);
+ }
+
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_local_path(char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (sizeof(opt_arg) > sizeof(SNMP_LOCAL_PATH)) {
+ warnx("Filename too long - %s", opt_arg);
+ return (-1);
+ }
+
+ strlcpy(snmp_client.local_path, opt_arg, sizeof(SNMP_LOCAL_PATH));
+ return (2);
+}
+
+int32_t
+parse_buflen(char *opt_arg)
+{
+ uint32_t size;
+ int32_t saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ size = strtoul(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx("Error parsing buffer size - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ if (size > MAX_BUFF_SIZE) {
+ warnx("Buffer size too big - %d max allowed", MAX_BUFF_SIZE);
+ errno = saved_errno;
+ return (-1);
+ }
+
+ snmp_client.txbuflen = snmp_client.rxbuflen = size;
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_debug(void)
+{
+ snmp_client.dump_pdus = 1;
+ return (1);
+}
+
+int32_t
+parse_discovery(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_EDISCOVER(snmptoolctx);
+ snmp_client.version = SNMP_V3;
+ return (1);
+}
+
+int32_t
+parse_local_key(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_LOCALKEY(snmptoolctx);
+ snmp_client.version = SNMP_V3;
+ return (1);
+}
+
+int32_t
+parse_num_oids(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_NUMERIC(snmptoolctx);
+ return (1);
+}
+
+int32_t
+parse_output(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (strlen(opt_arg) > strlen("verbose")) {
+ warnx( "Invalid output option - %s",opt_arg);
+ return (-1);
+ }
+
+ if (strncasecmp(opt_arg, "short", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_SHORT);
+ else if (strncasecmp(opt_arg, "verbose", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_VERBOSE);
+ else if (strncasecmp(opt_arg,"tabular", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_TABULAR);
+ else if (strncasecmp(opt_arg, "quiet", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_QUIET);
+ else {
+ warnx( "Invalid output option - %s", opt_arg);
+ return (-1);
+ }
+
+ return (2);
+}
+
+int32_t
+parse_errors(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_RETRY(snmptoolctx);
+ return (1);
+}
+
+int32_t
+parse_skip_access(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_ERRIGNORE(snmptoolctx);
+ return (1);
+}
+
+char *
+snmp_parse_suboid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ asn_subid_t suboid;
+
+ if (*str == '.')
+ str++;
+
+ if (*str < '0' || *str > '9')
+ return (str);
+
+ do {
+ suboid = strtoul(str, &endptr, 10);
+ if ((asn_subid_t) suboid > ASN_MAXID) {
+ warnx("Suboid %u > ASN_MAXID", suboid);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, suboid) < 0)
+ return (NULL);
+ str = endptr + 1;
+ } while (*endptr == '.');
+
+ return (endptr);
+}
+
+static char *
+snmp_int2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ int32_t v, saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtol(str, &endptr, 10);
+ if (errno != 0) {
+ warnx("Integer value %s not supported - %s", str,
+ strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+ errno = saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+/* It is a bit weird to have a table indexed by OID but still... */
+static char *
+snmp_oid2asn_oid(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct asn_oid *oid)
+{
+ int32_t i;
+ char string[MAXSTR], *endptr;
+ struct snmp_object obj;
+
+ for (i = 0; i < MAXSTR; i++)
+ if (isalpha (*(str + i)) == 0)
+ break;
+
+ endptr = str + i;
+ memset(&obj, 0, sizeof(struct snmp_object));
+ if (i == 0) {
+ if ((endptr = snmp_parse_suboid(str, &(obj.val.var))) == NULL)
+ return (NULL);
+ if (snmp_suboid_append(oid, (asn_subid_t) obj.val.var.len) < 0)
+ return (NULL);
+ } else {
+ strlcpy(string, str, i + 1);
+ string[i] = '\0';
+ if (snmp_lookup_enumoid(snmptoolctx, &obj, string) < 0) {
+ warnx("Unknown string - %s",string);
+ return (NULL);
+ }
+ free(string);
+ }
+
+ asn_append_oid(oid, &(obj.val.var));
+ return (endptr);
+}
+
+static char *
+snmp_ip2asn_oid(char *str, struct asn_oid *oid)
+{
+ uint32_t v;
+ int32_t i;
+ char *endptr, *ptr;
+
+ ptr = str;
+ for (i = 0; i < 4; i++) {
+ v = strtoul(ptr, &endptr, 10);
+ if (v > 0xff)
+ return (NULL);
+ if (*endptr != '.' && strchr("],\0", *endptr) == NULL && i != 3)
+ return (NULL);
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+ ptr = endptr + 1;
+ }
+
+ return (endptr);
+}
+
+/* 32-bit counter, gauge, timeticks. */
+static char *
+snmp_uint2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ uint32_t v;
+ int32_t saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(str, &endptr, 10);
+ if (errno != 0) {
+ warnx("Integer value %s not supported - %s\n", str,
+ strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+ errno = saved_errno;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static char *
+snmp_cnt64_2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ uint64_t v;
+ int32_t saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(str, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Integer value %s not supported - %s", str,
+ strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+ errno = saved_errno;
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xffffffff)) < 0)
+ return (NULL);
+
+ if (snmp_suboid_append(oid, (asn_subid_t) (v >> 32)) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+enum snmp_syntax
+parse_syntax(char *str)
+{
+ int32_t i;
+
+ for (i = 0; i < SNMP_SYNTAX_UNKNOWN; i++) {
+ if (strncmp(syntax_strings[i].str, str,
+ strlen(syntax_strings[i].str)) == 0)
+ return (syntax_strings[i].stx);
+ }
+
+ return (SNMP_SYNTAX_NULL);
+}
+
+static char *
+snmp_parse_subindex(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct index *idx, struct snmp_object *object)
+{
+ char *ptr;
+ int32_t i;
+ enum snmp_syntax stx;
+ char syntax[MAX_CMD_SYNTAX_LEN];
+
+ ptr = str;
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) {
+ for (i = 0; i < MAX_CMD_SYNTAX_LEN ; i++) {
+ if (*(ptr + i) == ':')
+ break;
+ }
+
+ if (i >= MAX_CMD_SYNTAX_LEN) {
+ warnx("Unknown syntax in OID - %s", str);
+ return (NULL);
+ }
+ /* Expect a syntax string here. */
+ if ((stx = parse_syntax(str)) <= SNMP_SYNTAX_NULL) {
+ warnx("Invalid syntax - %s",syntax);
+ return (NULL);
+ }
+
+ if (stx != idx->syntax && !ISSET_ERRIGNORE(snmptoolctx)) {
+ warnx("Syntax mismatch - %d expected, %d given",
+ idx->syntax, stx);
+ return (NULL);
+ }
+ /*
+ * That is where the suboid started + the syntax length + one
+ * character for ':'.
+ */
+ ptr = str + i + 1;
+ } else
+ stx = idx->syntax;
+
+ switch (stx) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_int2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_OID:
+ return (snmp_oid2asn_oid(snmptoolctx, ptr,
+ &(object->val.var)));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_ip2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_COUNTER:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_GAUGE:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_uint2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_cnt64_2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_tc2oid(idx->tc, ptr, &(object->val.var)));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (NULL);
+}
+
+char *
+snmp_parse_index(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct snmp_object *object)
+{
+ char *ptr;
+ struct index *temp;
+
+ if (object->info->table_idx == NULL)
+ return (NULL);
+
+ ptr = NULL;
+ STAILQ_FOREACH(temp, &(OBJECT_IDX_LIST(object)), link) {
+ if ((ptr = snmp_parse_subindex(snmptoolctx, str, temp, object))
+ == NULL)
+ return (NULL);
+
+ if (*ptr != ',' && *ptr != ']')
+ return (NULL);
+ str = ptr + 1;
+ }
+
+ if (ptr == NULL || *ptr != ']') {
+ warnx("Mismatching index - %s", str);
+ return (NULL);
+ }
+
+ return (ptr + 1);
+}
+
+/*
+ * Fill in the struct asn_oid member of snmp_value with suboids from input.
+ * If an error occurs - print message on stderr and return (-1).
+ * If all is ok - return the length of the oid.
+ */
+int32_t
+snmp_parse_numoid(char *argv, struct asn_oid *var)
+{
+ char *endptr, *str;
+ asn_subid_t suboid;
+
+ str = argv;
+
+ if (*str == '.')
+ str++;
+
+ do {
+ if (var->len == ASN_MAXOIDLEN) {
+ warnx("Oid too long - %u", var->len);
+ return (-1);
+ }
+
+ suboid = strtoul(str, &endptr, 10);
+ if (suboid > ASN_MAXID) {
+ warnx("Oid too long - %u", var->len);
+ return (-1);
+ }
+
+ var->subs[var->len++] = suboid;
+ str = endptr + 1;
+ } while ( *endptr == '.');
+
+ if (*endptr != '\0') {
+ warnx("Invalid oid string - %s", argv);
+ return (-1);
+ }
+
+ return (var->len);
+}
+
+/* Append a length 1 suboid to an asn_oid structure. */
+int32_t
+snmp_suboid_append(struct asn_oid *var, asn_subid_t suboid)
+{
+ if (var == NULL)
+ return (-1);
+
+ if (var->len >= ASN_MAXOIDLEN) {
+ warnx("Oid too long - %u", var->len);
+ return (-1);
+ }
+
+ var->subs[var->len++] = suboid;
+
+ return (1);
+}
+
+/* Pop the last suboid from an asn_oid structure. */
+int32_t
+snmp_suboid_pop(struct asn_oid *var)
+{
+ asn_subid_t suboid;
+
+ if (var == NULL)
+ return (-1);
+
+ if (var->len < 1)
+ return (-1);
+
+ suboid = var->subs[--(var->len)];
+ var->subs[var->len] = 0;
+
+ return (suboid);
+}
+
+/*
+ * Parse the command-line provided string into an OID - alocate memory for a new
+ * snmp object, fill in its fields and insert it in the object list. A
+ * (snmp_verify_inoid_f) function must be provided to validate the input string.
+ */
+int32_t
+snmp_object_add(struct snmp_toolinfo *snmptoolctx, snmp_verify_inoid_f func,
+ char *string)
+{
+ struct snmp_object *obj;
+
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ /* XXX-BZ does that chack make sense? */
+ if (snmptoolctx->objects >= SNMP_MAX_BINDINGS) {
+ warnx("Too many bindings in PDU - %u", snmptoolctx->objects + 1);
+ return (-1);
+ }
+
+ if ((obj = malloc(sizeof(struct snmp_object))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(obj, 0, sizeof(struct snmp_object));
+ if (func(snmptoolctx, obj, string) < 0) {
+ warnx("Invalid OID - %s", string);
+ free(obj);
+ return (-1);
+ }
+
+ snmptoolctx->objects++;
+ SLIST_INSERT_HEAD(&snmptoolctx->snmp_objectlist, obj, link);
+
+ return (1);
+}
+
+/* Given an OID, find it in the object list and remove it. */
+int32_t
+snmp_object_remove(struct snmp_toolinfo *snmptoolctx, struct asn_oid *oid)
+{
+ struct snmp_object *temp;
+
+ if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist)) {
+ warnx("Object list already empty");
+ return (-1);
+ }
+
+
+ SLIST_FOREACH(temp, &snmptoolctx->snmp_objectlist, link)
+ if (asn_compare_oid(&(temp->val.var), oid) == 0)
+ break;
+
+ if (temp == NULL) {
+ warnx("No such object in list");
+ return (-1);
+ }
+
+ SLIST_REMOVE(&snmptoolctx->snmp_objectlist, temp, snmp_object, link);
+ if (temp->val.syntax == SNMP_SYNTAX_OCTETSTRING &&
+ temp->val.v.octetstring.octets != NULL)
+ free(temp->val.v.octetstring.octets);
+ free(temp);
+
+ return (1);
+}
+
+static void
+snmp_object_freeall(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_object *o;
+
+ while ((o = SLIST_FIRST(&snmptoolctx->snmp_objectlist)) != NULL) {
+ SLIST_REMOVE_HEAD(&snmptoolctx->snmp_objectlist, link);
+
+ if (o->val.syntax == SNMP_SYNTAX_OCTETSTRING &&
+ o->val.v.octetstring.octets != NULL)
+ free(o->val.v.octetstring.octets);
+ free(o);
+ }
+}
+
+/* Do all possible memory release before exit. */
+void
+snmp_tool_freeall(struct snmp_toolinfo *snmptoolctx)
+{
+ if (snmp_client.chost != NULL) {
+ free(snmp_client.chost);
+ snmp_client.chost = NULL;
+ }
+
+ if (snmp_client.cport != NULL) {
+ free(snmp_client.cport);
+ snmp_client.cport = NULL;
+ }
+
+ snmp_mapping_free(snmptoolctx);
+ free_filelist(snmptoolctx);
+ snmp_object_freeall(snmptoolctx);
+
+ if (snmptoolctx->passwd != NULL) {
+ free(snmptoolctx->passwd);
+ snmptoolctx->passwd = NULL;
+ }
+}
+
+/*
+ * Fill all variables from the object list into a PDU. (snmp_verify_vbind_f)
+ * function should check whether the variable is consistent in this PDU
+ * (e.g do not add non-leaf OIDs to a GET PDU, or OIDs with read access only to
+ * a SET PDU) - might be NULL though. (snmp_add_vbind_f) function is the
+ * function actually adds the variable to the PDU and must not be NULL.
+ */
+int32_t
+snmp_pdu_add_bindings(struct snmp_toolinfo *snmptoolctx,
+ snmp_verify_vbind_f vfunc, snmp_add_vbind_f afunc,
+ struct snmp_pdu *pdu, int32_t maxcount)
+{
+ int32_t nbindings, abind;
+ struct snmp_object *obj;
+
+ if (pdu == NULL || afunc == NULL)
+ return (-1);
+
+ /* Return 0 in case of no more work todo. */
+ if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist))
+ return (0);
+
+ if (maxcount < 0 || maxcount > SNMP_MAX_BINDINGS) {
+ warnx("maxcount out of range: <0 || >SNMP_MAX_BINDINGS");
+ return (-1);
+ }
+
+ nbindings = 0;
+ SLIST_FOREACH(obj, &snmptoolctx->snmp_objectlist, link) {
+ if ((vfunc != NULL) && (vfunc(snmptoolctx, pdu, obj) < 0)) {
+ nbindings = -1;
+ break;
+ }
+ if ((abind = afunc(pdu, obj)) < 0) {
+ nbindings = -1;
+ break;
+ }
+
+ if (abind > 0) {
+ /* Do not put more varbindings than requested. */
+ if (++nbindings >= maxcount)
+ break;
+ }
+ }
+
+ return (nbindings);
+}
+
+/*
+ * Locate an object in the object list and set a corresponding error status.
+ */
+int32_t
+snmp_object_seterror(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_value *err_value, int32_t error_status)
+{
+ struct snmp_object *obj;
+
+ if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist) || err_value == NULL)
+ return (-1);
+
+ SLIST_FOREACH(obj, &snmptoolctx->snmp_objectlist, link)
+ if (asn_compare_oid(&(err_value->var), &(obj->val.var)) == 0) {
+ obj->error = error_status;
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Check a PDU received in responce to a SNMP_PDU_GET/SNMP_PDU_GETBULK request
+ * but don't compare syntaxes - when sending a request PDU they must be null.
+ * This is a (almost) complete copy of snmp_pdu_check() - with matching syntaxes
+ * checks and some other checks skiped.
+ */
+int32_t
+snmp_parse_get_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ uint32_t i;
+
+ for (i = 0; i < req->nbindings; i++) {
+ if (asn_compare_oid(&req->bindings[i].var,
+ &resp->bindings[i].var) != 0) {
+ warnx("Bad OID in response");
+ return (-1);
+ }
+
+ if (snmp_client.version != SNMP_V1 && (resp->bindings[i].syntax
+ == SNMP_SYNTAX_NOSUCHOBJECT || resp->bindings[i].syntax ==
+ SNMP_SYNTAX_NOSUCHINSTANCE))
+ return (0);
+ }
+
+ return (1);
+}
+
+int32_t
+snmp_parse_getbulk_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ int32_t N, R, M, r;
+
+ if (req->error_status > (int32_t) resp->nbindings) {
+ warnx("Bad number of bindings in response");
+ return (-1);
+ }
+
+ for (N = 0; N < req->error_status; N++) {
+ if (asn_is_suboid(&req->bindings[N].var,
+ &resp->bindings[N].var) == 0)
+ return (0);
+ if (resp->bindings[N].syntax == SNMP_SYNTAX_ENDOFMIBVIEW)
+ return (0);
+ }
+
+ for (R = N , r = N; R < (int32_t) req->nbindings; R++) {
+ for (M = 0; M < req->error_index && (r + M) <
+ (int32_t) resp->nbindings; M++) {
+ if (asn_is_suboid(&req->bindings[R].var,
+ &resp->bindings[r + M].var) == 0)
+ return (0);
+
+ if (resp->bindings[r + M].syntax ==
+ SNMP_SYNTAX_ENDOFMIBVIEW) {
+ M++;
+ break;
+ }
+ }
+ r += M;
+ }
+
+ return (0);
+}
+
+int32_t
+snmp_parse_getnext_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ uint32_t i;
+
+ for (i = 0; i < req->nbindings; i++) {
+ if (asn_is_suboid(&req->bindings[i].var, &resp->bindings[i].var)
+ == 0)
+ return (0);
+
+ if (resp->version != SNMP_V1 && resp->bindings[i].syntax ==
+ SNMP_SYNTAX_ENDOFMIBVIEW)
+ return (0);
+ }
+
+ return (1);
+}
+
+/*
+ * Should be called to check a responce to get/getnext/getbulk.
+ */
+int32_t
+snmp_parse_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ if (resp == NULL || req == NULL)
+ return (-2);
+
+ if (resp->version != req->version) {
+ warnx("Response has wrong version");
+ return (-1);
+ }
+
+ if (resp->error_status == SNMP_ERR_NOSUCHNAME) {
+ warnx("Error - No Such Name");
+ return (0);
+ }
+
+ if (resp->error_status != SNMP_ERR_NOERROR) {
+ warnx("Error %d in responce", resp->error_status);
+ return (-1);
+ }
+
+ if (resp->nbindings != req->nbindings && req->type != SNMP_PDU_GETBULK){
+ warnx("Bad number of bindings in response");
+ return (-1);
+ }
+
+ switch (req->type) {
+ case SNMP_PDU_GET:
+ return (snmp_parse_get_resp(resp,req));
+ case SNMP_PDU_GETBULK:
+ return (snmp_parse_getbulk_resp(resp,req));
+ case SNMP_PDU_GETNEXT:
+ return (snmp_parse_getnext_resp(resp,req));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (-2);
+}
+
+static void
+snmp_output_octetstring(struct snmp_toolinfo *snmptoolctx, enum snmp_tc tc,
+ uint32_t len, uint8_t *octets)
+{
+ char *buf;
+
+ if (len == 0 || octets == NULL)
+ return;
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_OCTETSTRING].str);
+
+ if ((buf = snmp_oct2tc(tc, len, (char *) octets)) != NULL) {
+ fprintf(stdout, "%s", buf);
+ free(buf);
+ }
+}
+
+static void
+snmp_output_octetindex(struct snmp_toolinfo *snmptoolctx, enum snmp_tc tc,
+ struct asn_oid *oid)
+{
+ uint32_t i;
+ uint8_t *s;
+
+ if ((s = malloc(oid->subs[0] + 1)) == NULL)
+ syslog(LOG_ERR, "malloc failed - %s", strerror(errno));
+ else {
+ for (i = 0; i < oid->subs[0]; i++)
+ s[i] = (u_char) (oid->subs[i + 1]);
+
+ snmp_output_octetstring(snmptoolctx, tc, oid->subs[0], s);
+ free(s);
+ }
+}
+
+/*
+ * Check and output syntax type and value.
+ */
+static void
+snmp_output_oid_value(struct snmp_toolinfo *snmptoolctx, struct asn_oid *oid)
+{
+ char oid_string[ASN_OIDSTRLEN];
+ struct snmp_object obj;
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ", syntax_strings[SNMP_SYNTAX_OID].str);
+
+ if(!ISSET_NUMERIC(snmptoolctx)) {
+ memset(&obj, 0, sizeof(struct snmp_object));
+ asn_append_oid(&(obj.val.var), oid);
+
+ if (snmp_lookup_enumstring(snmptoolctx, &obj) > 0)
+ fprintf(stdout, "%s" , obj.info->string);
+ else if (snmp_lookup_oidstring(snmptoolctx, &obj) > 0)
+ fprintf(stdout, "%s" , obj.info->string);
+ else if (snmp_lookup_nodestring(snmptoolctx, &obj) > 0)
+ fprintf(stdout, "%s" , obj.info->string);
+ else {
+ (void) asn_oid2str_r(oid, oid_string);
+ fprintf(stdout, "%s", oid_string);
+ }
+ } else {
+ (void) asn_oid2str_r(oid, oid_string);
+ fprintf(stdout, "%s", oid_string);
+ }
+}
+
+static void
+snmp_output_int(struct snmp_toolinfo *snmptoolctx, struct enum_pairs *enums,
+ int32_t int_val)
+{
+ char *string;
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_INTEGER].str);
+
+ if (enums != NULL && (string = enum_string_lookup(enums, int_val))
+ != NULL)
+ fprintf(stdout, "%s", string);
+ else
+ fprintf(stdout, "%d", int_val);
+}
+
+static void
+snmp_output_ipaddress(struct snmp_toolinfo *snmptoolctx, uint8_t *ip)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_IPADDRESS].str);
+
+ fprintf(stdout, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
+}
+
+static void
+snmp_output_counter(struct snmp_toolinfo *snmptoolctx, uint32_t counter)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_COUNTER].str);
+
+ fprintf(stdout, "%u", counter);
+}
+
+static void
+snmp_output_gauge(struct snmp_toolinfo *snmptoolctx, uint32_t gauge)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ", syntax_strings[SNMP_SYNTAX_GAUGE].str);
+
+ fprintf(stdout, "%u", gauge);
+}
+
+static void
+snmp_output_ticks(struct snmp_toolinfo *snmptoolctx, uint32_t ticks)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_TIMETICKS].str);
+
+ fprintf(stdout, "%u", ticks);
+}
+
+static void
+snmp_output_counter64(struct snmp_toolinfo *snmptoolctx, uint64_t counter64)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_COUNTER64].str);
+
+ fprintf(stdout,"%ju", counter64);
+}
+
+int32_t
+snmp_output_numval(struct snmp_toolinfo *snmptoolctx, struct snmp_value *val,
+ struct snmp_oid2str *entry)
+{
+ if (val == NULL)
+ return (-1);
+
+ if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET)
+ fprintf(stdout, " = ");
+
+ switch (val->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ if (entry != NULL)
+ snmp_output_int(snmptoolctx, entry->snmp_enum,
+ val->v.integer);
+ else
+ snmp_output_int(snmptoolctx, NULL, val->v.integer);
+ break;
+
+ case SNMP_SYNTAX_OCTETSTRING:
+ if (entry != NULL)
+ snmp_output_octetstring(snmptoolctx, entry->tc,
+ val->v.octetstring.len, val->v.octetstring.octets);
+ else
+ snmp_output_octetstring(snmptoolctx, SNMP_STRING,
+ val->v.octetstring.len, val->v.octetstring.octets);
+ break;
+
+ case SNMP_SYNTAX_OID:
+ snmp_output_oid_value(snmptoolctx, &(val->v.oid));
+ break;
+
+ case SNMP_SYNTAX_IPADDRESS:
+ snmp_output_ipaddress(snmptoolctx, val->v.ipaddress);
+ break;
+
+ case SNMP_SYNTAX_COUNTER:
+ snmp_output_counter(snmptoolctx, val->v.uint32);
+ break;
+
+ case SNMP_SYNTAX_GAUGE:
+ snmp_output_gauge(snmptoolctx, val->v.uint32);
+ break;
+
+ case SNMP_SYNTAX_TIMETICKS:
+ snmp_output_ticks(snmptoolctx, val->v.uint32);
+ break;
+
+ case SNMP_SYNTAX_COUNTER64:
+ snmp_output_counter64(snmptoolctx, val->v.counter64);
+ break;
+
+ case SNMP_SYNTAX_NOSUCHOBJECT:
+ fprintf(stdout, "No Such Object\n");
+ return (val->syntax);
+
+ case SNMP_SYNTAX_NOSUCHINSTANCE:
+ fprintf(stdout, "No Such Instance\n");
+ return (val->syntax);
+
+ case SNMP_SYNTAX_ENDOFMIBVIEW:
+ fprintf(stdout, "End of Mib View\n");
+ return (val->syntax);
+
+ case SNMP_SYNTAX_NULL:
+ /* NOTREACHED */
+ fprintf(stdout, "agent returned NULL Syntax\n");
+ return (val->syntax);
+
+ default:
+ /* NOTREACHED - If here - then all went completely wrong. */
+ fprintf(stdout, "agent returned unknown syntax\n");
+ return (-1);
+ }
+
+ fprintf(stdout, "\n");
+
+ return (0);
+}
+
+static int32_t
+snmp_fill_object(struct snmp_toolinfo *snmptoolctx, struct snmp_object *obj,
+ struct snmp_value *val)
+{
+ int32_t rc;
+ asn_subid_t suboid;
+
+ if (obj == NULL || val == NULL)
+ return (-1);
+
+ if ((suboid = snmp_suboid_pop(&(val->var))) > ASN_MAXID)
+ return (-1);
+
+ memset(obj, 0, sizeof(struct snmp_object));
+ asn_append_oid(&(obj->val.var), &(val->var));
+ obj->val.syntax = val->syntax;
+
+ if (obj->val.syntax > 0)
+ rc = snmp_lookup_leafstring(snmptoolctx, obj);
+ else
+ rc = snmp_lookup_nonleaf_string(snmptoolctx, obj);
+
+ (void) snmp_suboid_append(&(val->var), suboid);
+ (void) snmp_suboid_append(&(obj->val.var), suboid);
+
+ return (rc);
+}
+
+static int32_t
+snmp_output_index(struct snmp_toolinfo *snmptoolctx, struct index *stx,
+ struct asn_oid *oid)
+{
+ uint8_t ip[4];
+ uint32_t bytes = 1;
+ uint64_t cnt64;
+ struct asn_oid temp, out;
+
+ if (oid->len < bytes)
+ return (-1);
+
+ memset(&temp, 0, sizeof(struct asn_oid));
+ asn_append_oid(&temp, oid);
+
+ switch (stx->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ snmp_output_int(snmptoolctx, stx->snmp_enum, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_OCTETSTRING:
+ if ((temp.subs[0] > temp.len -1 ) || (temp.subs[0] >
+ ASN_MAXOCTETSTRING))
+ return (-1);
+ snmp_output_octetindex(snmptoolctx, stx->tc, &temp);
+ bytes += temp.subs[0];
+ break;
+
+ case SNMP_SYNTAX_OID:
+ if ((temp.subs[0] > temp.len -1) || (temp.subs[0] >
+ ASN_MAXOIDLEN))
+ return (-1);
+
+ bytes += temp.subs[0];
+ memset(&out, 0, sizeof(struct asn_oid));
+ asn_slice_oid(&out, &temp, 1, bytes);
+ snmp_output_oid_value(snmptoolctx, &out);
+ break;
+
+ case SNMP_SYNTAX_IPADDRESS:
+ if (temp.len < 4)
+ return (-1);
+ for (bytes = 0; bytes < 4; bytes++)
+ ip[bytes] = temp.subs[bytes];
+
+ snmp_output_ipaddress(snmptoolctx, ip);
+ bytes = 4;
+ break;
+
+ case SNMP_SYNTAX_COUNTER:
+ snmp_output_counter(snmptoolctx, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_GAUGE:
+ snmp_output_gauge(snmptoolctx, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_TIMETICKS:
+ snmp_output_ticks(snmptoolctx, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_COUNTER64:
+ if (oid->len < 2)
+ return (-1);
+ bytes = 2;
+ memcpy(&cnt64, temp.subs, bytes);
+ snmp_output_counter64(snmptoolctx, cnt64);
+ break;
+
+ default:
+ return (-1);
+ }
+
+ return (bytes);
+}
+
+static int32_t
+snmp_output_object(struct snmp_toolinfo *snmptoolctx, struct snmp_object *o)
+{
+ int32_t i, first, len;
+ struct asn_oid oid;
+ struct index *temp;
+
+ if (ISSET_NUMERIC(snmptoolctx))
+ return (-1);
+
+ if (o->info->table_idx == NULL) {
+ fprintf(stdout,"%s.%d", o->info->string,
+ o->val.var.subs[o->val.var.len - 1]);
+ return (1);
+ }
+
+ fprintf(stdout,"%s[", o->info->string);
+ memset(&oid, 0, sizeof(struct asn_oid));
+
+ len = 1;
+ asn_slice_oid(&oid, &(o->val.var), (o->info->table_idx->var.len + len),
+ o->val.var.len);
+
+ first = 1;
+ STAILQ_FOREACH(temp, &(OBJECT_IDX_LIST(o)), link) {
+ if(first)
+ first = 0;
+ else
+ fprintf(stdout, ", ");
+ if ((i = snmp_output_index(snmptoolctx, temp, &oid)) < 0)
+ break;
+ len += i;
+ memset(&oid, 0, sizeof(struct asn_oid));
+ asn_slice_oid(&oid, &(o->val.var),
+ (o->info->table_idx->var.len + len), o->val.var.len + 1);
+ }
+
+ fprintf(stdout,"]");
+ return (1);
+}
+
+void
+snmp_output_err_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
+{
+ char buf[ASN_OIDSTRLEN];
+ struct snmp_object object;
+
+ if (pdu == NULL || (pdu->error_index > (int32_t) pdu->nbindings)) {
+ fprintf(stdout,"Invalid error index in PDU\n");
+ return;
+ }
+
+ fprintf(stdout, "Agent %s:%s returned error \n", snmp_client.chost,
+ snmp_client.cport);
+
+ if (!ISSET_NUMERIC(snmptoolctx) && (snmp_fill_object(snmptoolctx, &object,
+ &(pdu->bindings[pdu->error_index - 1])) > 0))
+ snmp_output_object(snmptoolctx, &object);
+ else {
+ asn_oid2str_r(&(pdu->bindings[pdu->error_index - 1].var), buf);
+ fprintf(stdout,"%s", buf);
+ }
+
+ fprintf(stdout," caused error - ");
+ if ((pdu->error_status > 0) && (pdu->error_status <=
+ SNMP_ERR_INCONS_NAME))
+ fprintf(stdout, "%s\n", error_strings[pdu->error_status].str);
+ else
+ fprintf(stdout,"%s\n", error_strings[SNMP_ERR_UNKNOWN].str);
+}
+
+int32_t
+snmp_output_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
+{
+ int32_t error;
+ char p[ASN_OIDSTRLEN];
+ uint32_t i;
+ struct snmp_object object;
+
+ for (i = 0, error = 0; i < pdu->nbindings; i++) {
+ if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET) {
+ if (!ISSET_NUMERIC(snmptoolctx) &&
+ (snmp_fill_object(snmptoolctx, &object,
+ &(pdu->bindings[i])) > 0))
+ snmp_output_object(snmptoolctx, &object);
+ else {
+ asn_oid2str_r(&(pdu->bindings[i].var), p);
+ fprintf(stdout, "%s", p);
+ }
+ }
+ error |= snmp_output_numval(snmptoolctx, &(pdu->bindings[i]), object.info);
+ }
+
+ return (error);
+}
+
+void
+snmp_output_engine(void)
+{
+ uint32_t i;
+ char *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2];
+
+ cptr = engine;
+ for (i = 0; i < snmp_client.engine.engine_len; i++)
+ cptr += sprintf(cptr, "%.2x", snmp_client.engine.engine_id[i]);
+ *cptr++ = '\0';
+
+ fprintf(stdout, "Engine ID 0x%s\n", engine);
+ fprintf(stdout, "Boots : %u\t\tTime : %d\n",
+ snmp_client.engine.engine_boots,
+ snmp_client.engine.engine_time);
+}
+
+void
+snmp_output_keys(void)
+{
+ uint32_t i, keylen = 0;
+ char *cptr, extkey[2 * SNMP_AUTH_KEY_SIZ + 2];
+
+ fprintf(stdout, "Localized keys for %s\n", snmp_client.user.sec_name);
+ if (snmp_client.user.auth_proto == SNMP_AUTH_HMAC_MD5) {
+ fprintf(stdout, "MD5 : 0x");
+ keylen = SNMP_AUTH_HMACMD5_KEY_SIZ;
+ } else if (snmp_client.user.auth_proto == SNMP_AUTH_HMAC_SHA) {
+ fprintf(stdout, "SHA : 0x");
+ keylen = SNMP_AUTH_HMACSHA_KEY_SIZ;
+ }
+ if (snmp_client.user.auth_proto != SNMP_AUTH_NOAUTH) {
+ cptr = extkey;
+ for (i = 0; i < keylen; i++)
+ cptr += sprintf(cptr, "%.2x",
+ snmp_client.user.auth_key[i]);
+ *cptr++ = '\0';
+ fprintf(stdout, "%s\n", extkey);
+ }
+
+ if (snmp_client.user.priv_proto == SNMP_PRIV_DES) {
+ fprintf(stdout, "DES : 0x");
+ keylen = SNMP_PRIV_DES_KEY_SIZ;
+ } else if (snmp_client.user.priv_proto == SNMP_PRIV_AES) {
+ fprintf(stdout, "AES : 0x");
+ keylen = SNMP_PRIV_AES_KEY_SIZ;
+ }
+ if (snmp_client.user.priv_proto != SNMP_PRIV_NOPRIV) {
+ cptr = extkey;
+ for (i = 0; i < keylen; i++)
+ cptr += sprintf(cptr, "%.2x",
+ snmp_client.user.priv_key[i]);
+ *cptr++ = '\0';
+ fprintf(stdout, "%s\n", extkey);
+ }
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
new file mode 100644
index 0000000..6e62186
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
@@ -0,0 +1,331 @@
+/*-
+ * Copyright (c) 2005-2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation 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 or documentation 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.
+ *
+ * Helper functions common for all tools.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BSNMP_TOOLS_H_
+#define _BSNMP_TOOLS_H_
+
+/* From asn1.h + 1 byte for trailing zero. */
+#define MAX_OCTSTRING_LEN ASN_MAXOCTETSTRING + 1
+#define MAX_CMD_SYNTAX_LEN 12
+
+/* Arbitrary upper limit on node names and function names - gensnmptree.c. */
+#define MAXSTR 1000
+
+/* Should be enough to fetch the biggest allowed octet string. */
+#define MAX_BUFF_SIZE (ASN_MAXOCTETSTRING + 50)
+
+#define SNMP_DEFS_DIR "/usr/share/snmp/defs/"
+#define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock"
+
+enum snmp_access {
+ SNMP_ACCESS_NONE = 0,
+ SNMP_ACCESS_GET,
+ SNMP_ACCESS_SET,
+ SNMP_ACCESS_GETSET,
+};
+
+/* A structure for integer-string enumerations. */
+struct enum_pair {
+ int32_t enum_val;
+ char *enum_str;
+ STAILQ_ENTRY(enum_pair) link;
+};
+
+STAILQ_HEAD(enum_pairs, enum_pair);
+
+struct enum_type {
+ char *name;
+ uint32_t syntax;
+ int32_t is_enum;
+ int32_t is_bits;
+ struct enum_pairs *snmp_enum;
+ SLIST_ENTRY(enum_type) link;
+};
+
+SLIST_HEAD(snmp_enum_tc, enum_type);
+
+struct index {
+ enum snmp_tc tc;
+ enum snmp_syntax syntax;
+ struct enum_pairs *snmp_enum;
+ STAILQ_ENTRY(index) link;
+};
+
+STAILQ_HEAD(snmp_idxlist, index);
+
+struct snmp_index_entry {
+ char *string;
+ uint32_t strlen;
+ struct asn_oid var;
+ struct snmp_idxlist index_list;
+ SLIST_ENTRY(snmp_index_entry) link;
+};
+
+/* Information needed for oid to string conversion. */
+struct snmp_oid2str {
+ char *string;
+ uint32_t strlen;
+ enum snmp_tc tc;
+ enum snmp_syntax syntax;
+ enum snmp_access access;
+ struct asn_oid var;
+ /* A pointer to a entry from the table list - OK if NULL. */
+ struct snmp_index_entry *table_idx;
+ /*
+ * A singly-linked tail queue of all (int, string) pairs -
+ * for INTEGER syntax only.
+ */
+ struct enum_pairs *snmp_enum;
+ SLIST_ENTRY(snmp_oid2str) link;
+};
+
+/* A structure to hold each oid input by user. */
+struct snmp_object {
+ /* Flag - if set, the variable caused error in a previous request. */
+ int32_t error;
+ /*
+ * A pointer in the mapping lists - not used if OIDs are input as
+ * numericals.
+ */
+ struct snmp_oid2str *info;
+ /* A snmp value to hold the actual oid, syntax and value. */
+ struct snmp_value val;
+ SLIST_ENTRY(snmp_object) link;
+};
+
+struct fname {
+ char *name;
+ int32_t done;
+ struct asn_oid cut;
+ SLIST_ENTRY(fname) link;
+};
+
+SLIST_HEAD(snmp_mapping, snmp_oid2str);
+SLIST_HEAD(fname_list, fname);
+SLIST_HEAD(snmp_table_index, snmp_index_entry);
+
+/*
+ * Keep a list for every syntax type.
+ */
+struct snmp_mappings {
+ /* The list containing all non-leaf nodes. */
+ struct snmp_mapping nodelist;
+ /* INTEGER/INTEGER32 types. */
+ struct snmp_mapping intlist;
+ /* OCTETSTRING types. */
+ struct snmp_mapping octlist;
+ /* OID types. */
+ struct snmp_mapping oidlist;
+ /* IPADDRESS types. */
+ struct snmp_mapping iplist;
+ /* TIMETICKS types. */
+ struct snmp_mapping ticklist;
+ /* COUNTER types. */
+ struct snmp_mapping cntlist;
+ /* GAUGE types. */
+ struct snmp_mapping gaugelist;
+ /* COUNTER64 types. */
+ struct snmp_mapping cnt64list;
+ /* ENUM values for oid types. */
+ struct snmp_mapping enumlist;
+ /* Description of all table entry types. */
+ struct snmp_table_index tablelist;
+ /* Defined enumerated textual conventions. */
+ struct snmp_enum_tc tclist;
+};
+
+struct snmp_toolinfo {
+ uint32_t flags;
+ /* Number of initially input OIDs. */
+ int32_t objects;
+ /* List of all input OIDs. */
+ SLIST_HEAD(snmp_objectlist, snmp_object) snmp_objectlist;
+ /* All known OID to string mapping data. */
+ struct snmp_mappings *mappings;
+ /* A list of .defs filenames to search oid<->string mapping. */
+ struct fname_list filelist;
+ /* SNMPv3 USM user credentials */
+ char *passwd;
+};
+
+/* XXX we might want to get away with this and will need to touch
+ * XXX the MACROS then too */
+extern struct snmp_toolinfo snmptool;
+
+/* Definitions for some flags' bits. */
+#define OUTPUT_BITS 0x00000003 /* bits 0-1 for output type */
+#define NUMERIC_BIT 0x00000004 /* bit 2 for numeric oids */
+#define RETRY_BIT 0x00000008 /* bit 3 for retry on error responce */
+#define ERRIGNORE_BIT 0x00000010 /* bit 4 for skip sanity checking */
+#define ERRIGNORE_BIT 0x00000010 /* bit 4 for skip sanity checking */
+#define EDISCOVER_BIT 0x00000020 /* bit 5 for SNMP Engine Discovery */
+#define LOCALKEY_BIT 0x00000040 /* bit 6 for using localized key */
+ /* 0x00000080 */ /* bit 7 reserverd */
+#define PDUTYPE_BITS 0x00000f00 /* bits 8-11 for pdu type */
+ /* 0x0000f000 */ /* bit 12-15 reserverd */
+#define MAXREP_BITS 0x00ff0000 /* bits 16-23 for max-repetit. value */
+#define NONREP_BITS 0xff000000 /* bits 24-31 for non-repeaters value */
+
+#define OUTPUT_SHORT 0x0
+#define OUTPUT_VERBOSE 0x1
+#define OUTPUT_TABULAR 0x2
+#define OUTPUT_QUIET 0x3
+
+/* Macros for playing with flags' bits. */
+#define SET_OUTPUT(ctx, type) ((ctx)->flags |= ((type) & OUTPUT_BITS))
+#define GET_OUTPUT(ctx) ((ctx)->flags & OUTPUT_BITS)
+
+#define SET_NUMERIC(ctx) ((ctx)->flags |= NUMERIC_BIT)
+#define ISSET_NUMERIC(ctx) ((ctx)->flags & NUMERIC_BIT)
+
+#define SET_RETRY(ctx) ((ctx)->flags |= RETRY_BIT)
+#define ISSET_RETRY(ctx) ((ctx)->flags & RETRY_BIT)
+
+#define SET_ERRIGNORE(ctx) ((ctx)->flags |= ERRIGNORE_BIT)
+#define ISSET_ERRIGNORE(ctx) ((ctx)->flags & ERRIGNORE_BIT)
+
+#define SET_EDISCOVER(ctx) ((ctx)->flags |= EDISCOVER_BIT)
+#define ISSET_EDISCOVER(ctx) ((ctx)->flags & EDISCOVER_BIT)
+
+#define SET_LOCALKEY(ctx) ((ctx)->flags |= LOCALKEY_BIT)
+#define ISSET_LOCALKEY(ctx) ((ctx)->flags & LOCALKEY_BIT)
+
+#define SET_PDUTYPE(ctx, type) (((ctx)->flags |= (((type) & 0xf) << 8)))
+#define GET_PDUTYPE(ctx) (((ctx)->flags & PDUTYPE_BITS) >> 8)
+
+#define SET_MAXREP(ctx, i) (((ctx)->flags |= (((i) & 0xff) << 16)))
+#define GET_MAXREP(ctx) (((ctx)->flags & MAXREP_BITS) >> 16)
+
+#define SET_NONREP(ctx, i) (((ctx)->flags |= (((i) & 0xff) << 24)))
+#define GET_NONREP(ctx) (((ctx)->flags & NONREP_BITS) >> 24)
+
+
+extern const struct asn_oid IsoOrgDod_OID;
+
+int snmptool_init(struct snmp_toolinfo *);
+int32_t snmp_import_file(struct snmp_toolinfo *, struct fname *);
+int32_t snmp_import_all(struct snmp_toolinfo *);
+int32_t add_filename(struct snmp_toolinfo *, const char *,
+ const struct asn_oid *, int32_t);
+void free_filelist(struct snmp_toolinfo *);
+void snmp_tool_freeall(struct snmp_toolinfo *);
+void snmp_import_dump(int);
+
+/* bsnmpmap.c */
+struct snmp_mappings *snmp_mapping_init(void);
+int32_t snmp_mapping_free(struct snmp_toolinfo *);
+void snmp_index_listfree(struct snmp_idxlist *);
+void snmp_dump_oid2str(struct snmp_oid2str *);
+int32_t snmp_node_insert(struct snmp_toolinfo *, struct snmp_oid2str *);
+int32_t snmp_leaf_insert(struct snmp_toolinfo *, struct snmp_oid2str *);
+int32_t snmp_enum_insert(struct snmp_toolinfo *, struct snmp_oid2str *);
+struct enum_pairs *enum_pairs_init(void);
+void enum_pairs_free(struct enum_pairs *);
+void snmp_mapping_entryfree(struct snmp_oid2str *);
+int32_t enum_pair_insert(struct enum_pairs *, int32_t, char *);
+char *enum_string_lookup(struct enum_pairs *, int32_t);
+int32_t enum_number_lookup(struct enum_pairs *, char *);
+int32_t snmp_syntax_insert(struct snmp_idxlist *, struct enum_pairs *,
+ enum snmp_syntax, enum snmp_tc);
+int32_t snmp_table_insert(struct snmp_toolinfo *, struct snmp_index_entry *);
+
+struct enum_type *snmp_enumtc_init(char *);
+void snmp_enumtc_free(struct enum_type *);
+void snmp_enumtc_insert(struct snmp_toolinfo *, struct enum_type *);
+struct enum_type *snmp_enumtc_lookup(struct snmp_toolinfo *, char *);
+
+void snmp_mapping_dump(struct snmp_toolinfo *);
+int32_t snmp_lookup_leafstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_enumstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_oidstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_nonleaf_string(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_allstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_nodestring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_oidall(struct snmp_toolinfo *, struct snmp_object *, char *);
+int32_t snmp_lookup_enumoid(struct snmp_toolinfo *, struct snmp_object *, char *);
+int32_t snmp_lookup_oid(struct snmp_toolinfo *, struct snmp_object *, char *);
+
+/* Functions parsing common options for all tools. */
+int32_t parse_server(char *);
+int32_t parse_timeout(char *);
+int32_t parse_retry(char *);
+int32_t parse_version(char *);
+int32_t parse_local_path(char *);
+int32_t parse_buflen(char *);
+int32_t parse_debug(void);
+int32_t parse_discovery(struct snmp_toolinfo *);
+int32_t parse_local_key(struct snmp_toolinfo *);
+int32_t parse_num_oids(struct snmp_toolinfo *);
+int32_t parse_file(struct snmp_toolinfo *, char *);
+int32_t parse_include(struct snmp_toolinfo *, char *);
+int32_t parse_output(struct snmp_toolinfo *, char *);
+int32_t parse_errors(struct snmp_toolinfo *);
+int32_t parse_skip_access(struct snmp_toolinfo *);
+int32_t parse_authentication(struct snmp_toolinfo *, char *);
+int32_t parse_privacy(struct snmp_toolinfo *, char *);
+int32_t parse_context(struct snmp_toolinfo *, char *);
+int32_t parse_user_security(struct snmp_toolinfo *, char *);
+
+typedef int32_t (*snmp_verify_inoid_f) (struct snmp_toolinfo *,
+ struct snmp_object *, char *);
+int32_t snmp_object_add(struct snmp_toolinfo *, snmp_verify_inoid_f, char *);
+int32_t snmp_object_remove(struct snmp_toolinfo *, struct asn_oid *oid);
+int32_t snmp_object_seterror(struct snmp_toolinfo *, struct snmp_value *,
+ int32_t);
+
+enum snmp_syntax parse_syntax(char *);
+char *snmp_parse_suboid(char *, struct asn_oid *);
+char *snmp_parse_index(struct snmp_toolinfo *, char *, struct snmp_object *);
+int32_t snmp_parse_numoid(char *, struct asn_oid *);
+int32_t snmp_suboid_append(struct asn_oid *, asn_subid_t);
+int32_t snmp_suboid_pop(struct asn_oid *);
+
+typedef int32_t (*snmp_verify_vbind_f) (struct snmp_toolinfo *,
+ struct snmp_pdu *, struct snmp_object *);
+typedef int32_t (*snmp_add_vbind_f) (struct snmp_pdu *, struct snmp_object *);
+int32_t snmp_pdu_add_bindings(struct snmp_toolinfo *, snmp_verify_vbind_f,
+ snmp_add_vbind_f, struct snmp_pdu *, int32_t);
+
+int32_t snmp_parse_get_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_parse_getbulk_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_parse_getnext_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_parse_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_output_numval(struct snmp_toolinfo *, struct snmp_value *,
+ struct snmp_oid2str *);
+void snmp_output_val(struct snmp_value *);
+int32_t snmp_output_resp(struct snmp_toolinfo *, struct snmp_pdu *);
+void snmp_output_err_resp(struct snmp_toolinfo *, struct snmp_pdu *);
+void snmp_output_engine(void);
+void snmp_output_keys(void);
+
+#endif /* _BSNMP_TOOLS_H_ */
diff --git a/usr.sbin/config/SMM.doc/0.t b/usr.sbin/config/SMM.doc/0.t
deleted file mode 100644
index ae5bf77..0000000
--- a/usr.sbin/config/SMM.doc/0.t
+++ /dev/null
@@ -1,88 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)0.t 8.1 (Berkeley) 7/5/93
-.\"
-.bd S B 3
-.de UX
-.ie \\n(GA>0 \\$2UNIX\\$1
-.el \{\
-.if n \\$2UNIX\\$1*
-.if t \\$2UNIX\\$1\\f1\(dg\\fP
-.FS
-.if n *UNIX
-.if t \(dgUNIX
-.ie \\$3=1 is a Footnote of Bell Laboratories.
-.el is a Trademark of Bell Laboratories.
-.FE
-.nr GA 1\}
-..
-.de BR
-\fB\\$1\fP\\$2
-..
-.TL
-Building 4.4BSD Kernels with Config
-.AU
-Samuel J. Leffler and Michael J. Karels
-.AI
-Computer Systems Research Group
-Department of Electrical Engineering and Computer Science
-University of California, Berkeley
-Berkeley, California 94720
-.de IR
-\fI\\$1\fP\\$2
-..
-.de DT
-.TA 8 16 24 32 40 48 56 64 72 80
-..
-.AB
-.PP
-This document describes the use of
-\fIconfig\fP\|(8) to configure and create bootable
-4.4BSD system images.
-It discusses the structure of system
-configuration files and how to configure
-systems with non-standard hardware configurations.
-Sections describing the preferred way to
-add new code to the system and how the system's autoconfiguration
-process operates are included. An appendix
-contains a summary of the rules used by the system
-in calculating the size of system data structures,
-and also indicates some of the standard system size
-limitations (and how to change them).
-Other configuration options are also listed.
-.sp
-.LP
-Revised July 5, 1993
-.AE
-.LP
-.OH 'Building 4.4BSD Kernels with Config''SMM:2-%'
-.EH 'SMM:2-%''Building 4.4BSD Kernels with Config'
diff --git a/usr.sbin/config/SMM.doc/1.t b/usr.sbin/config/SMM.doc/1.t
deleted file mode 100644
index 453041b..0000000
--- a/usr.sbin/config/SMM.doc/1.t
+++ /dev/null
@@ -1,61 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)1.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH Introduction
-.ne 2i
-.sp 3
-.NH
-INTRODUCTION
-.PP
-.I Config
-is a tool used in building 4.4BSD system images (the UNIX kernel).
-It takes a file describing a system's tunable parameters and
-hardware support, and generates a collection
-of files which are then used to build a copy of UNIX appropriate
-to that configuration.
-.I Config
-simplifies system maintenance by isolating system dependencies
-in a single, easy to understand, file.
-.PP
-This document describes the content and
-format of system configuration
-files and the rules which must be followed when creating
-these files. Example configuration files are constructed
-and discussed.
-.PP
-Later sections suggest guidelines to be used in modifying
-system source and explain some of the inner workings of the
-autoconfiguration process. Appendix D summarizes the rules
-used in calculating the most important system data structures
-and indicates some inherent system data structure size
-limitations (and how to go about modifying them).
diff --git a/usr.sbin/config/SMM.doc/2.t b/usr.sbin/config/SMM.doc/2.t
deleted file mode 100644
index 34e6b63..0000000
--- a/usr.sbin/config/SMM.doc/2.t
+++ /dev/null
@@ -1,188 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)2.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Configuration File Contents
-.ne 2i
-.NH
-CONFIGURATION FILE CONTENTS
-.PP
-A system configuration must include at least the following
-pieces of information:
-.IP \(bu 3
-machine type
-.IP \(bu 3
-cpu type
-.IP \(bu 3
-system identification
-.IP \(bu 3
-timezone
-.IP \(bu 3
-maximum number of users
-.IP \(bu 3
-location of the root file system
-.IP \(bu 3
-available hardware
-.PP
-.I Config
-allows multiple system images to be generated from a single
-configuration description. Each system image is configured
-for identical hardware, but may have different locations for the root
-file system and, possibly, other system devices.
-.NH 2
-Machine type
-.PP
-The
-.I "machine type"
-indicates if the system is going to operate on a DEC VAX-11\(dg computer,
-.FS
-\(dg DEC, VAX, UNIBUS, MASSBUS and MicroVAX are trademarks of Digital
-Equipment Corporation.
-.FE
-or some other machine on which 4.4BSD operates. The machine type
-is used to locate certain data files which are machine specific, and
-also to select rules used in constructing the resultant
-configuration files.
-.NH 2
-Cpu type
-.PP
-The
-.I "cpu type"
-indicates which, of possibly many, cpu's the system is to operate on.
-For example, if the system is being configured for a VAX-11, it could
-be running on a VAX 8600, VAX-11/780, VAX-11/750, VAX-11/730 or MicroVAX II.
-(Other VAX cpu types, including the 8650, 785 and 725, are configured using
-the cpu designation for compatible machines introduced earlier.)
-Specifying
-more than one cpu type implies that the system should be configured to run
-on any of the cpu's specified. For some types of machines this is not
-possible and
-.I config
-will print a diagnostic indicating such.
-.NH 2
-System identification
-.PP
-The
-.I "system identification"
-is a moniker attached to the system, and often the machine on which the
-system is to run. For example, at Berkeley we have machines named Ernie
-(Co-VAX), Kim (No-VAX), and so on. The system identifier selected is used to
-create a global C ``#define'' which may be used to isolate system dependent
-pieces of code in the kernel. For example, Ernie's Varian driver used
-to be special cased because its interrupt vectors were wired together. The
-code in the driver which understood how to handle this non-standard hardware
-configuration was conditionally compiled in only if the system
-was for Ernie.
-.PP
-The system identifier ``GENERIC'' is given to a system which
-will run on any cpu of a particular machine type; it should not
-otherwise be used for a system identifier.
-.NH 2
-Timezone
-.PP
-The timezone in which the system is to run is used to define the
-information returned by the \fIgettimeofday\fP\|(2)
-system call. This value is specified as the number of hours east
-or west of GMT. Negative numbers indicate a value east of GMT.
-The timezone specification may also indicate the
-type of daylight savings time rules to be applied.
-.NH 2
-Maximum number of users
-.PP
-The system allocates many system data structures at boot time
-based on the maximum number of users the system will support.
-This number is normally between 8 and 40, depending
-on the hardware and expected job mix. The rules
-used to calculate system data structures are discussed in
-Appendix D.
-.NH 2
-Root file system location
-.PP
-When the system boots it must know the location of
-the root of the file system
-tree. This location and the part(s) of the disk(s) to be used
-for paging and swapping must be specified in order to create
-a complete configuration description.
-.I Config
-uses many rules to calculate default locations for these items;
-these are described in Appendix B.
-.PP
-When a generic system is configured, the root file system is left
-undefined until the system is booted. In this case, the root file
-system need not be specified, only that the system is a generic system.
-.NH 2
-Hardware devices
-.PP
-When the system boots it goes through an
-.I autoconfiguration
-phase. During this period, the system searches for all
-those hardware devices
-which the system builder has indicated might be present. This probing
-sequence requires certain pieces of information such as register
-addresses, bus interconnects, etc. A system's hardware may be configured
-in a very flexible manner or be specified without any flexibility
-whatsoever. Most people do not configure hardware devices into the
-system unless they are currently present on the machine, expect
-them to be present in the near future, or are simply guarding
-against a hardware
-failure somewhere else at the site (it is often wise to configure in
-extra disks in case an emergency requires moving one off a machine which
-has hardware problems).
-.PP
-The specification of hardware devices usually occupies the majority of
-the configuration file. As such, a large portion of this document will
-be spent understanding it. Section 6.3 contains a description of
-the autoconfiguration process, as it applies to those planning to
-write, or modify existing, device drivers.
-.NH 2
-Pseudo devices
-.PP
-Several system facilities are configured in a manner like that used
-for hardware devices although they are not associated with specific hardware.
-These system options are configured as
-.IR pseudo-devices .
-Some pseudo devices allow an optional parameter that sets the limit
-on the number of instances of the device that are active simultaneously.
-.NH 2
-System options
-.PP
-Other than the mandatory pieces of information described above, it
-is also possible to include various optional system facilities
-or to modify system behavior and/or limits.
-For example, 4.4BSD can be configured to support binary compatibility for
-programs built under 4.3BSD. Also, optional support is provided
-for disk quotas and tracing the performance of the virtual memory
-subsystem. Any optional facilities to be configured into
-the system are specified in the configuration file. The resultant
-files generated by
-.I config
-will automatically include the necessary pieces of the system.
diff --git a/usr.sbin/config/SMM.doc/3.t b/usr.sbin/config/SMM.doc/3.t
deleted file mode 100644
index e0b6234..0000000
--- a/usr.sbin/config/SMM.doc/3.t
+++ /dev/null
@@ -1,299 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)3.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "System Building Process
-.ne 2i
-.NH
-SYSTEM BUILDING PROCESS
-.PP
-In this section we consider the steps necessary to build a bootable system
-image. We assume the system source is located in the ``/sys'' directory
-and that, initially, the system is being configured from source code.
-.PP
-Under normal circumstances there are 5 steps in building a system.
-.IP 1) 3
-Create a configuration file for the system.
-.IP 2) 3
-Make a directory for the system to be constructed in.
-.IP 3) 3
-Run
-.I config
-on the configuration file to generate the files required
-to compile and load the system image.
-.IP 4)
-Construct the source code interdependency rules for the
-configured system with
-.I make depend
-using
-.IR make (1).
-.IP 5)
-Compile and load the system with
-.IR make .
-.PP
-Steps 1 and 2 are usually done only once. When a system configuration
-changes it usually suffices to just run
-.I config
-on the modified configuration file, rebuild the source code dependencies,
-and remake the system. Sometimes,
-however, configuration dependencies may not be noticed in which case
-it is necessary to clean out the relocatable object files saved
-in the system's directory; this will be discussed later.
-.NH 2
-Creating a configuration file
-.PP
-Configuration files normally reside in the directory ``/sys/conf''.
-A configuration file is most easily constructed by copying an
-existing configuration file and modifying it. The 4.4BSD distribution
-contains a number of configuration files for machines at Berkeley;
-one may be suitable or, in worst case, a copy
-of the generic configuration file may be edited.
-.PP
-The configuration file must have the same name as the directory in
-which the configured system is to be built.
-Further,
-.I config
-assumes this directory is located in the parent directory of
-the directory in which it
-is run. For example, the generic
-system has a configuration file ``/sys/conf/GENERIC'' and an accompanying
-directory named ``/sys/GENERIC''.
-Although it is not required that the system sources and configuration
-files reside in ``/sys,'' the configuration and compilation procedure
-depends on the relative locations of directories within that hierarchy,
-as most of the system code and the files created by
-.I config
-use pathnames of the form ``../''.
-If the system files are not located in ``/sys,''
-it is desirable to make a symbolic link there for use in installation
-of other parts of the system that share files with the kernel.
-.PP
-When building the configuration file, be sure to include the items
-described in section 2. In particular, the machine type,
-cpu type, timezone, system identifier, maximum users, and root device
-must be specified. The specification of the hardware present may take
-a bit of work; particularly if your hardware is configured at non-standard
-places (e.g. device registers located at funny places or devices not
-supported by the system). Section 4 of this document
-gives a detailed description of the configuration file syntax,
-section 5 explains some sample configuration files, and
-section 6 discusses how to add new devices to
-the system. If the devices to be configured are not already
-described in one of the existing configuration files you should check
-the manual pages in section 4 of the UNIX Programmers Manual. For each
-supported device, the manual page synopsis entry gives a
-sample configuration line.
-.PP
-Once the configuration file is complete, run it through
-.I config
-and look for any errors. Never try and use a system which
-.I config
-has complained about; the results are unpredictable.
-For the most part,
-.IR config 's
-error diagnostics are self explanatory. It may be the case that
-the line numbers given with the error messages are off by one.
-.PP
-A successful run of
-.I config
-on your configuration file will generate a number of files in
-the configuration directory. These files are:
-.IP \(bu 3
-A file to be used by \fImake\fP\|(1)
-in compiling and loading the system,
-.IR Makefile .
-.IP \(bu 3
-One file for each possible system image for this machine,
-.IR swapxxx.c ,
-where
-.I xxx
-is the name of the system image,
-which describes where swapping, the root file system, and other
-miscellaneous system devices are located.
-.IP \(bu 3
-A collection of header files, one per possible device the
-system supports, which define the hardware configured.
-.IP \(bu 3
-A file containing the I/O configuration tables used by the system
-during its
-.I autoconfiguration
-phase,
-.IR ioconf.c .
-.IP \(bu 3
-An assembly language file of interrupt vectors which
-connect interrupts from the machine's external buses to the main
-system path for handling interrupts,
-and a file that contains counters and names for the interrupt vectors.
-.PP
-Unless you have reason to doubt
-.IR config ,
-or are curious how the system's autoconfiguration scheme
-works, you should never have to look at any of these files.
-.NH 2
-Constructing source code dependencies
-.PP
-When
-.I config
-is done generating the files needed to compile and link your system it
-will terminate with a message of the form ``Don't forget to run make depend''.
-This is a reminder that you should change over to the configuration
-directory for the system just configured and type ``make depend''
-to build the rules used by
-.I make
-to recognize interdependencies in the system source code.
-This will insure that any changes to a piece of the system
-source code will result in the proper modules being recompiled
-the next time
-.I make
-is run.
-.PP
-This step is particularly important if your site makes changes
-to the system include files. The rules generated specify which source code
-files are dependent on which include files. Without these rules,
-.I make
-will not recognize when it must rebuild modules
-due to the modification of a system header file.
-The dependency rules are generated by a pass of the C preprocessor
-and reflect the global system options.
-This step must be repeated when the configuration file is changed
-and
-.I config
-is used to regenerate the system makefile.
-.NH 2
-Building the system
-.PP
-The makefile constructed by
-.I config
-should allow a new system to be rebuilt by simply typing ``make image-name''.
-For example, if you have named your bootable system image ``kernel'',
-then ``make kernel''
-will generate a bootable image named ``kernel''. Alternate system image names
-are used when the root file system location and/or swapping configuration
-is done in more than one way. The makefile which
-.I config
-creates has entry points for each system image defined in
-the configuration file.
-Thus, if you have configured ``kernel'' to be a system with the root file
-system on an ``hp'' device and ``hkkernel'' to be a system with the root
-file system on an ``hk'' device, then ``make kernel hkkernel'' will generate
-binary images for each.
-As the system will generally use the disk from which it is loaded
-as the root filesystem, separate system images are only required
-to support different swap configurations.
-.PP
-Note that the name of a bootable image is different from the system
-identifier. All bootable images are configured for the same system;
-only the information about the root file system and paging devices differ.
-(This is described in more detail in section 4.)
-.PP
-The last step in the system building process is to rearrange certain commonly
-used symbols in the symbol table of the system image; the makefile
-generated by
-.I config
-does this automatically for you.
-This is advantageous for programs such as
-\fInetstat\fP\|(1) and \fIvmstat\fP\|(1),
-which run much faster when the symbols they need are located at
-the front of the symbol table.
-Remember also that many programs expect
-the currently executing system to be named ``/kernel''. If you install
-a new system and name it something other than ``/kernel'', many programs
-are likely to give strange results.
-.NH 2
-Sharing object modules
-.PP
-If you have many systems which are all built on a single machine
-there are at least two approaches to saving time in building system
-images. The best way is to have a single system image which is run on
-all machines. This is attractive since it minimizes disk space used
-and time required to rebuild systems after making changes. However,
-it is often the case that one or more systems will require a separately
-configured system image. This may be due to limited memory (building
-a system with many unused device drivers can be expensive), or to
-configuration requirements (one machine may be a development machine
-where disk quotas are not needed, while another is a production machine
-where they are), etc. In these cases it is possible
-for common systems to share relocatable object modules which are not
-configuration dependent; most of the modules in the directory ``/sys/sys''
-are of this sort.
-.PP
-To share object modules, a generic system should be built. Then, for
-each system configure the system as before, but before recompiling and
-linking the system, type ``make links'' in the system compilation directory.
-This will cause the system
-to be searched for source modules which are safe to share between systems
-and generate symbolic links in the current directory to the appropriate
-object modules in the directory ``../GENERIC''. A shell script,
-``makelinks'' is generated with this request and may be checked for
-correctness. The file ``/sys/conf/defines'' contains a list of symbols
-which we believe are safe to ignore when checking the source code
-for modules which may be shared. Note that this list includes the definitions
-used to conditionally compile in the virtual memory tracing facilities, and
-the trace point support used only rarely (even at Berkeley).
-It may be necessary
-to modify this file to reflect local needs. Note further that
-interdependencies which are not directly visible
-in the source code are not caught. This means that if you place
-per-system dependencies in an include file, they will not be recognized
-and the shared code may be selected in an unexpected fashion.
-.NH 2
-Building profiled systems
-.PP
-It is simple to configure a system which will automatically
-collect profiling information as it operates. The profiling data
-may be collected with \fIkgmon\fP\|(8) and processed with
-\fIgprof\fP\|(1)
-to obtain information regarding the system's operation. Profiled
-systems maintain histograms of the program counter as well as the
-number of invocations of each routine. The \fIgprof\fP
-command will also generate a dynamic call graph of the executing
-system and propagate time spent in each routine along the arcs
-of the call graph (consult the \fIgprof\fP documentation for elaboration).
-The program counter sampling can be driven by the system clock, or
-if you have an alternate real time clock, this can be used. The
-latter is highly recommended, as use of the system clock will result
-in statistical anomalies, and time spent in the clock routine will
-not be accurately attributed.
-.PP
-To configure a profiled system, the
-.B \-p
-option should be supplied to \fIconfig\fP.
-A profiled system is about 5-10% larger in its text space due to
-the calls to count the subroutine invocations. When the system
-executes, the profiling data is stored in a buffer which is 1.2
-times the size of the text space. The overhead for running a
-profiled system varies; under normal load we see anywhere from 5-25%
-of the system time spent in the profiling code.
-.PP
-Note that systems configured for profiling should not be shared as
-described above unless all the other shared systems are also to be
-profiled.
diff --git a/usr.sbin/config/SMM.doc/4.t b/usr.sbin/config/SMM.doc/4.t
deleted file mode 100644
index 7498185..0000000
--- a/usr.sbin/config/SMM.doc/4.t
+++ /dev/null
@@ -1,442 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)4.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Configuration File Syntax
-.ne 2i
-.NH
-CONFIGURATION FILE SYNTAX
-.PP
-In this section we consider the specific rules used in writing
-a configuration file. A complete grammar for the input language
-can be found in Appendix A and may be of use if you should have
-problems with syntax errors.
-.PP
-A configuration file is broken up into three logical pieces:
-.IP \(bu 3
-configuration parameters global to all system images
-specified in the configuration file,
-.IP \(bu 3
-parameters specific to each
-system image to be generated, and
-.IP \(bu 3
-device specifications.
-.NH 2
-Global configuration parameters
-.PP
-The global configuration parameters are the type of machine,
-cpu types, options, timezone, system identifier, and maximum users.
-Each is specified with a separate line in the configuration file.
-.IP "\fBmachine\fP \fItype\fP"
-.br
-The system is to run on the machine type specified. No more than
-one machine type can appear in the configuration file. Legal values
-are
-.B vax
-and
-\fBsun\fP.
-.IP "\fBcpu\fP ``\fItype\fP''"
-.br
-This system is to run on the cpu type specified.
-More than one cpu type specification
-can appear in a configuration file.
-Legal types for a
-.B vax
-machine are
-\fBVAX8600\fP, \fBVAX780\fP, \fBVAX750\fP,
-\fBVAX730\fP
-and
-\fBVAX630\fP (MicroVAX II).
-The 8650 is listed as an 8600, the 785 as a 780, and a 725 as a 730.
-.IP "\fBoptions\fP \fIoptionlist\fP"
-.br
-Compile the listed optional code into the system.
-Options in this list are separated by commas.
-Possible options are listed at the top of the generic makefile.
-A line of the form ``options FUNNY,HAHA'' generates global ``#define''s
-\-DFUNNY \-DHAHA in the resultant makefile.
-An option may be given a value by following its name with ``\fB=\fP'',
-then the value enclosed in (double) quotes.
-The following are major options are currently in use:
-COMPAT (include code for compatibility with 4.1BSD binaries),
-INET (Internet communication protocols),
-NS (Xerox NS communication protocols),
-and
-QUOTA (enable disk quotas).
-Other kernel options controlling system sizes and limits
-are listed in Appendix D;
-options for the network are found in Appendix E.
-There are additional options which are associated with certain
-peripheral devices; those are listed in the Synopsis section
-of the manual page for the device.
-.IP "\fBmakeoptions\fP \fIoptionlist\fP"
-.br
-Options that are used within the system makefile
-and evaluated by
-.I make
-are listed as
-.IR makeoptions .
-Options are listed with their values with the form
-``makeoptions name=value,name2=value2.''
-The values must be enclosed in double quotes if they include numerals
-or begin with a dash.
-.IP "\fBtimezone\fP \fInumber\fP [ \fBdst\fP [ \fInumber\fP ] ]"
-.br
-Specifies the timezone used by the system. This is measured in the
-number of hours your timezone is west of GMT.
-EST is 5 hours west of GMT, PST is 8. Negative numbers
-indicate hours east of GMT. If you specify
-\fBdst\fP, the system will operate under daylight savings time.
-An optional integer or floating point number may be included
-to specify a particular daylight saving time correction algorithm;
-the default value is 1, indicating the United States.
-Other values are: 2 (Australian style), 3 (Western European),
-4 (Middle European), and 5 (Eastern European). See
-\fIgettimeofday\fP\|(2) and \fIctime\fP\|(3) for more information.
-.IP "\fBident\fP \fIname\fP"
-.br
-This system is to be known as
-.IR name .
-This is usually a cute name like ERNIE (short for Ernie Co-Vax) or
-VAXWELL (for Vaxwell Smart).
-This value is defined for use in conditional compilation,
-and is also used to locate an optional list of source files specific
-to this system.
-.IP "\fBmaxusers\fP \fInumber\fP"
-.br
-The maximum expected number of simultaneously active user on this system is
-.IR number .
-This number is used to size several system data structures.
-.NH 2
-System image parameters
-.PP
-Multiple bootable images may be specified in a single configuration
-file. The systems will have the same global configuration parameters
-and devices, but the location of the root file system and other
-system specific devices may be different. A system image is specified
-with a ``config'' line:
-.IP
-\fBconfig\fP\ \fIsysname\fP\ \fIconfig-clauses\fP
-.LP
-The
-.I sysname
-field is the name given to the loaded system image; almost everyone
-names their standard system image ``kernel''. The configuration clauses
-are one or more specifications indicating where the root file system
-is located and the number and location of paging devices.
-The device used by the system to process argument lists during
-.IR execve (2)
-calls may also be specified, though in practice this is almost
-always selected by
-.I config
-using one of its rules for selecting default locations for
-system devices.
-.PP
-A configuration clause is one of the following
-.IP
-.nf
-\fBroot\fP [ \fBon\fP ] \fIroot-device\fP
-\fBswap\fP [ \fBon\fP ] \fIswap-device\fP [ \fBand\fP \fIswap-device\fP ] ...
-\fBdumps\fP [ \fBon\fP ] \fIdump-device\fP
-\fBargs\fP [ \fBon\fP ] \fIarg-device\fP
-.LP
-(the ``on'' is optional.) Multiple configuration clauses
-are separated by white space;
-.I config
-allows specifications to be continued across multiple lines
-by beginning the continuation line with a tab character.
-The ``root'' clause specifies where the root file system
-is located, the ``swap'' clause indicates swapping and paging
-area(s), the ``dumps'' clause can be used to force system dumps
-to be taken on a particular device, and the ``args'' clause
-can be used to specify that argument list processing for
-.I execve
-should be done on a particular device.
-.PP
-The device names supplied in the clauses may be fully specified
-as a device, unit, and file system partition; or underspecified
-in which case
-.I config
-will use builtin rules to select default unit numbers and file
-system partitions. The defaulting rules are a bit complicated
-as they are dependent on the overall system configuration.
-For example, the swap area need not be specified at all if
-the root device is specified; in this case the swap area is
-placed in the ``b'' partition of the same disk where the root
-file system is located. Appendix B contains a complete list
-of the defaulting rules used in selecting system configuration
-devices.
-.PP
-The device names are translated to the
-appropriate major and minor device
-numbers on a per-machine basis. A file,
-``/sys/conf/devices.machine'' (where ``machine''
-is the machine type specified in the configuration file),
-is used to map a device name to its major block device number.
-The minor device number is calculated using the standard
-disk partitioning rules: on unit 0, partition ``a'' is minor device
-0, partition ``b'' is minor device 1, and so on; for units
-other than 0, add 8 times the unit number to get the minor
-device.
-.PP
-If the default mapping of device name to major/minor device
-number is incorrect for your configuration, it can be replaced
-by an explicit specification of the major/minor device.
-This is done by substituting
-.IP
-\fBmajor\fP \fIx\fP \fBminor\fP \fIy\fP
-.LP
-where the device name would normally be found. For example,
-.IP
-.nf
-\fBconfig\fP kernel \fBroot\fP \fBon\fP \fBmajor\fP 99 \fBminor\fP 1
-.fi
-.PP
-Normally, the areas configured for swap space are sized by the system
-at boot time. If a non-standard size is to be used for one
-or more swap areas (less than the full partition),
-this can also be specified. To do this, the
-device name specified for a swap area should have a ``size''
-specification appended. For example,
-.IP
-.nf
-\fBconfig\fP kernel \fBroot\fP \fBon\fP hp0 \fBswap\fP \fBon\fP hp0b \fBsize\fP 1200
-.fi
-.LP
-would force swapping to be done in partition ``b'' of ``hp0'' and
-the swap partition size would be set to 1200 sectors. A swap area
-sized larger than the associated disk partition is trimmed to the
-partition size.
-.PP
-To create a generic configuration, only the clause ``swap generic''
-should be specified; any extra clauses will cause an error.
-.NH 2
-Device specifications
-.PP
-Each device attached to a machine must be specified
-to
-.I config
-so that the system generated will know to probe for it during
-the autoconfiguration process carried out at boot time. Hardware
-specified in the configuration need not actually be present on
-the machine where the generated system is to be run. Only the
-hardware actually found at boot time will be used by the system.
-.PP
-The specification of hardware devices in the configuration file
-parallels the interconnection hierarchy of the machine to be
-configured. On the VAX, this means that a configuration file must
-indicate what MASSBUS and UNIBUS adapters are present, and to
-which \fInexi\fP they might be connected.*
-.FS
-* While VAX-11/750's and VAX-11/730 do not actually have
-nexi, the system treats them as having
-.I "simulated nexi"
-to simplify device configuration.
-.FE
-Similarly, devices
-and controllers must be indicated as possibly being connected
-to one or more adapters. A device description may provide a
-complete definition of the possible configuration parameters
-or it may leave certain parameters undefined and make the system
-probe for all the possible values. The latter allows a single
-device configuration list to match many possible physical
-configurations. For example, a disk may be indicated as present
-at UNIBUS adapter 0, or at any UNIBUS adapter which the system
-locates at boot time. The latter scheme, termed
-.IR wildcarding ,
-allows more flexibility in the physical configuration of a system;
-if a disk must be moved around for some reason, the system will
-still locate it at the alternate location.
-.PP
-A device specification takes one of the following forms:
-.IP
-.nf
-\fBmaster\fP \fIdevice-name\fP \fIdevice-info\fP
-\fBcontroller\fP \fIdevice-name\fP \fIdevice-info\fP [ \fIinterrupt-spec\fP ]
-\fBdevice\fP \fIdevice-name\fP \fIdevice-info\fP \fIinterrupt-spec\fP
-\fBdisk\fP \fIdevice-name\fP \fIdevice-info\fP
-\fBtape\fP \fIdevice-name\fP \fIdevice-info\fP
-.fi
-.LP
-A ``master'' is a MASSBUS tape controller; a ``controller'' is a
-disk controller, a UNIBUS tape controller, a MASSBUS adapter, or
-a UNIBUS adapter. A ``device'' is an autonomous device which
-connects directly to a UNIBUS adapter (as opposed to something
-like a disk which connects through a disk controller). ``Disk''
-and ``tape'' identify disk drives and tape drives connected to
-a ``controller'' or ``master.''
-.PP
-The
-.I device-name
-is one of the standard device names, as
-indicated in section 4 of the UNIX Programmers Manual,
-concatenated with the
-.I logical
-unit number to be assigned the device (the
-.I logical
-unit number may be different than the
-.I physical
-unit number indicated on the front of something
-like a disk; the
-.I logical
-unit number is used to refer to the UNIX device, not
-the physical unit number). For example, ``hp0'' is logical
-unit 0 of a MASSBUS storage device, even though it might
-be physical unit 3 on MASSBUS adapter 1.
-.PP
-The
-.I device-info
-clause specifies how the hardware is
-connected in the interconnection hierarchy. On the VAX,
-UNIBUS and MASSBUS adapters are connected to the internal
-system bus through
-a \fInexus\fP.
-Thus, one of the following
-specifications would be used:
-.IP
-.ta 1.5i 2.5i 4.0i
-.nf
-\fBcontroller\fP mba0 \fBat\fP \fBnexus\fP \fIx\fP
-\fBcontroller\fP uba0 \fBat\fP \fBnexus\fP \fIx\fP
-.fi
-.LP
-To tie a controller to a specific nexus, ``x'' would be supplied
-as the number of that nexus; otherwise ``x'' may be specified as
-``?'', in which
-case the system will probe all nexi present looking
-for the specified controller.
-.PP
-The remaining interconnections on the VAX are:
-.IP \(bu 3
-a controller
-may be connected to another controller (e.g. a disk controller attached
-to a UNIBUS adapter),
-.IP \(bu 3
-a master is always attached to a controller (a MASSBUS adapter),
-.IP \(bu 3
-a tape is always attached to a master (for MASSBUS
-tape drives),
-.IP \(bu 3
-a disk is always attached to a controller, and
-.IP \(bu 3
-devices
-are always attached to controllers (e.g. UNIBUS controllers attached
-to UNIBUS adapters).
-.LP
-The following lines give an example of each of these interconnections:
-.IP
-.ta 1.5i 2.5i 4.0i
-.nf
-\fBcontroller\fP hk0 \fBat\fP uba0 ...
-\fBmaster\fP ht0 \fBat\fP mba0 ...
-\fBdisk\fP hp0 \fBat\fP mba0 ...
-\fBtape\fP tu0 \fBat\fP ht0 ...
-\fBdisk\fP rk1 \fBat\fP hk0 ...
-\fBdevice\fP dz0 \fBat\fP uba0 ...
-.fi
-.LP
-Any piece of hardware which may be connected to a specific
-controller may also be wildcarded across multiple controllers.
-.PP
-The final piece of information needed by the system to configure
-devices is some indication of where or how a device will interrupt.
-For tapes and disks, simply specifying the \fIslave\fP or \fIdrive\fP
-number is sufficient to locate the control status register for the
-device.
-\fIDrive\fP numbers may be wildcarded
-on MASSBUS devices, but not on disks on a UNIBUS controller.
-For controllers, the control status register must be
-given explicitly, as well the number of interrupt vectors used and
-the names of the routines to which they should be bound.
-Thus the example lines given above might be completed as:
-.IP
-.ta 1.5i 2.5i 4.0i
-.nf
-\fBcontroller\fP hk0 \fBat\fP uba0 \fBcsr\fP 0177440 \fBvector\fP rkintr
-\fBmaster\fP ht0 \fBat\fP mba0 \fBdrive\fP 0
-\fBdisk\fP hp0 \fBat\fP mba0 \fBdrive\fP ?
-\fBtape\fP tu0 \fBat\fP ht0 \fBslave\fP 0
-\fBdisk\fP rk1 \fBat\fP hk0 \fBdrive\fP 1
-\fBdevice\fP dz0 \fBat\fP uba0 \fBcsr\fP 0160100 \fBvector\fP dzrint dzxint
-.fi
-.PP
-Certain device drivers require extra information passed to them
-at boot time to tailor their operation to the actual hardware present.
-The line printer driver, for example, needs to know how many columns
-are present on each non-standard line printer (i.e. a line printer
-with other than 80 columns). The drivers for the terminal multiplexors
-need to know which lines are attached to modem lines so that no one will
-be allowed to use them unless a connection is present. For this reason,
-one last parameter may be specified to a
-.IR device ,
-a
-.I flags
-field. It has the syntax
-.IP
-\fBflags\fP \fInumber\fP
-.LP
-and is usually placed after the
-.I csr
-specification. The
-.I number
-is passed directly to the associated driver. The manual pages
-in section 4 should be consulted to determine how each driver
-uses this value (if at all).
-Communications interface drivers commonly use the flags
-to indicate whether modem control signals are in use.
-.PP
-The exact syntax for each specific device is given in the Synopsis
-section of its manual page in section 4 of the manual.
-.NH 2
-Pseudo-devices
-.PP
-A number of drivers and software subsystems
-are treated like device drivers without any associated hardware.
-To include any of these pieces, a ``pseudo-device'' specification
-must be used. A specification for a pseudo device takes the form
-.IP
-.DT
-.nf
-\fBpseudo-device\fP \fIdevice-name\fP [ \fIhowmany\fP ]
-.fi
-.PP
-Examples of pseudo devices are
-\fBpty\fP, the pseudo terminal driver (where the optional
-.I howmany
-value indicates the number of pseudo terminals to configure, 32 default),
-and \fBloop\fP, the software loopback network pseudo-interface.
-Other pseudo devices for the network include
-\fBimp\fP (required when a CSS or ACC imp is configured)
-and \fBether\fP (used by the Address Resolution Protocol
-on 10 Mb/sec Ethernets).
-More information on configuring each of these can also be found
-in section 4 of the manual.
diff --git a/usr.sbin/config/SMM.doc/5.t b/usr.sbin/config/SMM.doc/5.t
deleted file mode 100644
index 81f2a52..0000000
--- a/usr.sbin/config/SMM.doc/5.t
+++ /dev/null
@@ -1,271 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)5.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Sample Configuration Files
-.ne 2i
-.NH
-SAMPLE CONFIGURATION FILES
-.PP
-In this section we will consider how to configure a
-sample VAX-11/780 system on which the hardware can be
-reconfigured to guard against various hardware mishaps.
-We then study the rules needed to configure a VAX-11/750
-to run in a networking environment.
-.NH 2
-VAX-11/780 System
-.PP
-Our VAX-11/780 is configured with hardware
-recommended in the document ``Hints on Configuring a VAX for 4.2BSD''
-(this is one of the high-end configurations).
-Table 1 lists the pertinent hardware to be configured.
-.DS B
-.TS
-box;
-l | l | l | l | l
-l | l | l | l | l.
-Item Vendor Connection Name Reference
-_
-cpu DEC VAX780
-MASSBUS controller Emulex nexus ? mba0 hp(4)
-disk Fujitsu mba0 hp0
-disk Fujitsu mba0 hp1
-MASSBUS controller Emulex nexus ? mba1
-disk Fujitsu mba1 hp2
-disk Fujitsu mba1 hp3
-UNIBUS adapter DEC nexus ?
-tape controller Emulex uba0 tm0 tm(4)
-tape drive Kennedy tm0 te0
-tape drive Kennedy tm0 te1
-terminal multiplexor Emulex uba0 dh0 dh(4)
-terminal multiplexor Emulex uba0 dh1
-terminal multiplexor Emulex uba0 dh2
-.TE
-.DE
-.ce
-Table 1. VAX-11/780 Hardware support.
-.LP
-We will call this machine ANSEL and construct a configuration
-file one step at a time.
-.PP
-The first step is to fill in the global configuration parameters.
-The machine is a VAX, so the
-.I "machine type"
-is ``vax''. We will assume this system will
-run only on this one processor, so the
-.I "cpu type"
-is ``VAX780''. The options are empty since this is going to
-be a ``vanilla'' VAX. The system identifier, as mentioned before,
-is ``ANSEL,'' and the maximum number of users we plan to support is
-about 40. Thus the beginning of the configuration file looks like
-this:
-.DS
-.ta 1.5i 2.5i 4.0i
-#
-# ANSEL VAX (a picture perfect machine)
-#
-machine vax
-cpu VAX780
-timezone 8 dst
-ident ANSEL
-maxusers 40
-.DE
-.PP
-To this we must then add the specifications for three
-system images. The first will be our standard system with the
-root on ``hp0'' and swapping on the same drive as the root.
-The second will have the root file system in the same location,
-but swap space interleaved among drives on each controller.
-Finally, the third will be a generic system,
-to allow us to boot off any of the four disk drives.
-.DS
-.ta 1.5i 2.5i
-config kernel root on hp0
-config hpkernel root on hp0 swap on hp0 and hp2
-config genkernel swap generic
-.DE
-.PP
-Finally, the hardware must be specified. Let us first just try
-transcribing the information from Table 1.
-.DS
-.ta 1.5i 2.5i 4.0i
-controller mba0 at nexus ?
-disk hp0 at mba0 disk 0
-disk hp1 at mba0 disk 1
-controller mba1 at nexus ?
-disk hp2 at mba1 disk 2
-disk hp3 at mba1 disk 3
-controller uba0 at nexus ?
-controller tm0 at uba0 csr 0172520 vector tmintr
-tape te0 at tm0 drive 0
-tape te1 at tm0 drive 1
-device dh0 at uba0 csr 0160020 vector dhrint dhxint
-device dm0 at uba0 csr 0170500 vector dmintr
-device dh1 at uba0 csr 0160040 vector dhrint dhxint
-device dh2 at uba0 csr 0160060 vector dhrint dhxint
-.DE
-.LP
-(Oh, I forgot to mention one panel of the terminal multiplexor
-has modem control, thus the ``dm0'' device.)
-.PP
-This will suffice, but leaves us with little flexibility. Suppose
-our first disk controller were to break. We would like to recable the
-drives normally on the second controller so that all our disks could
-still be used without reconfiguring the system. To do this we wildcard
-the MASSBUS adapter connections and also the slave numbers. Further,
-we wildcard the UNIBUS adapter connections in case we decide some time
-in the future to purchase another adapter to offload the single UNIBUS
-we currently have. The revised device specifications would then be:
-.DS
-.ta 1.5i 2.5i 4.0i
-controller mba0 at nexus ?
-disk hp0 at mba? disk ?
-disk hp1 at mba? disk ?
-controller mba1 at nexus ?
-disk hp2 at mba? disk ?
-disk hp3 at mba? disk ?
-controller uba0 at nexus ?
-controller tm0 at uba? csr 0172520 vector tmintr
-tape te0 at tm0 drive 0
-tape te1 at tm0 drive 1
-device dh0 at uba? csr 0160020 vector dhrint dhxint
-device dm0 at uba? csr 0170500 vector dmintr
-device dh1 at uba? csr 0160040 vector dhrint dhxint
-device dh2 at uba? csr 0160060 vector dhrint dhxint
-.DE
-.LP
-The completed configuration file for ANSEL is shown in Appendix C.
-.NH 2
-VAX-11/750 with network support
-.PP
-Our VAX-11/750 system will be located on two 10Mb/s Ethernet
-local area networks and also the DARPA Internet. The system
-will have a MASSBUS drive for the root file system and two
-UNIBUS drives. Paging is interleaved among all three drives.
-We have sold our standard DEC terminal multiplexors since this
-machine will be accessed solely through the network. This
-machine is not intended to have a large user community, it
-does not have a great deal of memory. First the global parameters:
-.DS
-.ta 1.5i 2.5i 4.0i
-#
-# UCBVAX (Gateway to the world)
-#
-machine vax
-cpu "VAX780"
-cpu "VAX750"
-ident UCBVAX
-timezone 8 dst
-maxusers 32
-options INET
-options NS
-.DE
-.PP
-The multiple cpu types allow us to replace UCBVAX with a
-more powerful cpu without reconfiguring the system. The
-value of 32 given for the maximum number of users is done to
-force the system data structures to be over-allocated. That
-is desirable on this machine because, while it is not expected
-to support many users, it is expected to perform a great deal
-of work.
-The ``INET'' indicates that we plan to use the
-DARPA standard Internet protocols on this machine,
-and ``NS'' also includes support for Xerox NS protocols.
-Note that unlike 4.2BSD configuration files,
-the network protocol options do not require corresponding pseudo devices.
-.PP
-The system images and disks are configured next.
-.DS
-.ta 1.5i 2.5i 4.0i
-config kernel root on hp swap on hp and rk0 and rk1
-config upkernel root on up
-config hkkernel root on hk swap on rk0 and rk1
-
-controller mba0 at nexus ?
-controller uba0 at nexus ?
-disk hp0 at mba? drive 0
-disk hp1 at mba? drive 1
-controller sc0 at uba? csr 0176700 vector upintr
-disk up0 at sc0 drive 0
-disk up1 at sc0 drive 1
-controller hk0 at uba? csr 0177440 vector rkintr
-disk rk0 at hk0 drive 0
-disk rk1 at hk0 drive 1
-.DE
-.PP
-UCBVAX requires heavy interleaving of its paging area to keep up
-with all the mail traffic it handles. The limiting factor on this
-system's performance is usually the number of disk arms, as opposed
-to memory or cpu cycles. The extra UNIBUS controller, ``sc0'',
-is in case the MASSBUS controller breaks and a spare controller
-must be installed (most of our old UNIBUS controllers have been
-replaced with the newer MASSBUS controllers, so we have a number
-of these around as spares).
-.PP
-Finally, we add in the network devices.
-Pseudo terminals are needed to allow users to
-log in across the network (remember the only hardwired terminal
-is the console).
-The software loopback device is used for on-machine communications.
-The connection to the Internet is through
-an IMP, this requires yet another
-.I pseudo-device
-(in addition to the actual hardware device used by the
-IMP software). And, finally, there are the two Ethernet devices.
-These use a special protocol, the Address Resolution Protocol (ARP),
-to map between Internet and Ethernet addresses. Thus, yet another
-.I pseudo-device
-is needed. The additional device specifications are show below.
-.DS
-.ta 1.5i 2.5i 4.0i
-pseudo-device pty
-pseudo-device loop
-pseudo-device imp
-device acc0 at uba? csr 0167600 vector accrint accxint
-pseudo-device ether
-device ec0 at uba? csr 0164330 vector ecrint eccollide ecxint
-device il0 at uba? csr 0164000 vector ilrint ilcint
-.DE
-.LP
-The completed configuration file for UCBVAX is shown in Appendix C.
-.NH 2
-Miscellaneous comments
-.PP
-It should be noted in these examples that neither system was
-configured to use disk quotas or the 4.1BSD compatibility mode.
-To use these optional facilities, and others, we would probably
-clean out our current configuration, reconfigure the system, then
-recompile and relink the system image(s). This could, of course,
-be avoided by figuring out which relocatable object files are
-affected by the reconfiguration, then reconfiguring and recompiling
-only those files affected by the configuration change. This technique
-should be used carefully.
diff --git a/usr.sbin/config/SMM.doc/6.t b/usr.sbin/config/SMM.doc/6.t
deleted file mode 100644
index 49f6e91..0000000
--- a/usr.sbin/config/SMM.doc/6.t
+++ /dev/null
@@ -1,233 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)6.t 8.1 (Berkeley) 6/8/93
-.\" $FreeBSD$
-.\"
-.\".ds RH "Adding New Devices
-.ne 2i
-.NH
-ADDING NEW SYSTEM SOFTWARE
-.PP
-This section is not for the novice, it describes
-some of the inner workings of the configuration process as
-well as the pertinent parts of the system autoconfiguration process.
-It is intended to give
-those people who intend to install new device drivers and/or
-other system facilities sufficient information to do so in the
-manner which will allow others to easily share the changes.
-.PP
-This section is broken into four parts:
-.IP \(bu 3
-general guidelines to be followed in modifying system code,
-.IP \(bu 3
-how to add non-standard system facilities to 4.4BSD,
-.IP \(bu 3
-how to add a device driver to 4.4BSD, and
-.NH 2
-Modifying system code
-.PP
-If you wish to make site-specific modifications to the system
-it is best to bracket them with
-.DS
-#ifdef SITENAME
-\&...
-#endif
-.DE
-to allow your source to be easily distributed to others, and
-also to simplify \fIdiff\fP\|(1) listings. If you choose not
-to use a source code control system (e.g. SCCS, RCS), and
-perhaps even if you do, it is
-recommended that you save the old code with something
-of the form:
-.DS
-#ifndef SITENAME
-\&...
-#endif
-.DE
-We try to isolate our site-dependent code in individual files
-which may be configured with pseudo-device specifications.
-.PP
-Indicate machine-specific code with ``#ifdef vax'' (or other machine,
-as appropriate).
-4.4BSD underwent extensive work to make it extremely portable to
-machines with similar architectures\- you may someday find
-yourself trying to use a single copy of the source code on
-multiple machines.
-.NH 2
-Adding non-standard system facilities
-.PP
-This section considers the work needed to augment
-.IR config 's
-data base files for non-standard system facilities.
-.I Config
-uses a set of files that list the source modules that may be required
-when building a system.
-The data bases are taken from the directory in which
-.I config
-is run, normally /sys/conf.
-Three such files may be used:
-.IR files ,
-.IR files .machine,
-and
-.IR files .ident.
-The first is common to all systems,
-the second contains files unique to a single machine type,
-and the third is an optional list of modules for use on a specific machine.
-This last file may override specifications in the first two.
-The format of the
-.I files
-file has grown somewhat complex over time. Entries are normally of
-the form
-.IP
-.nf
-.DT
-\fIdir/source.c\fP \fItype\fP \fIoption-list\fP \fImodifiers\fP
-.LP
-for example,
-.IP
-.nf
-.DT
-\fIvaxuba/foo.c\fP \fBoptional\fP foo \fBdevice-driver\fP
-.LP
-The
-.I type
-is one of
-.B standard
-or
-.BR optional .
-Files marked as standard are included in all system configurations.
-Optional file specifications include a list of one or more system
-options that together require the inclusion of this module.
-The options in the list may be either names of devices that may
-be in the configuration file,
-or the names of system options that may be defined.
-An optional file may be listed multiple times with different options;
-if all of the options for any of the entries are satisfied,
-the module is included.
-.PP
-If a file is specified as a
-.IR device-driver ,
-any special compilation options for device drivers will be invoked.
-On the VAX this results in the use of the
-.B \-i
-option for the C optimizer. This is required when pointer references
-are made to memory locations in the VAX I/O address space.
-.PP
-Two other optional keywords modify the usage of the file.
-.I Config
-understands that certain files are used especially for
-kernel profiling. These files are indicated in the
-.I files
-files with a
-.I profiling-routine
-keyword. For example, the current profiling subroutines
-are sequestered off in a separate file with the following
-entry:
-.IP
-.nf
-.DT
-\fIsys/subr_mcount.c\fP \fBoptional\fP \fBprofiling-routine\fP
-.fi
-.LP
-The
-.I profiling-routine
-keyword forces
-.I config
-not to compile the source file with the
-.B \-pg
-option.
-.PP
-The second keyword which can be of use is the
-.I config-dependent
-keyword. This causes
-.I config
-to compile the indicated module with the global configuration
-parameters. This allows certain modules, such as
-.I machdep.c
-to size system data structures based on the maximum number
-of users configured for the system.
-.NH 2
-Adding device drivers to 4.4BSD
-.PP
-The I/O system and
-.I config
-have been designed to easily allow new device support to be added.
-The system source directories are organized as follows:
-.DS
-.TS
-lw(1.0i) l.
-/sys/h machine independent include files
-/sys/sys machine-independent system source files
-/sys/conf site configuration files and basic templates
-/sys/net network-protocol-independent, but network-related code
-/sys/netinet DARPA Internet code
-/sys/netimp IMP support code
-/sys/netns Xerox NS code
-/sys/vax VAX-specific mainline code
-/sys/vaxif VAX network interface code
-/sys/vaxmba VAX MASSBUS device drivers and related code
-/sys/vaxuba VAX UNIBUS device drivers and related code
-.TE
-.DE
-.PP
-Existing block and character device drivers for the VAX
-reside in ``/sys/vax'', ``/sys/vaxmba'', and ``/sys/vaxuba''. Network
-interface drivers reside in ``/sys/vaxif''. Any new device
-drivers should be placed in the appropriate source code directory
-and named so as not to conflict with existing devices.
-Normally, definitions for things like device registers are placed in
-a separate file in the same directory. For example, the ``dh''
-device driver is named ``dh.c'' and its associated include file is
-named ``dhreg.h''.
-.PP
-Once the source for the device driver has been placed in a directory,
-the file ``/sys/conf/files.machine'', and possibly
-``/sys/conf/devices.machine'' should be modified. The
-.I files
-files in the conf directory contain a line for each C source or binary-only
-file in the system. Those files which are machine independent are
-located in ``/sys/conf/files,'' while machine specific files
-are in ``/sys/conf/files.machine.'' The ``devices.machine'' file
-is used to map device names to major block device numbers. If the device
-driver being added provides support for a new disk
-you will want to modify this file (the format is obvious).
-.PP
-In addition to including the driver in the
-.I files
-file, it must also be added to the device configuration tables. These
-are located in ``/sys/vax/conf.c'', or similar for machines other than
-the VAX. If you don't understand what to add to this file, you should
-study an entry for an existing driver.
-Remember that the position in the
-device table specifies the major device number.
-The block major number is needed in the ``devices.machine'' file
-if the device is a disk.
diff --git a/usr.sbin/config/SMM.doc/a.t b/usr.sbin/config/SMM.doc/a.t
deleted file mode 100644
index dfcb954..0000000
--- a/usr.sbin/config/SMM.doc/a.t
+++ /dev/null
@@ -1,162 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)a.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Configuration File Grammar
-.bp
-.LG
-.B
-.ce
-APPENDIX A. CONFIGURATION FILE GRAMMAR
-.sp
-.R
-.NL
-.PP
-The following grammar is a compressed form of the actual
-\fIyacc\fP\|(1) grammar used by
-.I config
-to parse configuration files.
-Terminal symbols are shown all in upper case, literals
-are emboldened; optional clauses are enclosed in brackets, ``[''
-and ``]''; zero or more instantiations are denoted with ``*''.
-.sp
-.nf
-.DT
-Configuration ::= [ Spec \fB;\fP ]*
-
-Spec ::= Config_spec
- | Device_spec
- | \fBtrace\fP
- | /* lambda */
-
-/* configuration specifications */
-
-Config_spec ::= \fBmachine\fP ID
- | \fBcpu\fP ID
- | \fBoptions\fP Opt_list
- | \fBident\fP ID
- | System_spec
- | \fBtimezone\fP [ \fB\-\fP ] NUMBER [ \fBdst\fP [ NUMBER ] ]
- | \fBtimezone\fP [ \fB\-\fP ] FPNUMBER [ \fBdst\fP [ NUMBER ] ]
- | \fBmaxusers\fP NUMBER
-
-/* system configuration specifications */
-
-System_spec ::= \fBconfig\fP ID System_parameter [ System_parameter ]*
-
-System_parameter ::= swap_spec | root_spec | dump_spec | arg_spec
-
-swap_spec ::= \fBswap\fP [ \fBon\fP ] swap_dev [ \fBand\fP swap_dev ]*
-
-swap_dev ::= dev_spec [ \fBsize\fP NUMBER ]
-
-root_spec ::= \fBroot\fP [ \fBon\fP ] dev_spec
-
-dump_spec ::= \fBdumps\fP [ \fBon\fP ] dev_spec
-
-arg_spec ::= \fBargs\fP [ \fBon\fP ] dev_spec
-
-dev_spec ::= dev_name | major_minor
-
-major_minor ::= \fBmajor\fP NUMBER \fBminor\fP NUMBER
-
-dev_name ::= ID [ NUMBER [ ID ] ]
-
-/* option specifications */
-
-Opt_list ::= Option [ \fB,\fP Option ]*
-
-Option ::= ID [ \fB=\fP Opt_value ]
-
-Opt_value ::= ID | NUMBER
-
-Mkopt_list ::= Mkoption [ \fB,\fP Mkoption ]*
-
-Mkoption ::= ID \fB=\fP Opt_value
-
-/* device specifications */
-
-Device_spec ::= \fBdevice\fP Dev_name Dev_info Int_spec
- | \fBmaster\fP Dev_name Dev_info
- | \fBdisk\fP Dev_name Dev_info
- | \fBtape\fP Dev_name Dev_info
- | \fBcontroller\fP Dev_name Dev_info [ Int_spec ]
- | \fBpseudo-device\fP Dev [ NUMBER ]
-
-Dev_name ::= Dev NUMBER
-
-Dev ::= \fBuba\fP | \fBmba\fP | ID
-
-Dev_info ::= Con_info [ Info ]*
-
-Con_info ::= \fBat\fP Dev NUMBER
- | \fBat\fP \fBnexus\fP NUMBER
-
-Info ::= \fBcsr\fP NUMBER
- | \fBdrive\fP NUMBER
- | \fBslave\fP NUMBER
- | \fBflags\fP NUMBER
-
-Int_spec ::= \fBvector\fP ID [ ID ]*
- | \fBpriority\fP NUMBER
-.fi
-.sp
-.SH
-Lexical Conventions
-.LP
-The terminal symbols are loosely defined as:
-.IP ID
-.br
-One or more alphabetics, either upper or lower case, and underscore,
-``_''.
-.IP NUMBER
-.br
-Approximately the C language specification for an integer number.
-That is, a leading ``0x'' indicates a hexadecimal value,
-a leading ``0'' indicates an octal value, otherwise the number is
-expected to be a decimal value. Hexadecimal numbers may use either
-upper or lower case alphabetics.
-.IP FPNUMBER
-.br
-A floating point number without exponent. That is a number of the
-form ``nnn.ddd'', where the fractional component is optional.
-.LP
-In special instances a question mark, ``?'', can be substituted for
-a ``NUMBER'' token. This is used to effect wildcarding in device
-interconnection specifications.
-.LP
-Comments in configuration files are indicated by a ``#'' character
-at the beginning of the line; the remainder of the line is discarded.
-.LP
-A specification
-is interpreted as a continuation of the previous line
-if the first character of the line is tab.
diff --git a/usr.sbin/config/SMM.doc/b.t b/usr.sbin/config/SMM.doc/b.t
deleted file mode 100644
index 901a009..0000000
--- a/usr.sbin/config/SMM.doc/b.t
+++ /dev/null
@@ -1,137 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)b.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Device Defaulting Rules
-.bp
-.LG
-.B
-.ce
-APPENDIX B. RULES FOR DEFAULTING SYSTEM DEVICES
-.sp
-.R
-.NL
-.PP
-When \fIconfig\fP processes a ``config'' rule which does
-not fully specify the location of the root file system,
-paging area(s), device for system dumps, and device for
-argument list processing it applies a set of rules to
-define those values left unspecified. The following list
-of rules are used in defaulting system devices.
-.IP 1) 3
-If a root device is not specified, the swap
-specification must indicate a ``generic'' system is to be built.
-.IP 2) 3
-If the root device does not specify a unit number, it
-defaults to unit 0.
-.IP 3) 3
-If the root device does not include a partition specification,
-it defaults to the ``a'' partition.
-.IP 4) 3
-If no swap area is specified, it defaults to the ``b''
-partition of the root device.
-.IP 5) 3
-If no device is specified for processing argument lists, the
-first swap partition is selected.
-.IP 6) 3
-If no device is chosen for system dumps, the first swap
-partition is selected (see below to find out where dumps are
-placed within the partition).
-.PP
-The following table summarizes the default partitions selected
-when a device specification is incomplete, e.g. ``hp0''.
-.DS
-.TS
-l l.
-Type Partition
-_
-root ``a''
-swap ``b''
-args ``b''
-dumps ``b''
-.TE
-.DE
-.SH
-Multiple swap/paging areas
-.PP
-When multiple swap partitions are specified, the system treats the
-first specified as a ``primary'' swap area which is always used.
-The remaining partitions are then interleaved into the paging
-system at the time a
-.IR swapon (2)
-system call is made. This is normally done at boot time with
-a call to
-.IR swapon (8)
-from the /etc/rc file.
-.SH
-System dumps
-.PP
-System dumps are automatically taken after a system crash,
-provided the device driver for the ``dumps'' device supports
-this. The dump contains the contents of memory, but not
-the swap areas. Normally the dump device is a disk in
-which case the information is copied to a location at the
-back of the partition. The dump is placed in the back of the
-partition because the primary swap and dump device are commonly
-the same device and this allows the system to be rebooted without
-immediately overwriting the saved information. When a dump has
-occurred, the system variable \fIdumpsize\fP
-is set to a non-zero value indicating the size (in bytes) of
-the dump. The \fIsavecore\fP\|(8)
-program then copies the information from the dump partition to
-a file in a ``crash'' directory and also makes a copy of the
-system which was running at the time of the crash (usually
-``/kernel''). The offset to the system dump is defined in the
-system variable \fIdumplo\fP (a sector offset from
-the front of the dump partition). The
-.I savecore
-program operates by reading the contents of \fIdumplo\fP, \fIdumpdev\fP,
-and \fIdumpmagic\fP from /dev/kmem, then comparing the value
-of \fIdumpmagic\fP read from /dev/kmem to that located in
-corresponding location in the dump area of the dump partition.
-If a match is found,
-.I savecore
-assumes a crash occurred and reads \fIdumpsize\fP from the dump area
-of the dump partition. This value is then used in copying the
-system dump. Refer to
-\fIsavecore\fP\|(8)
-for more information about its operation.
-.PP
-The value \fIdumplo\fP is calculated to be
-.DS
-\fIdumpdev-size\fP \- \fImemsize\fP
-.DE
-where \fIdumpdev-size\fP is the size of the disk partition
-where system dumps are to be placed, and
-\fImemsize\fP is the size of physical memory.
-If the disk partition is not large enough to hold a full
-dump, \fIdumplo\fP is set to 0 (the start of the partition).
diff --git a/usr.sbin/config/SMM.doc/c.t b/usr.sbin/config/SMM.doc/c.t
deleted file mode 100644
index 67b63ec..0000000
--- a/usr.sbin/config/SMM.doc/c.t
+++ /dev/null
@@ -1,109 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)c.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Sample Config Files
-.bp
-.LG
-.B
-.ce
-APPENDIX C. SAMPLE CONFIGURATION FILES
-.sp
-.R
-.NL
-.PP
-The following configuration files are developed in section 5;
-they are included here for completeness.
-.sp 2
-.nf
-.ta 1.5i 2.5i 4.0i
-#
-# ANSEL VAX (a picture perfect machine)
-#
-machine vax
-cpu VAX780
-timezone 8 dst
-ident ANSEL
-maxusers 40
-
-config kernel root on hp0
-config hpkernel root on hp0 swap on hp0 and hp2
-config genkernel swap generic
-
-controller mba0 at nexus ?
-disk hp0 at mba? disk ?
-disk hp1 at mba? disk ?
-controller mba1 at nexus ?
-disk hp2 at mba? disk ?
-disk hp3 at mba? disk ?
-controller uba0 at nexus ?
-controller tm0 at uba? csr 0172520 vector tmintr
-tape te0 at tm0 drive 0
-tape te1 at tm0 drive 1
-device dh0 at uba? csr 0160020 vector dhrint dhxint
-device dm0 at uba? csr 0170500 vector dmintr
-device dh1 at uba? csr 0160040 vector dhrint dhxint
-device dh2 at uba? csr 0160060 vector dhrint dhxint
-.bp
-#
-# UCBVAX - Gateway to the world
-#
-machine vax
-cpu "VAX780"
-cpu "VAX750"
-ident UCBVAX
-timezone 8 dst
-maxusers 32
-options INET
-options NS
-
-config kernel root on hp swap on hp and rk0 and rk1
-config upkernel root on up
-config hkkernel root on hk swap on rk0 and rk1
-
-controller mba0 at nexus ?
-controller uba0 at nexus ?
-disk hp0 at mba? drive 0
-disk hp1 at mba? drive 1
-controller sc0 at uba? csr 0176700 vector upintr
-disk up0 at sc0 drive 0
-disk up1 at sc0 drive 1
-controller hk0 at uba? csr 0177440 vector rkintr
-disk rk0 at hk0 drive 0
-disk rk1 at hk0 drive 1
-pseudo-device pty
-pseudo-device loop
-pseudo-device imp
-device acc0 at uba? csr 0167600 vector accrint accxint
-pseudo-device ether
-device ec0 at uba? csr 0164330 vector ecrint eccollide ecxint
-device il0 at uba? csr 0164000 vector ilrint ilcint
diff --git a/usr.sbin/config/SMM.doc/d.t b/usr.sbin/config/SMM.doc/d.t
deleted file mode 100644
index db9ab80..0000000
--- a/usr.sbin/config/SMM.doc/d.t
+++ /dev/null
@@ -1,272 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)d.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Data Structure Sizing Rules
-.bp
-.LG
-.B
-.ce
-APPENDIX D. VAX KERNEL DATA STRUCTURE SIZING RULES
-.sp
-.R
-.NL
-.PP
-Certain system data structures are sized at compile time
-according to the maximum number of simultaneous users expected,
-while others are calculated at boot time based on the
-physical resources present, e.g. memory. This appendix lists
-both sets of rules and also includes some hints on changing
-built-in limitations on certain data structures.
-.SH
-Compile time rules
-.PP
-The file \fI/sys/conf\|/param.c\fP contains the definitions of
-almost all data structures sized at compile time. This file
-is copied into the directory of each configured system to allow
-configuration-dependent rules and values to be maintained.
-(Each copy normally depends on the copy in /sys/conf,
-and global modifications cause the file to be recopied unless
-the makefile is modified.)
-The rules implied by its contents are summarized below (here
-MAXUSERS refers to the value defined in the configuration file
-in the ``maxusers'' rule).
-Most limits are computed at compile time and stored in global variables
-for use by other modules; they may generally be patched in the system
-binary image before rebooting to test new values.
-.IP \fBnproc\fP
-.br
-The maximum number of processes which may be running at any time.
-It is referred to in other calculations as NPROC and is defined to be
-.DS
-20 + 8 * MAXUSERS
-.DE
-.IP \fBntext\fP
-.br
-The maximum number of active shared text segments.
-The constant is intended to allow for network servers and common commands
-that remain in the table.
-It is defined as
-.DS
-36 + MAXUSERS.
-.DE
-.IP \fBninode\fP
-.br
-The maximum number of files in the file system which may be
-active at any time. This includes files in use by users, as
-well as directory files being read or written by the system
-and files associated with bound sockets in the UNIX IPC domain.
-It is defined as
-.DS
-(NPROC + 16 + MAXUSERS) + 32
-.DE
-.IP \fBnfile\fP
-.br
-The number of ``file table'' structures. One file
-table structure is used for each open, unshared, file descriptor.
-Multiple file descriptors may reference a single file table
-entry when they are created through a \fIdup\fP call, or as the
-result of a \fIfork\fP. This is defined to be
-.DS
-16 * (NPROC + 16 + MAXUSERS) / 10 + 32
-.DE
-.IP \fBncallout\fP
-.br
-The number of ``callout'' structures. One callout
-structure is used per internal system event handled with
-a timeout. Timeouts are used for terminal delays,
-watchdog routines in device drivers, protocol timeout processing, etc.
-This is defined as
-.DS
-16 + NPROC
-.DE
-.IP \fBnclist\fP
-.br
-The number of ``c-list'' structures. C-list structures are
-used in terminal I/O, and currently each holds 60 characters.
-Their number is defined as
-.DS
-60 + 12 * MAXUSERS
-.DE
-.IP \fBnmbclusters\fP
-.br
-The maximum number of pages which may be allocated by the network.
-This is defined as 256 (a quarter megabyte of memory) in /sys/h/mbuf.h.
-In practice, the network rarely uses this much memory. It starts off
-by allocating 8 kilobytes of memory, then requesting more as
-required. This value represents an upper bound.
-.IP \fBnquota\fP
-.br
-The number of ``quota'' structures allocated. Quota structures
-are present only when disc quotas are configured in the system. One
-quota structure is kept per user. This is defined to be
-.DS
-(MAXUSERS * 9) / 7 + 3
-.DE
-.IP \fBndquot\fP
-.br
-The number of ``dquot'' structures allocated. Dquot structures
-are present only when disc quotas are configured in the system.
-One dquot structure is required per user, per active file system quota.
-That is, when a user manipulates a file on a file system on which
-quotas are enabled, the information regarding the user's quotas on
-that file system must be in-core. This information is cached, so
-that not all information must be present in-core all the time.
-This is defined as
-.DS
-NINODE + (MAXUSERS * NMOUNT) / 4
-.DE
-where NMOUNT is the maximum number of mountable file systems.
-.LP
-In addition to the above values, the system page tables (used to
-map virtual memory in the kernel's address space) are sized at
-compile time by the SYSPTSIZE definition in the file /sys/vax/vmparam.h.
-This is defined to be
-.DS
-20 + MAXUSERS
-.DE
-pages of page tables.
-Its definition affects
-the size of many data structures allocated at boot time because
-it constrains the amount of virtual memory which may be addressed
-by the running system. This is often the limiting factor
-in the size of the buffer cache, in which case a message is printed
-when the system configures at boot time.
-.SH
-Run-time calculations
-.PP
-The most important data structures sized at run-time are those used in
-the buffer cache. Allocation is done by allocating physical memory
-(and system virtual memory) immediately after the system
-has been started up; look in the file /sys/vax/machdep.c.
-The amount of physical memory which may be allocated to the buffer
-cache is constrained by the size of the system page tables, among
-other things. While the system may calculate
-a large amount of memory to be allocated to the buffer cache,
-if the system page
-table is too small to map this physical
-memory into the virtual address space
-of the system, only as much as can be mapped will be used.
-.PP
-The buffer cache is comprised of a number of ``buffer headers''
-and a pool of pages attached to these headers. Buffer headers
-are divided into two categories: those used for swapping and
-paging, and those used for normal file I/O. The system tries
-to allocate 10% of the first two megabytes and 5% of the remaining
-available physical memory for the buffer
-cache (where \fIavailable\fP does not count that space occupied by
-the system's text and data segments). If this results in fewer
-than 16 pages of memory allocated, then 16 pages are allocated.
-This value is kept in the initialized variable \fIbufpages\fP
-so that it may be patched in the binary image (to allow tuning
-without recompiling the system),
-or the default may be overridden with a configuration-file option.
-For example, the option \fBoptions BUFPAGES="3200"\fP
-causes 3200 pages (3.2M bytes) to be used by the buffer cache.
-A sufficient number of file I/O buffer headers are then allocated
-to allow each to hold 2 pages each.
-Each buffer maps 8K bytes.
-If the number of buffer pages is larger than can be mapped
-by the buffer headers, the number of pages is reduced.
-The number of buffer headers allocated
-is stored in the global variable \fInbuf\fP,
-which may be patched before the system is booted.
-The system option \fBoptions NBUF="1000"\fP forces the allocation
-of 1000 buffer headers.
-Half as many swap I/O buffer headers as file I/O buffers
-are allocated,
-but no more than 256.
-.SH
-System size limitations
-.PP
-As distributed, the sum of the virtual sizes of the core-resident
-processes is limited to 256M bytes. The size of the text
-segment of a single process is currently limited to 6M bytes.
-It may be increased to no greater than the data segment size limit
-(see below) by redefining MAXTSIZ.
-This may be done with a configuration file option,
-e.g. \fBoptions MAXTSIZ="(10*1024*1024)"\fP
-to set the limit to 10 million bytes.
-Other per-process limits discussed here may be changed with similar options
-with names given in parentheses.
-Soft, user-changeable limits are set to 512K bytes for stack (DFLSSIZ)
-and 6M bytes for the data segment (DFLDSIZ) by default;
-these may be increased up to the hard limit
-with the \fIsetrlimit\fP\|(2) system call.
-The data and stack segment size hard limits are set by a system configuration
-option to one of 17M, 33M or 64M bytes.
-One of these sizes is chosen based on the definition of MAXDSIZ;
-with no option, the limit is 17M bytes; with an option
-\fBoptions MAXDSIZ="(32*1024*1024)"\fP (or any value between 17M and 33M),
-the limit is increased to 33M bytes, and values larger than 33M
-result in a limit of 64M bytes.
-You must be careful in doing this that you have adequate paging space.
-As normally configured , the system has 16M or 32M bytes per paging area,
-depending on disk size.
-The best way to get more space is to provide multiple, thereby
-interleaved, paging areas.
-Increasing the virtual memory limits results in interleaving of
-swap space in larger sections (from 500K bytes to 1M or 2M bytes).
-.PP
-By default, the virtual memory system allocates enough memory
-for system page tables mapping user page tables
-to allow 256 megabytes of simultaneous active virtual memory.
-That is, the sum of the virtual memory sizes of all (completely- or partially-)
-resident processes can not exceed this limit.
-If the limit is exceeded, some process(es) must be swapped out.
-To increase the amount of resident virtual space possible,
-you can alter the constant USRPTSIZE (in
-/sys/vax/vmparam.h).
-Each page of system page tables allows 8 megabytes of user virtual memory.
-.PP
-Because the file system block numbers are stored in
-page table \fIpg_blkno\fP
-entries, the maximum size of a file system is limited to
-2^24 1024 byte blocks. Thus no file system can be larger than 8 gigabytes.
-.PP
-The number of mountable file systems is set at 20 by the definition
-of NMOUNT in /sys/h/param.h.
-This should be sufficient; if not, the value can be increased up to 255.
-If you have many disks, it makes sense to make some of
-them single file systems, and the paging areas don't count in this total.
-.PP
-The limit to the number of files that a process may have open simultaneously
-is set to 64.
-This limit is set by the NOFILE definition in /sys/h/param.h.
-It may be increased arbitrarily, with the caveat that the user structure
-expands by 5 bytes for each file, and thus UPAGES (/sys/vax/machparam.h)
-must be increased accordingly.
-.PP
-The amount of physical memory is currently limited to 64 Mb
-by the size of the index fields in the core-map (/sys/h/cmap.h).
-The limit may be increased by following instructions in that file
-to enlarge those fields.
diff --git a/usr.sbin/config/SMM.doc/e.t b/usr.sbin/config/SMM.doc/e.t
deleted file mode 100644
index 0a9505b..0000000
--- a/usr.sbin/config/SMM.doc/e.t
+++ /dev/null
@@ -1,114 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)e.t 8.1 (Berkeley) 6/8/93
-.\"
-.\".ds RH "Network configuration options
-.bp
-.LG
-.B
-.ce
-APPENDIX E. NETWORK CONFIGURATION OPTIONS
-.sp
-.R
-.NL
-.PP
-The network support in the kernel is self-configuring
-according to the protocol support options (INET and NS) and the network
-hardware discovered during autoconfiguration.
-There are several changes that may be made to customize network behavior
-due to local restrictions.
-Within the Internet protocol routines, the following options
-set in the system configuration file are supported:
-.IP \fBGATEWAY\fP
-.br
-The machine is to be used as a gateway.
-This option currently makes only minor changes.
-First, the size of the network routing hash table is increased.
-Secondly, machines that have only a single hardware network interface
-will not forward IP packets; without this option, they will also refrain
-from sending any error indication to the source of unforwardable packets.
-Gateways with only a single interface are assumed to have missing
-or broken interfaces, and will return ICMP unreachable errors to hosts
-sending them packets to be forwarded.
-.IP \fBTCP_COMPAT_42\fP
-.br
-This option forces the system to limit its initial TCP sequence numbers
-to positive numbers.
-Without this option, 4.4BSD systems may have problems with TCP connections
-to 4.2BSD systems that connect but never transfer data.
-The problem is a bug in the 4.2BSD TCP.
-.IP \fBIPFORWARDING\fP
-.br
-Normally, 4.4BSD machines with multiple network interfaces
-will forward IP packets received that should be resent to another host.
-If the line ``options IPFORWARDING="0"'' is in the system configuration
-file, IP packet forwarding will be disabled.
-.IP \fBIPSENDREDIRECTS\fP
-.br
-When forwarding IP packets, 4.4BSD IP will note when a packet is forwarded
-using the same interface on which it arrived.
-When this is noted, if the source machine is on the directly-attached
-network, an ICMP redirect is sent to the source host.
-If the packet was forwarded using a route to a host or to a subnet,
-a host redirect is sent, otherwise a network redirect is sent.
-The generation of redirects may be inhibited with the configuration
-option ``options IPSENDREDIRECTS="0".''
-.br
-.IP \fBSUBNETSARELOCAL\fP
-TCP calculates a maximum segment size to use for each connection,
-and sends no datagrams larger than that size.
-This size will be no larger than that supported on the outgoing
-interface.
-Furthermore, if the destination is not on the local network,
-the size will be no larger than 576 bytes.
-For this test, other subnets of a directly-connected subnetted
-network are considered to be local unless the line
-``options SUBNETSARELOCAL="0"'' is used in the system configuration file.
-.LP
-The following options are supported by the Xerox NS protocols:
-.IP \fBNSIP\fP
-.br
-This option allows NS IDP datagrams to be encapsulated in Internet IP
-packets for transmission to a collaborating NSIP host.
-This may be used to pass IDP packets through IP-only link layer networks.
-See
-.IR nsip (4P)
-for details.
-.IP \fBTHREEWAYSHAKE\fP
-.br
-The NS Sequenced Packet Protocol does not require a three-way handshake
-before considering a connection to be in the established state.
-(A three-way handshake consists of a connection request, an acknowledgement
-of the request along with a symmetrical opening indication,
-and then an acknowledgement of the reciprocal opening packet.)
-This option forces a three-way handshake before data may be transmitted
-on Sequenced Packet sockets.
diff --git a/usr.sbin/config/SMM.doc/spell.ok b/usr.sbin/config/SMM.doc/spell.ok
deleted file mode 100644
index dfc5df1..0000000
--- a/usr.sbin/config/SMM.doc/spell.ok
+++ /dev/null
@@ -1,305 +0,0 @@
-# $FreeBSD$
-ACC
-ANSEL
-ARP
-Autoconfiguration
-BUFPAGES
-CANTWAIT
-CH
-COMPAT
-CSS
-Co
-Config
-Config''SMM:2
-DCLR
-DFLDSIZ
-DFLSSIZ
-DFUNNY
-DHAHA
-DMA
-Dev
-Dquot
-ECC
-EMULEX
-Emulex
-Ethernet
-FPNUMBER
-FUNNY,HAHA
-HAVEBDP
-ICMP
-IDP
-IE
-INET
-IP
-IPC
-IPFORWARDING
-IPL
-IPSENDREDIRECTS
-Info
-Karels
-LH
-Leffler
-MASSBUS
-MAXDSIZ
-MAXTSIZ
-Makefile
-Mb
-MicroVAX
-Mkopt
-Mkoption
-NBUF
-NEED16
-NEEDBDP
-NINODE
-NMOUNT
-NOFILE
-NPROC
-NS
-NSC
-NSIP
-NUP
-PST
-RCS
-RDY
-RH
-RK07
-RK611
-SCCS
-SITENAME
-SMM:2
-SUBNETSARELOCAL
-SYSPTSIZE
-TCP
-THREEWAYSHAKE
-Timezone
-UCBVAX
-UDP
-UNIBUS
-UPAGES
-UPCS2
-USRPTSIZE
-VAX
-VAX630
-VAX730
-VAX750
-VAX780
-VAX8600
-VAXWELL
-VAXen
-Vax
-Vaxwell
-acc0
-accrint
-accxint
-addr
-arg
-args
-assym.s
-autoconfiguration
-autoconfigure
-autoconfigured
-backpointer
-badaddr
-blkno
-br
-br5
-buf
-bufpages
-buses
-caddr
-callout
-catchall
-cmap.h
-cmd
-conf
-conf.c
-config
-csr
-ct.c
-ctlr
-cvec
-datagrams
-define''s
-dev
-devices.machine
-dgo
-dh.c
-dh0
-dh1
-dh2
-dhreg.h
-dhrint
-dhxint
-dinfo
-dk
-dk.h
-dm0
-dmintr
-dname
-dquot
-dst
-dumpdev
-dumplo
-dumpmagic
-dumpsize
-dz.c
-dz0
-dzrint
-dzxint
-ec0
-eccollide
-ecrint
-ecxint
-endif
-es
-files.machine
-filesystem
-foo
-foo.c
-genkernel
-gettimeofday
-gigabytes
-gprof
-hardwired
-hd
-hk
-hk0
-hkkernel
-howmany
-hp0
-hp0b
-hp1
-hp2
-hp3
-hpkernel
-ht0
-hz
-ident
-ifdef
-ifndef
-il0
-ilcint
-ilrint
-info
-intr
-ioconf.c
-kgmon
-linterrs
-loopback
-machdep.c
-machparam.h
-makefile
-makelinks
-makeoptions
-maxusers
-mba
-mba0
-mba1
-mbuf.h
-mcount.c
-memsize
-minfo
-mname
-moniker
-mspw
-nbuf
-ncallout
-nclist
-ndquot
-ndrive
-netimp
-netinet
-netns
-netstat
-nexi
-nexus
-nfile
-ninode
-nmbclusters
-nnn.ddd
-nproc
-nquota
-nsip
-ntext
-optionlist
-param.c
-param.h
-pathnames
-pg
-physaddr
-pty
-rc
-reg
-rk.c
-rk0
-rk1
-rkintr
-savecore
-sc
-sc0
-sc1
-scdriver
-setrlimit
-sizeof
-softc
-source.c
-subr
-swapxxx.c
-sysname
-te0
-te1
-timezone
-tm0
-tmintr
-tu0
-uba
-uba.c
-uba0
-ubago
-uballoc
-ubamem
-ubanum
-ubareg.h
-ubarelse
-ubavar.h
-ubglue.s
-ubinfo
-ud
-ui
-um
-up.c
-up0
-up1
-up2
-upaddr
-upattach
-upba
-upcs1
-upcs2
-updevice
-updgo
-updinfo
-updtab
-upintr
-upip
-upmaptype
-upminfo
-upprobe
-upslave
-upstd
-upkernel
-upwatch
-upwstart
-value,name2
-value2
-vax
-vaxif
-vaxmba
-vaxuba
-vmparam.h
-kernel
-wildcard
-wildcarded
-wildcarding
-xclu
-xxx
diff --git a/usr.sbin/cxgbtool/cxgbtool.c b/usr.sbin/cxgbtool/cxgbtool.c
index b705ff8..f73f1a4 100644
--- a/usr.sbin/cxgbtool/cxgbtool.c
+++ b/usr.sbin/cxgbtool/cxgbtool.c
@@ -1014,6 +1014,8 @@ load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
op.len = len;
if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0)
err(1, "load firmware");
+
+ close(fd);
return 0;
}
@@ -1048,6 +1050,7 @@ load_boot(int argc, char *argv[], int start_arg, const char *iff_name)
if (doit(iff_name, CHELSIO_LOAD_BOOT, &op) < 0)
err(1, "load boot image");
+ close(fd);
return 0;
}
diff --git a/usr.sbin/extattrctl/extattrctl.c b/usr.sbin/extattrctl/extattrctl.c
index 1929f79..377d3ba 100644
--- a/usr.sbin/extattrctl/extattrctl.c
+++ b/usr.sbin/extattrctl/extattrctl.c
@@ -144,9 +144,11 @@ initattr(int argc, char *argv[])
if (error == -1) {
perror(argv[1]);
unlink(argv[1]);
+ close(i);
return (-1);
}
+ close(i);
return (0);
}
@@ -168,21 +170,25 @@ showattr(int argc, char *argv[])
i = read(fd, &uef, sizeof(uef));
if (i == -1) {
perror(argv[0]);
+ close(fd);
return (-1);
}
if (i != sizeof(uef)) {
fprintf(stderr, "%s: invalid file header\n", argv[0]);
+ close(fd);
return (-1);
}
if (uef.uef_magic != UFS_EXTATTR_MAGIC) {
fprintf(stderr, "%s: bad magic\n", argv[0]);
+ close(fd);
return (-1);
}
printf("%s: version %d, size %d\n", argv[0], uef.uef_version,
uef.uef_size);
+ close(fd);
return (0);
}
diff --git a/usr.sbin/fifolog/lib/fifolog_write.h b/usr.sbin/fifolog/lib/fifolog_write.h
index 06b3233..22a307d 100644
--- a/usr.sbin/fifolog/lib/fifolog_write.h
+++ b/usr.sbin/fifolog/lib/fifolog_write.h
@@ -44,8 +44,6 @@ struct fifolog_writer {
unsigned syncrate;
unsigned compression;
- unsigned writes_since_sync;
-
int cleanup;
intmax_t cnt[FIFOLOG_NPOINT];
@@ -55,9 +53,11 @@ struct fifolog_writer {
int flag;
time_t last;
+ u_int obufsize;
+ u_char *obuf;
+
u_int ibufsize;
u_char *ibuf;
- u_char *iptr;
time_t starttime;
time_t lastwrite;
diff --git a/usr.sbin/fifolog/lib/fifolog_write_poll.c b/usr.sbin/fifolog/lib/fifolog_write_poll.c
index 4fc5204..abb015b 100644
--- a/usr.sbin/fifolog/lib/fifolog_write_poll.c
+++ b/usr.sbin/fifolog/lib/fifolog_write_poll.c
@@ -33,6 +33,9 @@
#include <unistd.h>
#include <time.h>
#include <sys/endian.h>
+#if 0
+#include <sys/uio.h>
+#endif
#include <zlib.h>
@@ -65,9 +68,8 @@ fifolog_write_assert(const struct fifolog_writer *f)
{
CHECK_OBJ_NOTNULL(f, FIFOLOG_WRITER_MAGIC);
- assert(f->iptr == f->ff->zs->next_in + f->ff->zs->avail_in);
assert(f->ff->zs->next_out + f->ff->zs->avail_out == \
- f->ff->recbuf + f->ff->recsize);
+ f->obuf + f->obufsize);
}
struct fifolog_writer *
@@ -75,8 +77,8 @@ fifolog_write_new(void)
{
struct fifolog_writer *f;
- ALLOC(&f, sizeof *f);
- f->magic = FIFOLOG_WRITER_MAGIC;
+ ALLOC_OBJ(f, FIFOLOG_WRITER_MAGIC);
+ assert(f != NULL);
return (f);
}
@@ -94,36 +96,11 @@ fifolog_write_close(struct fifolog_writer *f)
CHECK_OBJ_NOTNULL(f, FIFOLOG_WRITER_MAGIC);
fifolog_int_close(&f->ff);
free(f->ff);
- if (f->ibuf != NULL)
- free(f->ibuf);
+ if (f->obuf != NULL)
+ free(f->obuf);
free(f);
}
-static void
-fifo_prepobuf(struct fifolog_writer *f, time_t now, int flag)
-{
-
- memset(f->ff->recbuf, 0, f->ff->recsize);
- f->ff->zs->next_out = f->ff->recbuf + 5;
- f->ff->zs->avail_out = f->ff->recsize - 5;
- if (f->recno == 0 && f->seq == 0) {
- srandomdev();
- do {
- f->seq = random();
- } while (f->seq == 0);
- }
- be32enc(f->ff->recbuf, f->seq++);
- f->ff->recbuf[4] = f->flag;
- f->flag = 0;
- if (flag) {
- f->ff->recbuf[4] |= FIFOLOG_FLG_SYNC;
- be32enc(f->ff->recbuf + 5, (u_int)now);
- f->ff->zs->next_out += 4;
- f->ff->zs->avail_out -= 4;
- }
- fifolog_write_assert(f);
-}
-
const char *
fifolog_write_open(struct fifolog_writer *f, const char *fn, unsigned writerate, unsigned syncrate, int compression)
{
@@ -164,144 +141,154 @@ fifolog_write_open(struct fifolog_writer *f, const char *fn, unsigned writerate,
f->seq++;
}
- f->ibufsize = 32768;
- ALLOC(&f->ibuf, f->ibufsize);
- f->iptr = f->ibuf;
- f->ff->zs->next_in = f->iptr;
+ f->obufsize = f->ff->recsize;
+ ALLOC(&f->obuf, f->obufsize);
+
i = deflateInit(f->ff->zs, (int)f->compression);
assert(i == Z_OK);
f->flag |= FIFOLOG_FLG_RESTART;
+ f->flag |= FIFOLOG_FLG_SYNC;
+ f->ff->zs->next_out = f->obuf + 9;
+ f->ff->zs->avail_out = f->obufsize - 9;
time(&now);
- fifo_prepobuf(f, now, 1);
f->starttime = now;
+ f->lastsync = now;
+ f->lastwrite = now;
fifolog_write_assert(f);
return (NULL);
}
-static void
-fifo_writerec(struct fifolog_writer *f)
+static int
+fifolog_write_output(struct fifolog_writer *f, int fl, time_t now)
{
- int i;
- time_t t;
+ long h, l = f->ff->zs->next_out - f->obuf;
+ int i, w;
+
+ h = 4; /* seq */
+ be32enc(f->obuf, f->seq);
+ f->obuf[h] = f->flag;
+ h += 1; /* flag */
+ if (f->flag & FIFOLOG_FLG_SYNC) {
+ be32enc(f->obuf + h, now);
+ h += 4; /* timestamp */
+ }
- fifolog_write_assert(f);
- f->writes_since_sync++;
-
- assert(f->recno < f->ff->logsize);
- f->cnt[FIFOLOG_PT_BYTES_POST] += f->ff->recsize - f->ff->zs->avail_out;
- if (f->ff->zs->avail_out == 0) {
- /* nothing */
- } else if (f->ff->zs->avail_out <= 255) {
- f->ff->recbuf[f->ff->recsize - 1] =
- (u_char)f->ff->zs->avail_out;
- f->ff->recbuf[4] |= FIFOLOG_FLG_1BYTE;
- } else {
- be32enc(f->ff->recbuf + f->ff->recsize - 4,
- f->ff->zs->avail_out);
- f->ff->recbuf[4] |= FIFOLOG_FLG_4BYTE;
+ assert(l <= (long)f->ff->recsize);
+ assert(l >= h);
+ if (l == h)
+ return (0);
+
+
+ if (h + l < (long)f->ff->recsize && fl == Z_NO_FLUSH)
+ return (0);
+
+ w = f->ff->recsize - l;
+ if (w > 255) {
+ be32enc(f->obuf + f->ff->recsize - 4, w);
+ f->obuf[4] |= FIFOLOG_FLG_4BYTE;
+ } else if (w > 0) {
+ f->obuf[f->ff->recsize - 1] = w;
+ f->obuf[4] |= FIFOLOG_FLG_1BYTE;
}
- i = pwrite(f->ff->fd, f->ff->recbuf, f->ff->recsize,
- (f->recno + 1) * f->ff->recsize);
- assert (i == (int)f->ff->recsize);
- if (++f->recno == f->ff->logsize)
- f->recno = 0;
+
+ f->cnt[FIFOLOG_PT_BYTES_POST] += w;
+
+#ifdef DBG
+fprintf(stderr, "W: fl=%d h=%ld l=%ld w=%d recno=%jd fx %02x\n",
+ fl, h, l, w, f->recno, f->obuf[4]);
+#endif
+
+ i = pwrite(f->ff->fd, f->obuf, f->ff->recsize,
+ (f->recno + 1) * f->ff->recsize);
+ assert(i == (int)f->ff->recsize);
+
f->cnt[FIFOLOG_PT_WRITES]++;
- time(&t);
- f->cnt[FIFOLOG_PT_RUNTIME] = t - f->starttime; /*lint !e776 */
- fifolog_write_assert(f);
+
+ f->lastwrite = now;
+ f->seq++;
+ f->recno++;
+#ifdef DBG
+if (f->flag)
+fprintf(stderr, "SYNC- %d\n", __LINE__);
+#endif
+ f->flag = 0;
+
+ memset(f->obuf, 0, f->obufsize);
+ f->ff->zs->next_out = f->obuf + 5;
+ f->ff->zs->avail_out = f->obufsize - 5;
+ return (1);
}
-int
-fifolog_write_poll(struct fifolog_writer *f, time_t now)
+static void
+fifolog_write_gzip(struct fifolog_writer *f, const void *p, int len, time_t now, int fin)
{
- int i, fl, bo, bf;
+ int i, fl;
- if (now == 0)
- time(&now);
+ f->cnt[FIFOLOG_PT_BYTES_PRE] += len;
- fifolog_write_assert(f);
- if (f->cleanup || now >= (int)(f->lastsync + f->syncrate)) {
- /*
- * We always check the sync timer, otherwise a flood of data
- * would not get any sync records at all
- */
+ if (fin == 0)
+ fl = Z_NO_FLUSH;
+ else if (f->cleanup || now >= (int)(f->lastsync + f->syncrate)) {
f->cleanup = 0;
fl = Z_FINISH;
- f->lastsync = now;
- f->lastwrite = now;
f->cnt[FIFOLOG_PT_SYNC]++;
- } else if (f->ff->zs->avail_in == 0 &&
- now >= (int)(f->lastwrite + f->writerate)) {
- /*
- * We only check for writerate timeouts when the input
- * buffer is empty. It would be silly to force a write if
- * pending input could cause it to happen on its own.
- */
+ } else if (now >= (int)(f->lastwrite + f->writerate)) {
fl = Z_SYNC_FLUSH;
- f->lastwrite = now;
f->cnt[FIFOLOG_PT_FLUSH]++;
- } else if (f->ff->zs->avail_in == 0)
- return (0); /* nothing to do */
+ } else if (p == NULL)
+ return;
else
fl = Z_NO_FLUSH;
- for (;;) {
- assert(f->ff->zs->avail_out > 0);
-
- bf = f->ff->zs->avail_out;
-
+ f->ff->zs->avail_in = len;
+ f->ff->zs->next_in = (void*)(uintptr_t)p;
+#ifdef DBG
+if (fl != Z_NO_FLUSH)
+fprintf(stderr, "Z len %3d fin %d now %ld fl %d ai %u ao %u\n",
+ len, fin, now, fl,
+ f->ff->zs->avail_in,
+ f->ff->zs->avail_out);
+#endif
+
+ while (1) {
i = deflate(f->ff->zs, fl);
- assert (i == Z_OK || i == Z_BUF_ERROR || i == Z_STREAM_END);
- bo = f->ff->zs->avail_out;
+#ifdef DBG
+if (i || f->ff->zs->avail_in)
+fprintf(stderr, "fl = %d, i = %d ai = %u ao = %u fx=%02x\n", fl, i,
+ f->ff->zs->avail_in,
+ f->ff->zs->avail_out, f->flag);
+#endif
- /* If we have output space and not in a hurry.. */
- if (bo > 0 && fl == Z_NO_FLUSH)
- break;
-
- /* Write output buffer, if anything in it */
- if (bo != bf)
- fifo_writerec(f);
-
- /* If the buffer were full, we need to check again */
- if (bo == 0) {
- fifo_prepobuf(f, now, 0);
- continue;
- }
+ assert(i == Z_OK || i == Z_BUF_ERROR || i == Z_STREAM_END);
+ assert(f->ff->zs->avail_in == 0);
- if (fl == Z_FINISH) {
- /* Make next record a SYNC record */
- fifo_prepobuf(f, now, 1);
- /* And reset the zlib engine */
- i = deflateReset(f->ff->zs);
- assert(i == Z_OK);
- f->writes_since_sync = 0;
- } else {
- fifo_prepobuf(f, now, 0);
- }
- break;
+ if (!fifolog_write_output(f, fl, now))
+ break;
}
-
- if (f->ff->zs->avail_in == 0) {
- /* Reset input buffer when empty */
- f->iptr = f->ibuf;
- f->ff->zs->next_in = f->iptr;
+ assert(f->ff->zs->avail_in == 0);
+ if (fl == Z_FINISH) {
+ f->flag |= FIFOLOG_FLG_SYNC;
+ f->ff->zs->next_out = f->obuf + 9;
+ f->ff->zs->avail_out = f->obufsize - 9;
+ f->lastsync = now;
+#ifdef DBG
+fprintf(stderr, "SYNC %d\n", __LINE__);
+#endif
+ assert(Z_OK == deflateReset(f->ff->zs));
}
-
- fifolog_write_assert(f);
- return (1);
}
-static void
-fifolog_acct(struct fifolog_writer *f, unsigned bytes)
+int
+fifolog_write_poll(struct fifolog_writer *f, time_t now)
{
-
- f->ff->zs->avail_in += bytes;
- f->iptr += bytes;
- f->cnt[FIFOLOG_PT_BYTES_PRE] += bytes;
+ if (now == 0)
+ time(&now);
+ fifolog_write_gzip(f, NULL, 0, now, 1);
+ return (0);
}
/*
@@ -312,8 +299,8 @@ fifolog_acct(struct fifolog_writer *f, unsigned bytes)
int
fifolog_write_bytes(struct fifolog_writer *f, uint32_t id, time_t now, const void *ptr, unsigned len)
{
- u_int l;
const unsigned char *p;
+ uint8_t buf[4];
fifolog_write_assert(f);
assert(!(id & (FIFOLOG_TIMESTAMP|FIFOLOG_LENGTH)));
@@ -322,46 +309,45 @@ fifolog_write_bytes(struct fifolog_writer *f, uint32_t id, time_t now, const voi
p = ptr;
if (len == 0) {
len = strlen(ptr) + 1;
- l = 4 + len; /* id */
} else {
assert(len <= 255);
id |= FIFOLOG_LENGTH;
- l = 5 + len; /* id + len */
}
- l += 4; /* A timestamp may be necessary */
-
/* Now do timestamp, if needed */
if (now == 0)
time(&now);
- assert(l < f->ibufsize);
-
- /* Return if there is not enough space */
- if (f->iptr + l > f->ibuf + f->ibufsize)
- return (0);
-
if (now != f->last) {
id |= FIFOLOG_TIMESTAMP;
f->last = now;
}
- /* Emit instance+flag and length */
- be32enc(f->iptr, id);
- fifolog_acct(f, 4);
+ /* Emit instance+flag */
+ be32enc(buf, id);
+ fifolog_write_gzip(f, buf, 4, now, 0);
if (id & FIFOLOG_TIMESTAMP) {
- be32enc(f->iptr, (uint32_t)f->last);
- fifolog_acct(f, 4);
+ be32enc(buf, (uint32_t)f->last);
+ fifolog_write_gzip(f, buf, 4, now, 0);
}
if (id & FIFOLOG_LENGTH) {
- f->iptr[0] = (u_char)len;
- fifolog_acct(f, 1);
+ buf[0] = (u_char)len;
+ fifolog_write_gzip(f, buf, 1, now, 0);
}
assert (len > 0);
- memcpy(f->iptr, p, len);
- fifolog_acct(f, len);
+#if 1
+ if (len > f->ibufsize) {
+ free(f->ibuf);
+ f->ibufsize = len;
+ ALLOC(&f->ibuf, f->ibufsize);
+ }
+ memcpy(f->ibuf, p, len);
+ fifolog_write_gzip(f, f->ibuf, len, now, 1);
+#else
+ fifolog_write_gzip(f, p, len, now, 1);
+#endif
fifolog_write_assert(f);
return (1);
}
@@ -384,7 +370,6 @@ fifolog_write_bytes_poll(struct fifolog_writer *f, uint32_t id, time_t now, cons
if (len == 0) {
while (!fifolog_write_bytes(f, id, now, ptr, len)) {
- (void)fifolog_write_poll(f, now);
(void)usleep(10000);
}
} else {
@@ -394,7 +379,6 @@ fifolog_write_bytes_poll(struct fifolog_writer *f, uint32_t id, time_t now, cons
if (l > 255)
l = 255;
while (!fifolog_write_bytes(f, id, now, p, l)) {
- (void)fifolog_write_poll(f, now);
(void)usleep(10000);
}
}
diff --git a/usr.sbin/fwcontrol/fwcontrol.c b/usr.sbin/fwcontrol/fwcontrol.c
index 509d25d..6aa365a 100644
--- a/usr.sbin/fwcontrol/fwcontrol.c
+++ b/usr.sbin/fwcontrol/fwcontrol.c
@@ -508,6 +508,7 @@ load_crom(char *filename, u_int32_t *p)
p, p+1, p+2, p+3, p+4, p+5, p+6, p+7);
p += 8;
}
+ fclose(file);
}
static void
diff --git a/usr.sbin/lpr/Makefile b/usr.sbin/lpr/Makefile
index 3cd0eb6..043ed8b 100644
--- a/usr.sbin/lpr/Makefile
+++ b/usr.sbin/lpr/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
SUBDIR= common_source chkprintcap lp lpc lpd lpq lpr lprm lptest pac \
- filters filters.ru SMM.doc
+ filters filters.ru
# Questions/ideas for lpr & friends could also be sent to:
# freebsd-print@bostonradio.org
diff --git a/usr.sbin/lpr/SMM.doc/0.t b/usr.sbin/lpr/SMM.doc/0.t
deleted file mode 100644
index 65ecd4e..0000000
--- a/usr.sbin/lpr/SMM.doc/0.t
+++ /dev/null
@@ -1,68 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)0.t 8.1 (Berkeley) 6/8/93
-.\"
-.if n .ND
-.TL
-4.3BSD Line Printer Spooler Manual
-.EH 'SMM:7-%''4.3BSD Line Printer Spooler Manual'
-.OH '4.3BSD Line Printer Spooler Manual''SMM:7-%'
-.AU
-Ralph Campbell
-.AI
-Computer Systems Research Group
-Computer Science Division
-Department of Electrical Engineering and Computer Science
-University of California, Berkeley
-Berkeley, CA 94720
-.AB
-.FS
-* UNIX is a trademark of Bell Laboratories.
-.FE
-This document describes the structure and installation procedure
-for the line printer spooling system
-developed for the 4.3BSD version
-of the UNIX* operating system.
-.de D?
-.ie \\n(.$>1 Revised \\$1 \\$2 \\$3
-.el DRAFT of \n(mo/\n(dy/\n(yr
-..
-.sp 2
-.LP
-.D? June 8, 1993
-.AE
-.de IR
-\fI\\$1\fP\\$2
-..
-.de DT
-.TA 8 16 24 32 40 48 56 64 72 80
-..
diff --git a/usr.sbin/lpr/SMM.doc/1.t b/usr.sbin/lpr/SMM.doc/1.t
deleted file mode 100644
index 1d34e9e..0000000
--- a/usr.sbin/lpr/SMM.doc/1.t
+++ /dev/null
@@ -1,77 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)1.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Overview
-.PP
-The line printer system supports:
-.IP \(bu 3
-multiple printers,
-.IP \(bu 3
-multiple spooling queues,
-.IP \(bu 3
-both local and remote
-printers, and
-.IP \(bu 3
-printers attached via serial lines that require
-line initialization such as the baud rate.
-.LP
-Raster output devices
-such as a Varian or Versatec, and laser printers such as an Imagen,
-are also supported by the line printer system.
-.PP
-The line printer system consists mainly of the
-following files and commands:
-.DS
-.TS
-l l.
-/etc/printcap printer configuration and capability data base
-/usr/lib/lpd line printer daemon, does all the real work
-/usr/ucb/lpr program to enter a job in a printer queue
-/usr/ucb/lpq spooling queue examination program
-/usr/ucb/lprm program to delete jobs from a queue
-/etc/lpc program to administer printers and spooling queues
-/dev/printer socket on which lpd listens
-.TE
-.DE
-The file /etc/printcap is a master data base describing line
-printers directly attached to a machine and, also, printers
-accessible across a network. The manual page entry
-.IR printcap (5)
-provides the authoritative definition of
-the format of this data base, as well as
-specifying default values for important items
-such as the directory in which spooling is performed.
-This document introduces some of the
-information that may be placed
-.IR printcap .
diff --git a/usr.sbin/lpr/SMM.doc/2.t b/usr.sbin/lpr/SMM.doc/2.t
deleted file mode 100644
index 9da2ae2..0000000
--- a/usr.sbin/lpr/SMM.doc/2.t
+++ /dev/null
@@ -1,141 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)2.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Commands
-.NH 2
-lpd \- line printer daemon
-.PP
-The program
-.IR lpd (8),
-usually invoked at boot time from the /etc/rc file, acts as
-a master server for coordinating and controlling
-the spooling queues configured in the printcap file.
-When
-.I lpd
-is started it makes a single pass through the
-.I printcap
-database restarting any printers that have jobs.
-In normal operation
-.I lpd
-listens for service requests on multiple sockets,
-one in the UNIX domain (named ``/dev/printer'') for
-local requests, and one in the Internet domain
-(under the ``printer'' service specification)
-for requests for printer access from off machine;
-see \fIsocket\fP\|(2) and \fIservices\fP\|(5)
-for more information on sockets and service
-specifications, respectively.
-.I Lpd
-spawns a copy of itself to process the request; the master daemon
-continues to listen for new requests.
-.PP
-Clients communicate with
-.I lpd
-using a simple transaction oriented protocol.
-Authentication of remote clients is done based
-on the ``privilege port'' scheme employed by
-\fIrshd\fP\|(8C) and \fIrcmd\fP\|(3X).
-The following table shows the requests
-understood by
-.IR lpd .
-In each request the first byte indicates the
-``meaning'' of the request, followed by the name
-of the printer to which it should be applied. Additional
-qualifiers may follow, depending on the request.
-.DS
-.TS
-l l.
-Request Interpretation
-_
-^Aprinter\en check the queue for jobs and print any found
-^Bprinter\en receive and queue a job from another machine
-^Cprinter [users ...] [jobs ...]\en return short list of current queue state
-^Dprinter [users ...] [jobs ...]\en return long list of current queue state
-^Eprinter person [users ...] [jobs ...]\en remove jobs from a queue
-.TE
-.DE
-.PP
-The \fIlpr\fP\|(1) command
-is used by users to enter a print job in a local queue and to notify
-the local
-.I lpd
-that there are new jobs in the spooling area.
-.I Lpd
-either schedules the job to be printed locally, or if
-printing remotely, attempts to forward
-the job to the appropriate machine.
-If the printer cannot be opened or the destination
-machine is unreachable, the job will remain queued until it is
-possible to complete the work.
-.NH 2
-lpq \- show line printer queue
-.PP
-The \fIlpq\fP\|(1)
-program works recursively backwards displaying the queue of the machine with
-the printer and then the queue(s) of the machine(s) that lead to it.
-.I Lpq
-has two forms of output: in the default, short, format it
-gives a single line of output per queued job; in the long
-format it shows the list of files, and their sizes, that
-comprise a job.
-.NH 2
-lprm \- remove jobs from a queue
-.PP
-The \fIlprm\fP\|(1) command deletes jobs from a spooling
-queue. If necessary, \fIlprm\fP will first kill off a
-running daemon that is servicing the queue and restart
-it after the required files are removed. When removing
-jobs destined for a remote printer, \fIlprm\fP acts
-similarly to \fIlpq\fP except it first checks locally
-for jobs to remove and then
-tries to remove files in queues off-machine.
-.NH 2
-lpc \- line printer control program
-.PP
-The
-.IR lpc (8)
-program is used by the system administrator to control the
-operation of the line printer system.
-For each line printer configured in /etc/printcap,
-.I lpc
-may be used to:
-.IP \(bu
-disable or enable a printer,
-.IP \(bu
-disable or enable a printer's spooling queue,
-.IP \(bu
-rearrange the order of jobs in a spooling queue,
-.IP \(bu
-find the status of printers, and their associated
-spooling queues and printer daemons.
diff --git a/usr.sbin/lpr/SMM.doc/3.t b/usr.sbin/lpr/SMM.doc/3.t
deleted file mode 100644
index 8c950a9..0000000
--- a/usr.sbin/lpr/SMM.doc/3.t
+++ /dev/null
@@ -1,73 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)3.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Access control
-.PP
-The printer system maintains protected spooling areas so that
-users cannot circumvent printer accounting or
-remove files other than their own.
-The strategy used to maintain protected
-spooling areas is as follows:
-.IP \(bu 3
-The spooling area is writable only by a \fIdaemon\fP user
-and \fIdaemon\fP group.
-.IP \(bu 3
-The \fIlpr\fP program runs set-user-id to \fIroot\fP and
-set-group-id to group \fIdaemon\fP. The \fIroot\fP access permits
-reading any file required. Accessibility is verified
-with an \fIaccess\fP\|(2) call. The group ID
-is used in setting up proper ownership of files
-in the spooling area for \fIlprm\fP.
-.IP \(bu 3
-Control files in a spooling area are made with \fIdaemon\fP
-ownership and group ownership \fIdaemon\fP. Their mode is 0660.
-This insures control files are not modified by a user
-and that no user can remove files except through \fIlprm\fP.
-.IP \(bu 3
-The spooling programs,
-\fIlpd\fP, \fIlpq\fP, and \fIlprm\fP run set-user-id to \fIroot\fP
-and set-group-id to group \fIdaemon\fP to access spool files and printers.
-.IP \(bu 3
-The printer server, \fIlpd\fP,
-uses the same verification procedures as \fIrshd\fP\|(8C)
-in authenticating remote clients. The host on which a client
-resides must be present in the file /etc/hosts.equiv or /etc/hosts.lpd and
-the request message must come from a reserved port number.
-.PP
-In practice, none of \fIlpd\fP, \fIlpq\fP, or
-\fIlprm\fP would have to run as user \fIroot\fP if remote
-spooling were not supported. In previous incarnations of
-the printer system \fIlpd\fP ran set-user-id to \fIdaemon\fP,
-set-group-id to group \fIspooling\fP, and \fIlpq\fP and \fIlprm\fP ran
-set-group-id to group \fIspooling\fP.
diff --git a/usr.sbin/lpr/SMM.doc/4.t b/usr.sbin/lpr/SMM.doc/4.t
deleted file mode 100644
index 8800bc0..0000000
--- a/usr.sbin/lpr/SMM.doc/4.t
+++ /dev/null
@@ -1,206 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)4.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Setting up
-.PP
-The 4.3BSD release comes with the necessary programs
-installed and with the default line printer queue
-created. If the system must be modified, the
-makefile in the directory /usr/src/usr.lib/lpr
-should be used in recompiling and reinstalling
-the necessary programs.
-.PP
-The real work in setting up is to create the
-.I printcap
-file and any printer filters for printers not supported
-in the distribution system.
-.NH 2
-Creating a printcap file
-.PP
-The
-.I printcap
-database contains one or more entries per printer.
-A printer should have a separate spooling directory;
-otherwise, jobs will be printed on
-different printers depending on which printer daemon starts first.
-This section describes how to create entries for printers that do not
-conform to the default printer description (an LP-11 style interface to a
-standard, band printer).
-.NH 3
-Printers on serial lines
-.PP
-When a printer is connected via a serial communication line
-it must have the proper baud rate and terminal modes set.
-The following example is for a DecWriter III printer connected
-locally via a 1200 baud serial line.
-.DS
-.DT
-lp|LA-180 DecWriter III:\e
- :lp=/dev/lp:br#1200:fs#06320:\e
- :tr=\ef:of=/usr/lib/lpf:lf=/usr/adm/lpd-errs:
-.DE
-The
-.B lp
-entry specifies the file name to open for output. Here it could
-be left out since ``/dev/lp'' is the default.
-The
-.B br
-entry sets the baud rate for the tty line and the
-.B fs
-entry sets CRMOD, no parity, and XTABS (see \fItty\fP\|(4)).
-The
-.B tr
-entry indicates that a form-feed should be printed when the queue
-empties so the paper can be torn off without turning the printer off-line and
-pressing form feed.
-The
-.B of
-entry specifies the filter program
-.I lpf
-should be used for printing the files;
-more will be said about filters later.
-The last entry causes errors
-to be written to the file ``/usr/adm/lpd-errs''
-instead of the console. Most errors from \fIlpd\fP are logged using
-\fIsyslogd\fP\|(8) and will not be logged in the specified file. The
-filters should use \fIsyslogd\fP to report errors; only those that
-write to standard error output will end up with errors in the \fBlf\fP file.
-(Occasionally errors sent to standard error output have not appeared
-in the log file; the use of \fIsyslogd\fP is highly recommended.)
-.NH 3
-Remote printers
-.PP
-Printers that reside on remote hosts should have an empty
-.B lp
-entry.
-For example, the following printcap entry would send output to the printer
-named ``lp'' on the machine ``ucbvax''.
-.DS
-.DT
-lp|default line printer:\e
- :lp=:rm=ucbvax:rp=lp:sd=/usr/spool/vaxlpd:
-.DE
-The
-.B rm
-entry is the name of the remote machine to connect to; this name must
-be a known host name for a machine on the network.
-The
-.B rp
-capability indicates
-the name of the printer on the remote machine is ``lp'';
-here it could be left out since this is the default value.
-The
-.B sd
-entry specifies ``/usr/spool/vaxlpd''
-as the spooling directory instead of the
-default value of ``/usr/spool/lpd''.
-.NH 2
-Output filters
-.PP
-Filters are used to handle device dependencies and to
-do accounting functions. The output filtering of
-.B of
-is used when accounting is
-not being done or when all text data must be passed through a filter.
-It is not intended to do accounting since it is started only once,
-all text files are filtered through it, and no provision is made for passing
-owners' login name, identifying the beginning and ending of jobs, etc.
-The other filters (if specified) are started for each file
-printed and do accounting if there is an
-.B af
-entry.
-If entries for both
-.B of
-and other filters are specified,
-the output filter is used only to print the banner page;
-it is then stopped to allow other filters access to the printer.
-An example of a printer that requires output filters
-is the Benson-Varian.
-.DS
-.DT
-va|varian|Benson-Varian:\e
- :lp=/dev/va0:sd=/usr/spool/vad:of=/usr/lib/vpf:\e
- :tf=/usr/lib/rvcat:mx#2000:pl#58:px=2112:py=1700:tr=\ef:
-.DE
-The
-.B tf
-entry specifies ``/usr/lib/rvcat'' as the filter to be
-used in printing \fItroff\fP\|(1) output.
-This filter is needed to set the device into print mode
-for text, and plot mode for printing
-.I troff
-files and raster images (see \fIva\fP\|(4V)).
-Note that the page length is set to 58 lines by the
-.B pl
-entry for 8.5" by 11" fan-fold paper.
-To enable accounting, the varian entry would be
-augmented with an
-.B af
-filter as shown below.
-.DS
-.DT
-va|varian|Benson-Varian:\e
- :lp=/dev/va0:sd=/usr/spool/vad:of=/usr/lib/vpf:\e
- :if=/usr/lib/vpf:tf=/usr/lib/rvcat:af=/usr/adm/vaacct:\e
- :mx#2000:pl#58:px=2112:py=1700:tr=\ef:
-.DE
-.NH 2
-Access Control
-.PP
-Local access to printer queues is controlled with the
-.B rg
-printcap entry.
-.DS
- :rg=lprgroup:
-.DE
-Users must be in the group
-.I lprgroup
-to submit jobs to the specified printer.
-The default is to allow all users access.
-Note that once the files are in the local queue, they can be printed
-locally or forwarded to another host depending on the configuration.
-.PP
-Remote access is controlled by listing the hosts in either the file
-/etc/hosts.equiv or /etc/hosts.lpd, one host per line. Note that
-.IR rsh (1)
-and
-.IR rlogin (1)
-use /etc/hosts.equiv to determine which hosts are equivalent for allowing logins
-without passwords. The file /etc/hosts.lpd is only used to control
-which hosts have line printer access.
-Remote access can be further restricted to only allow remote users with accounts
-on the local host to print jobs by using the \fBrs\fP printcap entry.
-.DS
- :rs:
-.DE
diff --git a/usr.sbin/lpr/SMM.doc/5.t b/usr.sbin/lpr/SMM.doc/5.t
deleted file mode 100644
index 137a342..0000000
--- a/usr.sbin/lpr/SMM.doc/5.t
+++ /dev/null
@@ -1,116 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)5.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Output filter specifications
-.PP
-The filters supplied with 4.3BSD
-handle printing and accounting for most common
-line printers, the Benson-Varian, the wide (36") and
-narrow (11") Versatec printer/plotters. For other devices or accounting
-methods, it may be necessary to create a new filter.
-.PP
-Filters are spawned by \fIlpd\fP
-with their standard input the data to be printed, and standard output
-the printer. The standard error is attached to the
-.B lf
-file for logging errors or \fIsyslogd\fP may be used for logging errors.
-A filter must return a 0 exit
-code if there were no errors, 1 if the job should be reprinted,
-and 2 if the job should be thrown away.
-When \fIlprm\fP
-sends a kill signal to the \fIlpd\fP process controlling
-printing, it sends a SIGINT signal
-to all filters and descendents of filters.
-This signal can be trapped by filters that need
-to do cleanup operations such as
-deleting temporary files.
-.PP
-Arguments passed to a filter depend on its type.
-The
-.B of
-filter is called with the following arguments.
-.DS
-\fIfilter\fP \fB\-w\fPwidth \fB\-l\fPlength
-.DE
-The \fIwidth\fP and \fIlength\fP values come from the
-.B pw
-and
-.B pl
-entries in the printcap database.
-The
-.B if
-filter is passed the following parameters.
-.DS
-\fIfilter\fP [\|\fB\-c\fP\|] \fB\-w\fPwidth \fB\-l\fPlength \fB\-i\fPindent \fB\-n\fP login \fB\-h\fP host accounting_file
-.DE
-The
-.B \-c
-flag is optional, and only supplied when control characters
-are to be passed uninterpreted to the printer (when using the
-.B \-l
-option of
-.I lpr
-to print the file).
-The
-.B \-w
-and
-.B \-l
-parameters are the same as for the
-.B of
-filter.
-The
-.B \-n
-and
-.B \-h
-parameters specify the login name and host name of the job owner.
-The last argument is the name of the accounting file from
-.IR printcap .
-.PP
-All other filters are called with the following arguments:
-.DS
-\fIfilter\fP \fB\-x\fPwidth \fB\-y\fPlength \fB\-n\fP login \fB\-h\fP host accounting_file
-.DE
-The
-.B \-x
-and
-.B \-y
-options specify the horizontal and vertical page
-size in pixels (from the
-.B px
-and
-.B py
-entries in the printcap file).
-The rest of the arguments are the same as for the
-.B if
-filter.
diff --git a/usr.sbin/lpr/SMM.doc/6.t b/usr.sbin/lpr/SMM.doc/6.t
deleted file mode 100644
index 7087790..0000000
--- a/usr.sbin/lpr/SMM.doc/6.t
+++ /dev/null
@@ -1,94 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)6.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Line printer Administration
-.PP
-The
-.I lpc
-program provides local control over line printer activity.
-The major commands and their intended use will be described.
-The command format and remaining commands are described in
-.IR lpc (8).
-.LP
-\fBabort\fP and \fBstart\fP
-.IP
-.I Abort
-terminates an active spooling daemon on the local host immediately and
-then disables printing (preventing new daemons from being started by
-.IR lpr ).
-This is normally used to forcibly restart a hung line printer daemon
-(i.e., \fIlpq\fP reports that there is a daemon present but nothing is
-happening). It does not remove any jobs from the queue
-(use the \fIlprm\fP command instead).
-.I Start
-enables printing and requests \fIlpd\fP to start printing jobs.
-.LP
-\fBenable\fP and \fBdisable\fP
-.IP
-\fIEnable\fP and \fIdisable\fP allow spooling in the local queue to be
-turned on/off.
-This will allow/prevent
-.I lpr
-from putting new jobs in the spool queue. It is frequently convenient
-to turn spooling off while testing new line printer filters since the
-.I root
-user can still use
-.I lpr
-to put jobs in the queue but no one else can.
-The other main use is to prevent users from putting jobs in the queue
-when the printer is expected to be unavailable for a long time.
-.LP
-\fBrestart\fP
-.IP
-.I Restart
-allows ordinary users to restart printer daemons when
-.I lpq
-reports that there is no daemon present.
-.LP
-\fBstop\fP
-.IP
-.I Stop
-halts a spooling daemon after the current job completes;
-this also disables printing. This is a clean way to shutdown a
-printer to do maintenance, etc. Note that users can still enter jobs in a
-spool queue while a printer is
-.IR stopped .
-.LP
-\fBtopq\fP
-.IP
-.I Topq
-places jobs at the top of a printer queue. This can be used
-to reorder high priority jobs since
-.I lpr
-only provides first-come-first-serve ordering of jobs.
diff --git a/usr.sbin/lpr/SMM.doc/7.t b/usr.sbin/lpr/SMM.doc/7.t
deleted file mode 100644
index a6f6bea..0000000
--- a/usr.sbin/lpr/SMM.doc/7.t
+++ /dev/null
@@ -1,226 +0,0 @@
-.\" Copyright (c) 1983, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)7.t 8.1 (Berkeley) 6/8/93
-.\"
-.NH 1
-Troubleshooting
-.PP
-There are several messages that may be generated by the
-the line printer system. This section
-categorizes the most common and explains the cause
-for their generation. Where the message implies a failure,
-directions are given to remedy the problem.
-.PP
-In the examples below, the name
-.I printer
-is the name of the printer from the
-.I printcap
-database.
-.NH 2
-LPR
-.SH
-lpr: \fIprinter\fP\|: unknown printer
-.IP
-The
-.I printer
-was not found in the
-.I printcap
-database. Usually this is a typing mistake; however, it may indicate
-a missing or incorrect entry in the /etc/printcap file.
-.SH
-lpr: \fIprinter\fP\|: jobs queued, but cannot start daemon.
-.IP
-The connection to
-.I lpd
-on the local machine failed.
-This usually means the printer server started at
-boot time has died or is hung. Check the local socket
-/dev/printer to be sure it still exists (if it does not exist,
-there is no
-.I lpd
-process running).
-Usually it is enough to get a super-user to type the following to
-restart
-.IR lpd .
-.DS
-% /usr/lib/lpd
-.DE
-You can also check the state of the master printer daemon with the following.
-.DS
-% ps l`cat /usr/spool/lpd.lock`
-.DE
-.IP
-Another possibility is that the
-.I lpr
-program is not set-user-id to \fIroot\fP, set-group-id to group \fIdaemon\fP.
-This can be checked with
-.DS
-% ls \-lg /usr/ucb/lpr
-.DE
-.SH
-lpr: \fIprinter\fP\|: printer queue is disabled
-.IP
-This means the queue was turned off with
-.DS
-% lpc disable \fIprinter\fP
-.DE
-to prevent
-.I lpr
-from putting files in the queue. This is normally
-done by the system manager when a printer is
-going to be down for a long time. The
-printer can be turned back on by a super-user with
-.IR lpc .
-.NH 2
-LPQ
-.SH
-waiting for \fIprinter\fP to become ready (offline ?)
-.IP
-The printer device could not be opened by the daemon.
-This can happen for several reasons,
-the most common is that the printer is turned off-line.
-This message can also be generated if the printer is out
-of paper, the paper is jammed, etc.
-The actual reason is dependent on the meaning
-of error codes returned by system device driver.
-Not all printers supply enough information
-to distinguish when a printer is off-line or having
-trouble (e.g. a printer connected through a serial line).
-Another possible cause of this message is
-some other process, such as an output filter,
-has an exclusive open on the device. Your only recourse
-here is to kill off the offending program(s) and
-restart the printer with
-.IR lpc .
-.SH
-\fIprinter\fP is ready and printing
-.IP
-The
-.I lpq
-program checks to see if a daemon process exists for
-.I printer
-and prints the file \fIstatus\fP located in the spooling directory.
-If the daemon is hung, a super user can use
-.I lpc
-to abort the current daemon and start a new one.
-.SH
-waiting for \fIhost\fP to come up
-.IP
-This implies there is a daemon trying to connect to the remote
-machine named
-.I host
-to send the files in the local queue.
-If the remote machine is up,
-.I lpd
-on the remote machine is probably dead or
-hung and should be restarted as mentioned for
-.IR lpr .
-.SH
-sending to \fIhost\fP
-.IP
-The files should be in the process of being transferred to the remote
-.IR host .
-If not, the local daemon should be aborted and started with
-.IR lpc .
-.SH
-Warning: \fIprinter\fP is down
-.IP
-The printer has been marked as being unavailable with
-.IR lpc .
-.SH
-Warning: no daemon present
-.IP
-The \fIlpd\fP process overseeing
-the spooling queue, as specified in the ``lock'' file
-in that directory, does not exist. This normally occurs
-only when the daemon has unexpectedly died.
-The error log file for the printer and the \fIsyslogd\fP logs
-should be checked for a
-diagnostic from the deceased process.
-To restart an \fIlpd\fP, use
-.DS
-% lpc restart \fIprinter\fP
-.DE
-.SH
-no space on remote; waiting for queue to drain
-.IP
-This implies that there is insufficient disk space on the remote.
-If the file is large enough, there will never be enough space on
-the remote (even after the queue on the remote is empty). The solution here
-is to move the spooling queue or make more free space on the remote.
-.NH 2
-LPRM
-.SH
-lprm: \fIprinter\fP\|: cannot restart printer daemon
-.IP
-This case is the same as when
-.I lpr
-prints that the daemon cannot be started.
-.NH 2
-LPD
-.PP
-The
-.I lpd
-program can log many different messages using \fIsyslogd\fP\|(8).
-Most of these messages are about files that can not
-be opened and usually imply that the
-.I printcap
-file or the protection modes of the files are
-incorrect. Files may also be inaccessible if people
-manually manipulate the line printer system (i.e. they
-bypass the
-.I lpr
-program).
-.PP
-In addition to messages generated by
-.IR lpd ,
-any of the filters that
-.I lpd
-spawns may log messages using \fIsyslogd\fP or to the error log file
-(the file specified in the \fBlf\fP entry in \fIprintcap\fP\|).
-.NH 2
-LPC
-.PP
-.SH
-couldn't start printer
-.IP
-This case is the same as when
-.I lpr
-reports that the daemon cannot be started.
-.SH
-cannot examine spool directory
-.IP
-Error messages beginning with ``cannot ...'' are usually because of
-incorrect ownership or protection mode of the lock file, spooling
-directory or the
-.I lpc
-program.
diff --git a/usr.sbin/lpr/SMM.doc/Makefile b/usr.sbin/lpr/SMM.doc/Makefile
deleted file mode 100644
index d80c8ce..0000000
--- a/usr.sbin/lpr/SMM.doc/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# From: @(#)Makefile 8.1 (Berkeley) 6/8/93
-# $FreeBSD$
-
-BINDIR= /usr/share/doc
-VOLUME= smm/07.lpd
-SRCS= 0.t 1.t 2.t 3.t 4.t 5.t 6.t 7.t
-MACROS= -ms
-
-USE_TBL=
-SRCDIR= ${.CURDIR}
-
-.include <bsd.doc.mk>
diff --git a/usr.sbin/lpr/SMM.doc/spell.ok b/usr.sbin/lpr/SMM.doc/spell.ok
deleted file mode 100644
index bf31319..0000000
--- a/usr.sbin/lpr/SMM.doc/spell.ok
+++ /dev/null
@@ -1,70 +0,0 @@
-Aprinter
-Bprinter
-CRMOD
-Cprinter
-DecWriter
-Dprinter
-Eprinter
-LPC
-LPD
-Lpd
-Manual''SMM:5
-SIGINT
-SMM:5
-Topq
-XTABS
-adm
-af
-br
-daemon
-daemons
-dev
-f:of
-fs
-hosts.equiv
-hosts.lpd
-lf
-lg
-lib
-lp:br
-lp:sd
-lpc
-lpd
-lpd.lock
-lpf
-lpf:lf
-lprgroup
-makefile
-mx
-offline
-pl
-printcap
-pw
-py
-rc
-rcmd
-rg
-rlogin
-rp
-rs
-rsh
-rshd
-rvcat
-rvcat:af
-rvcat:mx
-sd
-src
-syslogd
-tf
-topq
-ucb
-ucbvax
-ucbvax:rp
-usr.lib
-va0:sd
-vaacct
-vad:of
-varian
-vaxlpd
-vpf
-vpf:tf
diff --git a/usr.sbin/rarpd/rarpd.c b/usr.sbin/rarpd/rarpd.c
index a500dd5..66055f3 100644
--- a/usr.sbin/rarpd/rarpd.c
+++ b/usr.sbin/rarpd/rarpd.c
@@ -666,6 +666,7 @@ struct {
static void
update_arptab(u_char *ep, in_addr_t ipaddr)
{
+ struct timespec tp;
int cc;
struct sockaddr_inarp *ar, *ar2;
struct sockaddr_dl *ll, *ll2;
@@ -731,7 +732,8 @@ update_arptab(u_char *ep, in_addr_t ipaddr)
rt->rtm_version = RTM_VERSION;
rt->rtm_addrs = RTA_DST | RTA_GATEWAY;
rt->rtm_inits = RTV_EXPIRE;
- rt->rtm_rmx.rmx_expire = time(0) + ARPSECS;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ rt->rtm_rmx.rmx_expire = tp.tv_sec + ARPSECS;
rt->rtm_flags = RTF_HOST | RTF_STATIC;
rt->rtm_type = RTM_ADD;
rt->rtm_seq = ++seq;
diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c
index 716a054..8ef8544 100644
--- a/usr.sbin/sysinstall/dist.c
+++ b/usr.sbin/sysinstall/dist.c
@@ -757,6 +757,9 @@ distExtract(char *parent, Distribution *me)
canceled = 1;
status = FALSE;
+ } else {
+ // ignore any failures with DIST_LOCAL
+ status = TRUE;
}
}
break;
@@ -913,7 +916,7 @@ distExtractAll(dialogMenuItem *self)
restorescr(w);
if (extract_status == FALSE)
- status = DITEM_FAILURE;
+ status = FALSE;
return status;
}
diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
index db347e2..daacaa6 100644
--- a/usr.sbin/sysinstall/install.c
+++ b/usr.sbin/sysinstall/install.c
@@ -855,7 +855,7 @@ try_media:
i = distExtractAll(self);
if (i == FALSE)
- return FALSE;
+ return DITEM_FAILURE;
/* When running as init, *now* it's safe to grab the rc.foo vars */
installEnvironment();
diff --git a/usr.sbin/timed/SMM.doc/timed/Makefile b/usr.sbin/timed/SMM.doc/timed/Makefile
deleted file mode 100644
index 9afa6c6..0000000
--- a/usr.sbin/timed/SMM.doc/timed/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/8/93
-# $FreeBSD$
-
-DIR= smm/12.timed
-SRCS= timed.ms
-MACROS= -ms
-PRINTER=Pdp
-
-paper.${PRINTER}: ${SRCS}
- ${SOELIM} ${SRCS} | ${TBL} | ${ROFF} > ${.TARGET}
-
-.include <bsd.doc.mk>
diff --git a/usr.sbin/timed/SMM.doc/timed/date b/usr.sbin/timed/SMM.doc/timed/date
deleted file mode 100644
index e4e4d58..0000000
--- a/usr.sbin/timed/SMM.doc/timed/date
+++ /dev/null
@@ -1,53 +0,0 @@
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)date 8.1 (Berkeley) 6/8/93
-.\"
-.ft B
-.TS
-center;
-ce | ce | ce | ce
-| c | c | c | s |
-| c s s s |.
-Byte 1 Byte 2 Byte 3 Byte 4
-=
-Type Version No. Sequence No.
-_
-Seconds of Time to Set
-_
-Microseconds of Time to Set
-_
-Machine Name
-_
-\&. . .
-_
-.TE
-.ft R
diff --git a/usr.sbin/timed/SMM.doc/timed/loop b/usr.sbin/timed/SMM.doc/timed/loop
deleted file mode 100644
index 11ccb4d..0000000
--- a/usr.sbin/timed/SMM.doc/timed/loop
+++ /dev/null
@@ -1,54 +0,0 @@
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)loop 8.1 (Berkeley) 6/8/93
-.\"
-.ft B
-.TS
-center;
-ce | ce | ce | ce
-| c | c | c | s |
-| c | c s s |
-| c s s s |.
-Byte 1 Byte 2 Byte 3 Byte 4
-=
-Type Version No. Sequence No.
-_
-Hop Count ( unused )
-_
-( unused )
-_
-Machine Name
-_
-\&. . .
-_
-.TE
-.ft R
diff --git a/usr.sbin/timed/SMM.doc/timed/spell.ok b/usr.sbin/timed/SMM.doc/timed/spell.ok
deleted file mode 100644
index 8ecfe15..0000000
--- a/usr.sbin/timed/SMM.doc/timed/spell.ok
+++ /dev/null
@@ -1,34 +0,0 @@
-ACK
-ADJTIME
-Adjtime
-CS
-CSELT
-Candidature
-DATEACK
-DoD
-Gusella
-MASTERACK
-MASTERREQ
-MASTERUP
-MSITE
-MSITEREQ
-Protocol''SMM:22
-Riccardo
-SETDATE
-SETDATEREQ
-SETTIME
-SLAVEUP
-SMM:22
-Stefano
-TRACEOFF
-TRACEON
-TSP
-Timedc
-UDP
-USENIX
-Zatti
-candidature
-ce
-daemon
-daemons
-timedc
diff --git a/usr.sbin/timed/SMM.doc/timed/time b/usr.sbin/timed/SMM.doc/timed/time
deleted file mode 100644
index 619d171..0000000
--- a/usr.sbin/timed/SMM.doc/timed/time
+++ /dev/null
@@ -1,53 +0,0 @@
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)time 8.1 (Berkeley) 6/8/93
-.\"
-.ft B
-.TS
-center;
-ce | ce | ce | ce
-| c | c | c | s |
-| c s s s |.
-Byte 1 Byte 2 Byte 3 Byte 4
-=
-Type Version No. Sequence No.
-_
-Seconds of Adjustment
-_
-Microseconds of Adjustment
-_
-Machine Name
-_
-\&. . .
-_
-.TE
-.ft R
diff --git a/usr.sbin/timed/SMM.doc/timed/timed.ms b/usr.sbin/timed/SMM.doc/timed/timed.ms
deleted file mode 100644
index 412399a..0000000
--- a/usr.sbin/timed/SMM.doc/timed/timed.ms
+++ /dev/null
@@ -1,462 +0,0 @@
-.\" $FreeBSD$
-.\"
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)timed.ms 8.1 (Berkeley) 6/8/93
-.\"
-.TL
-The Berkeley
-.UX
-.br
-Time Synchronization Protocol
-.AU
-Riccardo Gusella, Stefano Zatti, and James M. Bloom
-.AI
-Computer Systems Research Group
-Computer Science Division
-Department of Electrical Engineering and Computer Science
-University of California, Berkeley
-Berkeley, CA 94720
-.FS
-This work was sponsored by the Defense Advanced Research Projects Agency
-(DoD), monitored by the Naval Electronics Systems
-Command under contract No. N00039-84-C-0089, and by the Italian CSELT
-Corporation.
-The views and conclusions contained in this document are those of the
-authors and should not be interpreted as representing official policies,
-either expressed or implied, of the Defense Research Projects Agency,
-of the US Government, or of CSELT.
-.FE
-.LP
-.OH 'The Berkeley UNIX Time Synchronization Protocol''SMM:12-%'
-.EH 'SMM:12-%''The Berkeley UNIX Time Synchronization Protocol'
-.SH
-Introduction
-.PP
-The Time Synchronization Protocol (TSP)
-has been designed for specific use by the program \fItimed\fP,
-a local area network clock synchronizer for
-the UNIX 4.3BSD operating
-system.
-Timed is built on the DARPA UDP protocol [4] and
-is based on a master slave scheme.
-.PP
-TSP serves a dual purpose.
-First, it supports messages for the synchronization of the clocks
-of the various hosts in a local area network.
-Second, it supports messages for the election that occurs
-among slave time daemons when, for any reason, the master disappears.
-The synchronization mechanism and the election procedure
-employed by the program timed are described
-in other documents [1,2,3].
-.PP
-Briefly, the synchronization software, which works in a
-local area network, consists of a collection of \fItime daemons\fP
-(one per machine) and is based on a master-slave
-structure.
-The present implementation keeps processor clocks synchronized
-within 20 milliseconds.
-A \fImaster time daemon\fP measures the time
-difference between the clock of the machine on which it
-is running and those of all other machines. The current implementation
-uses ICMP \fITime Stamp Requests\fP [5] to measure the clock difference
-between machines.
-The master computes the \fInetwork time\fP as the average of the
-times provided by nonfaulty clocks.\**
-.FS
-A clock is considered to be faulty when its value
-is more than a small specified
-interval apart from the majority of the clocks
-of the machines on the same network.
-See [1,2] for more details.
-.FE
-It then sends to each \fIslave time daemon\fP the
-correction that should be performed on the clock of its machine.
-This process is repeated periodically.
-Since the correction is expressed as a time difference rather than an
-absolute time, transmission delays do not interfere with synchronization.
-When a machine comes up and joins the network,
-it starts a slave time daemon, which
-will ask the master for the correct time and will reset the machine's clock
-before any user activity can begin.
-The time daemons therefore maintain a single network time in spite of
-the drift of clocks away from each other.
-.PP
-Additionally, a time daemon on gateway machines may run as
-a \fIsubmaster\fP.
-A submaster time daemon functions as a slave on one network that
-already has a master and as master on other networks.
-In addition, a submaster is responsible for propagating broadcast
-packets from one network to the other.
-.PP
-To ensure that service provided is continuous and reliable,
-it is necessary to implement an election algorithm that will elect a
-new master should the machine running the current master crash, the master
-terminate (for example, because of a run-time error), or the network be
-partitioned.
-Under our algorithm, slaves are able to realize when the master has
-stopped functioning and to elect a new master from among themselves.
-It is important to note that since the failure of the master results
-only in a gradual divergence of clock values, the election
-need not occur immediately.
-.PP
-All the communication occurring among time daemons uses the TSP
-protocol.
-While some messages need not be sent in a reliable way,
-most communication in TSP requires reliability not provided by the underlying
-protocol.
-Reliability is achieved by the use of acknowledgements, sequence numbers, and
-retransmission when message losses occur.
-When a message that requires acknowledgment is not acknowledged after
-multiple attempts,
-the time daemon that has sent the message will assume that the
-addressee is down.
-This document will not describe the details of how reliability is
-implemented, but will only point out when
-a message type requires a reliable transport mechanism.
-.PP
-The message format in TSP is the same for all message types;
-however, in some instances, one or more fields are not used.
-The next section describes the message format.
-The following sections describe
-in detail the different message types, their use and the contents
-of each field. NOTE: The message format is likely to change in
-future versions of timed.
-.sp 2
-.SH
-Message Format
-.PP
-All fields are based upon 8-bit bytes. Fields should be sent in
-network byte order if they are more than one byte long.
-The structure of a TSP message is the following:
-.IP 1)
-A one byte message type.
-.IP 2)
-A one byte version number, specifying the protocol version which the
-message uses.
-.IP 3)
-A two byte sequence number to be used for recognizing duplicate messages
-that occur when messages are retransmitted.
-.IP 4)
-Eight bytes of packet specific data. This field contains two 4 byte time
-values, a one byte hop count, or may be unused depending on the type
-of the packet.
-.IP 5)
-A zero-terminated string of up to 256 \s-2ASCII\s+2 characters with the name of
-the machine sending the message.
-.PP
-The following charts describe the message types,
-show their fields, and explain their usages.
-For the purpose of the following discussion, a time daemon can
-be considered to be in
-one of three states: slave, master, or candidate for election to master.
-Also, the term \fIbroadcast\fP refers to
-the sending of a message to all active time daemons.
-.sp 1
-.SH
-Adjtime Message
-.so time
-.LP
-Type: TSP_ADJTIME (1)
-.sp 1
-.PP
-The master sends this message to a slave to communicate
-the difference between
-the clock of the slave and
-the network time the master has just computed.
-The slave will accordingly
-adjust the time of its machine.
-This message requires an acknowledgment.
-.sp 1
-.SH
-Acknowledgment Message
-.so unused
-.LP
-Type: TSP_ACK (2)
-.sp 1
-.PP
-Both the master and the slaves use this message for
-acknowledgment only.
-It is used in several different contexts, for example
-in reply to an Adjtime message.
-.sp 1
-.SH
-Master Request Message
-.so unused
-.LP
-Type: TSP_MASTERREQ (3)
-.sp 1
-.PP
-A newly-started time daemon broadcasts this message to
-locate a master. No other action is implied by this packet.
-It requires a Master Acknowledgment.
-.sp 1
-.SH
-Master Acknowledgement
-.so unused
-.LP
-Type: TSP_MASTERACK (4)
-.sp 1
-.PP
-The master sends this message to acknowledge the Master Request message
-and the Conflict Resolution Message.
-.sp 1
-.SH
-Set Network Time Message
-.so date
-.LP
-Type: TSP_SETTIME (5)
-.sp 1
-.PP
-The master sends this message to slave time daemons to set their time.
-This packet is sent to newly started time daemons and when the network
-date is changed.
-It contains the master's time as an approximation of the network time.
-It requires an acknowledgment.
-The next
-synchronization round will eliminate the small time difference
-caused by the random delay in the communication channel.
-.sp 1
-.SH
-Master Active Message
-.so unused
-.LP
-Type: TSP_MASTERUP (6)
-.sp 1
-.PP
-The master broadcasts this message to
-solicit the names of the active slaves.
-Slaves will reply with a Slave Active message.
-.sp 1
-.SH
-Slave Active Message
-.so unused
-.LP
-Type: TSP_SLAVEUP (7)
-.sp 1
-.PP
-A slave sends this message to the master in answer to a Master Active message.
-This message is also sent when a new slave starts up to inform the master that
-it wants to be synchronized.
-.sp 1
-.SH
-Master Candidature Message
-.so unused
-.LP
-Type: TSP_ELECTION (8)
-.sp 1
-.PP
-A slave eligible to become a master broadcasts this message when its election
-timer expires.
-The message declares that the slave wishes to become the new master.
-.sp 1
-.SH
-Candidature Acceptance Message
-.so unused
-.LP
-Type: TSP_ACCEPT (9)
-.sp 1
-.PP
-A slave sends this message to accept the candidature of the time daemon
-that has broadcast an Election message.
-The candidate will add the slave's name to the list of machines that it
-will control should it become the master.
-.sp 1
-.SH
-Candidature Rejection Message
-.so unused
-.LP
-Type: TSP_REFUSE (10)
-.sp 1
-.PP
-After a slave accepts the candidature of a time daemon, it will reply
-to any election messages from other slaves
-with this message.
-This rejects any candidature other than the first received.
-.sp 1
-.SH
-Multiple Master Notification Message
-.so unused
-.LP
-Type: TSP_CONFLICT (11)
-.sp 1
-.PP
-When two or more masters reply to a Master Request message, the slave
-uses this message to inform one of them that more than one master exists.
-.sp 1
-.SH
-Conflict Resolution Message
-.so unused
-.LP
-Type: TSP_RESOLVE (12)
-.sp 1
-.PP
-A master which has been informed of the existence of other masters
-broadcasts this message to determine who the other masters are.
-.sp 1
-.SH
-Quit Message
-.so unused
-.LP
-Type: TSP_QUIT (13)
-.sp 1
-.PP
-This message is sent by the master in three different contexts:
-1) to a candidate that broadcasts a Master Candidature message,
-2) to another master when notified of its existence,
-3) to another master if a loop is detected.
-In all cases, the recipient time daemon will become a slave.
-This message requires an acknowledgement.
-.sp 1
-.SH
-Set Date Message
-.so date
-.LP
-Type: TSP_SETDATE (22)
-.sp 1
-.PP
-The program \fIdate\fP\|(1) sends this message to the local time daemon
-when a super-user wants to set the network date.
-If the local time daemon is the master, it will set the date;
-if it is a slave, it will communicate the desired date to the master.
-.sp 1
-.SH
-Set Date Request Message
-.so date
-.LP
-Type: TSP_SETDATEREQ (23)
-.sp 1
-.PP
-A slave that has received a Set Date message will communicate the
-desired date to the master using this message.
-.sp 1
-.SH
-Set Date Acknowledgment Message
-.so unused
-.LP
-Type: TSP_DATEACK (16)
-.sp 1
-.PP
-The master sends this message to a slave in acknowledgment of a
-Set Date Request Message.
-The same message is sent by the local time daemon to the program
-\fIdate(1)\fP to confirm that the network date has been set by the
-master.
-.sp 1
-.SH
-Start Tracing Message
-.so unused
-.LP
-Type: TSP_TRACEON (17)
-.sp 1
-.PP
-The controlling program \fItimedc\fP sends this message to the local
-time daemon to start the recording in a system file of
-all messages received.
-.sp 1
-.SH
-Stop Tracing Message
-.so unused
-.LP
-Type: TSP_TRACEOFF (18)
-.sp 1
-.PP
-\fITimedc\fP sends this message to the local
-time daemon to stop the recording of
-messages received.
-.sp 1
-.SH
-Master Site Message
-.so unused
-.LP
-Type: TSP_MSITE (19)
-.sp 1
-.PP
-\fITimedc\fP sends this message to the local time daemon to find out
-where the master is running.
-.sp 1
-.SH
-Remote Master Site Message
-.so unused
-.LP
-Type: TSP_MSITEREQ (20)
-.sp 1
-.PP
-A local time daemon broadcasts this message to find the location
-of the master.
-It then uses the Acknowledgement message to
-communicate this location to \fItimedc\fP.
-.sp 1
-.SH
-Test Message
-.so unused
-.LP
-Type: TSP_TEST (21)
-.sp 1
-.PP
-For testing purposes, \fItimedc\fP sends this message to a slave
-to cause its election timer to expire. NOTE: \fItimed\fP
-is not normally compiled to support this.
-.sp 1
-.SH
-.SH
-Loop Detection Message
-.so loop
-.LP
-Type: TSP_LOOP (24)
-.sp 1
-.PP
-This packet is initiated by all masters occasionally to attempt to detect loops.
-All submasters forward this packet onto the networks over which they are master.
-If a master receives a packet it sent out initially,
-it knows that a loop exists and tries to correct the problem.
-.SH
-References
-.IP 1.
-R. Gusella and S. Zatti,
-\fITEMPO: A Network Time Controller for Distributed Berkeley UNIX System\fP,
-USENIX Summer Conference Proceedings, Salt Lake City, June 1984.
-.IP 2.
-R. Gusella and S. Zatti, \fIClock Synchronization in a Local Area Network\fP,
-University of California, Berkeley, Technical Report, \fIto appear\fP.
-.IP 3.
-R. Gusella and S. Zatti,
-\fIAn Election Algorithm for a Distributed Clock Synchronization Program\fP,
-University of California, Berkeley, CS Technical Report #275, Dec. 1985.
-.IP 4.
-Postel, J., \fIUser Datagram Protocol\fP, RFC 768.
-Network Information Center, SRI International, Menlo Park, California,
-August 1980.
-.IP 5.
-Postel, J., \fIInternet Control Message Protocol\fP, RFC 792.
-Network Information Center, SRI International, Menlo Park, California,
-September 1981.
diff --git a/usr.sbin/timed/SMM.doc/timed/unused b/usr.sbin/timed/SMM.doc/timed/unused
deleted file mode 100644
index adadfc3..0000000
--- a/usr.sbin/timed/SMM.doc/timed/unused
+++ /dev/null
@@ -1,53 +0,0 @@
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)unused 8.1 (Berkeley) 6/8/93
-.\"
-.ft B
-.TS
-center;
-ce | ce | ce | ce
-| c | c | c | s |
-| c s s s |.
-Byte 1 Byte 2 Byte 3 Byte 4
-=
-Type Version No. Sequence No.
-_
-( unused )
-_
-( unused )
-_
-Machine Name
-_
-\&. . .
-_
-.TE
-.ft R
diff --git a/usr.sbin/timed/SMM.doc/timedop/Makefile b/usr.sbin/timed/SMM.doc/timedop/Makefile
deleted file mode 100644
index 7d52a32..0000000
--- a/usr.sbin/timed/SMM.doc/timedop/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/8/93
-# $FreeBSD$
-
-DIR= smm/11.timedop
-SRCS= timed.ms
-MACROS= -ms
-
-.include <bsd.doc.mk>
diff --git a/usr.sbin/timed/SMM.doc/timedop/timed.ms b/usr.sbin/timed/SMM.doc/timedop/timed.ms
deleted file mode 100644
index feea0b5..0000000
--- a/usr.sbin/timed/SMM.doc/timedop/timed.ms
+++ /dev/null
@@ -1,279 +0,0 @@
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)timed.ms 8.1 (Berkeley) 6/8/93
-.\"
-.TL
-Timed Installation and Operation Guide
-.AU
-Riccardo Gusella, Stefano Zatti, James M. Bloom
-.AI
-Computer Systems Research Group
-Computer Science Division
-Department of Electrical Engineering and Computer Science
-University of California, Berkeley
-Berkeley, CA 94720
-.AU
-Kirk Smith
-.AI
-Engineering Computer Network
-Department of Electrical Engineering
-Purdue University
-West Lafayette, IN 47906
-.FS
-This work was sponsored by the Defense Advanced Research Projects Agency
-(DoD), monitored by the Naval Electronics Systems
-Command under contract No. N00039-84-C-0089, and by the CSELT
-Corporation of Italy.
-The views and conclusions contained in this document are those of the
-authors and should not be interpreted as representing official policies,
-either expressed or implied, of the Defense Research Projects Agency,
-of the US Government, or of CSELT.
-.FE
-.LP
-.EH 'SMM:11-%''Timed Installation and Operation'
-.OH 'Timed Installation and Operation''SMM:11-%'
-.SH
-Introduction
-.PP
-The clock synchronization service for
-the UNIX 4.3BSD operating system is composed of a collection of
-time daemons (\fItimed\fP) running on the machines in a local
-area network.
-The algorithms implemented by the service is based on a master-slave scheme.
-The time daemons communicate with each other using the
-\fITime Synchronization Protocol\fP (TSP) which
-is built on the DARPA UDP protocol and described in detail in [4].
-.PP
-A time daemon has a twofold function.
-First, it supports the synchronization of the clocks
-of the various hosts in a local area network.
-Second, it starts (or takes part in) the election that occurs
-among slave time daemons when, for any reason, the master disappears.
-The synchronization mechanism and the election procedure
-employed by the program \fItimed\fP are described
-in other documents [1,2,3].
-The next paragraphs are a brief overview of how the time daemon works.
-This document is mainly concerned with the administrative and technical
-issues of running \fItimed\fP at a particular site.
-.PP
-A \fImaster time daemon\fP measures the time
-differences between the clock of the machine on which it
-is running and those of all other machines.
-The master computes the \fInetwork time\fP as the average of the
-times provided by nonfaulty clocks.\**
-.FS
-A clock is considered to be faulty when its value
-is more than a small specified
-interval apart from the majority of the clocks
-of the other machines [1,2].
-.FE
-It then sends to each \fIslave time daemon\fP the
-correction that should be performed on the clock of its machine.
-This process is repeated periodically.
-Since the correction is expressed as a time difference rather than an
-absolute time, transmission delays do not interfere with
-the accuracy of the synchronization.
-When a machine comes up and joins the network,
-it starts a slave time daemon which
-will ask the master for the correct time and will reset the machine's clock
-before any user activity can begin.
-The time daemons are able to maintain a single network time in spite of
-the drift of clocks away from each other.
-The present implementation keeps processor clocks synchronized
-within 20 milliseconds.
-.PP
-To ensure that the service provided is continuous and reliable,
-it is necessary to implement an election algorithm to elect a
-new master should the machine running the current master crash, the master
-terminate (for example, because of a run-time error), or
-the network be partitioned.
-Under our algorithm, slaves are able to realize when the master has
-stopped functioning and to elect a new master from among themselves.
-It is important to note that, since the failure of the master results
-only in a gradual divergence of clock values, the election
-need not occur immediately.
-.PP
-The machines that are gateways between distinct local area
-networks require particular care.
-A time daemon on such machines may act as a \fIsubmaster\fP.
-This artifact depends on the current inability of
-transmission protocols to broadcast a message on a network
-other than the one to which the broadcasting machine is connected.
-The submaster appears as a slave on one network, and as a master
-on one or more of the other networks to which it is connected.
-.PP
-A submaster classifies each network as one of three types.
-A \fIslave network\fP is a network on which the submaster acts as a slave.
-There can only be one slave network.
-A \fImaster network\fP is a network on which the submaster acts as a master.
-An \fIignored network\fP is any other network which already has a valid master.
-The submaster tries periodically to become master on an ignored
-network, but gives up immediately if a master already exists.
-.SH
-Guidelines
-.PP
-While the synchronization algorithm is quite general, the election
-one, requiring a broadcast mechanism, puts constraints on
-the kind of network on which time daemons can run.
-The time daemon will only work on networks with broadcast capability
-augmented with point-to-point links.
-Machines that are only connected to point-to-point,
-non-broadcast networks may not use the time daemon.
-.PP
-If we exclude submasters, there will normally be, at most, one master time
-daemon in a local area internetwork.
-During an election, only one of the slave time daemons
-will become the new master.
-However, because of the characteristics of its machine,
-a slave can be prevented from becoming the master.
-Therefore, a subset of machines must be designated as potential
-master time daemons.
-A master time daemon will require CPU resources
-proportional to the number of slaves, in general, more than
-a slave time daemon, so it may be advisable to limit master time
-daemons to machines with more powerful processors or lighter loads.
-Also, machines with inaccurate clocks should not be used as masters.
-This is a purely administrative decision: an organization may
-well allow all of its machines to run master time daemons.
-.PP
-At the administrative level, a time daemon on a machine
-with multiple network interfaces, may be told to ignore all
-but one network or to ignore one network.
-This is done with the \fI\-n network\fP and \fI\-i network\fP
-options respectively at start-up time.
-Typically, the time daemon would be instructed to ignore all but
-the networks belonging to the local administrative control.
-.PP
-There are some limitations to the current
-implementation of the time daemon.
-It is expected that these limitations will be removed in future releases.
-The constant NHOSTS in /usr/src/etc/timed/globals.h limits the
-maximum number of machines that may be directly controlled by one
-master time daemon.
-The current maximum is 29 (NHOSTS \- 1).
-The constant must be changed and the program recompiled if a site wishes to
-run \fItimed\fP on a larger (inter)network.
-.PP
-In addition, there is a \fIpathological situation\fP to
-be avoided at all costs, that might occur when
-time daemons run on multiply-connected local area networks.
-In this case, as we have seen, time daemons running on gateway machines
-will be submasters and they will act on some of those
-networks as master time daemons.
-Consider machines A and B that are both gateways between
-networks X and Y.
-If time daemons were started on both A and B without constraints, it would be
-possible for submaster time daemon A to be a slave on network X
-and the master on network Y, while submaster time daemon B is a slave on
-network Y and the master on network X.
-This \fIloop\fP of master time daemons will not function properly
-or guarantee a unique time on both networks, and will cause
-the submasters to use large amounts of system resources in the form
-of network bandwidth and CPU time.
-In fact, this kind of \fIloop\fP can also be generated with more
-than two master time daemons,
-when several local area networks are interconnected.
-.SH
-Installation
-.PP
-In order to start the time daemon on a given machine,
-the following lines should be
-added to the \fIlocal daemons\fP section in the file \fI/etc/rc.local\fP:
-.sp 2
-.in 1i
-.nf
-if [ -f /etc/timed ]; then
- /etc/timed \fIflags\fP & echo -n ' timed' >/dev/console
-fi
-.fi
-.in -1i
-.sp
-.LP
-In any case, they must appear after the network
-is configured via ifconfig(8).
-.PP
-Also, the file \fI/etc/services\fP should contain the following
-line:
-.sp 2
-.ti 1i
-timed 525/udp timeserver
-.sp
-.LP
-The \fIflags\fP are:
-.IP "-n network" 13
-to consider the named network.
-.IP "-i network"
-to ignore the named network.
-.IP -t
-to place tracing information in \fI/usr/adm/timed.log\fP.
-.IP -M
-to allow this time daemon to become a master.
-A time daemon run without this option will be forced in the state of
-slave during an election.
-.SH
-Daily Operation
-.PP
-\fITimedc(8)\fP is used to control the operation of the time daemon.
-It may be used to:
-.IP \(bu
-measure the differences between machines' clocks,
-.IP \(bu
-find the location where the master \fItimed\fP is running,
-.IP \(bu
-cause election timers on several machines to expire at the same time,
-.IP \(bu
-enable or disable tracing of messages received by \fItimed\fP.
-.LP
-See the manual page on \fItimed\fP\|(8) and \fItimedc\fP\|(8)
-for more detailed information.
-.PP
-The \fIdate(1)\fP command can be used to set the network date.
-In order to set the time on a single machine, the \fI-n\fP flag
-can be given to date(1).
-.bp
-.SH
-References
-.IP 1.
-R. Gusella and S. Zatti,
-\fITEMPO: A Network Time Controller for Distributed Berkeley UNIX System\fP,
-USENIX Summer Conference Proceedings, Salt Lake City, June 1984.
-.IP 2.
-R. Gusella and S. Zatti, \fIClock Synchronization in a Local Area Network\fP,
-University of California, Berkeley, Technical Report, \fIto appear\fP.
-.IP 3.
-R. Gusella and S. Zatti,
-\fIAn Election Algorithm for a Distributed Clock Synchronization Program\fP,
-University of California, Berkeley, CS Technical Report #275, Dec. 1985.
-.IP 4.
-R. Gusella and S. Zatti,
-\fIThe Berkeley UNIX 4.3BSD Time Synchronization Protocol\fP,
-UNIX Programmer's Manual, 4.3 Berkeley Software Distribution, Volume 2c.
diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile
index c77244f..103d206 100644
--- a/usr.sbin/traceroute/Makefile
+++ b/usr.sbin/traceroute/Makefile
@@ -31,7 +31,7 @@ LDADD= -lipsec
CFLAGS+= -I${TRACEROUTE_DISTDIR}
-WARNS?= 0
+WARNS?= 3
version.c: ${TRACEROUTE_DISTDIR}/VERSION
@rm -f ${.TARGET}
diff --git a/usr.sbin/traceroute6/Makefile b/usr.sbin/traceroute6/Makefile
index e0b72a1..4428d5b 100644
--- a/usr.sbin/traceroute6/Makefile
+++ b/usr.sbin/traceroute6/Makefile
@@ -25,7 +25,7 @@ BINMODE= 4555
CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
-WARNS?= 1
+WARNS?= 3
DPADD= ${LIBIPSEC}
LDADD= -lipsec
diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c
index 699af68..1a67173 100644
--- a/usr.sbin/traceroute6/traceroute6.c
+++ b/usr.sbin/traceroute6/traceroute6.c
@@ -66,7 +66,7 @@
*/
#ifndef lint
-static char copyright[] =
+static const char copyright[] =
"@(#) Copyright (c) 1990, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
@@ -322,7 +322,7 @@ void send_probe(int, u_long);
void *get_uphdr(struct ip6_hdr *, u_char *);
int get_hoplim(struct msghdr *);
double deltaT(struct timeval *, struct timeval *);
-char *pr_type(int);
+const char *pr_type(int);
int packet_ok(struct msghdr *, int, int);
void print(struct msghdr *, int);
const char *inetname(struct sockaddr *);
@@ -372,12 +372,12 @@ main(argc, argv)
{
int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
- int ch, i, on = 1, seq, rcvcmsglen, error, minlen;
+ int ch, i, on = 1, seq, rcvcmsglen, error;
struct addrinfo hints, *res;
static u_char *rcvcmsgbuf;
u_long probe, hops, lport;
struct hostent *hp;
- size_t size;
+ size_t size, minlen;
uid_t uid;
/*
@@ -671,11 +671,11 @@ main(argc, argv)
datalen = minlen;
else if (datalen >= MAXPACKET) {
fprintf(stderr,
- "traceroute6: packet size must be %d <= s < %ld.\n",
- minlen, (long)MAXPACKET);
+ "traceroute6: packet size must be %zu <= s < %d.\n",
+ minlen, MAXPACKET);
exit(1);
}
- outpacket = (struct opacket *)malloc((unsigned)datalen);
+ outpacket = malloc(datalen);
if (!outpacket) {
perror("malloc");
exit(1);
@@ -913,7 +913,7 @@ main(argc, argv)
for (hops = first_hop; hops <= max_hops; ++hops) {
struct in6_addr lastaddr;
int got_there = 0;
- int unreachable = 0;
+ unsigned unreachable = 0;
printf("%2lu ", hops);
bzero(&lastaddr, sizeof(lastaddr));
@@ -1089,7 +1089,7 @@ send_probe(seq, hops)
i = sendto(sndsock, (char *)outpacket, datalen, 0,
(struct sockaddr *)&Dst, Dst.sin6_len);
- if (i < 0 || i != datalen) {
+ if (i < 0 || (u_long)i != datalen) {
if (i < 0)
perror("sendto");
printf("traceroute6: wrote %s %lu chars, ret=%d\n",
@@ -1129,12 +1129,11 @@ deltaT(t1p, t2p)
/*
* Convert an ICMP "type" field to a printable string.
*/
-char *
-pr_type(t0)
- int t0;
+const char *
+pr_type(int t0)
{
u_char t = t0 & 0xff;
- char *cp;
+ const char *cp;
switch (t) {
case ICMP6_DST_UNREACH:
@@ -1221,7 +1220,7 @@ packet_ok(mhdr, cc, seq)
cc -= hlen;
icp = (struct icmp6_hdr *)(buf + hlen);
#else
- if (cc < sizeof(struct icmp6_hdr)) {
+ if (cc < (int)sizeof(struct icmp6_hdr)) {
if (verbose) {
if (getnameinfo((struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
diff --git a/usr.sbin/usbdevs/Makefile b/usr.sbin/usbdevs/Makefile
deleted file mode 100644
index 3cfc8ef..0000000
--- a/usr.sbin/usbdevs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $NetBSD: Makefile,v 1.2 1998/07/12 20:40:45 augustss Exp $
-# FreeBSD $FreeBSD$
-
-PROG= usbdevs
-MAN= usbdevs.8
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/usbdevs/usbdevs.8 b/usr.sbin/usbdevs/usbdevs.8
deleted file mode 100644
index dd56fc8..0000000
--- a/usr.sbin/usbdevs/usbdevs.8
+++ /dev/null
@@ -1,70 +0,0 @@
-.\" $NetBSD: usbdevs.8,v 1.5 2000/10/15 12:44:11 bjh21 Exp $
-.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
-.\" All rights reserved.
-.\"
-.\" Author: Lennart Augustsson
-.\"
-.\" 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd May 24, 2004
-.Dt USBDEVS 8
-.Os
-.Sh NAME
-.Nm usbdevs
-.Nd show USB devices connected to the system
-.Sh SYNOPSIS
-.Nm
-.Op Fl a Ar addr
-.Op Fl d
-.Op Fl f Ar dev
-.Op Fl o
-.Op Fl v
-.Sh DESCRIPTION
-The
-.Nm
-utility prints a listing of all USB devices connected to the system
-with some information about each device.
-The indentation of each line indicates its distance from the root.
-.Pp
-The options are as follows:
-.Bl -tag -width ".Fl a Ar addr"
-.It Fl a Ar addr
-only print information about the device at the given address.
-.It Fl d
-Show the device drivers associated with each device.
-.It Fl f Ar dev
-only print information for the given USB controller.
-.It Fl o
-One-line output (only useful in combination with
-.Fl d ) .
-.It Fl v
-Be verbose.
-.El
-.Sh SEE ALSO
-.Xr usb 4
-.Sh HISTORY
-The
-.Nm
-utility appeared in
-.Nx 1.4 .
diff --git a/usr.sbin/usbdevs/usbdevs.c b/usr.sbin/usbdevs/usbdevs.c
deleted file mode 100644
index b51e3c5..0000000
--- a/usr.sbin/usbdevs/usbdevs.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* $NetBSD: usbdevs.c,v 1.22 2003/11/12 13:31:08 grant Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (augustss@NetBSD.org).
- *
- * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <err.h>
-#include <errno.h>
-#include <dev/usb/usb.h>
-#if defined(__FreeBSD__)
-#include <sys/ioctl.h>
-#endif
-
-#define USBDEV "/dev/usb"
-
-int verbose = 0;
-int showdevs = 0;
-int oneline = 0;
-
-void usage(void);
-void usbdev(int f, int a, int rec);
-void usbdump(int f);
-void dumpone(char *name, int f, int addr);
-int main(int, char **);
-
-void
-usage()
-{
- fprintf(stderr, "usage: %s [-a addr] [-d] [-f dev] [-o] [-v]\n",
- getprogname());
- exit(1);
-}
-
-char done[USB_MAX_DEVICES];
-int indent;
-
-void
-usbdev(int f, int a, int rec)
-{
- struct usb_device_info di;
- int e, p, i;
-
- di.udi_addr = a;
- e = ioctl(f, USB_DEVICEINFO, &di);
- if (e) {
- if (errno != ENXIO)
- printf("addr %d: I/O error\n", a);
- return;
- }
- printf("addr %d: ", a);
- done[a] = 1;
- if (verbose) {
- switch (di.udi_speed) {
- case USB_SPEED_LOW: printf("low speed, "); break;
- case USB_SPEED_FULL: printf("full speed, "); break;
- case USB_SPEED_HIGH: printf("high speed, "); break;
- default: break;
- }
- if (di.udi_power)
- printf("power %d mA, ", di.udi_power);
- else
- printf("self powered, ");
- if (di.udi_config)
- printf("config %d, ", di.udi_config);
- else
- printf("unconfigured, ");
- }
- if (verbose) {
- printf("%s(0x%04x), %s(0x%04x), rev %s",
- di.udi_product, di.udi_productNo,
- di.udi_vendor, di.udi_vendorNo, di.udi_release);
- } else
- printf("%s, %s", di.udi_product, di.udi_vendor);
- if (!oneline)
- printf("\n");
- if (showdevs) {
- for (i = 0; i < USB_MAX_DEVNAMES; i++) {
- if (di.udi_devnames[i][0]) {
- if (oneline)
- printf(", device %s",
- di.udi_devnames[i]);
- else
- printf("%*s %s\n", indent, "",
- di.udi_devnames[i]);
- }
- }
- }
- if (oneline)
- printf("\n");
- if (!rec)
- return;
- for (p = 0; p < di.udi_nports; p++) {
- int s = di.udi_ports[p];
- if (s >= USB_MAX_DEVICES) {
- if (verbose) {
- printf("%*sport %d %s\n", indent+1, "", p+1,
- s == USB_PORT_ENABLED ? "enabled" :
- s == USB_PORT_SUSPENDED ? "suspended" :
- s == USB_PORT_POWERED ? "powered" :
- s == USB_PORT_DISABLED ? "disabled" :
- "???");
-
- }
- continue;
- }
- indent++;
- printf("%*s", indent, "");
- if (verbose)
- printf("port %d ", p+1);
- if (s == 0)
- printf("addr 0 should never happen!\n");
- else
- usbdev(f, s, 1);
- indent--;
- }
-}
-
-void
-usbdump(int f)
-{
- int a;
-
- for (a = 1; a < USB_MAX_DEVICES; a++) {
- if (!done[a])
- usbdev(f, a, 1);
- }
-}
-
-void
-dumpone(char *name, int f, int addr)
-{
- if (verbose)
- printf("Controller %s:\n", name);
- indent = 0;
- memset(done, 0, sizeof done);
- if (addr)
- usbdev(f, addr, 0);
- else
- usbdump(f);
-}
-
-int
-main(int argc, char **argv)
-{
- int ch, i, f;
- char buf[50];
- char *dev = 0;
- int addr = 0;
- int ncont;
-
- while ((ch = getopt(argc, argv, "a:df:ov?")) != -1) {
- switch(ch) {
- case 'a':
- addr = atoi(optarg);
- break;
- case 'd':
- showdevs++;
- break;
- case 'f':
- dev = optarg;
- break;
- case 'o':
- oneline++;
- break;
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (dev == 0) {
- for (ncont = 0, i = 0; i < 10; i++) {
- snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
- f = open(buf, O_RDONLY);
- if (f >= 0) {
- dumpone(buf, f, addr);
- close(f);
- } else {
- if (errno == ENOENT || errno == ENXIO)
- continue;
- warn("%s", buf);
- }
- ncont++;
- }
- if (verbose && ncont == 0)
- printf("%s: no USB controllers found\n",
- getprogname());
- } else {
- f = open(dev, O_RDONLY);
- if (f >= 0)
- dumpone(dev, f, addr);
- else
- err(1, "%s", dev);
- }
- exit(0);
-}
diff --git a/usr.sbin/usbdump/usbdump.c b/usr.sbin/usbdump/usbdump.c
index 93e9f21..c6f9048 100644
--- a/usr.sbin/usbdump/usbdump.c
+++ b/usr.sbin/usbdump/usbdump.c
@@ -247,7 +247,7 @@ print_apacket(const struct bpf_xhdr *hdr, struct usbpf_pkthdr *up,
printf(" usbus%d.%d 0x%02x %s %s", up->up_busunit, up->up_address,
up->up_endpoint,
xfertype_table[up->up_xfertype],
- up->up_type == USBPF_XFERTAP_SUBMIT ? ">" : "<");
+ up->up_type == USBPF_XFERTAP_SUBMIT ? "S" : "D");
printf(" (%d/%d)", up->up_frames, up->up_length);
if (up->up_type == USBPF_XFERTAP_DONE)
printf(" %s", errstr_table[up->up_error]);
OpenPOWER on IntegriCloud