summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn van Duren <martijn@cvs.openbsd.org>2019-08-09 06:18:00 +0000
committerMartijn van Duren <martijn@cvs.openbsd.org>2019-08-09 06:18:00 +0000
commitc40c38c1cb03eb7c7657aa0ee18619645c1af25b (patch)
treece2fce22ef0051535375bf512a3f75083db502cb
parentea211d258edb2cee19972e1f78cdb099919304f7 (diff)
Import snmp(1), a new snmp client which aims to be netsnmp compatible for
supported features. It only supports get, getnext, walk, bulkget, bulkwalk, trap, mibtree, and is SNMPv1 and SNMPv2c for now. This will shortly replace snmpctl entirely. People using snmpctl are encouraged to test and migrate to this code as soon as possible. Much help with the manpage from schwarze@ and jmc@ No objections from reyk@ "Roll it in" deraadt@
-rw-r--r--usr.bin/snmp/Makefile16
-rw-r--r--usr.bin/snmp/mib.c492
-rw-r--r--usr.bin/snmp/mib.h1352
-rw-r--r--usr.bin/snmp/smi.c627
-rw-r--r--usr.bin/snmp/smi.h91
-rw-r--r--usr.bin/snmp/snmp.1351
-rw-r--r--usr.bin/snmp/snmp.c288
-rw-r--r--usr.bin/snmp/snmp.h136
-rw-r--r--usr.bin/snmp/snmpc.c906
9 files changed, 4259 insertions, 0 deletions
diff --git a/usr.bin/snmp/Makefile b/usr.bin/snmp/Makefile
new file mode 100644
index 00000000000..62bb5565a30
--- /dev/null
+++ b/usr.bin/snmp/Makefile
@@ -0,0 +1,16 @@
+# $OpenBSD: Makefile,v 1.1 2019/08/09 06:17:59 martijn Exp $
+
+PROG= snmp
+SRCS= mib.c smi.c snmp.c snmpc.c
+LDADD+= -lutil
+DPADD+= ${LIBUTIL}
+
+MAN= snmp.1
+
+CFLAGS+= -Wall -I${.CURDIR}
+CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS+= -Wmissing-declarations
+CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
+CFLAGS+= -Wsign-compare
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/snmp/mib.c b/usr.bin/snmp/mib.c
new file mode 100644
index 00000000000..cda4c0e629b
--- /dev/null
+++ b/usr.bin/snmp/mib.c
@@ -0,0 +1,492 @@
+/* $OpenBSD: mib.c,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2012 Joel Knight <joel@openbsd.org>
+ * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <sys/tree.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include "ber.h"
+#include "mib.h"
+#include "smi.h"
+
+static struct oid mib_tree[] = MIB_TREE;
+static struct oid base_mib[] = {
+ { MIB(mib_2), OID_MIB },
+ { MIB(sysDescr), OID_RD },
+ { MIB(sysOID), OID_RD },
+ { MIB(sysUpTime), OID_RD },
+ { MIB(sysContact), OID_RW },
+ { MIB(sysName), OID_RW },
+ { MIB(sysLocation), OID_RW },
+ { MIB(sysServices), OID_RS },
+ { MIB(sysORLastChange), OID_RD },
+ { MIB(sysORIndex), OID_TRD },
+ { MIB(sysORID), OID_TRD },
+ { MIB(sysORDescr), OID_TRD },
+ { MIB(sysORUpTime), OID_TRD },
+ { MIB(snmp), OID_MIB },
+ { MIB(snmpInPkts), OID_RD },
+ { MIB(snmpOutPkts), OID_RD },
+ { MIB(snmpInBadVersions), OID_RD },
+ { MIB(snmpInBadCommunityNames), OID_RD },
+ { MIB(snmpInBadCommunityUses), OID_RD },
+ { MIB(snmpInASNParseErrs), OID_RD },
+ { MIB(snmpInTooBigs), OID_RD },
+ { MIB(snmpInNoSuchNames), OID_RD },
+ { MIB(snmpInBadValues), OID_RD },
+ { MIB(snmpInReadOnlys), OID_RD },
+ { MIB(snmpInGenErrs), OID_RD },
+ { MIB(snmpInTotalReqVars), OID_RD },
+ { MIB(snmpInTotalSetVars), OID_RD },
+ { MIB(snmpInGetRequests), OID_RD },
+ { MIB(snmpInGetNexts), OID_RD },
+ { MIB(snmpInSetRequests), OID_RD },
+ { MIB(snmpInGetResponses), OID_RD },
+ { MIB(snmpInTraps), OID_RD },
+ { MIB(snmpOutTooBigs), OID_RD },
+ { MIB(snmpOutNoSuchNames), OID_RD },
+ { MIB(snmpOutBadValues), OID_RD },
+ { MIB(snmpOutGenErrs), OID_RD },
+ { MIB(snmpOutGetRequests), OID_RD },
+ { MIB(snmpOutGetNexts), OID_RD },
+ { MIB(snmpOutSetRequests), OID_RD },
+ { MIB(snmpOutGetResponses), OID_RD },
+ { MIB(snmpOutTraps), OID_RD },
+ { MIB(snmpEnableAuthenTraps), OID_RW },
+ { MIB(snmpSilentDrops), OID_RD },
+ { MIB(snmpProxyDrops), OID_RD },
+ { MIBEND }
+};
+
+static struct oid usm_mib[] = {
+ { MIB(snmpEngine), OID_MIB },
+ { MIB(snmpEngineID), OID_RD },
+ { MIB(snmpEngineBoots), OID_RD },
+ { MIB(snmpEngineTime), OID_RD },
+ { MIB(snmpEngineMaxMsgSize), OID_RD },
+ { MIB(usmStats), OID_MIB },
+ { MIB(usmStatsUnsupportedSecLevels), OID_RD },
+ { MIB(usmStatsNotInTimeWindow), OID_RD },
+ { MIB(usmStatsUnknownUserNames), OID_RD },
+ { MIB(usmStatsUnknownEngineId), OID_RD },
+ { MIB(usmStatsWrongDigests), OID_RD },
+ { MIB(usmStatsDecryptionErrors), OID_RD },
+ { MIBEND }
+};
+
+static struct oid hr_mib[] = {
+ { MIB(host), OID_MIB },
+ { MIB(hrSystemUptime), OID_RD },
+ { MIB(hrSystemDate), OID_RD },
+ { MIB(hrSystemProcesses), OID_RD },
+ { MIB(hrSystemMaxProcesses), OID_RD },
+ { MIB(hrMemorySize), OID_RD },
+ { MIB(hrStorageIndex), OID_TRD },
+ { MIB(hrStorageType), OID_TRD },
+ { MIB(hrStorageDescr), OID_TRD },
+ { MIB(hrStorageAllocationUnits), OID_TRD },
+ { MIB(hrStorageSize), OID_TRD },
+ { MIB(hrStorageUsed), OID_TRD },
+ { MIB(hrStorageAllocationFailures), OID_TRD },
+ { MIB(hrDeviceIndex), OID_TRD },
+ { MIB(hrDeviceType), OID_TRD },
+ { MIB(hrDeviceDescr), OID_TRD },
+ { MIB(hrDeviceID), OID_TRD },
+ { MIB(hrDeviceStatus), OID_TRD },
+ { MIB(hrDeviceErrors), OID_TRD },
+ { MIB(hrProcessorFrwID), OID_TRD },
+ { MIB(hrProcessorLoad), OID_TRD },
+ { MIB(hrSWRunIndex), OID_TRD },
+ { MIB(hrSWRunName), OID_TRD },
+ { MIB(hrSWRunID), OID_TRD },
+ { MIB(hrSWRunPath), OID_TRD },
+ { MIB(hrSWRunParameters), OID_TRD },
+ { MIB(hrSWRunType), OID_TRD },
+ { MIB(hrSWRunStatus), OID_TRD },
+ { MIBEND }
+};
+
+static struct oid if_mib[] = {
+ { MIB(ifMIB), OID_MIB },
+ { MIB(ifName), OID_TRD },
+ { MIB(ifInMulticastPkts), OID_TRD },
+ { MIB(ifInBroadcastPkts), OID_TRD },
+ { MIB(ifOutMulticastPkts), OID_TRD },
+ { MIB(ifOutBroadcastPkts), OID_TRD },
+ { MIB(ifHCInOctets), OID_TRD },
+ { MIB(ifHCInUcastPkts), OID_TRD },
+ { MIB(ifHCInMulticastPkts), OID_TRD },
+ { MIB(ifHCInBroadcastPkts), OID_TRD },
+ { MIB(ifHCOutOctets), OID_TRD },
+ { MIB(ifHCOutUcastPkts), OID_TRD },
+ { MIB(ifHCOutMulticastPkts), OID_TRD },
+ { MIB(ifHCOutBroadcastPkts), OID_TRD },
+ { MIB(ifLinkUpDownTrapEnable), OID_TRD },
+ { MIB(ifHighSpeed), OID_TRD },
+ { MIB(ifPromiscuousMode), OID_TRD },
+ { MIB(ifConnectorPresent), OID_TRD },
+ { MIB(ifAlias), OID_TRD },
+ { MIB(ifCounterDiscontinuityTime), OID_TRD },
+ { MIB(ifRcvAddressStatus), OID_TRD },
+ { MIB(ifRcvAddressType), OID_TRD },
+ { MIB(ifStackLastChange), OID_RD },
+ { MIB(ifNumber), OID_RD },
+ { MIB(ifIndex), OID_TRD },
+ { MIB(ifDescr), OID_TRD },
+ { MIB(ifType), OID_TRD },
+ { MIB(ifMtu), OID_TRD },
+ { MIB(ifSpeed), OID_TRD },
+ { MIB(ifPhysAddress), OID_TRD },
+ { MIB(ifAdminStatus), OID_TRD },
+ { MIB(ifOperStatus), OID_TRD },
+ { MIB(ifLastChange), OID_TRD },
+ { MIB(ifInOctets), OID_TRD },
+ { MIB(ifInUcastPkts), OID_TRD },
+ { MIB(ifInNUcastPkts), OID_TRD },
+ { MIB(ifInDiscards), OID_TRD },
+ { MIB(ifInErrors), OID_TRD },
+ { MIB(ifInUnknownProtos), OID_TRD },
+ { MIB(ifOutOctets), OID_TRD },
+ { MIB(ifOutUcastPkts), OID_TRD },
+ { MIB(ifOutNUcastPkts), OID_TRD },
+ { MIB(ifOutDiscards), OID_TRD },
+ { MIB(ifOutErrors), OID_TRD },
+ { MIB(ifOutQLen), OID_TRD },
+ { MIB(ifSpecific), OID_TRD },
+ { MIBEND }
+};
+
+static struct oid ip_mib[] = {
+ { MIB(ipMIB), OID_MIB },
+ { MIB(ipForwarding), OID_RD },
+ { MIB(ipDefaultTTL), OID_RD },
+ { MIB(ipInReceives), OID_RD },
+ { MIB(ipInHdrErrors), OID_RD },
+ { MIB(ipInAddrErrors), OID_RD },
+ { MIB(ipForwDatagrams), OID_RD },
+ { MIB(ipInUnknownProtos), OID_RD },
+ { MIB(ipInDelivers), OID_RD },
+ { MIB(ipOutRequests), OID_RD },
+ { MIB(ipOutDiscards), OID_RD },
+ { MIB(ipOutNoRoutes), OID_RD },
+ { MIB(ipReasmTimeout), OID_RD },
+ { MIB(ipReasmReqds), OID_RD },
+ { MIB(ipReasmOKs), OID_RD },
+ { MIB(ipReasmFails), OID_RD },
+ { MIB(ipFragOKs), OID_RD },
+ { MIB(ipFragFails), OID_RD },
+ { MIB(ipFragCreates), OID_RD },
+ { MIB(ipAdEntAddr), OID_TRD },
+ { MIB(ipAdEntIfIndex), OID_TRD },
+ { MIB(ipAdEntNetMask), OID_TRD },
+ { MIB(ipAdEntBcastAddr), OID_TRD },
+ { MIB(ipAdEntReasmMaxSize), OID_TRD },
+ { MIB(ipNetToMediaIfIndex), OID_TRD },
+ { MIB(ipNetToMediaPhysAddress), OID_TRD },
+ { MIB(ipNetToMediaNetAddress), OID_TRD },
+ { MIB(ipNetToMediaType), OID_TRD },
+ { MIBEND }
+};
+
+static struct oid ipf_mib[] = {
+ { MIB(ipfMIB), OID_MIB },
+ { MIB(ipfInetCidrRouteNumber), OID_RD },
+ { MIB(ipfRouteEntIfIndex), OID_TRD },
+ { MIB(ipfRouteEntType), OID_TRD },
+ { MIB(ipfRouteEntProto), OID_TRD },
+ { MIB(ipfRouteEntAge), OID_TRD },
+ { MIB(ipfRouteEntNextHopAS), OID_TRD },
+ { MIB(ipfRouteEntRouteMetric1), OID_TRD },
+ { MIB(ipfRouteEntRouteMetric2), OID_TRD },
+ { MIB(ipfRouteEntRouteMetric3), OID_TRD },
+ { MIB(ipfRouteEntRouteMetric4), OID_TRD },
+ { MIB(ipfRouteEntRouteMetric5), OID_TRD },
+ { MIB(ipfRouteEntStatus), OID_TRD },
+ { MIBEND }
+};
+
+static struct oid bridge_mib[] = {
+ { MIB(dot1dBridge), OID_MIB },
+ { MIB(dot1dBaseBridgeAddress) },
+ { MIB(dot1dBaseNumPorts), OID_RD },
+ { MIB(dot1dBaseType), OID_RD },
+ { MIB(dot1dBasePort), OID_TRD },
+ { MIB(dot1dBasePortIfIndex), OID_TRD },
+ { MIB(dot1dBasePortCircuit), OID_TRD},
+ { MIB(dot1dBasePortDelayExceededDiscards), OID_TRD },
+ { MIB(dot1dBasePortMtuExceededDiscards), OID_TRD },
+ { MIBEND }
+};
+
+static struct oid diskio_mib[] = {
+ { MIB(ucdDiskIOMIB), OID_MIB },
+ { MIB(diskIOIndex), OID_TRD },
+ { MIB(diskIODevice), OID_TRD },
+ { MIB(diskIONRead), OID_TRD },
+ { MIB(diskIONWritten), OID_TRD },
+ { MIB(diskIOReads), OID_TRD },
+ { MIB(diskIOWrites), OID_TRD },
+ { MIB(diskIONReadX), OID_TRD },
+ { MIB(diskIONWrittenX), OID_TRD },
+ { MIBEND }
+};
+
+static struct oid openbsd_mib[] = {
+ { MIB(pfMIBObjects), OID_MIB },
+ { MIB(pfRunning), OID_RD },
+ { MIB(pfRuntime), OID_RD },
+ { MIB(pfDebug), OID_RD },
+ { MIB(pfHostid), OID_RD },
+ { MIB(pfCntMatch), OID_RD },
+ { MIB(pfCntBadOffset), OID_RD },
+ { MIB(pfCntFragment), OID_RD },
+ { MIB(pfCntShort), OID_RD },
+ { MIB(pfCntNormalize), OID_RD },
+ { MIB(pfCntMemory), OID_RD },
+ { MIB(pfCntTimestamp), OID_RD },
+ { MIB(pfCntCongestion), OID_RD },
+ { MIB(pfCntIpOptions), OID_RD },
+ { MIB(pfCntProtoCksum), OID_RD },
+ { MIB(pfCntStateMismatch), OID_RD },
+ { MIB(pfCntStateInsert), OID_RD },
+ { MIB(pfCntStateLimit), OID_RD },
+ { MIB(pfCntSrcLimit), OID_RD },
+ { MIB(pfCntSynproxy), OID_RD },
+ { MIB(pfCntTranslate), OID_RD },
+ { MIB(pfCntNoRoute), OID_RD },
+ { MIB(pfStateCount), OID_RD },
+ { MIB(pfStateSearches), OID_RD },
+ { MIB(pfStateInserts), OID_RD },
+ { MIB(pfStateRemovals), OID_RD },
+ { MIB(pfLogIfName), OID_RD },
+ { MIB(pfLogIfIpBytesIn), OID_RD },
+ { MIB(pfLogIfIpBytesOut), OID_RD },
+ { MIB(pfLogIfIpPktsInPass), OID_RD },
+ { MIB(pfLogIfIpPktsInDrop), OID_RD },
+ { MIB(pfLogIfIpPktsOutPass), OID_RD },
+ { MIB(pfLogIfIpPktsOutDrop), OID_RD },
+ { MIB(pfLogIfIp6BytesIn), OID_RD },
+ { MIB(pfLogIfIp6BytesOut), OID_RD },
+ { MIB(pfLogIfIp6PktsInPass), OID_RD },
+ { MIB(pfLogIfIp6PktsInDrop), OID_RD },
+ { MIB(pfLogIfIp6PktsOutPass), OID_RD },
+ { MIB(pfLogIfIp6PktsOutDrop), OID_RD },
+ { MIB(pfSrcTrackCount), OID_RD },
+ { MIB(pfSrcTrackSearches), OID_RD },
+ { MIB(pfSrcTrackInserts), OID_RD },
+ { MIB(pfSrcTrackRemovals), OID_RD },
+ { MIB(pfLimitStates), OID_RD },
+ { MIB(pfLimitSourceNodes), OID_RD },
+ { MIB(pfLimitFragments), OID_RD },
+ { MIB(pfLimitMaxTables), OID_RD },
+ { MIB(pfLimitMaxTableEntries), OID_RD },
+ { MIB(pfTimeoutTcpFirst), OID_RD },
+ { MIB(pfTimeoutTcpOpening), OID_RD },
+ { MIB(pfTimeoutTcpEstablished), OID_RD },
+ { MIB(pfTimeoutTcpClosing), OID_RD },
+ { MIB(pfTimeoutTcpFinWait), OID_RD },
+ { MIB(pfTimeoutTcpClosed), OID_RD },
+ { MIB(pfTimeoutUdpFirst), OID_RD },
+ { MIB(pfTimeoutUdpSingle), OID_RD },
+ { MIB(pfTimeoutUdpMultiple), OID_RD },
+ { MIB(pfTimeoutIcmpFirst), OID_RD },
+ { MIB(pfTimeoutIcmpError), OID_RD },
+ { MIB(pfTimeoutOtherFirst), OID_RD },
+ { MIB(pfTimeoutOtherSingle), OID_RD },
+ { MIB(pfTimeoutOtherMultiple), OID_RD },
+ { MIB(pfTimeoutFragment), OID_RD },
+ { MIB(pfTimeoutInterval), OID_RD },
+ { MIB(pfTimeoutAdaptiveStart), OID_RD },
+ { MIB(pfTimeoutAdaptiveEnd), OID_RD },
+ { MIB(pfTimeoutSrcTrack), OID_RD },
+ { MIB(pfIfNumber), OID_RD },
+ { MIB(pfIfIndex), OID_TRD },
+ { MIB(pfIfDescr), OID_TRD },
+ { MIB(pfIfType), OID_TRD },
+ { MIB(pfIfRefs), OID_TRD },
+ { MIB(pfIfRules), OID_TRD },
+ { MIB(pfIfIn4PassPkts), OID_TRD },
+ { MIB(pfIfIn4PassBytes), OID_TRD },
+ { MIB(pfIfIn4BlockPkts), OID_TRD },
+ { MIB(pfIfIn4BlockBytes), OID_TRD },
+ { MIB(pfIfOut4PassPkts), OID_TRD },
+ { MIB(pfIfOut4PassBytes), OID_TRD },
+ { MIB(pfIfOut4BlockPkts), OID_TRD },
+ { MIB(pfIfOut4BlockBytes), OID_TRD },
+ { MIB(pfIfIn6PassPkts), OID_TRD },
+ { MIB(pfIfIn6PassBytes), OID_TRD },
+ { MIB(pfIfIn6BlockPkts), OID_TRD },
+ { MIB(pfIfIn6BlockBytes), OID_TRD },
+ { MIB(pfIfOut6PassPkts), OID_TRD },
+ { MIB(pfIfOut6PassBytes), OID_TRD },
+ { MIB(pfIfOut6BlockPkts), OID_TRD },
+ { MIB(pfIfOut6BlockBytes), OID_TRD },
+ { MIB(pfTblNumber), OID_RD },
+ { MIB(pfTblIndex), OID_TRD },
+ { MIB(pfTblName), OID_TRD },
+ { MIB(pfTblAddresses), OID_TRD },
+ { MIB(pfTblAnchorRefs), OID_TRD },
+ { MIB(pfTblRuleRefs), OID_TRD },
+ { MIB(pfTblEvalsMatch), OID_TRD },
+ { MIB(pfTblEvalsNoMatch), OID_TRD },
+ { MIB(pfTblInPassPkts), OID_TRD },
+ { MIB(pfTblInPassBytes), OID_TRD },
+ { MIB(pfTblInBlockPkts), OID_TRD },
+ { MIB(pfTblInBlockBytes), OID_TRD },
+ { MIB(pfTblInXPassPkts), OID_TRD },
+ { MIB(pfTblInXPassBytes), OID_TRD },
+ { MIB(pfTblOutPassPkts), OID_TRD },
+ { MIB(pfTblOutPassBytes), OID_TRD },
+ { MIB(pfTblOutBlockPkts), OID_TRD },
+ { MIB(pfTblOutBlockBytes), OID_TRD },
+ { MIB(pfTblOutXPassPkts), OID_TRD },
+ { MIB(pfTblOutXPassBytes), OID_TRD },
+ { MIB(pfTblStatsCleared), OID_TRD },
+ { MIB(pfTblInMatchPkts), OID_TRD },
+ { MIB(pfTblInMatchBytes), OID_TRD },
+ { MIB(pfTblOutMatchPkts), OID_TRD },
+ { MIB(pfTblOutMatchBytes), OID_TRD },
+ { MIB(pfTblAddrTblIndex), OID_TRD },
+ { MIB(pfTblAddrNet), OID_TRD },
+ { MIB(pfTblAddrMask), OID_TRD },
+ { MIB(pfTblAddrCleared), OID_TRD },
+ { MIB(pfTblAddrInBlockPkts), OID_TRD },
+ { MIB(pfTblAddrInBlockBytes), OID_TRD },
+ { MIB(pfTblAddrInPassPkts), OID_TRD },
+ { MIB(pfTblAddrInPassBytes), OID_TRD },
+ { MIB(pfTblAddrOutBlockPkts), OID_TRD },
+ { MIB(pfTblAddrOutBlockBytes), OID_TRD },
+ { MIB(pfTblAddrOutPassPkts), OID_TRD },
+ { MIB(pfTblAddrOutPassBytes), OID_TRD },
+ { MIB(pfTblAddrInMatchPkts), OID_TRD },
+ { MIB(pfTblAddrInMatchBytes), OID_TRD },
+ { MIB(pfTblAddrOutMatchPkts), OID_TRD },
+ { MIB(pfTblAddrOutMatchBytes), OID_TRD },
+ { MIB(pfLabelNumber), OID_RD },
+ { MIB(pfLabelIndex), OID_TRD },
+ { MIB(pfLabelName), OID_TRD },
+ { MIB(pfLabelEvals), OID_TRD },
+ { MIB(pfLabelPkts), OID_TRD },
+ { MIB(pfLabelBytes), OID_TRD },
+ { MIB(pfLabelInPkts), OID_TRD },
+ { MIB(pfLabelInBytes), OID_TRD },
+ { MIB(pfLabelOutPkts), OID_TRD },
+ { MIB(pfLabelOutBytes), OID_TRD },
+ { MIB(pfLabelTotalStates), OID_TRD },
+ { MIB(pfsyncIpPktsRecv), OID_RD },
+ { MIB(pfsyncIp6PktsRecv), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadInterface), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadTtl), OID_RD },
+ { MIB(pfsyncPktShorterThanHeader), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadVersion), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadAction), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadLength), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadAuth), OID_RD },
+ { MIB(pfsyncPktDiscardsForStaleState), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadValues), OID_RD },
+ { MIB(pfsyncPktDiscardsForBadState), OID_RD },
+ { MIB(pfsyncIpPktsSent), OID_RD },
+ { MIB(pfsyncIp6PktsSent), OID_RD },
+ { MIB(pfsyncNoMemory), OID_RD },
+ { MIB(pfsyncOutputErrors), OID_RD },
+ { MIB(sensorsMIBObjects), OID_MIB },
+ { MIB(sensorNumber), OID_RD },
+ { MIB(sensorIndex), OID_TRD },
+ { MIB(sensorDescr), OID_TRD },
+ { MIB(sensorType), OID_TRD },
+ { MIB(sensorDevice), OID_TRD },
+ { MIB(sensorValue), OID_TRD },
+ { MIB(sensorUnits), OID_TRD },
+ { MIB(sensorStatus), OID_TRD },
+ { MIB(carpMIBObjects), OID_MIB },
+ { MIB(carpAllow), OID_RD },
+ { MIB(carpPreempt), OID_RD },
+ { MIB(carpLog), OID_RD },
+ { MIB(carpIpPktsRecv), OID_RD },
+ { MIB(carpIp6PktsRecv), OID_RD },
+ { MIB(carpPktDiscardsBadIface), OID_RD },
+ { MIB(carpPktDiscardsBadTtl), OID_RD },
+ { MIB(carpPktShorterThanHdr), OID_RD },
+ { MIB(carpDiscardsBadCksum), OID_RD },
+ { MIB(carpDiscardsBadVersion), OID_RD },
+ { MIB(carpDiscardsTooShort), OID_RD },
+ { MIB(carpDiscardsBadAuth), OID_RD },
+ { MIB(carpDiscardsBadVhid), OID_RD },
+ { MIB(carpDiscardsBadAddrList), OID_RD },
+ { MIB(carpIpPktsSent), OID_RD },
+ { MIB(carpIp6PktsSent), OID_RD },
+ { MIB(carpNoMemory), OID_RD },
+ { MIB(carpTransitionsToMaster), OID_RD },
+ { MIB(carpIfNumber), OID_RD },
+ { MIB(carpIfIndex), OID_TRD },
+ { MIB(carpIfDescr), OID_TRD },
+ { MIB(carpIfVhid), OID_TRD },
+ { MIB(carpIfDev ), OID_TRD },
+ { MIB(carpIfAdvbase), OID_TRD },
+ { MIB(carpIfAdvskew), OID_TRD },
+ { MIB(carpIfState), OID_TRD },
+ { MIB(carpGroupName), OID_TRD },
+ { MIB(carpGroupDemote), OID_TRD },
+ { MIB(memMIBObjects), OID_MIB },
+ { MIB(memMIBVersion), OID_RD },
+ { MIB(memIfName), OID_TRD },
+ { MIB(memIfLiveLocks), OID_TRD },
+ { MIBEND }
+};
+
+void
+mib_init(void)
+{
+ /*
+ * MIB declarations (to register the OID names)
+ */
+ smi_mibtree(mib_tree);
+
+ /*
+ * MIB definitions (the implementation)
+ */
+
+ /* SNMPv2-MIB */
+ smi_mibtree(base_mib);
+
+ /* SNMP-USER-BASED-SM-MIB */
+ smi_mibtree(usm_mib);
+
+ /* HOST-RESOURCES-MIB */
+ smi_mibtree(hr_mib);
+
+ /* IF-MIB */
+ smi_mibtree(if_mib);
+
+ /* IP-MIB */
+ smi_mibtree(ip_mib);
+
+ /* IP-FORWARD-MIB */
+ smi_mibtree(ipf_mib);
+
+ /* BRIDGE-MIB */
+ smi_mibtree(bridge_mib);
+
+ /* UCD-DISKIO-MIB */
+ smi_mibtree(diskio_mib);
+
+ /* OPENBSD-MIB */
+ smi_mibtree(openbsd_mib);
+}
diff --git a/usr.bin/snmp/mib.h b/usr.bin/snmp/mib.h
new file mode 100644
index 00000000000..520bda89b22
--- /dev/null
+++ b/usr.bin/snmp/mib.h
@@ -0,0 +1,1352 @@
+/* $OpenBSD: mib.h,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SNMPD_MIB_H
+#define SNMPD_MIB_H
+
+#define OID(...) { { MIB_##__VA_ARGS__ }, sizeof((u_int32_t[]) { MIB_##__VA_ARGS__ })/sizeof(u_int32_t) }
+#define MIB(...) { { MIB_##__VA_ARGS__ }, sizeof((u_int32_t[]) { MIB_##__VA_ARGS__ })/sizeof(u_int32_t) }, NULL
+#define MIBDECL(...) { { MIB_##__VA_ARGS__ }, sizeof((u_int32_t[]) { MIB_##__VA_ARGS__ })/sizeof(u_int32_t) }, #__VA_ARGS__
+#define MIBEND { { 0 } }, NULL
+
+/*
+ * Adding new MIBs:
+ * - add the OID definitions below
+ * - add the OIDs to the MIB_TREE table at the end of this file
+ * - optional: write the implementation in mib.c
+ */
+
+/* From the SNMPv2-SMI MIB */
+#define MIB_iso 1
+#define MIB_org MIB_iso, 3
+#define MIB_dod MIB_org, 6
+#define MIB_internet MIB_dod, 1
+#define MIB_directory MIB_internet, 1
+#define MIB_mgmt MIB_internet, 2
+#define MIB_mib_2 MIB_mgmt, 1 /* XXX mib-2 */
+#define MIB_system MIB_mib_2, 1
+#define OIDIDX_system 7
+#define MIB_sysDescr MIB_system, 1
+#define MIB_sysOID MIB_system, 2
+#define MIB_sysUpTime MIB_system, 3
+#define MIB_sysContact MIB_system, 4
+#define MIB_sysName MIB_system, 5
+#define MIB_sysLocation MIB_system, 6
+#define MIB_sysServices MIB_system, 7
+#define MIB_sysORLastChange MIB_system, 8
+#define MIB_sysORTable MIB_system, 9
+#define MIB_sysOREntry MIB_sysORTable, 1
+#define OIDIDX_sysOR 9
+#define OIDIDX_sysOREntry 10
+#define MIB_sysORIndex MIB_sysOREntry, 1
+#define MIB_sysORID MIB_sysOREntry, 2
+#define MIB_sysORDescr MIB_sysOREntry, 3
+#define MIB_sysORUpTime MIB_sysOREntry, 4
+#define MIB_transmission MIB_mib_2, 10
+#define MIB_snmp MIB_mib_2, 11
+#define OIDIDX_snmp 7
+#define MIB_snmpInPkts MIB_snmp, 1
+#define MIB_snmpOutPkts MIB_snmp, 2
+#define MIB_snmpInBadVersions MIB_snmp, 3
+#define MIB_snmpInBadCommunityNames MIB_snmp, 4
+#define MIB_snmpInBadCommunityUses MIB_snmp, 5
+#define MIB_snmpInASNParseErrs MIB_snmp, 6
+#define MIB_snmpInTooBigs MIB_snmp, 8
+#define MIB_snmpInNoSuchNames MIB_snmp, 9
+#define MIB_snmpInBadValues MIB_snmp, 10
+#define MIB_snmpInReadOnlys MIB_snmp, 11
+#define MIB_snmpInGenErrs MIB_snmp, 12
+#define MIB_snmpInTotalReqVars MIB_snmp, 13
+#define MIB_snmpInTotalSetVars MIB_snmp, 14
+#define MIB_snmpInGetRequests MIB_snmp, 15
+#define MIB_snmpInGetNexts MIB_snmp, 16
+#define MIB_snmpInSetRequests MIB_snmp, 17
+#define MIB_snmpInGetResponses MIB_snmp, 18
+#define MIB_snmpInTraps MIB_snmp, 19
+#define MIB_snmpOutTooBigs MIB_snmp, 20
+#define MIB_snmpOutNoSuchNames MIB_snmp, 21
+#define MIB_snmpOutBadValues MIB_snmp, 22
+#define MIB_snmpOutGenErrs MIB_snmp, 24
+#define MIB_snmpOutGetRequests MIB_snmp, 25
+#define MIB_snmpOutGetNexts MIB_snmp, 26
+#define MIB_snmpOutSetRequests MIB_snmp, 27
+#define MIB_snmpOutGetResponses MIB_snmp, 28
+#define MIB_snmpOutTraps MIB_snmp, 29
+#define MIB_snmpEnableAuthenTraps MIB_snmp, 30
+#define MIB_snmpSilentDrops MIB_snmp, 31
+#define MIB_snmpProxyDrops MIB_snmp, 32
+#define MIB_experimental MIB_internet, 3
+#define MIB_private MIB_internet, 4
+#define MIB_enterprises MIB_private, 1
+#define MIB_security MIB_internet, 5
+#define MIB_snmpV2 MIB_internet, 6
+#define MIB_snmpDomains MIB_snmpV2, 1
+#define MIB_snmpProxies MIB_snmpV2, 2
+#define MIB_snmpModules MIB_snmpV2, 3
+#define MIB_snmpMIB MIB_snmpModules, 1
+#define MIB_snmpMIBObjects MIB_snmpMIB, 1
+#define MIB_snmpTrap MIB_snmpMIBObjects, 4
+#define MIB_snmpTrapOID MIB_snmpTrap, 1
+#define MIB_snmpTrapEnterprise MIB_snmpTrap, 3
+#define MIB_snmpTraps MIB_snmpMIBObjects, 5
+#define MIB_coldStart MIB_snmpTraps, 1
+#define MIB_warmStart MIB_snmpTraps, 2
+#define MIB_linkDown MIB_snmpTraps, 3
+#define MIB_linkUp MIB_snmpTraps, 4
+#define MIB_authenticationFailure MIB_snmpTraps, 5
+#define MIB_egpNeighborLoss MIB_snmpTraps, 6
+
+/* SNMP-USER-BASED-SM-MIB */
+#define MIB_framework MIB_snmpModules, 10
+#define MIB_frameworkObjects MIB_framework, 2
+#define OIDIDX_snmpEngine 9
+#define MIB_snmpEngine MIB_frameworkObjects, 1
+#define MIB_snmpEngineID MIB_snmpEngine, 1
+#define MIB_snmpEngineBoots MIB_snmpEngine, 2
+#define MIB_snmpEngineTime MIB_snmpEngine, 3
+#define MIB_snmpEngineMaxMsgSize MIB_snmpEngine, 4
+#define MIB_usm MIB_snmpModules, 15
+#define MIB_usmObjects MIB_usm, 1
+#define MIB_usmStats MIB_usmObjects, 1
+#define OIDIDX_usmStats 9
+#define OIDVAL_usmErrSecLevel 1
+#define OIDVAL_usmErrTimeWindow 2
+#define OIDVAL_usmErrUserName 3
+#define OIDVAL_usmErrEngineId 4
+#define OIDVAL_usmErrDigest 5
+#define OIDVAL_usmErrDecrypt 6
+#define MIB_usmStatsUnsupportedSecLevels MIB_usmStats, OIDVAL_usmErrSecLevel
+#define MIB_usmStatsNotInTimeWindow MIB_usmStats, OIDVAL_usmErrTimeWindow
+#define MIB_usmStatsUnknownUserNames MIB_usmStats, OIDVAL_usmErrUserName
+#define MIB_usmStatsUnknownEngineId MIB_usmStats, OIDVAL_usmErrEngineId
+#define MIB_usmStatsWrongDigests MIB_usmStats, OIDVAL_usmErrDigest
+#define MIB_usmStatsDecryptionErrors MIB_usmStats, OIDVAL_usmErrDecrypt
+
+/* HOST-RESOURCES-MIB */
+#define MIB_host MIB_mib_2, 25
+#define MIB_hrSystem MIB_host, 1
+#define OIDIDX_hrsystem 8
+#define MIB_hrSystemUptime MIB_hrSystem, 1
+#define MIB_hrSystemDate MIB_hrSystem, 2
+#define MIB_hrSystemInitialLoadDevice MIB_hrSystem, 3
+#define MIB_hrSystemInitialLoadParameters MIB_hrSystem, 4
+#define MIB_hrSystemNumUsers MIB_hrSystem, 5
+#define MIB_hrSystemProcesses MIB_hrSystem, 6
+#define MIB_hrSystemMaxProcesses MIB_hrSystem, 7
+#define MIB_hrStorage MIB_host, 2
+#define MIB_hrStorageTypes MIB_hrStorage, 1
+#define MIB_hrStorageOther MIB_hrStorageTypes, 1
+#define MIB_hrStorageRam MIB_hrStorageTypes, 2
+#define MIB_hrStorageVirtualMemory MIB_hrStorageTypes, 3
+#define MIB_hrStorageFixedDisk MIB_hrStorageTypes, 4
+#define MIB_hrStorageRemovableDisk MIB_hrStorageTypes, 5
+#define MIB_hrStorageFloppyDisk MIB_hrStorageTypes, 6
+#define MIB_hrStorageCompactDisc MIB_hrStorageTypes, 7
+#define MIB_hrStorageRamDisk MIB_hrStorageTypes, 8
+#define MIB_hrStorageFlashMemory MIB_hrStorageTypes, 9
+#define MIB_hrStorageNetworkDisk MIB_hrStorageTypes, 10
+#define MIB_hrMemorySize MIB_hrStorage, 2
+#define MIB_hrStorageTable MIB_hrStorage, 3
+#define MIB_hrStorageEntry MIB_hrStorageTable, 1
+#define OIDIDX_hrStorage 10
+#define OIDIDX_hrStorageEntry 11
+#define MIB_hrStorageIndex MIB_hrStorageEntry, 1
+#define MIB_hrStorageType MIB_hrStorageEntry, 2
+#define MIB_hrStorageDescr MIB_hrStorageEntry, 3
+#define MIB_hrStorageAllocationUnits MIB_hrStorageEntry, 4
+#define MIB_hrStorageSize MIB_hrStorageEntry, 5
+#define MIB_hrStorageUsed MIB_hrStorageEntry, 6
+#define MIB_hrStorageAllocationFailures MIB_hrStorageEntry, 7
+#define MIB_hrDevice MIB_host, 3
+#define MIB_hrDeviceTypes MIB_hrDevice, 1
+#define MIB_hrDeviceOther MIB_hrDeviceTypes, 1
+#define MIB_hrDeviceUnknown MIB_hrDeviceTypes, 2
+#define MIB_hrDeviceProcessor MIB_hrDeviceTypes, 3
+#define MIB_hrDeviceNetwork MIB_hrDeviceTypes, 4
+#define MIB_hrDevicePrinter MIB_hrDeviceTypes, 5
+#define MIB_hrDeviceDiskStorage MIB_hrDeviceTypes, 6
+#define MIB_hrDeviceVideo MIB_hrDeviceTypes, 10
+#define MIB_hrDeviceAudio MIB_hrDeviceTypes, 11
+#define MIB_hrDeviceCoprocessor MIB_hrDeviceTypes, 12
+#define MIB_hrDeviceKeyboard MIB_hrDeviceTypes, 13
+#define MIB_hrDeviceModem MIB_hrDeviceTypes, 14
+#define MIB_hrDeviceParallelPort MIB_hrDeviceTypes, 15
+#define MIB_hrDevicePointing MIB_hrDeviceTypes, 16
+#define MIB_hrDeviceSerialPort MIB_hrDeviceTypes, 17
+#define MIB_hrDeviceTape MIB_hrDeviceTypes, 18
+#define MIB_hrDeviceClock MIB_hrDeviceTypes, 19
+#define MIB_hrDeviceVolatileMemory MIB_hrDeviceTypes, 20
+#define MIB_hrDeviceNonVolatileMemory MIB_hrDeviceTypes, 21
+#define MIB_hrDeviceTable MIB_hrDevice, 2
+#define MIB_hrDeviceEntry MIB_hrDeviceTable, 1
+#define OIDIDX_hrDevice 10
+#define OIDIDX_hrDeviceEntry 11
+#define MIB_hrDeviceIndex MIB_hrDeviceEntry, 1
+#define MIB_hrDeviceType MIB_hrDeviceEntry, 2
+#define MIB_hrDeviceDescr MIB_hrDeviceEntry, 3
+#define MIB_hrDeviceID MIB_hrDeviceEntry, 4
+#define MIB_hrDeviceStatus MIB_hrDeviceEntry, 5
+#define MIB_hrDeviceErrors MIB_hrDeviceEntry, 6
+#define MIB_hrProcessorTable MIB_hrDevice, 3
+#define MIB_hrProcessorEntry MIB_hrProcessorTable, 1
+#define OIDIDX_hrProcessor 10
+#define OIDIDX_hrProcessorEntry 11
+#define MIB_hrProcessorFrwID MIB_hrProcessorEntry, 1
+#define MIB_hrProcessorLoad MIB_hrProcessorEntry, 2
+#define MIB_hrSWRun MIB_host, 4
+#define MIB_hrSWOSIndex MIB_hrSWRun, 1
+#define MIB_hrSWRunTable MIB_hrSWRun, 2
+#define MIB_hrSWRunEntry MIB_hrSWRunTable, 1
+#define OIDIDX_hrSWRun 10
+#define OIDIDX_hrSWRunEntry 11
+#define MIB_hrSWRunIndex MIB_hrSWRunEntry, 1
+#define MIB_hrSWRunName MIB_hrSWRunEntry, 2
+#define MIB_hrSWRunID MIB_hrSWRunEntry, 3
+#define MIB_hrSWRunPath MIB_hrSWRunEntry, 4
+#define MIB_hrSWRunParameters MIB_hrSWRunEntry, 5
+#define MIB_hrSWRunType MIB_hrSWRunEntry, 6
+#define MIB_hrSWRunStatus MIB_hrSWRunEntry, 7
+#define MIB_hrSWRunPerf MIB_host, 5
+#define MIB_hrSWRunPerfTable MIB_hrSWRunPerf, 1
+#define OIDIDX_hrSWRunPerf 10
+#define OIDIDX_hrSWRunPerfEntry 11
+#define MIB_hrSWRunPerfEntry MIB_hrSWRunPerfTable, 1
+#define MIB_hrSWRunPerfCPU MIB_hrSWRunPerfEntry, 1
+#define MIB_hrSWRunPerfMem MIB_hrSWRunPerfEntry, 2
+#define MIB_hrSWInstalled MIB_host, 6
+#define MIB_hrMIBAdminInfo MIB_host, 7
+
+/* IF-MIB */
+#define MIB_ifMIB MIB_mib_2, 31
+#define MIB_ifMIBObjects MIB_ifMIB, 1
+#define MIB_ifXTable MIB_ifMIBObjects, 1
+#define MIB_ifXEntry MIB_ifXTable, 1
+#define OIDIDX_ifX 10
+#define OIDIDX_ifXEntry 11
+#define MIB_ifName MIB_ifXEntry, 1
+#define MIB_ifInMulticastPkts MIB_ifXEntry, 2
+#define MIB_ifInBroadcastPkts MIB_ifXEntry, 3
+#define MIB_ifOutMulticastPkts MIB_ifXEntry, 4
+#define MIB_ifOutBroadcastPkts MIB_ifXEntry, 5
+#define MIB_ifHCInOctets MIB_ifXEntry, 6
+#define MIB_ifHCInUcastPkts MIB_ifXEntry, 7
+#define MIB_ifHCInMulticastPkts MIB_ifXEntry, 8
+#define MIB_ifHCInBroadcastPkts MIB_ifXEntry, 9
+#define MIB_ifHCOutOctets MIB_ifXEntry, 10
+#define MIB_ifHCOutUcastPkts MIB_ifXEntry, 11
+#define MIB_ifHCOutMulticastPkts MIB_ifXEntry, 12
+#define MIB_ifHCOutBroadcastPkts MIB_ifXEntry, 13
+#define MIB_ifLinkUpDownTrapEnable MIB_ifXEntry, 14
+#define MIB_ifHighSpeed MIB_ifXEntry, 15
+#define MIB_ifPromiscuousMode MIB_ifXEntry, 16
+#define MIB_ifConnectorPresent MIB_ifXEntry, 17
+#define MIB_ifAlias MIB_ifXEntry, 18
+#define MIB_ifCounterDiscontinuityTime MIB_ifXEntry, 19
+#define MIB_ifStackTable MIB_ifMIBObjects, 2
+#define MIB_ifStackEntry MIB_ifStackTable, 1
+#define OIDIDX_ifStack 10
+#define OIDIDX_ifStackEntry 11
+#define MIB_ifStackStatus MIB_ifStackEntry, 3
+#define MIB_ifRcvAddressTable MIB_ifMIBObjects, 4
+#define MIB_ifRcvAddressEntry MIB_ifRcvAddressTable, 1
+#define OIDIDX_ifRcvAddress 10
+#define OIDIDX_ifRcvAddressEntry 11
+#define MIB_ifRcvAddressStatus MIB_ifRcvAddressEntry, 2
+#define MIB_ifRcvAddressType MIB_ifRcvAddressEntry, 3
+#define MIB_ifStackLastChange MIB_ifMIBObjects, 6
+#define MIB_interfaces MIB_mib_2, 2
+#define MIB_ifNumber MIB_interfaces, 1
+#define MIB_ifTable MIB_interfaces, 2
+#define MIB_ifEntry MIB_ifTable, 1
+#define OIDIDX_if 9
+#define OIDIDX_ifEntry 10
+#define MIB_ifIndex MIB_ifEntry, 1
+#define MIB_ifDescr MIB_ifEntry, 2
+#define MIB_ifType MIB_ifEntry, 3
+#define MIB_ifMtu MIB_ifEntry, 4
+#define MIB_ifSpeed MIB_ifEntry, 5
+#define MIB_ifPhysAddress MIB_ifEntry, 6
+#define MIB_ifAdminStatus MIB_ifEntry, 7
+#define MIB_ifOperStatus MIB_ifEntry, 8
+#define MIB_ifLastChange MIB_ifEntry, 9
+#define MIB_ifInOctets MIB_ifEntry, 10
+#define MIB_ifInUcastPkts MIB_ifEntry, 11
+#define MIB_ifInNUcastPkts MIB_ifEntry, 12
+#define MIB_ifInDiscards MIB_ifEntry, 13
+#define MIB_ifInErrors MIB_ifEntry, 14
+#define MIB_ifInUnknownProtos MIB_ifEntry, 15
+#define MIB_ifOutOctets MIB_ifEntry, 16
+#define MIB_ifOutUcastPkts MIB_ifEntry, 17
+#define MIB_ifOutNUcastPkts MIB_ifEntry, 18
+#define MIB_ifOutDiscards MIB_ifEntry, 19
+#define MIB_ifOutErrors MIB_ifEntry, 20
+#define MIB_ifOutQLen MIB_ifEntry, 21
+#define MIB_ifSpecific MIB_ifEntry, 22
+
+/* IP-MIB */
+#define MIB_ipMIB MIB_mib_2, 4
+#define OIDIDX_ip 7
+#define MIB_ipForwarding MIB_ipMIB, 1
+#define MIB_ipDefaultTTL MIB_ipMIB, 2
+#define MIB_ipInReceives MIB_ipMIB, 3
+#define MIB_ipInHdrErrors MIB_ipMIB, 4
+#define MIB_ipInAddrErrors MIB_ipMIB, 5
+#define MIB_ipForwDatagrams MIB_ipMIB, 6
+#define MIB_ipInUnknownProtos MIB_ipMIB, 7
+#define MIB_ipInDiscards MIB_ipMIB, 8
+#define MIB_ipInDelivers MIB_ipMIB, 9
+#define MIB_ipOutRequests MIB_ipMIB, 10
+#define MIB_ipOutDiscards MIB_ipMIB, 11
+#define MIB_ipOutNoRoutes MIB_ipMIB, 12
+#define MIB_ipReasmTimeout MIB_ipMIB, 13
+#define MIB_ipReasmReqds MIB_ipMIB, 14
+#define MIB_ipReasmOKs MIB_ipMIB, 15
+#define MIB_ipReasmFails MIB_ipMIB, 16
+#define MIB_ipFragOKs MIB_ipMIB, 17
+#define MIB_ipFragFails MIB_ipMIB, 18
+#define MIB_ipFragCreates MIB_ipMIB, 19
+#define MIB_ipAddrTable MIB_ipMIB, 20
+#define MIB_ipAddrEntry MIB_ipAddrTable, 1
+#define OIDIDX_ipAddr 9
+#define OIDIDX_ipAddrEntry 10
+#define MIB_ipAdEntAddr MIB_ipAddrEntry, 1
+#define MIB_ipAdEntIfIndex MIB_ipAddrEntry, 2
+#define MIB_ipAdEntNetMask MIB_ipAddrEntry, 3
+#define MIB_ipAdEntBcastAddr MIB_ipAddrEntry, 4
+#define MIB_ipAdEntReasmMaxSize MIB_ipAddrEntry, 5
+#define MIB_ipNetToMediaTable MIB_ipMIB, 22
+#define MIB_ipNetToMediaEntry MIB_ipNetToMediaTable, 1
+#define OIDIDX_ipNetToMedia 9
+#define MIB_ipNetToMediaIfIndex MIB_ipNetToMediaEntry, 1
+#define MIB_ipNetToMediaPhysAddress MIB_ipNetToMediaEntry, 2
+#define MIB_ipNetToMediaNetAddress MIB_ipNetToMediaEntry, 3
+#define MIB_ipNetToMediaType MIB_ipNetToMediaEntry, 4
+#define MIB_ipRoutingDiscards MIB_ipMIB, 23
+
+/* IP-FORWARD-MIB */
+#define MIB_ipfMIB MIB_ipMIB, 24
+#define MIB_ipfInetCidrRouteNumber MIB_ipfMIB, 6
+#define MIB_ipfInetCidrRouteTable MIB_ipfMIB, 7
+#define MIB_ipfInetCidrRouteEntry MIB_ipfInetCidrRouteTable, 1
+#define OIDIDX_ipfInetCidrRoute 10
+#define MIB_ipfRouteEntDestType MIB_ipfInetCidrRouteEntry, 1
+#define MIB_ipfRouteEntDest MIB_ipfInetCidrRouteEntry, 2
+#define MIB_ipfRouteEntPfxLen MIB_ipfInetCidrRouteEntry, 3
+#define MIB_ipfRouteEntPolicy MIB_ipfInetCidrRouteEntry, 4
+#define MIB_ipfRouteEntNextHopType MIB_ipfInetCidrRouteEntry, 5
+#define MIB_ipfRouteEntNextHop MIB_ipfInetCidrRouteEntry, 6
+#define MIB_ipfRouteEntIfIndex MIB_ipfInetCidrRouteEntry, 7
+#define MIB_ipfRouteEntType MIB_ipfInetCidrRouteEntry, 8
+#define MIB_ipfRouteEntProto MIB_ipfInetCidrRouteEntry, 9
+#define MIB_ipfRouteEntAge MIB_ipfInetCidrRouteEntry, 10
+#define MIB_ipfRouteEntNextHopAS MIB_ipfInetCidrRouteEntry, 11
+#define MIB_ipfRouteEntRouteMetric1 MIB_ipfInetCidrRouteEntry, 12
+#define MIB_ipfRouteEntRouteMetric2 MIB_ipfInetCidrRouteEntry, 13
+#define MIB_ipfRouteEntRouteMetric3 MIB_ipfInetCidrRouteEntry, 14
+#define MIB_ipfRouteEntRouteMetric4 MIB_ipfInetCidrRouteEntry, 15
+#define MIB_ipfRouteEntRouteMetric5 MIB_ipfInetCidrRouteEntry, 16
+#define MIB_ipfRouteEntStatus MIB_ipfInetCidrRouteEntry, 17
+#define MIB_ipfInetCidrRouteDiscards MIB_ipfMIB, 8
+
+/* BRIDGE-MIB */
+#define MIB_dot1dBridge MIB_mib_2, 17
+#define MIB_dot1dBase MIB_dot1dBridge, 1
+#define MIB_dot1dBaseBridgeAddress MIB_dot1dBase, 1
+#define MIB_dot1dBaseNumPorts MIB_dot1dBase, 2
+#define MIB_dot1dBaseType MIB_dot1dBase, 3
+#define MIB_dot1dBasePortTable MIB_dot1dBase, 4
+#define OIDIDX_dot1d 10
+#define OIDIDX_dot1dEntry 11
+#define MIB_dot1dBasePortEntry MIB_dot1dBasePortTable, 1
+#define MIB_dot1dBasePort MIB_dot1dBasePortEntry, 1
+#define MIB_dot1dBasePortIfIndex MIB_dot1dBasePortEntry, 2
+#define MIB_dot1dBasePortCircuit MIB_dot1dBasePortEntry, 3
+#define MIB_dot1dBasePortDelayExceededDiscards MIB_dot1dBasePortEntry, 4
+#define MIB_dot1dBasePortMtuExceededDiscards MIB_dot1dBasePortEntry, 5
+#define MIB_dot1dStp MIB_dot1dBridge, 2
+#define MIB_dot1dSr MIB_dot1dBridge, 3
+#define MIB_dot1dTp MIB_dot1dBridge, 4
+#define MIB_dot1dStatic MIB_dot1dBridge, 5
+
+/*
+ * PRIVATE ENTERPRISE NUMBERS from
+ * https://www.iana.org/assignments/enterprise-numbers
+ *
+ * This is not the complete list of private enterprise numbers, it only
+ * includes some well-known companies and especially network companies
+ * that are very common in the datacenters around the world, other
+ * companies that contributed to snmpd or OpenBSD in some way, or just
+ * any other organizations that we wanted to include. It would be an
+ * overkill to include ~30.000 entries for all the organizations from
+ * the official list.
+ */
+#define MIB_ibm MIB_enterprises, 2
+#define MIB_cmu MIB_enterprises, 3
+#define MIB_unix MIB_enterprises, 4
+#define MIB_ciscoSystems MIB_enterprises, 9
+#define MIB_hp MIB_enterprises, 11
+#define MIB_mit MIB_enterprises, 20
+#define MIB_nortelNetworks MIB_enterprises, 35
+#define MIB_sun MIB_enterprises, 42
+#define MIB_3com MIB_enterprises, 43
+#define MIB_synOptics MIB_enterprises, 45
+#define MIB_enterasys MIB_enterprises, 52
+#define MIB_sgi MIB_enterprises, 59
+#define MIB_apple MIB_enterprises, 63
+#define MIB_nasa MIB_enterprises, 71
+#define MIB_att MIB_enterprises, 74
+#define MIB_nokia MIB_enterprises, 94
+#define MIB_cern MIB_enterprises, 96
+#define MIB_oracle MIB_enterprises, 111
+#define MIB_motorola MIB_enterprises, 161
+#define MIB_ncr MIB_enterprises, 191
+#define MIB_ericsson MIB_enterprises, 193
+#define MIB_fsc MIB_enterprises, 231
+#define MIB_compaq MIB_enterprises, 232
+#define MIB_bmw MIB_enterprises, 513
+#define MIB_dell MIB_enterprises, 674
+#define MIB_iij MIB_enterprises, 770
+#define MIB_sandia MIB_enterprises, 1400
+#define MIB_mercedesBenz MIB_enterprises, 1635
+#define MIB_alteon MIB_enterprises, 1872
+#define MIB_extremeNetworks MIB_enterprises, 1916
+#define MIB_foundryNetworks MIB_enterprises, 1991
+#define MIB_huawaiTechnology MIB_enterprises, 2011
+#define MIB_ucDavis MIB_enterprises, 2021
+#define MIB_freeBSD MIB_enterprises, 2238
+#define MIB_checkPoint MIB_enterprises, 2620
+#define MIB_juniper MIB_enterprises, 2636
+#define MIB_printerWorkingGroup MIB_enterprises, 2699
+#define MIB_audi MIB_enterprises, 3195
+#define MIB_volkswagen MIB_enterprises, 3210
+#define MIB_genua MIB_enterprises, 3717
+#define MIB_amazon MIB_enterprises, 4843
+#define MIB_force10Networks MIB_enterprises, 6027
+#define MIB_vMware MIB_enterprises, 6876
+#define MIB_alcatelLucent MIB_enterprises, 7483
+#define MIB_snom MIB_enterprises, 7526
+#define MIB_netSNMP MIB_enterprises, 8072
+#define MIB_netflix MIB_enterprises, 10949
+#define MIB_google MIB_enterprises, 11129
+#define MIB_f5Networks MIB_enterprises, 12276
+#define MIB_bsws MIB_enterprises, 13635
+#define MIB_sFlow MIB_enterprises, 14706
+#define MIB_microSystems MIB_enterprises, 18623
+#define MIB_paloAltoNetworks MIB_enterprises, 25461
+#define MIB_h3c MIB_enterprises, 25506
+#define MIB_vantronix MIB_enterprises, 26766
+#define MIB_netBSD MIB_enterprises, 32388
+#define OIDVAL_openBSD_eid 30155
+#define MIB_openBSD MIB_enterprises, OIDVAL_openBSD_eid
+#define MIB_nicira MIB_enterprises, 39961
+#define MIB_esdenera MIB_enterprises, 42459
+#define MIB_arcaTrust MIB_enterprises, 52198
+
+/* UCD-DISKIO-MIB */
+#define MIB_ucdExperimental MIB_ucDavis, 13
+#define MIB_ucdDiskIOMIB MIB_ucdExperimental, 15
+#define MIB_diskIOTable MIB_ucdDiskIOMIB, 1
+#define MIB_diskIOEntry MIB_diskIOTable, 1
+#define OIDIDX_diskIO 11
+#define OIDIDX_diskIOEntry 12
+#define MIB_diskIOIndex MIB_diskIOEntry, 1
+#define MIB_diskIODevice MIB_diskIOEntry, 2
+#define MIB_diskIONRead MIB_diskIOEntry, 3
+#define MIB_diskIONWritten MIB_diskIOEntry, 4
+#define MIB_diskIOReads MIB_diskIOEntry, 5
+#define MIB_diskIOWrites MIB_diskIOEntry, 6
+#define MIB_diskIONReadX MIB_diskIOEntry, 12
+#define MIB_diskIONWrittenX MIB_diskIOEntry, 13
+
+/* OPENBSD-MIB */
+#define MIB_pfMIBObjects MIB_openBSD, 1
+#define MIB_pfInfo MIB_pfMIBObjects, 1
+#define MIB_pfRunning MIB_pfInfo, 1
+#define MIB_pfRuntime MIB_pfInfo, 2
+#define MIB_pfDebug MIB_pfInfo, 3
+#define MIB_pfHostid MIB_pfInfo, 4
+#define MIB_pfCounters MIB_pfMIBObjects, 2
+#define MIB_pfCntMatch MIB_pfCounters, 1
+#define MIB_pfCntBadOffset MIB_pfCounters, 2
+#define MIB_pfCntFragment MIB_pfCounters, 3
+#define MIB_pfCntShort MIB_pfCounters, 4
+#define MIB_pfCntNormalize MIB_pfCounters, 5
+#define MIB_pfCntMemory MIB_pfCounters, 6
+#define MIB_pfCntTimestamp MIB_pfCounters, 7
+#define MIB_pfCntCongestion MIB_pfCounters, 8
+#define MIB_pfCntIpOptions MIB_pfCounters, 9
+#define MIB_pfCntProtoCksum MIB_pfCounters, 10
+#define MIB_pfCntStateMismatch MIB_pfCounters, 11
+#define MIB_pfCntStateInsert MIB_pfCounters, 12
+#define MIB_pfCntStateLimit MIB_pfCounters, 13
+#define MIB_pfCntSrcLimit MIB_pfCounters, 14
+#define MIB_pfCntSynproxy MIB_pfCounters, 15
+#define MIB_pfCntTranslate MIB_pfCounters, 16
+#define MIB_pfCntNoRoute MIB_pfCounters, 17
+#define MIB_pfStateTable MIB_pfMIBObjects, 3
+#define MIB_pfStateCount MIB_pfStateTable, 1
+#define MIB_pfStateSearches MIB_pfStateTable, 2
+#define MIB_pfStateInserts MIB_pfStateTable, 3
+#define MIB_pfStateRemovals MIB_pfStateTable, 4
+#define MIB_pfLogInterface MIB_pfMIBObjects, 4
+#define MIB_pfLogIfName MIB_pfLogInterface, 1
+#define MIB_pfLogIfIpBytesIn MIB_pfLogInterface, 2
+#define MIB_pfLogIfIpBytesOut MIB_pfLogInterface, 3
+#define MIB_pfLogIfIpPktsInPass MIB_pfLogInterface, 4
+#define MIB_pfLogIfIpPktsInDrop MIB_pfLogInterface, 5
+#define MIB_pfLogIfIpPktsOutPass MIB_pfLogInterface, 6
+#define MIB_pfLogIfIpPktsOutDrop MIB_pfLogInterface, 7
+#define MIB_pfLogIfIp6BytesIn MIB_pfLogInterface, 8
+#define MIB_pfLogIfIp6BytesOut MIB_pfLogInterface, 9
+#define MIB_pfLogIfIp6PktsInPass MIB_pfLogInterface, 10
+#define MIB_pfLogIfIp6PktsInDrop MIB_pfLogInterface, 11
+#define MIB_pfLogIfIp6PktsOutPass MIB_pfLogInterface, 12
+#define MIB_pfLogIfIp6PktsOutDrop MIB_pfLogInterface, 13
+#define MIB_pfSrcTracking MIB_pfMIBObjects, 5
+#define MIB_pfSrcTrackCount MIB_pfSrcTracking, 1
+#define MIB_pfSrcTrackSearches MIB_pfSrcTracking, 2
+#define MIB_pfSrcTrackInserts MIB_pfSrcTracking, 3
+#define MIB_pfSrcTrackRemovals MIB_pfSrcTracking, 4
+#define MIB_pfLimits MIB_pfMIBObjects, 6
+#define MIB_pfLimitStates MIB_pfLimits, 1
+#define MIB_pfLimitSourceNodes MIB_pfLimits, 2
+#define MIB_pfLimitFragments MIB_pfLimits, 3
+#define MIB_pfLimitMaxTables MIB_pfLimits, 4
+#define MIB_pfLimitMaxTableEntries MIB_pfLimits, 5
+#define MIB_pfTimeouts MIB_pfMIBObjects, 7
+#define MIB_pfTimeoutTcpFirst MIB_pfTimeouts, 1
+#define MIB_pfTimeoutTcpOpening MIB_pfTimeouts, 2
+#define MIB_pfTimeoutTcpEstablished MIB_pfTimeouts, 3
+#define MIB_pfTimeoutTcpClosing MIB_pfTimeouts, 4
+#define MIB_pfTimeoutTcpFinWait MIB_pfTimeouts, 5
+#define MIB_pfTimeoutTcpClosed MIB_pfTimeouts, 6
+#define MIB_pfTimeoutUdpFirst MIB_pfTimeouts, 7
+#define MIB_pfTimeoutUdpSingle MIB_pfTimeouts, 8
+#define MIB_pfTimeoutUdpMultiple MIB_pfTimeouts, 9
+#define MIB_pfTimeoutIcmpFirst MIB_pfTimeouts, 10
+#define MIB_pfTimeoutIcmpError MIB_pfTimeouts, 11
+#define MIB_pfTimeoutOtherFirst MIB_pfTimeouts, 12
+#define MIB_pfTimeoutOtherSingle MIB_pfTimeouts, 13
+#define MIB_pfTimeoutOtherMultiple MIB_pfTimeouts, 14
+#define MIB_pfTimeoutFragment MIB_pfTimeouts, 15
+#define MIB_pfTimeoutInterval MIB_pfTimeouts, 16
+#define MIB_pfTimeoutAdaptiveStart MIB_pfTimeouts, 17
+#define MIB_pfTimeoutAdaptiveEnd MIB_pfTimeouts, 18
+#define MIB_pfTimeoutSrcTrack MIB_pfTimeouts, 19
+#define OIDIDX_pfstatus 9
+#define MIB_pfInterfaces MIB_pfMIBObjects, 8
+#define MIB_pfIfNumber MIB_pfInterfaces, 1
+#define MIB_pfIfTable MIB_pfInterfaces, 128
+#define MIB_pfIfEntry MIB_pfIfTable, 1
+#define OIDIDX_pfInterface 11
+#define OIDIDX_pfIfEntry 12
+#define MIB_pfIfIndex MIB_pfIfEntry, 1
+#define MIB_pfIfDescr MIB_pfIfEntry, 2
+#define MIB_pfIfType MIB_pfIfEntry, 3
+#define MIB_pfIfRefs MIB_pfIfEntry, 4
+#define MIB_pfIfRules MIB_pfIfEntry, 5
+#define MIB_pfIfIn4PassPkts MIB_pfIfEntry, 6
+#define MIB_pfIfIn4PassBytes MIB_pfIfEntry, 7
+#define MIB_pfIfIn4BlockPkts MIB_pfIfEntry, 8
+#define MIB_pfIfIn4BlockBytes MIB_pfIfEntry, 9
+#define MIB_pfIfOut4PassPkts MIB_pfIfEntry, 10
+#define MIB_pfIfOut4PassBytes MIB_pfIfEntry, 11
+#define MIB_pfIfOut4BlockPkts MIB_pfIfEntry, 12
+#define MIB_pfIfOut4BlockBytes MIB_pfIfEntry, 13
+#define MIB_pfIfIn6PassPkts MIB_pfIfEntry, 14
+#define MIB_pfIfIn6PassBytes MIB_pfIfEntry, 15
+#define MIB_pfIfIn6BlockPkts MIB_pfIfEntry, 16
+#define MIB_pfIfIn6BlockBytes MIB_pfIfEntry, 17
+#define MIB_pfIfOut6PassPkts MIB_pfIfEntry, 18
+#define MIB_pfIfOut6PassBytes MIB_pfIfEntry, 19
+#define MIB_pfIfOut6BlockPkts MIB_pfIfEntry, 20
+#define MIB_pfIfOut6BlockBytes MIB_pfIfEntry, 21
+#define MIB_pfTables MIB_pfMIBObjects, 9
+#define MIB_pfTblNumber MIB_pfTables, 1
+#define MIB_pfTblTable MIB_pfTables, 128
+#define MIB_pfTblEntry MIB_pfTblTable, 1
+#define OIDIDX_pfTable 11
+#define OIDIDX_pfTableEntry 12
+#define MIB_pfTblIndex MIB_pfTblEntry, 1
+#define MIB_pfTblName MIB_pfTblEntry, 2
+#define MIB_pfTblAddresses MIB_pfTblEntry, 3
+#define MIB_pfTblAnchorRefs MIB_pfTblEntry, 4
+#define MIB_pfTblRuleRefs MIB_pfTblEntry, 5
+#define MIB_pfTblEvalsMatch MIB_pfTblEntry, 6
+#define MIB_pfTblEvalsNoMatch MIB_pfTblEntry, 7
+#define MIB_pfTblInPassPkts MIB_pfTblEntry, 8
+#define MIB_pfTblInPassBytes MIB_pfTblEntry, 9
+#define MIB_pfTblInBlockPkts MIB_pfTblEntry, 10
+#define MIB_pfTblInBlockBytes MIB_pfTblEntry, 11
+#define MIB_pfTblInXPassPkts MIB_pfTblEntry, 12
+#define MIB_pfTblInXPassBytes MIB_pfTblEntry, 13
+#define MIB_pfTblOutPassPkts MIB_pfTblEntry, 14
+#define MIB_pfTblOutPassBytes MIB_pfTblEntry, 15
+#define MIB_pfTblOutBlockPkts MIB_pfTblEntry, 16
+#define MIB_pfTblOutBlockBytes MIB_pfTblEntry, 17
+#define MIB_pfTblOutXPassPkts MIB_pfTblEntry, 18
+#define MIB_pfTblOutXPassBytes MIB_pfTblEntry, 19
+#define MIB_pfTblStatsCleared MIB_pfTblEntry, 20
+#define MIB_pfTblInMatchPkts MIB_pfTblEntry, 21
+#define MIB_pfTblInMatchBytes MIB_pfTblEntry, 22
+#define MIB_pfTblOutMatchPkts MIB_pfTblEntry, 23
+#define MIB_pfTblOutMatchBytes MIB_pfTblEntry, 24
+#define MIB_pfTblAddrTable MIB_pfTables, 129
+#define MIB_pfTblAddrEntry MIB_pfTblAddrTable, 1
+#define OIDIDX_pfTblAddr 11
+#define MIB_pfTblAddrTblIndex MIB_pfTblAddrEntry, 1
+#define MIB_pfTblAddrNet MIB_pfTblAddrEntry, 2
+#define MIB_pfTblAddrMask MIB_pfTblAddrEntry, 3
+#define MIB_pfTblAddrCleared MIB_pfTblAddrEntry, 4
+#define MIB_pfTblAddrInBlockPkts MIB_pfTblAddrEntry, 5
+#define MIB_pfTblAddrInBlockBytes MIB_pfTblAddrEntry, 6
+#define MIB_pfTblAddrInPassPkts MIB_pfTblAddrEntry, 7
+#define MIB_pfTblAddrInPassBytes MIB_pfTblAddrEntry, 8
+#define MIB_pfTblAddrOutBlockPkts MIB_pfTblAddrEntry, 9
+#define MIB_pfTblAddrOutBlockBytes MIB_pfTblAddrEntry, 10
+#define MIB_pfTblAddrOutPassPkts MIB_pfTblAddrEntry, 11
+#define MIB_pfTblAddrOutPassBytes MIB_pfTblAddrEntry, 12
+#define MIB_pfTblAddrInMatchPkts MIB_pfTblAddrEntry, 13
+#define MIB_pfTblAddrInMatchBytes MIB_pfTblAddrEntry, 14
+#define MIB_pfTblAddrOutMatchPkts MIB_pfTblAddrEntry, 15
+#define MIB_pfTblAddrOutMatchBytes MIB_pfTblAddrEntry, 16
+#define MIB_pfLabels MIB_pfMIBObjects, 10
+#define MIB_pfLabelNumber MIB_pfLabels, 1
+#define MIB_pfLabelTable MIB_pfLabels, 128
+#define OIDIDX_pfLabel 11
+#define OIDIDX_pfLabelEntry 12
+#define MIB_pfLabelEntry MIB_pfLabelTable, 1
+#define MIB_pfLabelIndex MIB_pfLabelEntry, 1
+#define MIB_pfLabelName MIB_pfLabelEntry, 2
+#define MIB_pfLabelEvals MIB_pfLabelEntry, 3
+#define MIB_pfLabelPkts MIB_pfLabelEntry, 4
+#define MIB_pfLabelBytes MIB_pfLabelEntry, 5
+#define MIB_pfLabelInPkts MIB_pfLabelEntry, 6
+#define MIB_pfLabelInBytes MIB_pfLabelEntry, 7
+#define MIB_pfLabelOutPkts MIB_pfLabelEntry, 8
+#define MIB_pfLabelOutBytes MIB_pfLabelEntry, 9
+#define MIB_pfLabelTotalStates MIB_pfLabelEntry, 10
+#define MIB_pfsyncStats MIB_pfMIBObjects, 11
+#define MIB_pfsyncIpPktsRecv MIB_pfsyncStats, 1
+#define MIB_pfsyncIp6PktsRecv MIB_pfsyncStats, 2
+#define MIB_pfsyncPktDiscardsForBadInterface MIB_pfsyncStats, 3
+#define MIB_pfsyncPktDiscardsForBadTtl MIB_pfsyncStats, 4
+#define MIB_pfsyncPktShorterThanHeader MIB_pfsyncStats, 5
+#define MIB_pfsyncPktDiscardsForBadVersion MIB_pfsyncStats, 6
+#define MIB_pfsyncPktDiscardsForBadAction MIB_pfsyncStats, 7
+#define MIB_pfsyncPktDiscardsForBadLength MIB_pfsyncStats, 8
+#define MIB_pfsyncPktDiscardsForBadAuth MIB_pfsyncStats, 9
+#define MIB_pfsyncPktDiscardsForStaleState MIB_pfsyncStats, 10
+#define MIB_pfsyncPktDiscardsForBadValues MIB_pfsyncStats, 11
+#define MIB_pfsyncPktDiscardsForBadState MIB_pfsyncStats, 12
+#define MIB_pfsyncIpPktsSent MIB_pfsyncStats, 13
+#define MIB_pfsyncIp6PktsSent MIB_pfsyncStats, 14
+#define MIB_pfsyncNoMemory MIB_pfsyncStats, 15
+#define MIB_pfsyncOutputErrors MIB_pfsyncStats, 16
+#define MIB_sensorsMIBObjects MIB_openBSD, 2
+#define MIB_sensors MIB_sensorsMIBObjects, 1
+#define MIB_sensorNumber MIB_sensors, 1
+#define MIB_sensorTable MIB_sensors, 2
+#define MIB_sensorEntry MIB_sensorTable, 1
+#define OIDIDX_sensor 11
+#define OIDIDX_sensorEntry 12
+#define MIB_sensorIndex MIB_sensorEntry, 1
+#define MIB_sensorDescr MIB_sensorEntry, 2
+#define MIB_sensorType MIB_sensorEntry, 3
+#define MIB_sensorDevice MIB_sensorEntry, 4
+#define MIB_sensorValue MIB_sensorEntry, 5
+#define MIB_sensorUnits MIB_sensorEntry, 6
+#define MIB_sensorStatus MIB_sensorEntry, 7
+#define MIB_relaydMIBObjects MIB_openBSD, 3
+#define MIB_relaydHostTrap MIB_relaydMIBObjects, 1
+#define MIB_relaydHostTrapHostName MIB_relaydHostTrap, 1
+#define MIB_relaydHostTrapUp MIB_relaydHostTrap, 2
+#define MIB_relaydHostTrapLastUp MIB_relaydHostTrap, 3
+#define MIB_relaydHostTrapUpCount MIB_relaydHostTrap, 4
+#define MIB_relaydHostTrapCheckCount MIB_relaydHostTrap, 5
+#define MIB_relaydHostTrapTableName MIB_relaydHostTrap, 6
+#define MIB_relaydHostTrapTableUp MIB_relaydHostTrap, 7
+#define MIB_relaydHostTrapRetry MIB_relaydHostTrap, 8
+#define MIB_relaydHostTrapRetryCount MIB_relaydHostTrap, 9
+#define MIB_ipsecMIBObjects MIB_openBSD, 4
+#define MIB_memMIBObjects MIB_openBSD, 5
+#define MIB_memMIBVersion MIB_memMIBObjects, 1
+#define OIDVER_OPENBSD_MEM 1
+#define MIB_memIfTable MIB_memMIBObjects, 2
+#define MIB_memIfEntry MIB_memIfTable, 1
+#define OIDIDX_memIf 10
+#define OIDIDX_memIfEntry 11
+#define MIB_memIfName MIB_memIfEntry, 1
+#define MIB_memIfLiveLocks MIB_memIfEntry, 2
+#define MIB_carpMIBObjects MIB_openBSD, 6
+#define MIB_carpSysctl MIB_carpMIBObjects, 1
+#define MIB_carpAllow MIB_carpSysctl, 1
+#define MIB_carpPreempt MIB_carpSysctl, 2
+#define MIB_carpLog MIB_carpSysctl, 3
+#define OIDIDX_carpsysctl 9
+#define MIB_carpIf MIB_carpMIBObjects, 2
+#define MIB_carpIfNumber MIB_carpIf, 1
+#define MIB_carpIfTable MIB_carpIf, 2
+#define MIB_carpIfEntry MIB_carpIfTable, 1
+#define OIDIDX_carpIf 11
+#define OIDIDX_carpIfEntry 12
+#define MIB_carpIfIndex MIB_carpIfEntry, 1
+#define MIB_carpIfDescr MIB_carpIfEntry, 2
+#define MIB_carpIfVhid MIB_carpIfEntry, 3
+#define MIB_carpIfDev MIB_carpIfEntry, 4
+#define MIB_carpIfAdvbase MIB_carpIfEntry, 5
+#define MIB_carpIfAdvskew MIB_carpIfEntry, 6
+#define MIB_carpIfState MIB_carpIfEntry, 7
+#define OIDIDX_carpstats 9
+#define MIB_carpStats MIB_carpMIBObjects, 3
+#define MIB_carpIpPktsRecv MIB_carpStats, 1
+#define MIB_carpIp6PktsRecv MIB_carpStats, 2
+#define MIB_carpPktDiscardsBadIface MIB_carpStats, 3
+#define MIB_carpPktDiscardsBadTtl MIB_carpStats, 4
+#define MIB_carpPktShorterThanHdr MIB_carpStats, 5
+#define MIB_carpDiscardsBadCksum MIB_carpStats, 6
+#define MIB_carpDiscardsBadVersion MIB_carpStats, 7
+#define MIB_carpDiscardsTooShort MIB_carpStats, 8
+#define MIB_carpDiscardsBadAuth MIB_carpStats, 9
+#define MIB_carpDiscardsBadVhid MIB_carpStats, 10
+#define MIB_carpDiscardsBadAddrList MIB_carpStats, 11
+#define MIB_carpIpPktsSent MIB_carpStats, 12
+#define MIB_carpIp6PktsSent MIB_carpStats, 13
+#define MIB_carpNoMemory MIB_carpStats, 14
+#define MIB_carpTransitionsToMaster MIB_carpStats, 15
+#define MIB_carpGroupTable MIB_carpMIBObjects, 4
+#define MIB_carpGroupEntry MIB_carpGroupTable, 1
+#define OIDIDX_carpGroupEntry 10
+#define OIDIDX_carpGroupIndex 11
+#define MIB_carpGroupName MIB_carpGroupEntry, 2
+#define MIB_carpGroupDemote MIB_carpGroupEntry, 3
+#define MIB_localSystem MIB_openBSD, 23
+#define MIB_SYSOID_DEFAULT MIB_openBSD, 23, 1
+#define MIB_localTest MIB_openBSD, 42
+
+#define MIB_TREE { \
+ { MIBDECL(iso) }, \
+ { MIBDECL(org) }, \
+ { MIBDECL(dod) }, \
+ { MIBDECL(internet) }, \
+ { MIBDECL(directory) }, \
+ { MIBDECL(mgmt) }, \
+ { MIBDECL(mib_2) }, \
+ { MIBDECL(system) }, \
+ { MIBDECL(sysDescr) }, \
+ { MIBDECL(sysOID) }, \
+ { MIBDECL(sysUpTime) }, \
+ { MIBDECL(sysContact) }, \
+ { MIBDECL(sysName) }, \
+ { MIBDECL(sysLocation) }, \
+ { MIBDECL(sysServices) }, \
+ { MIBDECL(sysORLastChange) }, \
+ { MIBDECL(sysORTable) }, \
+ { MIBDECL(sysOREntry) }, \
+ { MIBDECL(sysORIndex) }, \
+ { MIBDECL(sysORID) }, \
+ { MIBDECL(sysORDescr) }, \
+ { MIBDECL(sysORUpTime) }, \
+ { MIBDECL(transmission) }, \
+ { MIBDECL(snmp) }, \
+ { MIBDECL(snmpInPkts) }, \
+ { MIBDECL(snmpOutPkts) }, \
+ { MIBDECL(snmpInBadVersions) }, \
+ { MIBDECL(snmpInBadCommunityNames) }, \
+ { MIBDECL(snmpInBadCommunityUses) }, \
+ { MIBDECL(snmpInASNParseErrs) }, \
+ { MIBDECL(snmpInTooBigs) }, \
+ { MIBDECL(snmpInNoSuchNames) }, \
+ { MIBDECL(snmpInBadValues) }, \
+ { MIBDECL(snmpInReadOnlys) }, \
+ { MIBDECL(snmpInGenErrs) }, \
+ { MIBDECL(snmpInTotalReqVars) }, \
+ { MIBDECL(snmpInTotalSetVars) }, \
+ { MIBDECL(snmpInGetRequests) }, \
+ { MIBDECL(snmpInGetNexts) }, \
+ { MIBDECL(snmpInSetRequests) }, \
+ { MIBDECL(snmpInGetResponses) }, \
+ { MIBDECL(snmpInTraps) }, \
+ { MIBDECL(snmpOutTooBigs) }, \
+ { MIBDECL(snmpOutNoSuchNames) }, \
+ { MIBDECL(snmpOutBadValues) }, \
+ { MIBDECL(snmpOutGenErrs) }, \
+ { MIBDECL(snmpOutGetRequests) }, \
+ { MIBDECL(snmpOutGetNexts) }, \
+ { MIBDECL(snmpOutSetRequests) }, \
+ { MIBDECL(snmpOutGetResponses) }, \
+ { MIBDECL(snmpOutTraps) }, \
+ { MIBDECL(snmpEnableAuthenTraps) }, \
+ { MIBDECL(snmpSilentDrops) }, \
+ { MIBDECL(snmpProxyDrops) }, \
+ { MIBDECL(experimental) }, \
+ { MIBDECL(private) }, \
+ { MIBDECL(enterprises) }, \
+ { MIBDECL(security) }, \
+ { MIBDECL(snmpV2) }, \
+ { MIBDECL(snmpDomains) }, \
+ { MIBDECL(snmpProxies) }, \
+ { MIBDECL(snmpModules) }, \
+ { MIBDECL(snmpMIB) }, \
+ { MIBDECL(snmpMIBObjects) }, \
+ { MIBDECL(snmpTrap) }, \
+ { MIBDECL(snmpTrapOID) }, \
+ { MIBDECL(snmpTrapEnterprise) }, \
+ { MIBDECL(snmpTraps) }, \
+ { MIBDECL(coldStart) }, \
+ { MIBDECL(warmStart) }, \
+ { MIBDECL(linkDown) }, \
+ { MIBDECL(linkUp) }, \
+ { MIBDECL(authenticationFailure) }, \
+ { MIBDECL(egpNeighborLoss) }, \
+ \
+ { MIBDECL(framework) }, \
+ { MIBDECL(frameworkObjects) }, \
+ { MIBDECL(snmpEngine) }, \
+ { MIBDECL(snmpEngineID) }, \
+ { MIBDECL(snmpEngineBoots) }, \
+ { MIBDECL(snmpEngineTime) }, \
+ { MIBDECL(snmpEngineMaxMsgSize) }, \
+ { MIBDECL(usm) }, \
+ { MIBDECL(usmObjects) }, \
+ { MIBDECL(usmStats) }, \
+ { MIBDECL(usmStatsUnsupportedSecLevels) }, \
+ { MIBDECL(usmStatsNotInTimeWindow) }, \
+ { MIBDECL(usmStatsUnknownUserNames) }, \
+ { MIBDECL(usmStatsUnknownEngineId) }, \
+ { MIBDECL(usmStatsWrongDigests) }, \
+ { MIBDECL(usmStatsDecryptionErrors) }, \
+ \
+ { MIBDECL(host) }, \
+ { MIBDECL(hrSystem) }, \
+ { MIBDECL(hrSystemUptime) }, \
+ { MIBDECL(hrSystemDate) }, \
+ { MIBDECL(hrSystemInitialLoadDevice) }, \
+ { MIBDECL(hrSystemInitialLoadParameters) }, \
+ { MIBDECL(hrSystemNumUsers) }, \
+ { MIBDECL(hrSystemProcesses) }, \
+ { MIBDECL(hrSystemMaxProcesses) }, \
+ { MIBDECL(hrStorage) }, \
+ { MIBDECL(hrStorageTypes) }, \
+ { MIBDECL(hrMemorySize) }, \
+ { MIBDECL(hrStorageTable) }, \
+ { MIBDECL(hrStorageEntry) }, \
+ { MIBDECL(hrStorageIndex) }, \
+ { MIBDECL(hrStorageType) }, \
+ { MIBDECL(hrStorageDescr) }, \
+ { MIBDECL(hrStorageAllocationUnits) }, \
+ { MIBDECL(hrStorageSize) }, \
+ { MIBDECL(hrStorageUsed) }, \
+ { MIBDECL(hrStorageAllocationFailures) }, \
+ { MIBDECL(hrDevice) }, \
+ { MIBDECL(hrDeviceTypes) }, \
+ { MIBDECL(hrDeviceOther) }, \
+ { MIBDECL(hrDeviceUnknown) }, \
+ { MIBDECL(hrDeviceProcessor) }, \
+ { MIBDECL(hrDeviceNetwork) }, \
+ { MIBDECL(hrDevicePrinter) }, \
+ { MIBDECL(hrDeviceDiskStorage) }, \
+ { MIBDECL(hrDeviceVideo) }, \
+ { MIBDECL(hrDeviceAudio) }, \
+ { MIBDECL(hrDeviceCoprocessor) }, \
+ { MIBDECL(hrDeviceKeyboard) }, \
+ { MIBDECL(hrDeviceModem) }, \
+ { MIBDECL(hrDeviceParallelPort) }, \
+ { MIBDECL(hrDevicePointing) }, \
+ { MIBDECL(hrDeviceSerialPort) }, \
+ { MIBDECL(hrDeviceTape) }, \
+ { MIBDECL(hrDeviceClock) }, \
+ { MIBDECL(hrDeviceVolatileMemory) }, \
+ { MIBDECL(hrDeviceNonVolatileMemory) }, \
+ { MIBDECL(hrDeviceTable) }, \
+ { MIBDECL(hrDeviceEntry) }, \
+ { MIBDECL(hrDeviceIndex) }, \
+ { MIBDECL(hrDeviceType) }, \
+ { MIBDECL(hrDeviceDescr) }, \
+ { MIBDECL(hrDeviceID) }, \
+ { MIBDECL(hrDeviceStatus) }, \
+ { MIBDECL(hrDeviceErrors) }, \
+ { MIBDECL(hrProcessorTable) }, \
+ { MIBDECL(hrProcessorEntry) }, \
+ { MIBDECL(hrProcessorFrwID) }, \
+ { MIBDECL(hrProcessorLoad) }, \
+ { MIBDECL(hrSWRun) }, \
+ { MIBDECL(hrSWOSIndex) }, \
+ { MIBDECL(hrSWRunTable) }, \
+ { MIBDECL(hrSWRunEntry) }, \
+ { MIBDECL(hrSWRunIndex) }, \
+ { MIBDECL(hrSWRunName) }, \
+ { MIBDECL(hrSWRunID) }, \
+ { MIBDECL(hrSWRunPath) }, \
+ { MIBDECL(hrSWRunParameters) }, \
+ { MIBDECL(hrSWRunType) }, \
+ { MIBDECL(hrSWRunStatus) }, \
+ { MIBDECL(hrSWRunPerf) }, \
+ { MIBDECL(hrSWRunPerfTable) }, \
+ { MIBDECL(hrSWRunPerfEntry) }, \
+ { MIBDECL(hrSWRunPerfCPU) }, \
+ { MIBDECL(hrSWRunPerfMem) }, \
+ \
+ { MIBDECL(ifMIB) }, \
+ { MIBDECL(ifMIBObjects) }, \
+ { MIBDECL(ifXTable) }, \
+ { MIBDECL(ifXEntry) }, \
+ { MIBDECL(ifName) }, \
+ { MIBDECL(ifInMulticastPkts) }, \
+ { MIBDECL(ifInBroadcastPkts) }, \
+ { MIBDECL(ifOutMulticastPkts) }, \
+ { MIBDECL(ifOutBroadcastPkts) }, \
+ { MIBDECL(ifHCInOctets) }, \
+ { MIBDECL(ifHCInUcastPkts) }, \
+ { MIBDECL(ifHCInMulticastPkts) }, \
+ { MIBDECL(ifHCInBroadcastPkts) }, \
+ { MIBDECL(ifHCOutOctets) }, \
+ { MIBDECL(ifHCOutUcastPkts) }, \
+ { MIBDECL(ifHCOutMulticastPkts) }, \
+ { MIBDECL(ifHCOutBroadcastPkts) }, \
+ { MIBDECL(ifLinkUpDownTrapEnable) }, \
+ { MIBDECL(ifHighSpeed) }, \
+ { MIBDECL(ifPromiscuousMode) }, \
+ { MIBDECL(ifConnectorPresent) }, \
+ { MIBDECL(ifAlias) }, \
+ { MIBDECL(ifCounterDiscontinuityTime) }, \
+ { MIBDECL(ifStackTable) }, \
+ { MIBDECL(ifStackEntry) }, \
+ { MIBDECL(ifRcvAddressTable) }, \
+ { MIBDECL(ifRcvAddressEntry) }, \
+ { MIBDECL(ifRcvAddressStatus) }, \
+ { MIBDECL(ifRcvAddressType) }, \
+ { MIBDECL(ifStackLastChange) }, \
+ { MIBDECL(interfaces) }, \
+ { MIBDECL(ifNumber) }, \
+ { MIBDECL(ifTable) }, \
+ { MIBDECL(ifEntry) }, \
+ { MIBDECL(ifIndex) }, \
+ { MIBDECL(ifDescr) }, \
+ { MIBDECL(ifType) }, \
+ { MIBDECL(ifMtu) }, \
+ { MIBDECL(ifSpeed) }, \
+ { MIBDECL(ifPhysAddress) }, \
+ { MIBDECL(ifAdminStatus) }, \
+ { MIBDECL(ifOperStatus) }, \
+ { MIBDECL(ifLastChange) }, \
+ { MIBDECL(ifInOctets) }, \
+ { MIBDECL(ifInUcastPkts) }, \
+ { MIBDECL(ifInNUcastPkts) }, \
+ { MIBDECL(ifInDiscards) }, \
+ { MIBDECL(ifInErrors) }, \
+ { MIBDECL(ifInUnknownProtos) }, \
+ { MIBDECL(ifOutOctets) }, \
+ { MIBDECL(ifOutUcastPkts) }, \
+ { MIBDECL(ifOutNUcastPkts) }, \
+ { MIBDECL(ifOutDiscards) }, \
+ { MIBDECL(ifOutErrors) }, \
+ { MIBDECL(ifOutQLen) }, \
+ { MIBDECL(ifSpecific) }, \
+ \
+ { MIBDECL(dot1dBridge) }, \
+ { MIBDECL(dot1dBase) }, \
+ { MIBDECL(dot1dBaseBridgeAddress) }, \
+ { MIBDECL(dot1dBaseNumPorts) }, \
+ { MIBDECL(dot1dBaseType) }, \
+ { MIBDECL(dot1dBasePortTable) }, \
+ { MIBDECL(dot1dBasePortEntry) }, \
+ { MIBDECL(dot1dBasePort) }, \
+ { MIBDECL(dot1dBasePortIfIndex) }, \
+ { MIBDECL(dot1dBasePortCircuit) }, \
+ { MIBDECL(dot1dBasePortDelayExceededDiscards) },\
+ { MIBDECL(dot1dBasePortMtuExceededDiscards) }, \
+ { MIBDECL(dot1dStp) }, \
+ { MIBDECL(dot1dSr) }, \
+ { MIBDECL(dot1dTp) }, \
+ { MIBDECL(dot1dStatic) }, \
+ \
+ { MIBDECL(ibm) }, \
+ { MIBDECL(cmu) }, \
+ { MIBDECL(unix) }, \
+ { MIBDECL(ciscoSystems) }, \
+ { MIBDECL(hp) }, \
+ { MIBDECL(mit) }, \
+ { MIBDECL(nortelNetworks) }, \
+ { MIBDECL(sun) }, \
+ { MIBDECL(3com) }, \
+ { MIBDECL(synOptics) }, \
+ { MIBDECL(enterasys) }, \
+ { MIBDECL(sgi) }, \
+ { MIBDECL(apple) }, \
+ { MIBDECL(nasa) }, \
+ { MIBDECL(att) }, \
+ { MIBDECL(nokia) }, \
+ { MIBDECL(cern) }, \
+ { MIBDECL(oracle) }, \
+ { MIBDECL(motorola) }, \
+ { MIBDECL(ncr) }, \
+ { MIBDECL(ericsson) }, \
+ { MIBDECL(fsc) }, \
+ { MIBDECL(compaq) }, \
+ { MIBDECL(bmw) }, \
+ { MIBDECL(dell) }, \
+ { MIBDECL(iij) }, \
+ { MIBDECL(sandia) }, \
+ { MIBDECL(mercedesBenz) }, \
+ { MIBDECL(alteon) }, \
+ { MIBDECL(extremeNetworks) }, \
+ { MIBDECL(foundryNetworks) }, \
+ { MIBDECL(huawaiTechnology) }, \
+ { MIBDECL(ucDavis) }, \
+ { MIBDECL(freeBSD) }, \
+ { MIBDECL(checkPoint) }, \
+ { MIBDECL(juniper) }, \
+ { MIBDECL(printerWorkingGroup) }, \
+ { MIBDECL(audi) }, \
+ { MIBDECL(volkswagen) }, \
+ { MIBDECL(genua) }, \
+ { MIBDECL(amazon) }, \
+ { MIBDECL(force10Networks) }, \
+ { MIBDECL(vMware) }, \
+ { MIBDECL(alcatelLucent) }, \
+ { MIBDECL(snom) }, \
+ { MIBDECL(netSNMP) }, \
+ { MIBDECL(netflix) }, \
+ { MIBDECL(google) }, \
+ { MIBDECL(f5Networks) }, \
+ { MIBDECL(bsws) }, \
+ { MIBDECL(sFlow) }, \
+ { MIBDECL(microSystems) }, \
+ { MIBDECL(paloAltoNetworks) }, \
+ { MIBDECL(h3c) }, \
+ { MIBDECL(vantronix) }, \
+ { MIBDECL(netBSD) }, \
+ { MIBDECL(openBSD) }, \
+ { MIBDECL(nicira) }, \
+ { MIBDECL(esdenera) }, \
+ { MIBDECL(arcaTrust) }, \
+ \
+ { MIBDECL(ucdExperimental) }, \
+ { MIBDECL(ucdDiskIOMIB) }, \
+ { MIBDECL(diskIOTable) }, \
+ { MIBDECL(diskIOEntry) }, \
+ { MIBDECL(diskIOIndex) }, \
+ { MIBDECL(diskIODevice) }, \
+ { MIBDECL(diskIONRead) }, \
+ { MIBDECL(diskIONWritten) }, \
+ { MIBDECL(diskIOReads) }, \
+ { MIBDECL(diskIOWrites) }, \
+ { MIBDECL(diskIONReadX) }, \
+ { MIBDECL(diskIONWrittenX) }, \
+ \
+ { MIBDECL(pfMIBObjects) }, \
+ { MIBDECL(pfInfo) }, \
+ { MIBDECL(pfRunning) }, \
+ { MIBDECL(pfRuntime) }, \
+ { MIBDECL(pfDebug) }, \
+ { MIBDECL(pfHostid) }, \
+ { MIBDECL(pfCounters) }, \
+ { MIBDECL(pfCntMatch) }, \
+ { MIBDECL(pfCntBadOffset) }, \
+ { MIBDECL(pfCntFragment) }, \
+ { MIBDECL(pfCntShort) }, \
+ { MIBDECL(pfCntNormalize) }, \
+ { MIBDECL(pfCntMemory) }, \
+ { MIBDECL(pfCntTimestamp) }, \
+ { MIBDECL(pfCntCongestion) }, \
+ { MIBDECL(pfCntIpOptions) }, \
+ { MIBDECL(pfCntProtoCksum) }, \
+ { MIBDECL(pfCntStateMismatch) }, \
+ { MIBDECL(pfCntStateInsert) }, \
+ { MIBDECL(pfCntStateLimit) }, \
+ { MIBDECL(pfCntSrcLimit) }, \
+ { MIBDECL(pfCntSynproxy) }, \
+ { MIBDECL(pfCntTranslate) }, \
+ { MIBDECL(pfCntNoRoute) }, \
+ { MIBDECL(pfStateTable) }, \
+ { MIBDECL(pfStateCount) }, \
+ { MIBDECL(pfStateSearches) }, \
+ { MIBDECL(pfStateInserts) }, \
+ { MIBDECL(pfStateRemovals) }, \
+ { MIBDECL(pfLogInterface) }, \
+ { MIBDECL(pfLogIfName) }, \
+ { MIBDECL(pfLogIfIpBytesIn) }, \
+ { MIBDECL(pfLogIfIpBytesOut) }, \
+ { MIBDECL(pfLogIfIpPktsInPass) }, \
+ { MIBDECL(pfLogIfIpPktsInDrop) }, \
+ { MIBDECL(pfLogIfIpPktsOutPass) }, \
+ { MIBDECL(pfLogIfIpPktsOutDrop) }, \
+ { MIBDECL(pfLogIfIp6BytesIn) }, \
+ { MIBDECL(pfLogIfIp6BytesOut) }, \
+ { MIBDECL(pfLogIfIp6PktsInPass) }, \
+ { MIBDECL(pfLogIfIp6PktsInDrop) }, \
+ { MIBDECL(pfLogIfIp6PktsOutPass) }, \
+ { MIBDECL(pfLogIfIp6PktsOutDrop) }, \
+ { MIBDECL(pfSrcTracking) }, \
+ { MIBDECL(pfSrcTrackCount) }, \
+ { MIBDECL(pfSrcTrackSearches) }, \
+ { MIBDECL(pfSrcTrackInserts) }, \
+ { MIBDECL(pfSrcTrackRemovals) }, \
+ { MIBDECL(pfLimits) }, \
+ { MIBDECL(pfLimitStates) }, \
+ { MIBDECL(pfLimitSourceNodes) }, \
+ { MIBDECL(pfLimitFragments) }, \
+ { MIBDECL(pfLimitMaxTables) }, \
+ { MIBDECL(pfLimitMaxTableEntries) }, \
+ { MIBDECL(pfTimeouts) }, \
+ { MIBDECL(pfTimeoutTcpFirst) }, \
+ { MIBDECL(pfTimeoutTcpOpening) }, \
+ { MIBDECL(pfTimeoutTcpEstablished) }, \
+ { MIBDECL(pfTimeoutTcpClosing) }, \
+ { MIBDECL(pfTimeoutTcpFinWait) }, \
+ { MIBDECL(pfTimeoutTcpClosed) }, \
+ { MIBDECL(pfTimeoutUdpFirst) }, \
+ { MIBDECL(pfTimeoutUdpSingle) }, \
+ { MIBDECL(pfTimeoutUdpMultiple) }, \
+ { MIBDECL(pfTimeoutIcmpFirst) }, \
+ { MIBDECL(pfTimeoutIcmpError) }, \
+ { MIBDECL(pfTimeoutOtherFirst) }, \
+ { MIBDECL(pfTimeoutOtherSingle) }, \
+ { MIBDECL(pfTimeoutOtherMultiple) }, \
+ { MIBDECL(pfTimeoutFragment) }, \
+ { MIBDECL(pfTimeoutInterval) }, \
+ { MIBDECL(pfTimeoutAdaptiveStart) }, \
+ { MIBDECL(pfTimeoutAdaptiveEnd) }, \
+ { MIBDECL(pfTimeoutSrcTrack) }, \
+ { MIBDECL(pfInterfaces) }, \
+ { MIBDECL(pfIfNumber) }, \
+ { MIBDECL(pfIfTable) }, \
+ { MIBDECL(pfIfEntry) }, \
+ { MIBDECL(pfIfIndex) }, \
+ { MIBDECL(pfIfDescr) }, \
+ { MIBDECL(pfIfType) }, \
+ { MIBDECL(pfIfRefs) }, \
+ { MIBDECL(pfIfRules) }, \
+ { MIBDECL(pfIfIn4PassPkts) }, \
+ { MIBDECL(pfIfIn4PassBytes) }, \
+ { MIBDECL(pfIfIn4BlockPkts) }, \
+ { MIBDECL(pfIfIn4BlockBytes) }, \
+ { MIBDECL(pfIfOut4PassPkts) }, \
+ { MIBDECL(pfIfOut4PassBytes) }, \
+ { MIBDECL(pfIfOut4BlockPkts) }, \
+ { MIBDECL(pfIfOut4BlockBytes) }, \
+ { MIBDECL(pfIfIn6PassPkts) }, \
+ { MIBDECL(pfIfIn6PassBytes) }, \
+ { MIBDECL(pfIfIn6BlockPkts) }, \
+ { MIBDECL(pfIfIn6BlockBytes) }, \
+ { MIBDECL(pfIfOut6PassPkts) }, \
+ { MIBDECL(pfIfOut6PassBytes) }, \
+ { MIBDECL(pfIfOut6BlockPkts) }, \
+ { MIBDECL(pfIfOut6BlockBytes) }, \
+ { MIBDECL(pfTables) }, \
+ { MIBDECL(pfTblNumber) }, \
+ { MIBDECL(pfTblTable) }, \
+ { MIBDECL(pfTblEntry) }, \
+ { MIBDECL(pfTblIndex) }, \
+ { MIBDECL(pfTblName) }, \
+ { MIBDECL(pfTblAddresses) }, \
+ { MIBDECL(pfTblAnchorRefs) }, \
+ { MIBDECL(pfTblRuleRefs) }, \
+ { MIBDECL(pfTblEvalsMatch) }, \
+ { MIBDECL(pfTblEvalsNoMatch) }, \
+ { MIBDECL(pfTblInPassPkts) }, \
+ { MIBDECL(pfTblInPassBytes) }, \
+ { MIBDECL(pfTblInBlockPkts) }, \
+ { MIBDECL(pfTblInBlockBytes) }, \
+ { MIBDECL(pfTblInXPassPkts) }, \
+ { MIBDECL(pfTblInXPassBytes) }, \
+ { MIBDECL(pfTblOutPassPkts) }, \
+ { MIBDECL(pfTblOutPassBytes) }, \
+ { MIBDECL(pfTblOutBlockPkts) }, \
+ { MIBDECL(pfTblOutBlockBytes) }, \
+ { MIBDECL(pfTblOutXPassPkts) }, \
+ { MIBDECL(pfTblOutXPassBytes) }, \
+ { MIBDECL(pfTblStatsCleared) }, \
+ { MIBDECL(pfTblInMatchPkts) }, \
+ { MIBDECL(pfTblInMatchBytes) }, \
+ { MIBDECL(pfTblOutMatchPkts) }, \
+ { MIBDECL(pfTblOutMatchBytes) }, \
+ { MIBDECL(pfTblAddrTable) }, \
+ { MIBDECL(pfTblAddrEntry) }, \
+ { MIBDECL(pfTblAddrTblIndex) }, \
+ { MIBDECL(pfTblAddrNet) }, \
+ { MIBDECL(pfTblAddrMask) }, \
+ { MIBDECL(pfTblAddrCleared) }, \
+ { MIBDECL(pfTblAddrInBlockPkts) }, \
+ { MIBDECL(pfTblAddrInBlockBytes) }, \
+ { MIBDECL(pfTblAddrInPassPkts) }, \
+ { MIBDECL(pfTblAddrInPassBytes) }, \
+ { MIBDECL(pfTblAddrOutBlockPkts) }, \
+ { MIBDECL(pfTblAddrOutBlockBytes) }, \
+ { MIBDECL(pfTblAddrOutPassPkts) }, \
+ { MIBDECL(pfTblAddrOutPassBytes) }, \
+ { MIBDECL(pfTblAddrInMatchPkts) }, \
+ { MIBDECL(pfTblAddrInMatchBytes) }, \
+ { MIBDECL(pfTblAddrOutMatchPkts) }, \
+ { MIBDECL(pfTblAddrOutMatchBytes) }, \
+ { MIBDECL(pfLabels) }, \
+ { MIBDECL(pfLabelNumber) }, \
+ { MIBDECL(pfLabelTable) }, \
+ { MIBDECL(pfLabelEntry) }, \
+ { MIBDECL(pfLabelIndex) }, \
+ { MIBDECL(pfLabelName) }, \
+ { MIBDECL(pfLabelEvals) }, \
+ { MIBDECL(pfLabelPkts) }, \
+ { MIBDECL(pfLabelBytes) }, \
+ { MIBDECL(pfLabelInPkts) }, \
+ { MIBDECL(pfLabelInBytes) }, \
+ { MIBDECL(pfLabelOutPkts) }, \
+ { MIBDECL(pfLabelOutBytes) }, \
+ { MIBDECL(pfLabelTotalStates) }, \
+ { MIBDECL(pfsyncStats) }, \
+ { MIBDECL(pfsyncIpPktsRecv) }, \
+ { MIBDECL(pfsyncIp6PktsRecv) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadInterface) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadTtl) }, \
+ { MIBDECL(pfsyncPktShorterThanHeader) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadVersion) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadAction) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadLength) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadAuth) }, \
+ { MIBDECL(pfsyncPktDiscardsForStaleState) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadValues) }, \
+ { MIBDECL(pfsyncPktDiscardsForBadState) }, \
+ { MIBDECL(pfsyncIpPktsSent) }, \
+ { MIBDECL(pfsyncIp6PktsSent) }, \
+ { MIBDECL(pfsyncNoMemory) }, \
+ { MIBDECL(pfsyncOutputErrors) }, \
+ { MIBDECL(sensorsMIBObjects) }, \
+ { MIBDECL(relaydMIBObjects) }, \
+ { MIBDECL(relaydHostTrap) }, \
+ { MIBDECL(relaydHostTrapHostName) }, \
+ { MIBDECL(relaydHostTrapUp) }, \
+ { MIBDECL(relaydHostTrapLastUp) }, \
+ { MIBDECL(relaydHostTrapUpCount) }, \
+ { MIBDECL(relaydHostTrapCheckCount) }, \
+ { MIBDECL(relaydHostTrapTableName) }, \
+ { MIBDECL(relaydHostTrapTableUp) }, \
+ { MIBDECL(relaydHostTrapRetry) }, \
+ { MIBDECL(relaydHostTrapRetryCount) }, \
+ { MIBDECL(sensors) }, \
+ { MIBDECL(sensorNumber) }, \
+ { MIBDECL(sensorTable) }, \
+ { MIBDECL(sensorEntry) }, \
+ { MIBDECL(sensorIndex) }, \
+ { MIBDECL(sensorDescr) }, \
+ { MIBDECL(sensorType) }, \
+ { MIBDECL(sensorDevice) }, \
+ { MIBDECL(sensorValue) }, \
+ { MIBDECL(sensorUnits) }, \
+ { MIBDECL(sensorStatus) }, \
+ { MIBDECL(memMIBObjects) }, \
+ { MIBDECL(memMIBVersion) }, \
+ { MIBDECL(memIfTable) }, \
+ { MIBDECL(memIfEntry) }, \
+ { MIBDECL(memIfName) }, \
+ { MIBDECL(memIfLiveLocks) }, \
+ { MIBDECL(carpMIBObjects) }, \
+ { MIBDECL(carpSysctl) }, \
+ { MIBDECL(carpAllow) }, \
+ { MIBDECL(carpPreempt) }, \
+ { MIBDECL(carpLog) }, \
+ { MIBDECL(carpIf) }, \
+ { MIBDECL(carpIfNumber) }, \
+ { MIBDECL(carpIfTable) }, \
+ { MIBDECL(carpIfEntry) }, \
+ { MIBDECL(carpIfIndex) }, \
+ { MIBDECL(carpIfDescr) }, \
+ { MIBDECL(carpIfVhid) }, \
+ { MIBDECL(carpIfDev) }, \
+ { MIBDECL(carpIfAdvbase) }, \
+ { MIBDECL(carpIfAdvskew) }, \
+ { MIBDECL(carpIfState) }, \
+ { MIBDECL(carpStats) }, \
+ { MIBDECL(carpIpPktsRecv) }, \
+ { MIBDECL(carpIp6PktsRecv) }, \
+ { MIBDECL(carpPktDiscardsBadIface) }, \
+ { MIBDECL(carpPktDiscardsBadTtl) }, \
+ { MIBDECL(carpPktShorterThanHdr) }, \
+ { MIBDECL(carpDiscardsBadCksum) }, \
+ { MIBDECL(carpDiscardsBadVersion) }, \
+ { MIBDECL(carpDiscardsTooShort) }, \
+ { MIBDECL(carpDiscardsBadAuth) }, \
+ { MIBDECL(carpDiscardsBadVhid) }, \
+ { MIBDECL(carpDiscardsBadAddrList) }, \
+ { MIBDECL(carpIpPktsSent) }, \
+ { MIBDECL(carpIp6PktsSent) }, \
+ { MIBDECL(carpNoMemory) }, \
+ { MIBDECL(carpTransitionsToMaster) }, \
+ { MIBDECL(carpGroupTable) }, \
+ { MIBDECL(carpGroupEntry) }, \
+ { MIBDECL(carpGroupName) }, \
+ { MIBDECL(carpGroupDemote) }, \
+ { MIBDECL(localSystem) }, \
+ { MIBDECL(localTest) }, \
+ \
+ { MIBDECL(ipMIB) }, \
+ { MIBDECL(ipForwarding) }, \
+ { MIBDECL(ipDefaultTTL) }, \
+ { MIBDECL(ipInReceives) }, \
+ { MIBDECL(ipInHdrErrors) }, \
+ { MIBDECL(ipInAddrErrors) }, \
+ { MIBDECL(ipForwDatagrams) }, \
+ { MIBDECL(ipInUnknownProtos) }, \
+ { MIBDECL(ipInDiscards) }, \
+ { MIBDECL(ipInDelivers) }, \
+ { MIBDECL(ipOutRequests) }, \
+ { MIBDECL(ipOutDiscards) }, \
+ { MIBDECL(ipOutNoRoutes) }, \
+ { MIBDECL(ipReasmTimeout) }, \
+ { MIBDECL(ipReasmReqds) }, \
+ { MIBDECL(ipReasmOKs) }, \
+ { MIBDECL(ipReasmFails) }, \
+ { MIBDECL(ipFragOKs) }, \
+ { MIBDECL(ipFragFails) }, \
+ { MIBDECL(ipFragCreates) }, \
+ { MIBDECL(ipRoutingDiscards) }, \
+ { MIBDECL(ipAddrTable) }, \
+ { MIBDECL(ipAddrEntry) }, \
+ { MIBDECL(ipAdEntAddr) }, \
+ { MIBDECL(ipAdEntIfIndex) }, \
+ { MIBDECL(ipAdEntNetMask) }, \
+ { MIBDECL(ipAdEntBcastAddr) }, \
+ { MIBDECL(ipAdEntReasmMaxSize) }, \
+ { MIBDECL(ipNetToMediaTable) }, \
+ { MIBDECL(ipNetToMediaEntry) }, \
+ { MIBDECL(ipNetToMediaIfIndex) }, \
+ { MIBDECL(ipNetToMediaPhysAddress) }, \
+ { MIBDECL(ipNetToMediaNetAddress) }, \
+ { MIBDECL(ipNetToMediaType) }, \
+ \
+ { MIBDECL(ipfMIB) }, \
+ { MIBDECL(ipfInetCidrRouteNumber) }, \
+ { MIBDECL(ipfInetCidrRouteTable) }, \
+ { MIBDECL(ipfInetCidrRouteEntry) }, \
+ { MIBDECL(ipfRouteEntIfIndex) }, \
+ { MIBDECL(ipfRouteEntType) }, \
+ { MIBDECL(ipfRouteEntProto) }, \
+ { MIBDECL(ipfRouteEntAge) }, \
+ { MIBDECL(ipfRouteEntNextHopAS) }, \
+ { MIBDECL(ipfRouteEntRouteMetric1) }, \
+ { MIBDECL(ipfRouteEntRouteMetric2) }, \
+ { MIBDECL(ipfRouteEntRouteMetric3) }, \
+ { MIBDECL(ipfRouteEntRouteMetric4) }, \
+ { MIBDECL(ipfRouteEntRouteMetric5) }, \
+ { MIBDECL(ipfRouteEntStatus) }, \
+ { MIBEND } \
+}
+
+void mib_init(void);
+
+#endif /* SNMPD_MIB_H */
diff --git a/usr.bin/snmp/smi.c b/usr.bin/snmp/smi.c
new file mode 100644
index 00000000000..8c601df3244
--- /dev/null
+++ b/usr.bin/snmp/smi.c
@@ -0,0 +1,627 @@
+/* $OpenBSD: smi.c,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
+ * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/limits.h>
+#include <sys/tree.h>
+#include <sys/queue.h>
+
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+#include "ber.h"
+#include "mib.h"
+#include "snmp.h"
+#include "smi.h"
+
+#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
+
+int smi_oid_cmp(struct oid *, struct oid *);
+int smi_key_cmp(struct oid *, struct oid *);
+struct oid * smi_findkey(char *);
+
+RB_HEAD(oidtree, oid);
+RB_PROTOTYPE(oidtree, oid, o_element, smi_oid_cmp)
+struct oidtree smi_oidtree;
+
+RB_HEAD(keytree, oid);
+RB_PROTOTYPE(keytree, oid, o_keyword, smi_key_cmp)
+struct keytree smi_keytree;
+
+int
+smi_init(void)
+{
+ /* Initialize the Structure of Managed Information (SMI) */
+ RB_INIT(&smi_oidtree);
+ mib_init();
+ return (0);
+}
+
+void
+smi_debug_elements(struct ber_element *root)
+{
+ static int indent = 0;
+ char *value;
+ int constructed;
+
+ /* calculate lengths */
+ ber_calc_len(root);
+
+ switch (root->be_encoding) {
+ case BER_TYPE_SEQUENCE:
+ case BER_TYPE_SET:
+ constructed = root->be_encoding;
+ break;
+ default:
+ constructed = 0;
+ break;
+ }
+
+ fprintf(stderr, "%*slen %lu ", indent, "", root->be_len);
+ switch (root->be_class) {
+ case BER_CLASS_UNIVERSAL:
+ fprintf(stderr, "class: universal(%u) type: ", root->be_class);
+ switch (root->be_type) {
+ case BER_TYPE_EOC:
+ fprintf(stderr, "end-of-content");
+ break;
+ case BER_TYPE_BOOLEAN:
+ fprintf(stderr, "boolean");
+ break;
+ case BER_TYPE_INTEGER:
+ fprintf(stderr, "integer");
+ break;
+ case BER_TYPE_BITSTRING:
+ fprintf(stderr, "bit-string");
+ break;
+ case BER_TYPE_OCTETSTRING:
+ fprintf(stderr, "octet-string");
+ break;
+ case BER_TYPE_NULL:
+ fprintf(stderr, "null");
+ break;
+ case BER_TYPE_OBJECT:
+ fprintf(stderr, "object");
+ break;
+ case BER_TYPE_ENUMERATED:
+ fprintf(stderr, "enumerated");
+ break;
+ case BER_TYPE_SEQUENCE:
+ fprintf(stderr, "sequence");
+ break;
+ case BER_TYPE_SET:
+ fprintf(stderr, "set");
+ break;
+ }
+ break;
+ case BER_CLASS_APPLICATION:
+ fprintf(stderr, "class: application(%u) type: ",
+ root->be_class);
+ switch (root->be_type) {
+ case SNMP_T_IPADDR:
+ fprintf(stderr, "ipaddr");
+ break;
+ case SNMP_T_COUNTER32:
+ fprintf(stderr, "counter32");
+ break;
+ case SNMP_T_GAUGE32:
+ fprintf(stderr, "gauge32");
+ break;
+ case SNMP_T_TIMETICKS:
+ fprintf(stderr, "timeticks");
+ break;
+ case SNMP_T_OPAQUE:
+ fprintf(stderr, "opaque");
+ break;
+ case SNMP_T_COUNTER64:
+ fprintf(stderr, "counter64");
+ break;
+ }
+ break;
+ case BER_CLASS_CONTEXT:
+ fprintf(stderr, "class: context(%u) type: ",
+ root->be_class);
+ switch (root->be_type) {
+ case SNMP_C_GETREQ:
+ fprintf(stderr, "getreq");
+ break;
+ case SNMP_C_GETNEXTREQ:
+ fprintf(stderr, "nextreq");
+ break;
+ case SNMP_C_GETRESP:
+ fprintf(stderr, "getresp");
+ break;
+ case SNMP_C_SETREQ:
+ fprintf(stderr, "setreq");
+ break;
+ case SNMP_C_TRAP:
+ fprintf(stderr, "trap");
+ break;
+ case SNMP_C_GETBULKREQ:
+ fprintf(stderr, "getbulkreq");
+ break;
+ case SNMP_C_INFORMREQ:
+ fprintf(stderr, "informreq");
+ break;
+ case SNMP_C_TRAPV2:
+ fprintf(stderr, "trapv2");
+ break;
+ case SNMP_C_REPORT:
+ fprintf(stderr, "report");
+ break;
+ }
+ break;
+ case BER_CLASS_PRIVATE:
+ fprintf(stderr, "class: private(%u) type: ", root->be_class);
+ break;
+ default:
+ fprintf(stderr, "class: <INVALID>(%u) type: ", root->be_class);
+ break;
+ }
+ fprintf(stderr, "(%u) encoding %u ",
+ root->be_type, root->be_encoding);
+
+ if ((value = smi_print_element(root, 1, smi_os_default, smi_oidl_numeric)) == NULL)
+ goto invalid;
+
+ switch (root->be_encoding) {
+ case BER_TYPE_BOOLEAN:
+ fprintf(stderr, "%s", value);
+ break;
+ case BER_TYPE_INTEGER:
+ case BER_TYPE_ENUMERATED:
+ fprintf(stderr, "value %s", value);
+ break;
+ case BER_TYPE_BITSTRING:
+ fprintf(stderr, "hexdump %s", value);
+ break;
+ case BER_TYPE_OBJECT:
+ fprintf(stderr, "oid %s", value);
+ break;
+ case BER_TYPE_OCTETSTRING:
+ if (root->be_class == BER_CLASS_APPLICATION &&
+ root->be_type == SNMP_T_IPADDR) {
+ fprintf(stderr, "addr %s", value);
+ } else {
+ fprintf(stderr, "string %s", value);
+ }
+ break;
+ case BER_TYPE_NULL: /* no payload */
+ case BER_TYPE_EOC:
+ case BER_TYPE_SEQUENCE:
+ case BER_TYPE_SET:
+ default:
+ fprintf(stderr, "%s", value);
+ break;
+ }
+
+ invalid:
+ if (value == NULL)
+ fprintf(stderr, "<INVALID>");
+ else
+ free(value);
+ fprintf(stderr, "\n");
+
+ if (constructed)
+ root->be_encoding = constructed;
+
+ if (constructed && root->be_sub) {
+ indent += 2;
+ smi_debug_elements(root->be_sub);
+ indent -= 2;
+ }
+ if (root->be_next)
+ smi_debug_elements(root->be_next);
+}
+
+char *
+smi_print_element(struct ber_element *root, int print_hint,
+ enum smi_output_string output_string, enum smi_oid_lookup lookup)
+{
+ char *str = NULL, *buf, *p;
+ size_t len, i;
+ long long v, ticks;
+ int d;
+ int is_hex = 0;
+ struct ber_oid o;
+ char strbuf[BUFSIZ];
+ char *hint;
+ int days, hours, min, sec, csec;
+
+ switch (root->be_encoding) {
+ case BER_TYPE_BOOLEAN:
+ if (ber_get_boolean(root, &d) == -1)
+ goto fail;
+ if (print_hint) {
+ if (asprintf(&str, "INTEGER: %s(%d)",
+ d ? "true" : "false", d) == -1)
+ goto fail;
+ }
+ else
+ if (asprintf(&str, "%s", d ? "true" : "false") == -1)
+ goto fail;
+ break;
+ case BER_TYPE_INTEGER:
+ case BER_TYPE_ENUMERATED:
+ if (ber_get_integer(root, &v) == -1)
+ goto fail;
+ if (root->be_class == BER_CLASS_APPLICATION &&
+ root->be_type == SNMP_T_TIMETICKS) {
+ ticks = v;
+ days = ticks / (60 * 60 * 24 * 100);
+ ticks %= (60 * 60 * 24 * 100);
+ hours = ticks / (60 * 60 * 100);
+ ticks %= (60 * 60 * 100);
+ min = ticks / (60 * 100);
+ ticks %= (60 * 100);
+ sec = ticks / 100;
+ ticks %= 100;
+ csec = ticks;
+
+ if (print_hint) {
+ if (days == 0) {
+ if (asprintf(&str,
+ "Timeticks: (%lld) "
+ "%d:%02d:%02d.%02d",
+ v, hours, min, sec, csec) == -1)
+ goto fail;
+ } else if (days == 1) {
+ if (asprintf(&str,
+ "Timeticks: (%lld) "
+ "1 day %d:%02d:%02d.%02d",
+ v, hours, min, sec, csec) == -1)
+ goto fail;
+ } else {
+ if (asprintf(&str,
+ "Timeticks: (%lld) "
+ "%d day %d:%02d:%02d.%02d",
+ v, days, hours, min, sec, csec) ==
+ -1)
+ goto fail;
+ }
+ } else {
+ if (days == 0) {
+ if (asprintf(&str, "%d:%02d:%02d.%02d",
+ hours, min, sec, csec) == -1)
+ goto fail;
+ } else if (days == 1) {
+ if (asprintf(&str,
+ "1 day %d:%02d:%02d.%02d",
+ hours, min, sec, csec) == -1)
+ goto fail;
+ } else {
+ if (asprintf(&str,
+ "%d day %d:%02d:%02d.%02d",
+ days, hours, min, sec, csec) == -1)
+ goto fail;
+ }
+ }
+ break;
+ }
+ hint = "INTEGER: ";
+ if (root->be_class == BER_CLASS_APPLICATION) {
+ if (root->be_type == SNMP_T_COUNTER32)
+ hint = "Counter32: ";
+ else if (root->be_type == SNMP_T_GAUGE32)
+ hint = "Gauge32: ";
+ else if (root->be_type == SNMP_T_OPAQUE)
+ hint = "Opaque: ";
+ else if (root->be_type == SNMP_T_COUNTER64)
+ hint = "Counter64: ";
+ }
+ if (asprintf(&str, "%s%lld", print_hint ? hint : "", v)
+ == -1)
+ goto fail;
+ break;
+ case BER_TYPE_BITSTRING:
+ if (ber_get_bitstring(root, (void *)&buf, &len) == -1)
+ goto fail;
+ if ((str = calloc(1, len * 2 + 1 + sizeof("BITS: "))) == NULL)
+ goto fail;
+ p = str;
+ if (print_hint) {
+ strlcpy(str, "BITS: ", sizeof(str));
+ p += sizeof("BITS: ");
+ }
+ for (i = 0; i < len; i++) {
+ snprintf(p, 3, "%02x", buf[i]);
+ p += 2;
+ }
+ break;
+ case BER_TYPE_OBJECT:
+ if (ber_get_oid(root, &o) == -1)
+ goto fail;
+ if (asprintf(&str, "%s%s",
+ print_hint ? "OID: " : "",
+ smi_oid2string(&o, strbuf, sizeof(strbuf), lookup)) == -1)
+ goto fail;
+ break;
+ case BER_TYPE_OCTETSTRING:
+ if (ber_get_string(root, &buf) == -1)
+ goto fail;
+ if (root->be_class == BER_CLASS_APPLICATION &&
+ root->be_type == SNMP_T_IPADDR) {
+ if (asprintf(&str, "%s%s",
+ print_hint ? "IpAddress: " : "",
+ inet_ntoa(*(struct in_addr *)buf)) == -1)
+ goto fail;
+ } else if (root->be_class == BER_CLASS_CONTEXT &&
+ root->be_type == BER_TYPE_EOC) {
+ str = strdup("No Such Object available on this agent at this OID");
+
+ }else {
+ for (i = 0; i < root->be_len; i++) {
+ if (!isprint(buf[i])) {
+ if (output_string == smi_os_default)
+ output_string = smi_os_hex;
+ else if (output_string == smi_os_ascii)
+ is_hex = 1;
+ break;
+ }
+ }
+ /*
+ * hex is 3 * n (2 digits + n - 1 spaces + NUL-byte)
+ * ascii can be max (2 * n) + 2 quotes + NUL-byte
+ */
+ if ((p = str = reallocarray(NULL,
+ output_string == smi_os_hex ? 3 : 2,
+ root->be_len + 2)) == NULL)
+ goto fail;
+ if (is_hex)
+ *str++ = '"';
+ for (i = 0; i < root->be_len; i++) {
+ switch (output_string) {
+ case smi_os_default:
+ /* FALLTHROUGH */
+ case smi_os_ascii:
+ /*
+ * There's probably more edgecases here,
+ * not fully investigated
+ */
+ if (is_hex && buf[i] == '\\')
+ *str++ = '\\';
+ *str++ = isprint(buf[i]) ? buf[i] : '.';
+ break;
+ case smi_os_hex:
+ sprintf(str, "%s%02hhX",
+ i == 0 ? "" :
+ i % 16 == 0 ? "\n" : " ", buf[i]);
+ str += i == 0 ? 2 : 3;
+ break;
+ }
+ }
+ if (is_hex)
+ *str++ = '"';
+ *str = '\0';
+ str = NULL;
+ if (asprintf(&str, "%s%s",
+ print_hint ?
+ output_string == smi_os_hex ? "Hex-STRING: " :
+ "STRING: " :
+ "", p) == -1) {
+ free(p);
+ goto fail;
+ }
+ free(p);
+ }
+ break;
+ case BER_TYPE_NULL: /* no payload */
+ case BER_TYPE_EOC:
+ case BER_TYPE_SEQUENCE:
+ case BER_TYPE_SET:
+ default:
+ str = strdup("");
+ break;
+ }
+
+ return (str);
+
+ fail:
+ free(str);
+ return (NULL);
+}
+
+int
+smi_string2oid(const char *oidstr, struct ber_oid *o)
+{
+ char *sp, *p, str[BUFSIZ];
+ const char *errstr;
+ struct oid *oid;
+ struct ber_oid ko;
+
+ if (strlcpy(str, oidstr, sizeof(str)) >= sizeof(str))
+ return (-1);
+ bzero(o, sizeof(*o));
+
+ /*
+ * Parse OID strings in the common form n.n.n or n-n-n.
+ * Based on ber_string2oid with additional support for symbolic names.
+ */
+ p = sp = str[0] == '.' ? str + 1 : str;
+ for (; p != NULL; sp = p) {
+ if ((p = strpbrk(p, ".-")) != NULL)
+ *p++ = '\0';
+ if ((oid = smi_findkey(sp)) != NULL) {
+ bcopy(&oid->o_id, &ko, sizeof(ko));
+ if (o->bo_n && ber_oid_cmp(o, &ko) != 2)
+ return (-1);
+ bcopy(&ko, o, sizeof(*o));
+ errstr = NULL;
+ } else {
+ o->bo_id[o->bo_n++] =
+ strtonum(sp, 0, UINT_MAX, &errstr);
+ }
+ if (errstr || o->bo_n > BER_MAX_OID_LEN)
+ return (-1);
+ }
+
+ return (0);
+}
+
+unsigned int
+smi_application(struct ber_element *elm)
+{
+ if (elm->be_class != BER_CLASS_APPLICATION)
+ return (BER_TYPE_OCTETSTRING);
+
+ switch (elm->be_type) {
+ case SNMP_T_IPADDR:
+ return (BER_TYPE_OCTETSTRING);
+ case SNMP_T_COUNTER32:
+ case SNMP_T_GAUGE32:
+ case SNMP_T_TIMETICKS:
+ case SNMP_T_OPAQUE:
+ case SNMP_T_COUNTER64:
+ return (BER_TYPE_INTEGER);
+ default:
+ break;
+ }
+ return (BER_TYPE_OCTETSTRING);
+
+}
+
+char *
+smi_oid2string(struct ber_oid *o, char *buf, size_t len,
+ enum smi_oid_lookup lookup)
+{
+ char str[256];
+ struct oid *value, key;
+ size_t i;
+
+ bzero(buf, len);
+ bzero(&key, sizeof(key));
+ bcopy(o, &key.o_id, sizeof(struct ber_oid));
+ key.o_flags |= OID_KEY; /* do not match wildcards */
+
+ for (i = 0; i < o->bo_n; i++) {
+ key.o_oidlen = i + 1;
+ if (lookup != smi_oidl_numeric &&
+ (value = RB_FIND(oidtree, &smi_oidtree, &key)) != NULL) {
+ snprintf(str, sizeof(str), "%s", value->o_name);
+ if (lookup == smi_oidl_short && i + 1 < o->bo_n) {
+ key.o_oidlen = i + 2;
+ if (RB_FIND(oidtree, &smi_oidtree, &key) != NULL)
+ continue;
+ }
+ } else
+ snprintf(str, sizeof(str), "%d", key.o_oid[i]);
+ if (*buf != '\0' || i == 0)
+ strlcat(buf, ".", len);
+ strlcat(buf, str, len);
+ }
+
+ return (buf);
+}
+
+void
+smi_mibtree(struct oid *oids)
+{
+ struct oid *oid, *decl;
+ size_t i;
+
+ for (i = 0; oids[i].o_oid[0] != 0; i++) {
+ oid = &oids[i];
+ if (oid->o_name != NULL) {
+ RB_INSERT(oidtree, &smi_oidtree, oid);
+ RB_INSERT(keytree, &smi_keytree, oid);
+ continue;
+ }
+ decl = RB_FIND(oidtree, &smi_oidtree, oid);
+ decl->o_flags = oid->o_flags;
+ decl->o_get = oid->o_get;
+ decl->o_set = oid->o_set;
+ decl->o_table = oid->o_table;
+ decl->o_val = oid->o_val;
+ decl->o_data = oid->o_data;
+ }
+}
+
+struct oid *
+smi_findkey(char *name)
+{
+ struct oid oid;
+ if (name == NULL)
+ return (NULL);
+ oid.o_name = name;
+ return (RB_FIND(keytree, &smi_keytree, &oid));
+}
+
+struct oid *
+smi_foreach(struct oid *oid, u_int flags)
+{
+ /*
+ * Traverse the tree of MIBs with the option to check
+ * for specific OID flags.
+ */
+ if (oid == NULL) {
+ oid = RB_MIN(oidtree, &smi_oidtree);
+ if (oid == NULL)
+ return (NULL);
+ if (flags == 0 || (oid->o_flags & flags))
+ return (oid);
+ }
+ for (;;) {
+ oid = RB_NEXT(oidtree, &smi_oidtree, oid);
+ if (oid == NULL)
+ break;
+ if (flags == 0 || (oid->o_flags & flags))
+ return (oid);
+ }
+
+ return (oid);
+}
+
+int
+smi_oid_cmp(struct oid *a, struct oid *b)
+{
+ size_t i;
+
+ for (i = 0; i < MINIMUM(a->o_oidlen, b->o_oidlen); i++) {
+ if (a->o_oid[i] != b->o_oid[i])
+ return (a->o_oid[i] - b->o_oid[i]);
+ }
+
+ /*
+ * Return success if the matched object is a table
+ * or a MIB registered by a subagent
+ * (it will match any sub-elements)
+ */
+ if ((b->o_flags & OID_TABLE ||
+ b->o_flags & OID_REGISTERED) &&
+ (a->o_flags & OID_KEY) == 0 &&
+ (a->o_oidlen > b->o_oidlen))
+ return (0);
+
+ return (a->o_oidlen - b->o_oidlen);
+}
+
+int
+smi_key_cmp(struct oid *a, struct oid *b)
+{
+ if (a->o_name == NULL || b->o_name == NULL)
+ return (-1);
+ return (strcasecmp(a->o_name, b->o_name));
+}
+
+RB_GENERATE(oidtree, oid, o_element, smi_oid_cmp)
+RB_GENERATE(keytree, oid, o_keyword, smi_key_cmp)
diff --git a/usr.bin/snmp/smi.h b/usr.bin/snmp/smi.h
new file mode 100644
index 00000000000..42e1953b757
--- /dev/null
+++ b/usr.bin/snmp/smi.h
@@ -0,0 +1,91 @@
+/* $OpenBSD: smi.h,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
+ * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/tree.h>
+#include <sys/queue.h>
+
+#define OID_ROOT 0x00
+#define OID_RD 0x01
+#define OID_WR 0x02
+#define OID_IFSET 0x04 /* only if user-specified value */
+#define OID_DYNAMIC 0x08 /* free allocated data */
+#define OID_TABLE 0x10 /* dynamic sub-elements */
+#define OID_MIB 0x20 /* root-OID of a supported MIB */
+#define OID_KEY 0x40 /* lookup tables */
+#define OID_REGISTERED 0x80 /* OID registered by subagent */
+
+#define OID_RS (OID_RD|OID_IFSET)
+#define OID_WS (OID_WR|OID_IFSET)
+#define OID_RW (OID_RD|OID_WR)
+#define OID_RWS (OID_RW|OID_IFSET)
+
+#define OID_TRD (OID_RD|OID_TABLE)
+#define OID_TWR (OID_WR|OID_TABLE)
+#define OID_TRS (OID_RD|OID_IFSET|OID_TABLE)
+#define OID_TWS (OID_WR|OID_IFSET|OID_TABLE)
+#define OID_TRW (OID_RD|OID_WR|OID_TABLE)
+#define OID_TRWS (OID_RW|OID_IFSET|OID_TABLE)
+
+enum smi_output_string {
+ smi_os_default,
+ smi_os_hex,
+ smi_os_ascii
+};
+
+enum smi_oid_lookup {
+ smi_oidl_numeric,
+ smi_oidl_short,
+ smi_oidl_full
+};
+
+struct oid {
+ struct ber_oid o_id;
+#define o_oid o_id.bo_id
+#define o_oidlen o_id.bo_n
+
+ char *o_name;
+
+ u_int o_flags;
+
+ int (*o_get)(struct oid *, struct ber_oid *,
+ struct ber_element **);
+ int (*o_set)(struct oid *, struct ber_oid *,
+ struct ber_element **);
+ struct ber_oid *(*o_table)(struct oid *, struct ber_oid *,
+ struct ber_oid *);
+
+ long long o_val;
+ void *o_data;
+
+ struct ctl_conn *o_session;
+
+ RB_ENTRY(oid) o_element;
+ RB_ENTRY(oid) o_keyword;
+ TAILQ_ENTRY(oid) o_list;
+};
+
+int smi_init(void);
+unsigned int smi_application(struct ber_element *);
+int smi_string2oid(const char *, struct ber_oid *);
+char *smi_oid2string(struct ber_oid *, char *, size_t, enum smi_oid_lookup);
+void smi_mibtree(struct oid *);
+struct oid *smi_foreach(struct oid *, u_int);
+void smi_debug_elements(struct ber_element *);
+char *smi_print_element(struct ber_element *, int, enum smi_output_string,
+ enum smi_oid_lookup);
diff --git a/usr.bin/snmp/snmp.1 b/usr.bin/snmp/snmp.1
new file mode 100644
index 00000000000..179f3c0618d
--- /dev/null
+++ b/usr.bin/snmp/snmp.1
@@ -0,0 +1,351 @@
+.\" $OpenBSD: snmp.1,v 1.1 2019/08/09 06:17:59 martijn Exp $
+.\"
+.\" Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: August 9 2019 $
+.Dt SNMP 1
+.Os
+.Sh NAME
+.Nm snmp
+.Nd simple SNMP client
+.Sh SYNOPSIS
+.Nm
+.Cm get | getnext
+.Op Fl c Ar community
+.Op Fl O Cm afnQqSvx
+.Op Fl r Ar retries
+.Op Fl t Ar timeout
+.Op Fl v Ar version
+.Ar agent
+.Ar oid ...
+.Nm
+.Cm walk
+.Op Fl C Cm cIipt
+.Op Fl C Cm E Ar endoid
+.Op Fl c Ar community
+.Op Fl O Cm afnQqSvx
+.Op Fl r Ar retries
+.Op Fl t Ar timeout
+.Op Fl v Ar version
+.Ar agent
+.Op Ar oid
+.Nm
+.Cm bulkget
+.Op Fl C Cm n Ns Ar nonrep Ns Cm r Ns Ar maxrep
+.Op Fl c Ar community
+.Op Fl O Cm afnQqSvx
+.Op Fl r Ar retries
+.Op Fl t Ar timeout
+.Op Fl v Ar version
+.Ar agent
+.Ar oid ...
+.Nm
+.Cm bulkwalk
+.Op Fl C Cm cipn Ns Ar nonrep Ns Cm r Ns Ar maxrep
+.Op Fl c Ar community
+.Op Fl O Cm afnQqSvx
+.Op Fl r Ar retries
+.Op Fl t Ar timeout
+.Op Fl v Ar version
+.Ar agent
+.Op Ar oid
+.Nm
+.Cm trap
+.Op Fl c Ar community
+.Op Fl v Ar version
+.Ar agent uptime trapoid
+.Oo Ar varoid type value Oc ...
+.Nm
+.Cm mibtree
+.Op Fl O Cm fnS
+.Sh DESCRIPTION
+The
+.Nm
+utility is a simple SNMP client.
+.Pp
+The subcommands are as follows:
+.Bl -tag -width bulkwalk
+.It Cm get
+Retrieve the MIB for
+.Ar oid
+from the
+.Ar agent .
+If more than one
+.Ar oid
+is specified, retrieve the MIB for each one.
+.It Cm getnext
+Retrieve the MIB that follows
+.Ar oid
+from the
+.Ar agent .
+If more than one
+.Ar oid
+is specified, retrieve the MIB following each one of them.
+.It Cm walk
+Retrieve all the MIBs that are branches of
+.Ar oid
+from the
+.Ar agent .
+This uses the
+.Cm getnext
+subcommand internally and requests a single MIB at a time.
+If no OID is specified it defaults to mib-2
+.Pq .1.3.6.1.2.1 .
+.It Cm bulkget
+Retrieve the next 10 MIBs following each
+.Ar oid
+from the
+.Ar agent .
+This command is not available for
+.Fl v Cm 1 .
+.It Cm bulkwalk
+Retrieve all the MIBs from the
+.Ar agent
+that are branches of
+.Ar oid .
+This uses the
+.Cm bulkget
+subcommand internally to retrieve multiple MIBs at a time.
+This command is not available for
+.Fl v Cm 1 .
+.It Cm trap
+Send a trap message to the
+.Ar agent .
+The
+.Ar uptime
+is specified in timeticks
+.Pq centiseconds
+or defaults to the system uptime if an empty string is given.
+The
+.Ar trapoid
+is the identification OID used by the trap handler to determine its action.
+The triple
+.Op Ar varoid , type, value
+is described below
+.Sx Data types .
+This command is not available for
+.Fl v Cm 1 .
+.It Cm mibtree
+Dump the tree of compiled-in MIB objects.
+.El
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl C Ar appopt
+Set the application specific
+.Ar appopt
+options by supplying a string of one or more
+of the following modifier letters:
+.Bl -tag -width Ds
+.It Cm c
+During a
+.Cm walk
+or
+.Cm bulkwalk ,
+disable checking the order of MIBs.
+On some devices that return MIBs out of order,
+this may cause an infinite loop.
+.It Cm E Ar endoid
+Walk the tree up to but excluding
+.Ar endoid .
+.It Cm I
+If no branches are found during a
+.Cm walk ,
+do not fall back to returning the original MIB via a
+.Cm get
+request.
+.It Cm i
+Before starting a
+.Cm walk
+or
+.Cm bulkwalk ,
+always do a
+.Cm get
+request on the specified
+.Ar oid
+first.
+.It Cm n Ns Ar nonrep
+Set the non-repeaters field in the request to the non-negative integer
+.Ar nonrep .
+This causes the first
+.Ar nonrep
+.Ar oid
+arguments to only return a single MIB instead of
+.Ar maxrep .
+This value defaults to 0.
+.It Cm p
+At the end of a
+.Cm walk
+or
+.Cm bulkwalk ,
+show a summary of the total variables received.
+.It Cm r Ns Ar maxrep
+Set the max-repetitions field in the request to the positive integer
+.Ar maxrep .
+For
+.Cm bulkget
+or
+.Cm bulkwalk
+this determines the amount of MIBs to return for each specified OID.
+This value defaults to 10.
+.It Cm t
+Show how long it took to
+.Cm walk
+the entire tree.
+.El
+.It Fl c Ar community
+Set the
+.Ar community
+string.
+Defaults to
+.Cm public .
+.It Fl O Ar output
+Set the
+.Ar output
+options by supplying a string of one or more
+of the following modifier letters:
+.Bl -tag -width 1n
+.It Cm a
+Print the varbind string unchanged
+rather than replacing non-printable bytes with dots.
+.It Cm f
+When displaying an OID, include the full list of MIB objects.
+By default only the last textual MIB object is shown.
+.It Cm n
+Display the OID numerically.
+.It Cm Q
+Remove the type information.
+.It Cm q
+Remove the type information and the equal sign.
+.It Cm S
+Display the MIB name and the type information.
+This is the default behaviour.
+.It Cm v
+Only display the varbind value, removing the OID.
+.It Cm x
+Display the varbind string values as hexadecimal strings.
+.El
+.It Fl r Ar retries
+Set the number of
+.Ar retries
+in case of packet loss.
+Defaults to 5.
+.It Fl t Ar timeout
+Set the
+.Ar timeout
+to wait for a reply, in seconds.
+Defaults to 1.
+.It Fl v Ar version
+Set the snmp protocol
+.Ar version
+to either
+.Cm 1
+or
+.Cm 2c .
+Currently defaults to
+.Cm 2c .
+.El
+.Pp
+The syntax for the
+.Ar agent
+argument is
+.Oo Ar protocol : Oc Ns Ar address
+with the follwing forms:
+.Bl -column udp6XXXtcp6X address -offset indent
+.It Ar protocol Ta Ar address
+.It Cm udp | tcp Ta Ar hostname Ns Oo Pf : Ar port Oc |
+.Ar IPv4-address Ns Op Pf : Ar port
+.It Cm udp6 | tcp6 Ta Ar hostname Ns Oo Pf : Ar port Oc |
+.Cm \&[ Ns Ar IPv6-address Ns Cm \&] Ns Oo Pf : Ar port Oc |
+.Ar IPv6-address Ns Pf : Ar port
+.It Cm unix Ta Ar pathname
+.El
+.Pp
+The default
+.Ar protocol
+is
+.Cm udp
+and the default
+.Ar port
+is 161; except for the
+.Nm snmp Cm trap
+command which uses 162.
+.Cm udpv6
+and
+.Cm udpipv6
+are aliases for
+.Cm udp6 ;
+.Cm tcpv6
+and
+.Cm tcpipv6
+for
+.Cm tcp6 .
+To specify an IPv6-address without a
+.Ar port ,
+the
+.Ar IPv6-address
+must be enclosed in square brackets.
+If the square brackets are omitted,
+the value after the last colon is always interpreted as a
+.Ar port .
+.Ss Data types
+Additional data sent to the server is formatted by specifying one or more
+triples of
+.Ar varoid ,
+.Ar type ,
+and
+.Ar value .
+Supported types are:
+.Bl -tag -width 1n
+.It Cm a
+An IPv4 Address.
+.It Cm b
+A bitstring.
+A list of individual bit offsets separated by comma, space or tab.
+Must be supplied as a single argument.
+.It Cm c
+A counter32.
+.It Cm d
+A decimal string.
+A list of individual bytes in decimal form separated by space or tab.
+.It Cm i
+An integer.
+.It Cm n
+A null object.
+.It Cm o
+An OID.
+.It Cm s
+A regular string.
+.It Cm t
+Timeticks in centiseconds.
+.It Cm u
+Unsigned integer.
+Actually a normal integer for compatibility with netsnmp.
+.It Cm x
+A hex string.
+Similar to a decimal string, but in hexadecimal format.
+.El
+.Sh SEE ALSO
+.Xr snmpd 8
+.Sh HISTORY
+The
+.Nm
+program first appeared in
+.Ox 6.6 .
+.Sh AUTHORS
+The
+.Nm
+program was written by
+.An Martijn van Duren Aq Mt martijn@openbsd.org .
diff --git a/usr.bin/snmp/snmp.c b/usr.bin/snmp/snmp.c
new file mode 100644
index 00000000000..b1bbcb0ab76
--- /dev/null
+++ b/usr.bin/snmp/snmp.c
@@ -0,0 +1,288 @@
+/* $OpenBSD: snmp.c,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
+ * Copyright (c) 2013 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "ber.h"
+#include "smi.h"
+#include "snmp.h"
+
+static struct ber_element *
+ snmp_resolve(struct snmp_agent *, struct ber_element *, int);
+
+struct snmp_agent *
+snmp_connect_v12(int fd, enum snmp_version version, const char *community)
+{
+ struct snmp_agent *agent;
+
+ if (version != SNMP_V1 && version != SNMP_V2C) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if ((agent = malloc(sizeof(*agent))) == NULL)
+ return NULL;
+ agent->fd = fd;
+ agent->version = version;
+ if ((agent->community = strdup(community)) == NULL)
+ goto fail;
+ agent->timeout = 1;
+ agent->retries = 5;
+ return agent;
+
+fail:
+ free(agent->community);
+ free(agent);
+ return NULL;
+}
+
+void
+snmp_free_agent(struct snmp_agent *agent)
+{
+ free(agent->community);
+ free(agent);
+}
+
+struct ber_element *
+snmp_get(struct snmp_agent *agent, struct ber_oid *oid, size_t len)
+{
+ struct ber_element *pdu, *varbind;
+ size_t i;
+
+ if ((pdu = ber_add_sequence(NULL)) == NULL)
+ return NULL;
+ if ((varbind = ber_printf_elements(pdu, "tddd{", BER_CLASS_CONTEXT,
+ SNMP_C_GETREQ, arc4random() & 0x7fffffff, 0, 0)) == NULL)
+ goto fail;
+ for (i = 0; i < len; i++)
+ varbind = ber_printf_elements(varbind, "{O0}", &oid[i]);
+ if (varbind == NULL)
+ goto fail;
+
+ return snmp_resolve(agent, pdu, 1);
+fail:
+ ber_free_elements(pdu);
+ return NULL;
+}
+
+struct ber_element *
+snmp_getnext(struct snmp_agent *agent, struct ber_oid *oid, size_t len)
+{
+ struct ber_element *pdu, *varbind;
+ size_t i;
+
+ if ((pdu = ber_add_sequence(NULL)) == NULL)
+ return NULL;
+ if ((varbind = ber_printf_elements(pdu, "tddd{", BER_CLASS_CONTEXT,
+ SNMP_C_GETNEXTREQ, arc4random() & 0x7fffffff, 0, 0)) == NULL)
+ goto fail;
+ for (i = 0; i < len; i++)
+ varbind = ber_printf_elements(varbind, "{O0}", &oid[i]);
+ if (varbind == NULL)
+ goto fail;
+
+ return snmp_resolve(agent, pdu, 1);
+fail:
+ ber_free_elements(pdu);
+ return NULL;
+}
+
+int
+snmp_trap(struct snmp_agent *agent, struct timespec *uptime,
+ struct ber_oid *oid, struct ber_element *custvarbind)
+{
+ struct ber_element *pdu, *varbind;
+ struct ber_oid sysuptime, trap;
+ long long ticks;
+
+ if ((pdu = ber_add_sequence(NULL)) == NULL)
+ return -1;
+ if ((varbind = ber_printf_elements(pdu, "tddd{", BER_CLASS_CONTEXT,
+ SNMP_C_TRAPV2, arc4random() & 0x7fffffff, 0, 0)) == NULL)
+ goto fail;
+
+ ticks = uptime->tv_sec * 100;
+ ticks += uptime->tv_nsec / 10000000;
+ if (smi_string2oid("sysUpTime.0", &sysuptime) == -1)
+ goto fail;
+ if ((varbind = ber_printf_elements(varbind, "{Oit}", &sysuptime, ticks,
+ BER_CLASS_APPLICATION, SNMP_T_TIMETICKS)) == NULL)
+ goto fail;
+ if (smi_string2oid("snmpTrapOID.0", &trap) == -1)
+ goto fail;
+ if ((varbind = ber_printf_elements(varbind, "{OO}", &trap, oid)) == NULL)
+ goto fail;
+ if (custvarbind != NULL)
+ ber_link_elements(varbind, custvarbind);
+
+ snmp_resolve(agent, pdu, 0);
+ return 0;
+fail:
+ ber_free_elements(pdu);
+ return -1;
+}
+
+struct ber_element *
+snmp_getbulk(struct snmp_agent *agent, struct ber_oid *oid, size_t len,
+ int non_repeaters, int max_repetitions)
+{
+ struct ber_element *pdu, *varbind;
+ size_t i;
+
+ if ((pdu = ber_add_sequence(NULL)) == NULL)
+ return NULL;
+ if ((varbind = ber_printf_elements(pdu, "tddd{", BER_CLASS_CONTEXT,
+ SNMP_C_GETBULKREQ, arc4random() & 0x7fffffff, non_repeaters,
+ max_repetitions)) == NULL)
+ goto fail;
+ for (i = 0; i < len; i++)
+ varbind = ber_printf_elements(varbind, "{O0}", &oid[i]);
+ if (varbind == NULL)
+ goto fail;
+
+ return snmp_resolve(agent, pdu, 1);
+fail:
+ ber_free_elements(pdu);
+ return NULL;
+}
+
+static struct ber_element *
+snmp_resolve(struct snmp_agent *agent, struct ber_element *pdu, int reply)
+{
+ struct ber_element *message, *varbind;
+ struct ber_oid oid;
+ struct timespec start, now;
+ struct pollfd pfd;
+ struct ber ber;
+ ssize_t len;
+ long long reqid, rreqid;
+ long long version;
+ char *community;
+ short direction;
+ int to, nfds, ret;
+ int tries;
+ void *ptr;
+ char buf[READ_BUF_SIZE];
+
+ if (ber_scanf_elements(pdu, "{i", &reqid) != 0) {
+ errno = EINVAL;
+ ber_free_elements(pdu);
+ return NULL;
+ }
+
+ if ((message = ber_add_sequence(NULL)) == NULL) {
+ ber_free_elements(pdu);
+ return NULL;
+ }
+ if (ber_printf_elements(message, "dse", agent->version,
+ agent->community, pdu) == NULL) {
+ ber_free_elements(pdu);
+ ber_free_elements(message);
+ return NULL;
+ }
+ memset(&ber, 0, sizeof(ber));
+ ber_set_application(&ber, smi_application);
+ len = ber_write_elements(&ber, message);
+ ber_free_elements(message);
+ message = NULL;
+ if (ber_get_writebuf(&ber, &ptr) < 1)
+ goto fail;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ memcpy(&now, &start, sizeof(now));
+ direction = POLLOUT;
+ tries = agent->retries + 1;
+ while (tries) {
+ pfd.fd = agent->fd;
+ pfd.events = direction;
+ if (agent->timeout > 0) {
+ to = (agent->timeout - (now.tv_sec - start.tv_sec)) * 1000;
+ to -= (now.tv_nsec - start.tv_nsec) / 1000000;
+ } else
+ to = INFTIM;
+ nfds = poll(&pfd, 1, to);
+ if (nfds == 0) {
+ errno = ETIMEDOUT;
+ direction = POLLOUT;
+ tries--;
+ continue;
+ }
+ if (nfds == -1) {
+ if (errno == EINTR)
+ continue;
+ else
+ goto fail;
+ }
+ if (direction == POLLOUT) {
+ ret = send(agent->fd, ptr, len, MSG_DONTWAIT);
+ if (ret == -1)
+ goto fail;
+ if (ret < len) {
+ errno = EBADMSG;
+ goto fail;
+ }
+ if (!reply)
+ return NULL;
+ direction = POLLIN;
+ continue;
+ }
+ ret = recv(agent->fd, buf, sizeof(buf), MSG_DONTWAIT);
+ if (ret == 0)
+ errno = ECONNRESET;
+ if (ret <= 0)
+ goto fail;
+ ber_set_readbuf(&ber, buf, ret);
+ if ((message = ber_read_elements(&ber, NULL)) == NULL)
+ goto fail;
+ if (ber_scanf_elements(message, "{ise", &version, &community,
+ &pdu) != 0)
+ goto fail;
+ /* Skip invalid packets; should not happen */
+ if (version != agent->version ||
+ strcmp(community, agent->community) != 0)
+ continue;
+ /* Validate pdu format and check request id */
+ if (ber_scanf_elements(pdu, "{iSSe", &rreqid, &varbind) != 0 ||
+ varbind->be_encoding != BER_TYPE_SEQUENCE)
+ goto fail;
+ if (rreqid != reqid)
+ continue;
+ for (varbind = varbind->be_sub; varbind != NULL;
+ varbind = varbind->be_next) {
+ if (ber_scanf_elements(varbind, "{oS}", &oid) != 0)
+ goto fail;
+ }
+
+ ber_unlink_elements(message->be_sub->be_next);
+ ber_free_elements(message);
+ ber_free(&ber);
+ return pdu;
+ }
+
+fail:
+ ber_free_elements(message);
+ ber_free(&ber);
+ return NULL;
+}
diff --git a/usr.bin/snmp/snmp.h b/usr.bin/snmp/snmp.h
new file mode 100644
index 00000000000..502aa75df6e
--- /dev/null
+++ b/usr.bin/snmp/snmp.h
@@ -0,0 +1,136 @@
+/* $OpenBSD: snmp.h,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
+ * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SNMPD_SNMP_H
+#define SNMPD_SNMP_H
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <endian.h>
+
+#include <time.h>
+
+#define READ_BUF_SIZE 65535
+
+#define SNMP_MAX_OID_STRLEN 128 /* max size of the OID _string_ */
+
+/*
+ * SNMP BER types
+ */
+
+enum snmp_version {
+ SNMP_V1 = 0,
+ SNMP_V2C = 1, /* SNMPv2c */
+ SNMP_V3 = 3
+};
+
+enum snmp_context {
+ SNMP_C_GETREQ = 0,
+ SNMP_C_GETNEXTREQ = 1,
+ SNMP_C_GETRESP = 2,
+ SNMP_C_SETREQ = 3,
+ SNMP_C_TRAP = 4,
+
+ /* SNMPv2 */
+ SNMP_C_GETBULKREQ = 5,
+ SNMP_C_INFORMREQ = 6,
+ SNMP_C_TRAPV2 = 7,
+ SNMP_C_REPORT = 8
+};
+
+enum snmp_application {
+ SNMP_T_IPADDR = 0,
+ SNMP_T_COUNTER32 = 1,
+ SNMP_T_GAUGE32 = 2,
+ SNMP_T_UNSIGNED32 = 2,
+ SNMP_T_TIMETICKS = 3,
+ SNMP_T_OPAQUE = 4,
+ SNMP_T_NSAPADDR = 5,
+ SNMP_T_COUNTER64 = 6,
+ SNMP_T_UINTEGER32 = 7
+};
+
+enum snmp_generic_trap {
+ SNMP_TRAP_COLDSTART = 0,
+ SNMP_TRAP_WARMSTART = 1,
+ SNMP_TRAP_LINKDOWN = 2,
+ SNMP_TRAP_LINKUP = 3,
+ SNMP_TRAP_AUTHFAILURE = 4,
+ SNMP_TRAP_EGPNEIGHLOSS = 5,
+ SNMP_TRAP_ENTERPRISE = 6
+};
+
+enum snmp_error {
+ SNMP_ERROR_NONE = 0,
+ SNMP_ERROR_TOOBIG = 1,
+ SNMP_ERROR_NOSUCHNAME = 2,
+ SNMP_ERROR_BADVALUE = 3,
+ SNMP_ERROR_READONLY = 4,
+ SNMP_ERROR_GENERR = 5,
+
+ /* SNMPv2 */
+ SNMP_ERROR_NOACCESS = 6,
+ SNMP_ERROR_WRONGTYPE = 7,
+ SNMP_ERROR_WRONGLENGTH = 8,
+ SNMP_ERROR_WRONGENC = 9,
+ SNMP_ERROR_WRONGVALUE = 10,
+ SNMP_ERROR_NOCREATION = 11,
+ SNMP_ERROR_INCONVALUE = 12,
+ SNMP_ERROR_RESUNAVAIL = 13, /* EGAIN */
+ SNMP_ERROR_COMMITFAILED = 14,
+ SNMP_ERROR_UNDOFAILED = 15,
+ SNMP_ERROR_AUTHERROR = 16,
+ SNMP_ERROR_NOTWRITABLE = 17,
+ SNMP_ERROR_INCONNAME = 18
+};
+
+enum snmp_security_model {
+ SNMP_SEC_ANY = 0,
+ SNMP_SEC_SNMPv1 = 1,
+ SNMP_SEC_SNMPv2c = 2,
+ SNMP_SEC_USM = 3,
+ SNMP_SEC_TSM = 4
+};
+
+struct snmp_agent {
+ int fd;
+ enum snmp_version version;
+ char *community;
+ int timeout;
+ int retries;
+};
+
+#define SNMP_MSGFLAG_AUTH 0x01
+#define SNMP_MSGFLAG_PRIV 0x02
+#define SNMP_MSGFLAG_SECMASK (SNMP_MSGFLAG_AUTH | SNMP_MSGFLAG_PRIV)
+#define SNMP_MSGFLAG_REPORT 0x04
+
+#define SNMP_MAX_TIMEWINDOW 150 /* RFC3414 */
+
+struct snmp_agent *snmp_connect_v12(int, enum snmp_version, const char *);
+void snmp_free_agent(struct snmp_agent *);
+struct ber_element *
+ snmp_get(struct snmp_agent *agent, struct ber_oid *oid, size_t len);
+struct ber_element *snmp_getnext(struct snmp_agent *, struct ber_oid *, size_t);
+struct ber_element *
+ snmp_getbulk(struct snmp_agent *, struct ber_oid *, size_t, int, int);
+int snmp_trap(struct snmp_agent *, struct timespec *, struct ber_oid *,
+ struct ber_element *);
+
+#endif /* SNMPD_SNMP_H */
diff --git a/usr.bin/snmp/snmpc.c b/usr.bin/snmp/snmpc.c
new file mode 100644
index 00000000000..71ba913637d
--- /dev/null
+++ b/usr.bin/snmp/snmpc.c
@@ -0,0 +1,906 @@
+/* $OpenBSD: snmpc.c,v 1.1 2019/08/09 06:17:59 martijn Exp $ */
+
+/*
+ * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
+ * Copyright (c) 2013 Reyk Floeter <reyk@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <arpa/inet.h>
+
+#include <ber.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "smi.h"
+#include "snmp.h"
+
+#define GETOPT_COMMON "c:r:t:v:O:"
+
+int snmpc_get(int, char *[]);
+int snmpc_walk(int, char *[]);
+int snmpc_trap(int, char *[]);
+int snmpc_mibtree(int, char *[]);
+int snmpc_parseagent(char *, char *);
+int snmpc_print(struct ber_element *);
+__dead void snmpc_printerror(enum snmp_error, char *);
+void usage(void);
+
+struct snmp_app {
+ const char *name;
+ const int usecommonopt;
+ const char *optstring;
+ const char *usage;
+ int (*exec)(int, char *[]);
+};
+
+struct snmp_app snmp_apps[] = {
+ {"get", 1, NULL, "agent oid ...", snmpc_get},
+ {"getnext", 1, NULL, "agent oid ...", snmpc_get},
+ {"walk", 1, "C:", "[-C cIipt] [-C E OID] agent [oid]", snmpc_walk},
+ {"bulkget", 1, "C:", "[-C n<nonrep>r<maxrep>] agent oid ...", snmpc_get},
+ {"bulkwalk", 1, "C:", "[-C cipn<nonrep>r<maxrep>] agent [oid]", snmpc_walk},
+ { "trap", 1, NULL, "agent uptime oid [oid type value] ...", snmpc_trap},
+ {"mibtree", 0, "O:", "[-O fnS]", snmpc_mibtree}
+};
+struct snmp_app *snmp_app = NULL;
+
+char *community = "public";
+char *mib = "mib_2";
+int retries = 5;
+int timeout = 1;
+int version = SNMP_V2C;
+int print_equals = 1;
+int print_varbind_only = 0;
+int print_summary = 0;
+int print_time = 0;
+int walk_check_increase = 1;
+int walk_fallback_oid = 1;
+int walk_include_oid = 0;
+int smi_print_hint = 1;
+int non_repeaters = 0;
+int max_repetitions = 10;
+struct ber_oid walk_end = {{0}, 0};
+enum smi_oid_lookup oid_lookup = smi_oidl_short;
+enum smi_output_string output_string = smi_os_default;
+
+int
+main(int argc, char *argv[])
+{
+ char optstr[BUFSIZ];
+ const char *errstr;
+ char *strtolp;
+ int ch;
+ size_t i;
+
+ if (pledge("stdio inet dns", NULL) == -1)
+ err(1, "pledge");
+
+ if (argc <= 1)
+ usage();
+
+ for (i = 0; i < sizeof(snmp_apps)/sizeof(*snmp_apps); i++) {
+ if (strcmp(snmp_apps[i].name, argv[1]) == 0) {
+ snmp_app = &snmp_apps[i];
+ if (snmp_app->optstring != NULL) {
+ if (strlcpy(optstr, snmp_app->optstring,
+ sizeof(optstr)) > sizeof(optstr))
+ errx(1, "strlcat");
+ }
+ break;
+ }
+ }
+ if (snmp_app == NULL)
+ usage();
+
+ if (snmp_app->usecommonopt) {
+ if (strlcat(optstr, GETOPT_COMMON, sizeof(optstr)) >
+ sizeof(optstr))
+ errx(1, "strlcpy");
+ }
+
+ argc--;
+ argv++;
+
+ smi_init();
+
+ while ((ch = getopt(argc, argv, optstr)) != -1) {
+ switch (ch) {
+ case 'c':
+ community = optarg;
+ break;
+ case 'r':
+ if ((retries = strtonum(optarg, 0, INT_MAX,
+ &errstr)) == 0) {
+ if (errstr != NULL)
+ errx(1, "-r: %s argument", errstr);
+ }
+ break;
+ case 't':
+ if ((timeout = strtonum(optarg, 1, INT_MAX,
+ &errstr)) == 0) {
+ if (errstr != NULL)
+ errx(1, "-t: %s argument", errstr);
+ }
+ break;
+ case 'v':
+ if (strcmp(optarg, "1") == 0)
+ version = SNMP_V1;
+ else if (strcmp(optarg, "2c") == 0)
+ version = SNMP_V2C;
+ else
+ errc(1, EINVAL, "-v");
+ break;
+ case 'C':
+ for (i = 0; i < strlen(optarg); i++) {
+ switch (optarg[i]) {
+ case 'c':
+ if (strcmp(snmp_app->name, "walk") &&
+ strcmp(snmp_app->name, "bulkwalk"))
+ usage();
+ walk_check_increase = 0;
+ break;
+ case 'i':
+ if (strcmp(snmp_app->name, "walk") &&
+ strcmp(snmp_app->name, "bulkwalk"))
+ usage();
+ walk_include_oid = 1;
+ break;
+ case 'n':
+ if (strcmp(snmp_app->name, "bulkget") &&
+ strcmp(snmp_app->name, "bulkwalk"))
+ usage();
+ errno = 0;
+ non_repeaters = strtol(&optarg[i + 1],
+ &strtolp, 10);
+ if (non_repeaters < 0 ||
+ errno == ERANGE) {
+ if (non_repeaters < 0)
+ errx(1, "%s%s",
+ "-Cn: too small ",
+ "argument");
+ else
+ errx(1, "%s%s",
+ "-Cn: too large",
+ "argument");
+ } else if (&optarg[i + 1] == strtolp)
+ errx(1, "-Cn invalid argument");
+ i = strtolp - optarg - 1;
+ break;
+ case 'p':
+ if (strcmp(snmp_app->name, "walk") &&
+ strcmp(snmp_app->name, "bulkwalk"))
+ usage();
+ print_summary = 1;
+ break;
+ case 'r':
+ if (strcmp(snmp_app->name, "bulkget") &&
+ strcmp(snmp_app->name, "bulkwalk"))
+ usage();
+ errno = 0;
+ max_repetitions = strtol(&optarg[i + 1],
+ &strtolp, 10);
+ if (max_repetitions < 0 ||
+ errno == ERANGE) {
+ if (max_repetitions < 0)
+ errx(1, "%s%s",
+ "-Cr: too small ",
+ "argument");
+ else
+ errx(1, "%s%s",
+ "-Cr: too large",
+ "argument");
+ } else if (&optarg[i + 1] == strtolp)
+ errx(1, "-Cr invalid argument");
+ i = strtolp - optarg - 1;
+ break;
+ case 't':
+ if (strcmp(snmp_app->name, "walk"))
+ usage();
+ print_time = 1;
+ break;
+ case 'E':
+ if (strcmp(snmp_app->name, "walk"))
+ usage();
+ if (smi_string2oid(argv[optind],
+ &walk_end) != 0)
+ errx(1, "%s: %s",
+ "Unknown Object Identifier",
+ argv[optind]);
+ optind++;
+ continue;
+ case 'I':
+ if (strcmp(snmp_app->name, "walk"))
+ usage();
+ walk_fallback_oid = 0;
+ break;
+ default:
+ usage();
+ }
+ if (optarg[i] == 'E')
+ break;
+ }
+ break;
+ case 'O':
+ for (i = 0; i < strlen(optarg); i++) {
+ if (strcmp(snmp_app->name, "mibtree") == 0 &&
+ optarg[i] != 'f' && optarg[i] != 'n' &&
+ optarg[i] != 'S')
+ usage();
+ switch (optarg[i]) {
+ case 'a':
+ output_string = smi_os_ascii;
+ break;
+ case 'f':
+ oid_lookup = smi_oidl_full;
+ break;
+ case 'n':
+ oid_lookup = smi_oidl_numeric;
+ break;
+ case 'q':
+ print_equals = 0;
+ smi_print_hint = 0;
+ break;
+ case 'v':
+ print_varbind_only = 1;
+ break;
+ case 'x':
+ output_string = smi_os_hex;
+ break;
+ case 'S':
+ oid_lookup = smi_oidl_short;
+ break;
+ case 'Q':
+ smi_print_hint = 0;
+ break;
+ default:
+ usage();
+ }
+ }
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ return snmp_app->exec(argc, argv);
+}
+
+int
+snmpc_get(int argc, char *argv[])
+{
+ struct ber_oid *oid;
+ struct ber_element *pdu, *varbind;
+ struct snmp_agent *agent;
+ int errorstatus, errorindex;
+ int i;
+
+ if (argc < 2)
+ usage();
+
+ agent = snmp_connect_v12(snmpc_parseagent(argv[0], "161"), version,
+ community);
+ if (agent == NULL)
+ err(1, "%s", snmp_app->name);
+ agent->timeout = timeout;
+ agent->retries = retries;
+
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+ argc--;
+ argv++;
+
+ oid = reallocarray(NULL, argc, sizeof(*oid));
+ for (i = 0; i < argc; i++) {
+ if (smi_string2oid(argv[i], &oid[i]) == -1)
+ errx(1, "%s: Unknown object identifier", argv[0]);
+ }
+ if (strcmp(snmp_app->name, "getnext") == 0) {
+ if ((pdu = snmp_getnext(agent, oid, argc)) == NULL)
+ err(1, "getnext");
+ } else if (strcmp(snmp_app->name, "bulkget") == 0) {
+ if (version < SNMP_V2C)
+ errx(1, "Cannot send V2 PDU on V1 session");
+ if (non_repeaters > argc)
+ errx(1, "need more objects than -Cn<num>");
+ if ((pdu = snmp_getbulk(agent, oid, argc, non_repeaters,
+ max_repetitions)) == NULL)
+ err(1, "bulkget");
+ } else {
+ if ((pdu = snmp_get(agent, oid, argc)) == NULL)
+ err(1, "get");
+ }
+
+ (void) ber_scanf_elements(pdu, "{Sdd{e", &errorstatus, &errorindex,
+ &varbind);
+ if (errorstatus != 0)
+ snmpc_printerror((enum snmp_error) errorstatus,
+ argv[errorindex]);
+
+ for (; varbind != NULL; varbind = varbind->be_next) {
+ if (!snmpc_print(varbind))
+ err(1, "Can't print response");
+ }
+ ber_free_elements(pdu);
+ snmp_free_agent(agent);
+ return 0;
+}
+
+int
+snmpc_walk(int argc, char *argv[])
+{
+ struct ber_oid oid, loid, noid;
+ struct ber_element *pdu, *varbind, *value;
+ struct timespec start, finish;
+ struct snmp_agent *agent;
+ const char *oids;
+ char oidstr[SNMP_MAX_OID_STRLEN];
+ int n = 0, prev_cmp;
+ int errorstatus, errorindex;
+
+ if (strcmp(snmp_app->name, "bulkwalk") == 0 && version < SNMP_V2C)
+ errx(1, "Cannot send V2 PDU on V1 session");
+ if (argc < 1 || argc > 2)
+ usage();
+ oids = argc == 1 ? mib : argv[1];
+
+ agent = snmp_connect_v12(snmpc_parseagent(argv[0], "161"), version, community);
+ if (agent == NULL)
+ err(1, "%s", snmp_app->name);
+ agent->timeout = timeout;
+ agent->retries = retries;
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+
+ if (smi_string2oid(oids, &oid) == -1)
+ errx(1, "%s: Unknown object identifier", oids);
+ bcopy(&oid, &noid, sizeof(noid));
+ if (print_time)
+ clock_gettime(CLOCK_MONOTONIC, &start);
+
+ if (walk_include_oid) {
+ if ((pdu = snmp_get(agent, &oid, 1)) == NULL)
+ err(1, "%s", snmp_app->name);
+
+ (void) ber_scanf_elements(pdu, "{Sdd{e", &errorstatus,
+ &errorindex, &varbind);
+ if (errorstatus != 0)
+ snmpc_printerror((enum snmp_error) errorstatus,
+ argv[errorindex]);
+
+ if (!snmpc_print(varbind))
+ err(1, "Can't print response");
+ ber_free_element(pdu);
+ n++;
+ }
+ while (1) {
+ bcopy(&noid, &loid, sizeof(loid));
+ if (strcmp(snmp_app->name, "bulkwalk") == 0) {
+ if ((pdu = snmp_getbulk(agent, &noid, 1,
+ non_repeaters, max_repetitions)) == NULL)
+ err(1, "bulkwalk");
+ } else {
+ if ((pdu = snmp_getnext(agent, &noid, 1)) == NULL)
+ err(1, "walk");
+ }
+
+ (void) ber_scanf_elements(pdu, "{Sdd{e", &errorstatus,
+ &errorindex, &varbind);
+ if (errorstatus != 0) {
+ smi_oid2string(&noid, oidstr, sizeof(oidstr),
+ oid_lookup);
+ snmpc_printerror((enum snmp_error) errorstatus, oidstr);
+ }
+
+ for (;varbind != NULL; varbind = varbind->be_next) {
+ (void) ber_scanf_elements(varbind, "{oe}", &noid,
+ &value);
+ if (value->be_class == BER_CLASS_CONTEXT &&
+ value->be_type == BER_TYPE_EOC)
+ break;
+ prev_cmp = ber_oid_cmp(&loid, &noid);
+ if (walk_check_increase && prev_cmp == -1)
+ errx(1, "OID not increasing");
+ if (prev_cmp == 0 || ber_oid_cmp(&oid, &noid) != 2)
+ break;
+ if (walk_end.bo_n != 0 &&
+ ber_oid_cmp(&walk_end, &noid) != -1)
+ break;
+
+ if (!snmpc_print(varbind))
+ err(1, "Can't print response");
+ n++;
+ }
+ ber_free_elements(pdu);
+ if (varbind != NULL)
+ break;
+ }
+ if (walk_fallback_oid && n == 0) {
+ if ((pdu = snmp_get(agent, &oid, 1)) == NULL)
+ err(1, "%s", snmp_app->name);
+
+ (void) ber_scanf_elements(pdu, "{Sdd{e", &errorstatus,
+ &errorindex, &varbind);
+ if (errorstatus != 0)
+ snmpc_printerror((enum snmp_error) errorstatus,
+ argv[errorindex]);
+
+ if (!snmpc_print(varbind))
+ err(1, "Can't print response");
+ ber_free_element(pdu);
+ n++;
+ }
+ if (print_time)
+ clock_gettime(CLOCK_MONOTONIC, &finish);
+ if (print_summary)
+ printf("Variables found: %d\n", n);
+ if (print_time) {
+ if ((finish.tv_nsec -= start.tv_nsec) < 0) {
+ finish.tv_sec -= 1;
+ finish.tv_nsec += 1000000000;
+ }
+ finish.tv_sec -= start.tv_sec;
+ fprintf(stderr, "Total traversal time: %lld.%09ld seconds\n",
+ finish.tv_sec, finish.tv_nsec);
+ }
+ snmp_free_agent(agent);
+ return 0;
+}
+
+int
+snmpc_trap(int argc, char *argv[])
+{
+ struct snmp_agent *agent;
+ struct timespec ts;
+ struct ber_oid trapoid, oid, oidval;
+ struct in_addr addr4;
+ char *addr = (char *)&addr4;
+ char *str = NULL, *tmpstr, *endstr;
+ const char *errstr = NULL;
+ struct ber_element *varbind = NULL, *pdu = NULL;
+ long long lval;
+ int i, ret;
+ size_t strl, byte;
+
+ if (argc < 3 || argc % 3 != 0)
+ usage();
+ if (version == SNMP_V1)
+ errx(1, "trap is not supported for snmp v1");
+
+ agent = snmp_connect_v12(snmpc_parseagent(argv[0], "162"),
+ version, community);
+ if (agent == NULL)
+ err(1, "%s", snmp_app->name);
+
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+
+ if (argv[1][0] == '\0') {
+ if (clock_gettime(CLOCK_UPTIME, &ts) == -1)
+ err(1, "clock_gettime");
+ } else {
+ lval = strtonum(argv[1], 0, LLONG_MAX, &errstr);
+ if (errstr != NULL)
+ errx(1, "Bad value notation (%s)", argv[1]);
+ ts.tv_sec = lval / 100;
+ ts.tv_nsec = (lval % 100) * 10000000;
+ }
+ if (smi_string2oid(argv[2], &trapoid) == -1)
+ errx(1, "Invalid oid: %s\n", argv[2]);
+
+ argc -= 3;
+ argv += 3;
+ for (i = 0; i < argc; i += 3) {
+ if (smi_string2oid(argv[i], &oid) == -1)
+ errx(1, "Invalid oid: %s\n", argv[i]);
+ switch (argv[i + 1][0]) {
+ case 'a':
+ ret = inet_pton(AF_INET, argv[i + 2], &addr4);
+ if (ret == -1)
+ err(1, "inet_pton");
+ if (ret == 0)
+ errx(1, "%s: Bad value notation (%s)", argv[i],
+ argv[i + 2]);
+ if ((varbind = ber_printf_elements(varbind, "{Oxt}",
+ &oid, addr, sizeof(addr4), BER_CLASS_APPLICATION,
+ SNMP_T_IPADDR)) == NULL)
+ err(1, "ber_printf_elements");
+ break;
+ case 'b':
+ tmpstr = argv[i + 2];
+ strl = 0;
+ do {
+ lval = strtoll(tmpstr, &endstr, 10);
+ if (endstr[0] != ' ' && endstr[0] != '\t' &&
+ endstr[0] != ',' && endstr[0] != '\0')
+ errx(1, "%s: Bad value notation (%s)",
+ argv[i], argv[i + 2]);
+ if (tmpstr == endstr) {
+ tmpstr++;
+ continue;
+ }
+ if (lval < 0)
+ errx(1, "%s: Bad value notation (%s)",
+ argv[i], argv[i + 2]);
+ byte = lval / 8;
+ if (byte >= strl) {
+ if ((str = recallocarray(str, strl,
+ byte + 1, 1)) == NULL)
+ err(1, NULL);
+ strl = byte + 1;
+ }
+ str[byte] |= 0x80 >> (lval % 8);
+ tmpstr = endstr + 1;
+ } while (endstr[0] != '\0');
+ /*
+ * RFC3416 Section 2.5
+ * A BITS value is encoded as an OCTET STRING
+ */
+ goto pastestring;
+ case 'c':
+ lval = strtonum(argv[i + 2], INT32_MIN, INT32_MAX,
+ &errstr);
+ if (errstr != NULL)
+ errx(1, "%s: Bad value notation (%s)", argv[i],
+ argv[i + 2]);
+ if ((varbind = ber_printf_elements(varbind, "{Oit}",
+ &oid, lval, BER_CLASS_APPLICATION,
+ SNMP_T_COUNTER32)) == NULL)
+ err(1, "ber_printf_elements");
+ break;
+ case 'd':
+ /* String always shrinks */
+ if ((str = malloc(strlen(argv[i + 2]))) == NULL)
+ err(1, NULL);
+ tmpstr = argv[i + 2];
+ strl = 0;
+ do {
+ lval = strtoll(tmpstr, &endstr, 10);
+ if (endstr[0] != ' ' && endstr[0] != '\t' &&
+ endstr[0] != '\0')
+ errx(1, "%s: Bad value notation (%s)",
+ argv[i], argv[i + 2]);
+ if (tmpstr == endstr) {
+ tmpstr++;
+ continue;
+ }
+ if (lval < 0 || lval > 0xff)
+ errx(1, "%s: Bad value notation (%s)",
+ argv[i], argv[i + 2]);
+ str[strl++] = (unsigned char) lval;
+ tmpstr = endstr + 1;
+ } while (endstr[0] != '\0');
+ goto pastestring;
+ case 'u':
+ case 'i':
+ lval = strtonum(argv[i + 2], LLONG_MIN, LLONG_MAX,
+ &errstr);
+ if (errstr != NULL)
+ errx(1, "%s: Bad value notation (%s)", argv[i],
+ argv[i + 2]);
+ if ((varbind = ber_printf_elements(varbind, "{Oi}",
+ &oid, lval)) == NULL)
+ err(1, "ber_printf_elements");
+ break;
+ case 'n':
+ if ((varbind = ber_printf_elements(varbind, "{O0}",
+ &oid)) == NULL)
+ err(1, "ber_printf_elements");
+ break;
+ case 'o':
+ if (smi_string2oid(argv[i + 2], &oidval) == -1)
+ errx(1, "%s: Unknown Object Identifier (Sub-id "
+ "not found: (top) -> %s)", argv[i],
+ argv[i + 2]);
+ if ((varbind = ber_printf_elements(varbind, "{OO}",
+ &oid, &oidval)) == NULL)
+ err(1, "ber_printf_elements");
+ break;
+ case 's':
+ if ((str = strdup(argv[i + 2])) == NULL)
+ err(1, NULL);
+ strl = strlen(argv[i + 2]);
+pastestring:
+ if ((varbind = ber_printf_elements(varbind, "{Ox}",
+ &oid, str, strl)) == NULL)
+ err(1, "ber_printf_elements");
+ free(str);
+ break;
+ case 't':
+ lval = strtonum(argv[i + 2], LLONG_MIN, LLONG_MAX,
+ &errstr);
+ if (errstr != NULL)
+ errx(1, "%s: Bad value notation (%s)", argv[i],
+ argv[i + 2]);
+ if ((varbind = ber_printf_elements(varbind, "{Oit}",
+ &oid, lval, BER_CLASS_APPLICATION,
+ SNMP_T_TIMETICKS)) == NULL)
+ err(1, "ber_printf_elements");
+ break;
+ case 'x':
+ /* String always shrinks */
+ if ((str = malloc(strlen(argv[i + 2]))) == NULL)
+ err(1, NULL);
+ tmpstr = argv[i + 2];
+ strl = 0;
+ do {
+ lval = strtoll(tmpstr, &endstr, 16);
+ if (endstr[0] != ' ' && endstr[0] != '\t' &&
+ endstr[0] != '\0')
+ errx(1, "%s: Bad value notation (%s)",
+ argv[i], argv[i + 2]);
+ if (tmpstr == endstr) {
+ tmpstr++;
+ continue;
+ }
+ if (lval < 0 || lval > 0xff)
+ errx(1, "%s: Bad value notation (%s)",
+ argv[i], argv[i + 2]);
+ str[strl++] = (unsigned char) lval;
+ tmpstr = endstr + 1;
+ } while (endstr[0] != '\0');
+ goto pastestring;
+ default:
+ usage();
+ }
+ if (pdu == NULL)
+ pdu = varbind;
+ }
+
+ snmp_trap(agent, &ts, &trapoid, pdu);
+
+ return 0;
+}
+
+int
+snmpc_mibtree(int argc, char *argv[])
+{
+ struct oid *oid;
+ char buf[BUFSIZ];
+
+ for (oid = NULL; (oid = smi_foreach(oid, 0)) != NULL;) {
+ smi_oid2string(&oid->o_id, buf, sizeof(buf), oid_lookup);
+ printf("%s\n", buf);
+ }
+ return 0;
+}
+
+int
+snmpc_print(struct ber_element *elm)
+{
+ struct ber_oid oid;
+ char oids[SNMP_MAX_OID_STRLEN];
+ char *value;
+
+ elm = elm->be_sub;
+ if (ber_get_oid(elm, &oid) != 0) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ elm = elm->be_next;
+ value = smi_print_element(elm, smi_print_hint, output_string, oid_lookup);
+ if (value == NULL)
+ return 0;
+
+ if (print_varbind_only)
+ printf("%s\n", value);
+ else if (print_equals) {
+ smi_oid2string(&oid, oids, sizeof(oids), oid_lookup);
+ printf("%s = %s\n", oids, value);
+ } else {
+ smi_oid2string(&oid, oids, sizeof(oids), oid_lookup);
+ printf("%s %s\n", oids, value);
+ }
+ free(value);
+
+ return 1;
+}
+
+__dead void
+snmpc_printerror(enum snmp_error error, char *oid)
+{
+ switch (error)
+ {
+ case SNMP_ERROR_NONE:
+ errx(1, "No error, how did I get here?");
+ case SNMP_ERROR_TOOBIG:
+ errx(1, "Can't parse oid %s: Response too big", oid);
+ case SNMP_ERROR_NOSUCHNAME:
+ errx(1, "Can't parse oid %s: No such object", oid);
+ case SNMP_ERROR_BADVALUE:
+ errx(1, "Can't parse oid %s: Bad value", oid);
+ case SNMP_ERROR_READONLY:
+ errx(1, "Can't parse oid %s: Read only", oid);
+ case SNMP_ERROR_GENERR:
+ errx(1, "Can't parse oid %s: Generic error", oid);
+ case SNMP_ERROR_NOACCESS:
+ errx(1, "Can't parse oid %s: Access denied", oid);
+ case SNMP_ERROR_WRONGTYPE:
+ errx(1, "Can't parse oid %s: Wrong type", oid);
+ case SNMP_ERROR_WRONGLENGTH:
+ errx(1, "Can't parse oid %s: Wrong length", oid);
+ case SNMP_ERROR_WRONGENC:
+ errx(1, "Can't parse oid %s: Wrong encoding", oid);
+ case SNMP_ERROR_WRONGVALUE:
+ errx(1, "Can't parse oid %s: Wrong value", oid);
+ case SNMP_ERROR_NOCREATION:
+ errx(1, "Can't parse oid %s: Can't be created", oid);
+ case SNMP_ERROR_INCONVALUE:
+ errx(1, "Can't parse oid %s: Inconsistent value", oid);
+ case SNMP_ERROR_RESUNAVAIL:
+ errx(1, "Can't parse oid %s: Resource unavailable", oid);
+ case SNMP_ERROR_COMMITFAILED:
+ errx(1, "Can't parse oid %s: Commit failed", oid);
+ case SNMP_ERROR_UNDOFAILED:
+ errx(1, "Can't parse oid %s: Undo faild", oid);
+ case SNMP_ERROR_AUTHERROR:
+ errx(1, "Can't parse oid %s: Authorization error", oid);
+ case SNMP_ERROR_NOTWRITABLE:
+ errx(1, "Can't parse oid %s: Not writable", oid);
+ case SNMP_ERROR_INCONNAME:
+ errx(1, "Can't parse oid %s: Inconsistent name", oid);
+ }
+ errx(1, "Can't parse oid %s: Unknown error (%d)", oid, error);
+}
+
+int
+snmpc_parseagent(char *agent, char *defaultport)
+{
+ struct addrinfo hints, *ai, *ai0 = NULL;
+ struct sockaddr_un saddr;
+ char *agentdup, *specifier, *hostname, *port = NULL;
+ int error;
+ int s;
+
+ if ((agentdup = specifier = strdup(agent)) == NULL)
+ err(1, NULL);
+
+ bzero(&hints, sizeof(hints));
+ if ((hostname = strchr(specifier, ':')) != NULL) {
+ *hostname++ = '\0';
+ if (strcasecmp(specifier, "udp") == 0) {
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ } else if (strcasecmp(specifier, "tcp") == 0) {
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ } else if (strcasecmp(specifier, "udp6") == 0 ||
+ strcasecmp(specifier, "udpv6") == 0 ||
+ strcasecmp(specifier, "udpipv6") == 0) {
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_DGRAM;
+ } else if (strcasecmp(specifier, "tcp6") == 0 ||
+ strcasecmp(specifier, "tcpv6") == 0 ||
+ strcasecmp(specifier, "tcpipv6") == 0) {
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ } else if (strcasecmp(specifier, "unix") == 0) {
+ hints.ai_family = AF_UNIX;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_addr = (struct sockaddr *)&saddr;
+ hints.ai_addrlen = sizeof(saddr);
+ saddr.sun_len = sizeof(saddr);
+ saddr.sun_family = AF_UNIX;
+ if (strlcpy(saddr.sun_path, hostname,
+ sizeof(saddr.sun_path)) > sizeof(saddr.sun_path))
+ errx(1, "Hostname path too long");
+ ai = &hints;
+ } else {
+ port = hostname;
+ hostname = specifier;
+ specifier = NULL;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ }
+ if (port == NULL) {
+ if (hints.ai_family == AF_INET) {
+ if ((port = strchr(hostname, ':')) != NULL)
+ *port++ = '\0';
+ } else if (hints.ai_family == AF_INET6) {
+ if (hostname[0] == '[') {
+ hostname++;
+ if ((port = strchr(hostname, ']')) == NULL)
+ errx(1, "invalid agent");
+ *port++ = '\0';
+ if (port[0] == ':')
+ *port++ = '\0';
+ else
+ port = NULL;
+ } else {
+ if ((port = strrchr(hostname, ':')) == NULL)
+ errx(1, "invalid agent");
+ *port++ = '\0';
+ }
+ }
+ }
+ } else {
+ hostname = specifier;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ }
+
+ if (hints.ai_family != AF_UNIX) {
+ if (port == NULL)
+ port = defaultport;
+ error = getaddrinfo(hostname, port, &hints, &ai0);
+ if (error)
+ errx(1, "%s", gai_strerror(error));
+ s = -1;
+ for (ai = ai0; ai != NULL; ai = ai->ai_next) {
+ if ((s = socket(ai->ai_family, ai->ai_socktype,
+ ai->ai_protocol)) == -1)
+ continue;
+ break;
+ }
+ } else
+ s = socket(hints.ai_family, hints.ai_socktype,
+ hints.ai_protocol);
+ if (s == -1)
+ err(1, "socket");
+
+ if (connect(s, (struct sockaddr *)ai->ai_addr, ai->ai_addrlen) == -1)
+ err(1, "Can't connect to %s", agent);
+
+ if (ai0 != NULL)
+ freeaddrinfo(ai0);
+ free(agentdup);
+ return s;
+}
+
+__dead void
+usage(void)
+{
+ size_t i;
+
+ extern char *__progname;
+
+ if (snmp_app != NULL) {
+ fprintf(stderr, "usage: %s %s%s%s%s\n",
+ __progname, snmp_app->name,
+ snmp_app->usecommonopt ?
+ " [-c community] [-r retries] [-t timeout] "
+ "[-v protocol version] [-O afnqvxSQ]" : "",
+ snmp_app->usage == NULL ? "" : " ",
+ snmp_app->usage == NULL ? "" : snmp_app->usage);
+ exit(1);
+ }
+ fprintf(stderr, "usage: \n");
+ for (i = 0; i < (sizeof(snmp_apps)/sizeof(*snmp_apps)); i++) {
+ fprintf(stderr, "%*s %s%s%s%s\n",
+ (int) (sizeof("usage:") + strlen(__progname)),
+ __progname, snmp_apps[i].name,
+ snmp_apps[i].usecommonopt ?
+ " [-c community] [-r retries] [-t timeout] "
+ "[-v protocol version] [-O afnqvxSQ]" : "",
+ snmp_apps[i].usage == NULL ? "" : " ",
+ snmp_apps[i].usage == NULL ? "" : snmp_apps[i].usage);
+ }
+ exit(1);
+}