1/*	$OpenBSD: mib.c,v 1.9 2024/05/22 08:44:02 martijn Exp $	*/
2
3/*
4 * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org>
5 * Copyright (c) 2012 Joel Knight <joel@openbsd.org>
6 * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/signal.h>
23#include <sys/queue.h>
24#include <sys/proc.h>
25#include <sys/stat.h>
26#include <sys/socket.h>
27#include <sys/un.h>
28#include <sys/time.h>
29#include <sys/tree.h>
30#include <sys/utsname.h>
31#include <sys/sysctl.h>
32#include <sys/sensors.h>
33#include <sys/sched.h>
34#include <sys/mount.h>
35#include <sys/ioctl.h>
36#include <sys/disk.h>
37
38#include <netinet/in.h>
39#include <netinet/ip.h>
40#include <netinet/ip_carp.h>
41#include <netinet/ip_var.h>
42#include <arpa/inet.h>
43#include <net/if.h>
44#include <net/if_types.h>
45#include <net/pfvar.h>
46#include <netinet/ip_ipsp.h>
47#include <net/if_pfsync.h>
48
49#include <stdlib.h>
50#include <stdio.h>
51#include <errno.h>
52#include <event.h>
53#include <fcntl.h>
54#include <grp.h>
55#include <pwd.h>
56#include <string.h>
57#include <syslog.h>
58#include <time.h>
59#include <unistd.h>
60#include <libgen.h>
61#include <limits.h>
62#include <kvm.h>
63
64#include "log.h"
65#include "snmpd.h"
66#include "mib.h"
67
68struct event		 connev;
69const char		*agentxsocket = NULL;
70int			 agentxfd = -1;
71
72int			 pageshift;
73#define pagetok(size) ((size) << pageshift)
74
75void		 pageshift_init(void);
76void		 snmp_connect(struct agentx *, void *, int);
77void		 snmp_tryconnect(int, short, void *);
78void		 snmp_read(int, short, void *);
79
80struct agentx_context *sac;
81struct snmpd *snmpd_env;
82
83/* HOST-RESOURCES-MIB */
84struct agentx_object *hrSystemProcesses, *hrSystemMaxProcesses;
85struct agentx_index *hrStorageIdx;
86struct agentx_object *hrStorageIndex, *hrStorageType, *hrStorageDescr;
87struct agentx_object *hrStorageAllocationUnits, *hrStorageSize, *hrStorageUsed;
88struct agentx_object *hrStorageAllocationFailures;
89struct agentx_index *hrDeviceIdx;
90struct agentx_object *hrDeviceIndex, *hrDeviceType, *hrDeviceDescr, *hrDeviceID;
91struct agentx_object *hrDeviceStatus, *hrDeviceErrors, *hrProcessorFrwID;
92struct agentx_object *hrProcessorLoad;
93struct agentx_index *hrSWRunIdx;
94struct agentx_object *hrSWRunIndex, *hrSWRunName, *hrSWRunID, *hrSWRunPath;
95struct agentx_object *hrSWRunParameters, *hrSWRunType, *hrSWRunStatus;
96struct agentx_object *hrSWRunPerfCPU, *hrSWRunPerfMem;
97
98void	 mib_hrsystemuptime(struct agentx_varbind *);
99void	 mib_hrsystemdate(struct agentx_varbind *);
100void	 mib_hrsystemprocs(struct agentx_varbind *);
101void	 mib_hrmemory(struct agentx_varbind *);
102void	 mib_hrstorage(struct agentx_varbind *);
103void	 mib_hrdevice(struct agentx_varbind *);
104void	 mib_hrprocessor(struct agentx_varbind *);
105void	 mib_hrswrun(struct agentx_varbind *);
106
107int	 kinfo_proc_comp(const void *, const void *);
108int	 kinfo_proc(u_int32_t, struct kinfo_proc **);
109void	 kinfo_timer_cb(int, short, void *);
110void	 kinfo_proc_free(void);
111int	 kinfo_args(struct kinfo_proc *, char ***);
112int	 kinfo_path(struct kinfo_proc *, char **);
113int	 kinfo_parameters(struct kinfo_proc *, char **);
114
115/* IF-MIB */
116struct agentx_index *ifIdx;
117struct agentx_object *ifName, *ifInMulticastPkts, *ifInBroadcastPkts;
118struct agentx_object *ifOutMulticastPkts, *ifOutBroadcastPkts;
119struct agentx_object *ifOutBroadcastPkts, *ifHCInOctets, *ifHCInUcastPkts;
120struct agentx_object *ifHCInMulticastPkts, *ifHCInBroadcastPkts, *ifHCOutOctets;
121struct agentx_object *ifHCOutUcastPkts, *ifHCOutMulticastPkts;
122struct agentx_object *ifHCOutBroadcastPkts, *ifLinkUpDownTrapEnable;
123struct agentx_object *ifHighSpeed, *ifPromiscuousMode, *ifConnectorPresent;
124struct agentx_object *ifAlias, *ifCounterDiscontinuityTime;
125struct agentx_index *ifRcvAddressAddress;
126struct agentx_object *ifRcvAddressStatus, *ifRcvAddressType;
127struct agentx_object *ifStackLastChange, *ifNumber, *ifIndex, *ifDescr, *ifType;
128struct agentx_object *ifMtu, *ifSpeed, *ifPhysAddress, *ifAdminStatus;
129struct agentx_object *ifOperStatus, *ifLastChange, *ifInOctets, *ifInUcastPkts;
130struct agentx_object *ifInNUcastPkts, *ifInDiscards, *ifInErrors;
131struct agentx_object *ifInUnknownProtos, *ifOutOctets, *ifOutUcastPkts;
132struct agentx_object *ifOutNUcastPkts, *ifOutDiscards, *ifOutErrors, *ifOutQLen;
133struct agentx_object *ifSpecific;
134
135/* OPENBSD-PF-MIB */
136struct agentx_object *pfRunning, *pfRuntime, *pfDebug, *pfHostid;
137struct agentx_object *pfCntMatch, *pfCntBadOffset, *pfCntFragment, *pfCntShort;
138struct agentx_object *pfCntNormalize, *pfCntMemory, *pfCntTimestamp;
139struct agentx_object *pfCntCongestion, *pfCntIpOption, *pfCntProtoCksum;
140struct agentx_object *pfCntStateMismatch, *pfCntStateInsert, *pfCntStateLimit;
141struct agentx_object *pfCntSrcLimit, *pfCntSynproxy, *pfCntTranslate;
142struct agentx_object *pfCntNoRoute;
143struct agentx_object *pfStateCount, *pfStateSearches, *pfStateInserts;
144struct agentx_object *pfStateRemovals;
145struct agentx_object *pfLogIfName, *pfLogIfIpBytesIn, *pfLogIfIpBytesOut;
146struct agentx_object *pfLogIfIpPktsInPass, *pfLogIfIpPktsInDrop;
147struct agentx_object *pfLogIfIpPktsOutPass, *pfLogIfIpPktsOutDrop;
148struct agentx_object *pfLogIfIp6BytesIn, *pfLogIfIp6BytesOut;
149struct agentx_object *pfLogIfIp6PktsInPass, *pfLogIfIp6PktsInDrop;
150struct agentx_object *pfLogIfIp6PktsOutPass, *pfLogIfIp6PktsOutDrop;
151struct agentx_object *pfSrcTrackCount, *pfSrcTrackSearches, *pfSrcTrackInserts;
152struct agentx_object *pfSrcTrackRemovals;
153struct agentx_object *pfLimitStates, *pfLimitSourceNodes, *pfLimitFragments;
154struct agentx_object *pfLimitMaxTables, *pfLimitMaxTableEntries;
155struct agentx_object *pfTimeoutTcpFirst, *pfTimeoutTcpOpening;
156struct agentx_object *pfTimeoutTcpEstablished, *pfTimeoutTcpClosing;
157struct agentx_object *pfTimeoutTcpFinWait, *pfTimeoutTcpClosed;
158struct agentx_object *pfTimeoutUdpFirst, *pfTimeoutUdpSingle;
159struct agentx_object *pfTimeoutUdpMultiple, *pfTimeoutIcmpFirst;
160struct agentx_object *pfTimeoutIcmpError, *pfTimeoutOtherFirst;
161struct agentx_object *pfTimeoutOtherSingle, *pfTimeoutOtherMultiple;
162struct agentx_object *pfTimeoutFragment, *pfTimeoutInterval, *pfTimeoutInterval;
163struct agentx_object *pfTimeoutAdaptiveStart, *pfTimeoutAdaptiveEnd;
164struct agentx_object *pfTimeoutSrcTrack;
165struct agentx_index *pfIfIdx;
166struct agentx_object *pfIfNumber, *pfIfIndex, *pfIfDescr, *pfIfType, *pfIfRefs;
167struct agentx_object *pfIfRules, *pfIfIn4PassPkts, *pfIfIn4PassBytes;
168struct agentx_object *pfIfIn4BlockPkts, *pfIfIn4BlockBytes, *pfIfOut4PassPkts;
169struct agentx_object *pfIfOut4PassBytes, *pfIfOut4BlockPkts;
170struct agentx_object *pfIfOut4BlockBytes, *pfIfIn6PassPkts, *pfIfIn6PassBytes;
171struct agentx_object *pfIfIn6BlockPkts, *pfIfIn6BlockBytes, *pfIfOut6PassPkts;
172struct agentx_object *pfIfOut6PassBytes, *pfIfOut6BlockPkts;
173struct agentx_object *pfIfOut6BlockBytes;
174struct agentx_index *pfTblIdx;
175struct agentx_object *pfTblNumber, *pfTblIndex, *pfTblName, *pfTblAddresses;
176struct agentx_object *pfTblAnchorRefs, *pfTblRuleRefs, *pfTblEvalsMatch;
177struct agentx_object *pfTblEvalsNoMatch, *pfTblInPassPkts, *pfTblInPassBytes;
178struct agentx_object *pfTblInBlockPkts, *pfTblInBlockBytes, *pfTblInXPassPkts;
179struct agentx_object *pfTblInXPassBytes, *pfTblOutPassPkts, *pfTblOutPassBytes;
180struct agentx_object *pfTblOutBlockPkts, *pfTblOutBlockBytes;
181struct agentx_object *pfTblOutXPassPkts, *pfTblOutXPassBytes;
182struct agentx_object *pfTblStatsCleared, *pfTblInMatchPkts, *pfTblInMatchBytes;
183struct agentx_object *pfTblOutMatchPkts, *pfTblOutMatchBytes;
184struct agentx_index *pfTblAddrTblIdx, *pfTblAddrNetIdx, *pfTblAddrMaskIdx;
185struct agentx_object *pfTblAddrTblIndex, *pfTblAddrNet, *pfTblAddrMask;
186struct agentx_object *pfTblAddrCleared, *pfTblAddrInBlockPkts;
187struct agentx_object *pfTblAddrInBlockBytes, *pfTblAddrInPassPkts;
188struct agentx_object *pfTblAddrInPassBytes, *pfTblAddrOutBlockPkts;
189struct agentx_object *pfTblAddrOutBlockBytes, *pfTblAddrOutPassPkts;
190struct agentx_object *pfTblAddrOutPassBytes, *pfTblAddrInMatchPkts;
191struct agentx_object *pfTblAddrInMatchBytes, *pfTblAddrOutMatchPkts;
192struct agentx_object *pfTblAddrOutMatchBytes;
193struct agentx_index *pfLabelIdx;
194struct agentx_object *pfLabelNumber, *pfLabelIndex, *pfLabelName, *pfLabelEvals;
195struct agentx_object *pfLabelPkts, *pfLabelBytes, *pfLabelInPkts;
196struct agentx_object *pfLabelInBytes, *pfLabelOutPkts, *pfLabelOutBytes;
197struct agentx_object *pfLabelTotalStates;
198struct agentx_object *pfsyncIpPktsRecv, *pfsyncIp6PktsRecv;
199struct agentx_object *pfsyncPktDiscardsForBadInterface;
200struct agentx_object *pfsyncPktDiscardsForBadTtl, *pfsyncPktShorterThanHeader;
201struct agentx_object *pfsyncPktDiscardsForBadVersion;
202struct agentx_object *pfsyncPktDiscardsForBadAction;
203struct agentx_object *pfsyncPktDiscardsForBadLength;
204struct agentx_object *pfsyncPktDiscardsForBadAuth;
205struct agentx_object *pfsyncPktDiscardsForStaleState;
206struct agentx_object *pfsyncPktDiscardsForBadValues;
207struct agentx_object *pfsyncPktDiscardsForBadState;
208struct agentx_object *pfsyncIpPktsSent, *pfsyncIp6PktsSent, *pfsyncNoMemory;
209struct agentx_object *pfsyncOutputErrors;
210
211/* OPENBSD-SENSORS-MIB */
212struct agentx_index *sensorIdx;
213struct agentx_object *sensorNumber, *sensorIndex, *sensorDescr, *sensorType;
214struct agentx_object *sensorDevice, *sensorValue, *sensorUnits, *sensorStatus;
215
216/* OPENBSD-CARP-MIB */
217struct agentx_object *carpAllow, *carpPreempt, *carpLog;
218struct agentx_index *carpIfIdx;
219struct agentx_object *carpIfNumber, *carpIfIndex, *carpIfDescr, *carpIfVhid;
220struct agentx_object *carpIfDev, *carpIfAdvbase, *carpIfAdvskew, *carpIfState;
221struct agentx_index *carpGroupIdx;
222struct agentx_object *carpGroupIndex, *carpGroupName, *carpGroupDemote;
223struct agentx_object *carpIpPktsRecv, *carpIp6PktsRecv;
224struct agentx_object *carpPktDiscardsForBadInterface;
225struct agentx_object *carpPktDiscardsForWrongTtl, *carpPktShorterThanHeader;
226struct agentx_object *carpPktDiscardsForBadChecksum;
227struct agentx_object *carpPktDiscardsForBadVersion, *carpPktDiscardsForTooShort;
228struct agentx_object *carpPktDiscardsForBadAuth, *carpPktDiscardsForBadVhid;
229struct agentx_object *carpPktDiscardsForBadAddressList, *carpIpPktsSent;
230struct agentx_object *carpIp6PktsSent, *carpNoMemory, *carpTransitionsToMaster;
231
232/* OPENBSD-MEM-MIB */
233struct agentx_object *memMIBVersion, *memIfName, *memIfLiveLocks;
234
235/* IP-MIB */
236struct agentx_object *ipForwarding, *ipDefaultTTL, *ipInReceives;
237struct agentx_object *ipInHdrErrors, *ipInAddrErrors, *ipForwDatagrams;
238struct agentx_object *ipInUnknownProtos, *ipInDelivers, *ipOutRequests;
239struct agentx_object *ipOutDiscards, *ipOutNoRoutes, *ipReasmTimeout;
240struct agentx_object *ipReasmReqds, *ipReasmOKs, *ipReasmFails, *ipFragOKs;
241struct agentx_object *ipFragFails, *ipFragCreates, *ipAdEntAddr;
242struct agentx_index *ipAdEntAddrIdx;
243struct agentx_object *ipAdEntAddr, *ipAdEntIfIndex, *ipAdEntNetMask;
244struct agentx_object *ipAdEntBcastAddr, *ipAdEntReasmMaxSize;
245struct agentx_index *ipNetToMediaIfIdx, *ipNetToMediaNetAddressIdx;
246struct agentx_object *ipNetToMediaIfIndex, *ipNetToMediaPhysAddress;
247struct agentx_object *ipNetToMediaNetAddress, *ipNetToMediaType;
248
249/* IP-FORWARD-MIB */
250struct agentx_object *inetCidrRouteNumber;
251struct agentx_index *inetCidrRouteDestTypeIdx, *inetCidrRouteDestIdx;
252struct agentx_index *inetCidrRoutePfxLenIdx, *inetCidrRoutePolicyIdx;
253struct agentx_index *inetCidrRouteNextHopTypeIdx, *inetCidrRouteNextHopIdx;
254struct agentx_object *inetCidrRouteIfIndex, *inetCidrRouteType;
255struct agentx_object *inetCidrRouteProto, *inetCidrRouteAge;
256struct agentx_object *inetCidrRouteNextHopAS, *inetCidrRouteMetric1;
257struct agentx_object *inetCidrRouteMetric2, *inetCidrRouteMetric3;
258struct agentx_object *inetCidrRouteMetric4, *inetCidrRouteMetric5;
259struct agentx_object *inetCidrRouteStatus;
260
261/* UCD-DISKIO-MIB */
262struct agentx_index *diskIOIdx;
263struct agentx_object *diskIOIndex, *diskIODevice, *diskIONRead, *diskIONWritten;
264struct agentx_object *diskIOReads, *diskIOWrites, *diskIONReadX;
265struct agentx_object *diskIONWrittenX;
266
267/* BRIDGE-MIB */
268struct agentx_object *dot1dBaseNumPorts, *dot1dBaseType;
269struct agentx_index *dot1dBasePortIdx;
270struct agentx_object *dot1dBasePort, *dot1dBasePortIfIndex;
271struct agentx_object *dot1dBasePortCircuit, *dot1dBasePortDelayExceededDiscards;
272struct agentx_object *dot1dBasePortMtuExceededDiscards;
273
274/* HOST-RESOURCES-MIB */
275void
276mib_hrsystemuptime(struct agentx_varbind *vb)
277{
278	struct timespec  uptime;
279	long long	 ticks;
280
281	if (clock_gettime(CLOCK_BOOTTIME, &uptime) == -1) {
282		log_warn("clock_gettime");
283		agentx_varbind_error(vb);
284		return;
285	}
286	ticks = uptime.tv_sec * 100 + uptime.tv_nsec / 10000000;
287	agentx_varbind_timeticks(vb, ticks);
288}
289
290void
291mib_hrsystemdate(struct agentx_varbind *vb)
292{
293	struct tm	*ptm;
294	u_char		 s[11];
295	time_t		 now;
296	int		 tzoffset;
297	unsigned short	 year;
298
299	(void)time(&now);
300	ptm = localtime(&now);
301
302	if (ptm == NULL) {
303		log_warnx("localtime");
304		agentx_varbind_error(vb);
305		return;
306	}
307	year = htons(ptm->tm_year + 1900);
308	memcpy(s, &year, 2);
309	s[2] = ptm->tm_mon + 1;
310	s[3] = ptm->tm_mday;
311	s[4] = ptm->tm_hour;
312	s[5] = ptm->tm_min;
313	s[6] = ptm->tm_sec;
314	s[7] = 0;
315
316	tzoffset = ptm->tm_gmtoff;
317	if (tzoffset < 0)
318		s[8] = '-';
319	else
320		s[8] = '+';
321
322	s[9] = abs(tzoffset) / 3600;
323	s[10] = (abs(tzoffset) - (s[9] * 3600)) / 60;
324	agentx_varbind_nstring(vb, s, sizeof(s));
325}
326
327void
328mib_hrsystemprocs(struct agentx_varbind *vb)
329{
330	struct agentx_object	*obj;
331	char			 errbuf[_POSIX2_LINE_MAX];
332	int			 val;
333	int			 mib[] = { CTL_KERN, KERN_MAXPROC };
334	kvm_t			*kd;
335	size_t			 len;
336
337	obj = agentx_varbind_get_object(vb);
338	if (obj == hrSystemProcesses) {
339		if ((kd = kvm_openfiles(NULL, NULL, NULL,
340		    KVM_NO_FILES, errbuf)) == NULL) {
341			log_warn("kvm_openfiles");
342			agentx_varbind_error(vb);
343			return;
344		}
345
346		if (kvm_getprocs(kd, KERN_PROC_ALL, 0,
347		    sizeof(struct kinfo_proc), &val) == NULL) {
348			log_warn("kvm_getprocs");
349			kvm_close(kd);
350			agentx_varbind_error(vb);
351			return;
352		}
353
354		agentx_varbind_gauge32(vb, val);
355
356		kvm_close(kd);
357	} else if (obj == hrSystemMaxProcesses) {
358		len = sizeof(val);
359		if (sysctl(mib, 2, &val, &len, NULL, 0) == -1) {
360			log_warn("sysctl");
361			agentx_varbind_error(vb);
362			return;
363		}
364
365		agentx_varbind_integer(vb, val);
366	} else
367		fatal("%s: Unexpected object", __func__);
368}
369
370void
371mib_hrmemory(struct agentx_varbind *vb)
372{
373	int			 mib[] = { CTL_HW, HW_PHYSMEM64 };
374	u_int64_t		 physmem;
375	size_t			 len = sizeof(physmem);
376
377	if (sysctl(mib, nitems(mib), &physmem, &len, NULL, 0) == -1) {
378		log_warn("sysctl");
379		agentx_varbind_error(vb);
380		return;
381	}
382
383	agentx_varbind_integer(vb, physmem / 1024);
384}
385
386void
387mib_hrstorage(struct agentx_varbind *vb)
388{
389	struct agentx_object		*obj;
390	enum agentx_request_type	 req;
391	int32_t				 idx;
392	struct statfs			*mntbuf, *mnt;
393	int				 mntsize, maxsize;
394	uint64_t			 units, size, used, fail = 0;
395	const char			*descr = NULL;
396	int				 mib[] = { CTL_HW, 0 };
397	u_int64_t			 physmem, realmem;
398	struct uvmexp			 uvm;
399	size_t				 len;
400	uint32_t			 sop[] = { HRSTORAGEOTHER };
401
402	/* Physical memory, real memory, swap */
403	mib[1] = HW_PHYSMEM64;
404	len = sizeof(physmem);
405	if (sysctl(mib, nitems(mib), &physmem, &len, NULL, 0) == -1) {
406		log_warn("sysctl");
407		agentx_varbind_error(vb);
408		return;
409	}
410	mib[1] = HW_USERMEM64;
411	len = sizeof(realmem);
412	if (sysctl(mib, nitems(mib), &realmem, &len, NULL, 0) == -1) {
413		log_warn("sysctl");
414		agentx_varbind_error(vb);
415		return;
416	}
417	mib[0] = CTL_VM;
418	mib[1] = VM_UVMEXP;
419	len = sizeof(uvm);
420	if (sysctl(mib, nitems(mib), &uvm, &len, NULL, 0) == -1) {
421		log_warn("sysctl");
422		agentx_varbind_error(vb);
423		return;
424	}
425	maxsize = 10;
426
427	/* Disks */
428	if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
429		log_warn("getmntinfo");
430		agentx_varbind_error(vb);
431		return;
432	}
433	maxsize = 30 + mntsize;
434
435	/*
436	 * Get and verify the current row index.
437	 *
438	 * We use a special mapping here that is inspired by other SNMP
439	 * agents: index 1 + 2 for RAM, index 10 for swap, index 31 and
440	 * higher for disk storage.
441	 */
442	obj = agentx_varbind_get_object(vb);
443	req = agentx_varbind_request(vb);
444	idx = agentx_varbind_get_index_integer(vb, hrStorageIdx);
445	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
446		if (idx == INT32_MAX) {
447			agentx_varbind_notfound(vb);
448			return;
449		}
450		idx++;
451	}
452	if (idx > maxsize) {
453		agentx_varbind_notfound(vb);
454		return;
455	}
456	if (req == AGENTX_REQUEST_TYPE_GET) {
457		if (idx < 1 || (idx > 2 && idx < 10) ||
458		    (idx > 10 && idx < 31)) {
459			agentx_varbind_notfound(vb);
460			return;
461		}
462	} else {
463		if (idx < 1)
464			idx = 1;
465		else if (idx > 2 && idx < 10)
466			idx = 10;
467		else if (idx > 10 && idx < 31)
468			idx = 31;
469	}
470
471	switch (idx) {
472	case 1:
473		descr = "Physical memory";
474		units = uvm.pagesize;
475		size = physmem / uvm.pagesize;
476		used = size - uvm.free;
477		memcpy(sop, (uint32_t[]){ HRSTORAGERAM }, sizeof(sop));
478		break;
479	case 2:
480		descr = "Real memory";
481		units = uvm.pagesize;
482		size = realmem / uvm.pagesize;
483		used = size - uvm.free;
484		memcpy(sop, (uint32_t[]){ HRSTORAGERAM }, sizeof(sop));
485		break;
486	case 10:
487		descr = "Swap space";
488		units = uvm.pagesize;
489		size = uvm.swpages;
490		used = uvm.swpginuse;
491		memcpy(sop, (uint32_t[]){ HRSTORAGEVIRTUALMEMORY },
492		    sizeof(sop));
493		break;
494	default:
495		mnt = &mntbuf[idx - 31];
496		descr = mnt->f_mntonname;
497		units = mnt->f_bsize;
498		size = mnt->f_blocks;
499		used = mnt->f_blocks - mnt->f_bfree;
500		memcpy(sop, (uint32_t[]){ HRSTORAGEFIXEDDISK }, sizeof(sop));
501		break;
502	}
503
504	while (size > INT32_MAX) {
505		units *= 2;
506		size /= 2;
507		used /= 2;
508	}
509
510	agentx_varbind_set_index_integer(vb, hrStorageIdx, idx);
511
512	if (obj == hrStorageIndex)
513		agentx_varbind_integer(vb, idx);
514	else if (obj == hrStorageType)
515		agentx_varbind_oid(vb, sop, nitems(sop));
516	else if (obj == hrStorageDescr)
517		agentx_varbind_string(vb, descr);
518	else if (obj == hrStorageAllocationUnits)
519		agentx_varbind_integer(vb, units);
520	else if (obj == hrStorageSize)
521		agentx_varbind_integer(vb, size);
522	else if (obj == hrStorageUsed)
523		agentx_varbind_integer(vb, used);
524	else if (obj == hrStorageAllocationFailures)
525		agentx_varbind_counter32(vb, fail);
526	else
527		fatal("%s: Unexpected object", __func__);
528}
529
530void
531mib_hrdevice(struct agentx_varbind *vb)
532{
533	struct agentx_object		*obj;
534	enum agentx_request_type	 req;
535	int32_t				 idx;
536	uint32_t			 fail = 0;
537	int				 status;
538	int				 mib[] = { CTL_HW, HW_MODEL };
539	size_t				 len;
540	char				 descr[BUFSIZ];
541	uint32_t			 sop[] = { HRDEVICEPROCESSOR };
542
543	/* Get and verify the current row index */
544	obj = agentx_varbind_get_object(vb);
545	idx = agentx_varbind_get_index_integer(vb, hrDeviceIdx);
546	req = agentx_varbind_request(vb);
547	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
548		if (idx == INT32_MAX) {
549			agentx_varbind_notfound(vb);
550			return;
551		}
552		idx++;
553		if (idx < 1)
554			idx = 1;
555	} else if (req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
556		if (idx < 1)
557			idx = 1;
558	}
559	if (idx < 1 || idx > snmpd_env->sc_ncpu) {
560		agentx_varbind_notfound(vb);
561		return;
562	}
563
564	agentx_varbind_set_index_integer(vb, hrDeviceIdx, idx);
565
566	len = sizeof(descr);
567	if (sysctl(mib, nitems(mib), &descr, &len, NULL, 0) == -1) {
568		log_warn("sysctl");
569		agentx_varbind_error(vb);
570		return;
571	}
572	/* unknown(1), running(2), warning(3), testing(4), down(5) */
573	status = 2;
574
575	if (obj == hrDeviceIndex)
576		agentx_varbind_integer(vb, idx);
577	else if (obj == hrDeviceType)
578		agentx_varbind_oid(vb, sop, nitems(sop));
579	else if (obj == hrDeviceDescr)
580		agentx_varbind_string(vb, descr);
581	else if (obj == hrDeviceID)
582		agentx_varbind_oid(vb, AGENTX_OID(0, 0));
583	else if (obj == hrDeviceStatus)
584		agentx_varbind_integer(vb, status);
585	else if (obj == hrDeviceErrors)
586		agentx_varbind_counter32(vb, fail);
587	else
588		fatal("%s: Unexpected object", __func__);
589}
590
591void
592mib_hrprocessor(struct agentx_varbind *vb)
593{
594	struct agentx_object		*obj;
595	enum agentx_request_type	 req;
596	int32_t				 idx;
597	int64_t				*cptime2, val;
598
599	obj = agentx_varbind_get_object(vb);
600	idx = agentx_varbind_get_index_integer(vb, hrDeviceIdx);
601	req = agentx_varbind_request(vb);
602	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
603		if (idx == INT32_MAX) {
604			agentx_varbind_notfound(vb);
605			return;
606		}
607		idx++;
608		if (idx < 1)
609			idx = 1;
610	}
611	else if (req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
612		if (idx < 1)
613			idx = 1;
614	}
615	if (idx < 1 || idx > snmpd_env->sc_ncpu) {
616		agentx_varbind_notfound(vb);
617		return;
618	}
619
620	agentx_varbind_set_index_integer(vb, hrDeviceIdx, idx);
621
622	if (obj == hrProcessorFrwID)
623		agentx_varbind_oid(vb, AGENTX_OID(0, 0));
624	else if (obj == hrProcessorLoad) {
625		/*
626		 * The percentage of time that the system was not
627		 * idle during the last minute.
628		 */
629		if (snmpd_env->sc_cpustates == NULL) {
630			log_warnx("cpustates not initialized");
631			agentx_varbind_error(vb);
632			return;
633		}
634		cptime2 = snmpd_env->sc_cpustates + (CPUSTATES * (idx - 1));
635		val = 100 -
636		    (cptime2[CP_IDLE] > 1000 ? 1000 : (cptime2[CP_IDLE] / 10));
637		agentx_varbind_integer(vb, val);
638	} else
639		fatal("%s: Unexpected object", __func__);
640}
641
642void
643mib_hrswrun(struct agentx_varbind *vb)
644{
645	struct agentx_object		*obj;
646	enum agentx_request_type	 req;
647	int32_t				 idx;
648	int32_t				 time;
649	struct kinfo_proc		*kinfo;
650	char				*s;
651
652	obj = agentx_varbind_get_object(vb);
653	idx = agentx_varbind_get_index_integer(vb, hrSWRunIdx);
654	req = agentx_varbind_request(vb);
655
656	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
657		if (idx == INT32_MAX) {
658			agentx_varbind_notfound(vb);
659			return;
660		}
661		idx++;
662	}
663	/* Get and verify the current row index */
664	if (kinfo_proc(idx, &kinfo) == -1) {
665		log_warn("kinfo_proc");
666		agentx_varbind_error(vb);
667		return;
668	}
669
670	if (kinfo == NULL) {
671		agentx_varbind_notfound(vb);
672		return;
673	}
674	if (req == AGENTX_REQUEST_TYPE_GET) {
675		if (kinfo->p_pid != idx) {
676			agentx_varbind_notfound(vb);
677			return;
678		}
679	}
680	agentx_varbind_set_index_integer(vb, hrSWRunIdx, kinfo->p_pid);
681
682	if (obj == hrSWRunIndex)
683		agentx_varbind_integer(vb, kinfo->p_pid);
684	else if (obj == hrSWRunName)
685		agentx_varbind_string(vb, kinfo->p_comm);
686 	else if (obj == hrSWRunPath) {
687		if (kinfo_path(kinfo, &s) == -1) {
688			log_warn("kinfo_path");
689			agentx_varbind_error(vb);
690			return;
691		}
692
693		agentx_varbind_string(vb, s);
694	} else if (obj == hrSWRunID)
695		agentx_varbind_oid(vb, AGENTX_OID(0, 0));
696	else if (obj == hrSWRunParameters) {
697		if (kinfo_parameters(kinfo, &s) == -1) {
698			log_warn("kinfo_parameters");
699			agentx_varbind_error(vb);
700			return;
701		}
702
703		agentx_varbind_string(vb, s);
704	} else if (obj == hrSWRunType) {
705		if (kinfo->p_flag & P_SYSTEM) {
706			/* operatingSystem(2) */
707			agentx_varbind_integer(vb, 2);
708		} else {
709			/* application(4) */
710			agentx_varbind_integer(vb, 4);
711		}
712	} else if (obj == hrSWRunStatus) {
713		switch (kinfo->p_stat) {
714		case SONPROC:
715			/* running(1) */
716			agentx_varbind_integer(vb, 1);
717			break;
718		case SIDL:
719		case SRUN:
720		case SSLEEP:
721			/* runnable(2) */
722			agentx_varbind_integer(vb, 2);
723			break;
724		case SSTOP:
725			/* notRunnable(3) */
726			agentx_varbind_integer(vb, 3);
727			break;
728		case SDEAD:
729		default:
730			/* invalid(4) */
731			agentx_varbind_integer(vb, 4);
732			break;
733		}
734	} else if (obj == hrSWRunPerfCPU) {
735		time = kinfo->p_rtime_sec * 100;
736		time += (kinfo->p_rtime_usec + 5000) / 10000;
737		agentx_varbind_integer(vb, time);
738	} else if (obj == hrSWRunPerfMem) {
739		agentx_varbind_integer(vb, pagetok(kinfo->p_vm_tsize +
740		    kinfo->p_vm_dsize + kinfo->p_vm_ssize));
741	} else
742		fatal("%s: Unexpected object", __func__);
743}
744
745int
746kinfo_proc_comp(const void *a, const void *b)
747{
748	struct kinfo_proc * const *k1 = a;
749	struct kinfo_proc * const *k2 = b;
750
751	return (((*k1)->p_pid > (*k2)->p_pid) ? 1 : -1);
752}
753
754static struct event	  kinfo_timer;
755static struct kinfo_proc *kp = NULL;
756static struct kinfo_proc **klist = NULL;
757static size_t		  nkp = 0, nklist = 0;
758
759int
760kinfo_proc(u_int32_t idx, struct kinfo_proc **kinfo)
761{
762	int		 mib[] = { CTL_KERN, KERN_PROC,
763			    KERN_PROC_ALL, 0, sizeof(*kp), 0 };
764	size_t		 size, count, i;
765	struct timeval	 timer;
766
767	if (kp != NULL && klist != NULL)
768		goto cached;
769
770	kinfo_proc_free();
771	for (;;) {
772		size = nkp * sizeof(*kp);
773		mib[5] = nkp;
774		if (sysctl(mib, nitems(mib), kp, &size, NULL, 0) == -1) {
775			if (errno == ENOMEM) {
776				kinfo_proc_free();
777				continue;
778			}
779
780			return (-1);
781		}
782
783		count = size / sizeof(*kp);
784		if (count <= nkp)
785			break;
786
787		kp = malloc(size);
788		if (kp == NULL) {
789			kinfo_proc_free();
790			return (-1);
791		}
792		nkp = count;
793	}
794
795	klist = calloc(count, sizeof(*klist));
796	if (klist == NULL) {
797		kinfo_proc_free();
798		return (-1);
799	}
800	nklist = count;
801
802	for (i = 0; i < nklist; i++)
803		klist[i] = &kp[i];
804	qsort(klist, nklist, sizeof(*klist), kinfo_proc_comp);
805
806	evtimer_set(&kinfo_timer, kinfo_timer_cb, NULL);
807	timer.tv_sec = 5;
808	timer.tv_usec = 0;
809	evtimer_add(&kinfo_timer, &timer);
810
811cached:
812	*kinfo = NULL;
813	for (i = 0; i < nklist; i++) {
814		if (klist[i]->p_pid >= (int32_t)idx) {
815			*kinfo = klist[i];
816			break;
817		}
818	}
819
820	return (0);
821}
822
823void
824kinfo_timer_cb(int fd, short event, void *arg)
825{
826	kinfo_proc_free();
827}
828
829void
830kinfo_proc_free(void)
831{
832	free(kp);
833	kp = NULL;
834	nkp = 0;
835	free(klist);
836	klist = NULL;
837	nklist = 0;
838}
839
840int
841kinfo_args(struct kinfo_proc *kinfo, char ***s)
842{
843	static char		*buf = NULL;
844	static size_t		 buflen = 128;
845
846	int			 mib[] = { CTL_KERN, KERN_PROC_ARGS,
847				    kinfo->p_pid, KERN_PROC_ARGV };
848	char			*nbuf;
849
850	*s = NULL;
851	if (buf == NULL) {
852		buf = malloc(buflen);
853		if (buf == NULL)
854			return (-1);
855	}
856
857	while (sysctl(mib, nitems(mib), buf, &buflen, NULL, 0) == -1) {
858		if (errno != ENOMEM) {
859			/* some errors are expected, dont get too upset */
860			return (0);
861		}
862
863		nbuf = realloc(buf, buflen + 128);
864		if (nbuf == NULL)
865			return (-1);
866
867		buf = nbuf;
868		buflen += 128;
869	}
870
871	*s = (char **)buf;
872	return (0);
873}
874
875int
876kinfo_path(struct kinfo_proc *kinfo, char **s)
877{
878	static char		 str[129];
879	char			**argv;
880
881	if (kinfo_args(kinfo, &argv) == -1)
882		return (-1);
883
884	str[0] = '\0';
885	*s = str;
886	if (argv != NULL && argv[0] != NULL)
887		strlcpy(str, argv[0], sizeof(str));
888	return (0);
889}
890
891int
892kinfo_parameters(struct kinfo_proc *kinfo, char **s)
893{
894	static char		 str[129];
895	char			**argv;
896
897	if (kinfo_args(kinfo, &argv) == -1)
898		return (-1);
899
900	str[0] = '\0';
901	*s = str;
902	if (argv == NULL || argv[0] == NULL)
903		return (0);
904	argv++;
905
906	while (*argv != NULL) {
907		strlcat(str, *argv, sizeof(str));
908		argv++;
909		if (*argv != NULL)
910			strlcat(str, " ", sizeof(str));
911	}
912
913	return (0);
914}
915
916/*
917 * Defined in IF-MIB.txt (RFCs 1229, 1573, 2233, 2863)
918 */
919
920void	 mib_ifnumber(struct agentx_varbind *);
921struct kif
922	*mib_ifget(u_int);
923void	 mib_iftable(struct agentx_varbind *);
924void	 mib_ifxtable(struct agentx_varbind *);
925void	 mib_ifstacklast(struct agentx_varbind *);
926void	 mib_ifrcvtable(struct agentx_varbind *);
927
928static uint8_t ether_zeroaddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
929
930void
931mib_ifnumber(struct agentx_varbind *vb)
932{
933	agentx_varbind_integer(vb, kr_ifnumber());
934}
935
936struct kif *
937mib_ifget(u_int idx)
938{
939	struct kif	*kif;
940
941	if ((kif = kr_getif(idx)) == NULL) {
942		/*
943		 * It may happen that an interface with a specific index
944		 * does not exist or has been removed. Jump to the next
945		 * available interface index.
946		 */
947		for (kif = kr_getif(0); kif != NULL;
948		    kif = kr_getnextif(kif->if_index))
949			if (kif->if_index > idx)
950				break;
951		if (kif == NULL)
952			return (NULL);
953	}
954	idx = kif->if_index;
955
956	/* Update interface information */
957	kr_updateif(idx);
958	if ((kif = kr_getif(idx)) == NULL) {
959		log_debug("mib_ifxtable: interface %d disappeared?", idx);
960		return (NULL);
961	}
962
963	return (kif);
964}
965
966void
967mib_iftable(struct agentx_varbind *vb)
968{
969	struct agentx_object		*obj;
970	enum agentx_request_type	 req;
971	int32_t				 idx = 0;
972	struct kif			*kif;
973	long long			 i;
974
975	obj = agentx_varbind_get_object(vb);
976	idx = agentx_varbind_get_index_integer(vb, ifIdx);
977	req = agentx_varbind_request(vb);
978	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
979		if (idx == INT32_MAX) {
980			agentx_varbind_notfound(vb);
981			return;
982		}
983		idx++;
984	}
985	if ((kif = mib_ifget(idx)) == NULL) {
986		agentx_varbind_notfound(vb);
987		return;
988	}
989	if (req == AGENTX_REQUEST_TYPE_GET) {
990		if (idx != kif->if_index) {
991			agentx_varbind_notfound(vb);
992			return;
993		}
994	}
995	agentx_varbind_set_index_integer(vb, ifIdx, kif->if_index);
996
997	if (obj == ifIndex)
998		agentx_varbind_integer(vb, kif->if_index);
999	else if (obj == ifDescr) {
1000		/*
1001		 * The ifDescr should contain a vendor, product, etc.
1002		 * but we just use the interface name (like ifName).
1003		 * The interface name includes the driver name on OpenBSD.
1004		 */
1005		agentx_varbind_string(vb, kif->if_name);
1006	} else if (obj == ifType) {
1007		if (kif->if_type >= 0xf0) {
1008			/*
1009			 * It does not make sense to announce the private
1010			 * interface types for CARP, ENC, PFSYNC, etc.
1011			 */
1012			agentx_varbind_integer(vb, IFT_OTHER);
1013		} else
1014			agentx_varbind_integer(vb, kif->if_type);
1015	} else if (obj == ifMtu)
1016		agentx_varbind_integer(vb, kif->if_mtu);
1017	else if (obj == ifSpeed) {
1018		if (kif->if_baudrate > UINT32_MAX) {
1019			/* speed should be obtained from ifHighSpeed instead */
1020			agentx_varbind_gauge32(vb, UINT32_MAX);
1021		} else
1022			agentx_varbind_gauge32(vb, kif->if_baudrate);
1023	} else if (obj == ifPhysAddress) {
1024		if (bcmp(kif->if_lladdr, ether_zeroaddr,
1025		    sizeof(kif->if_lladdr)) == 0) {
1026			agentx_varbind_string(vb, "");
1027		} else {
1028			agentx_varbind_nstring(vb, kif->if_lladdr,
1029			    sizeof(kif->if_lladdr));
1030		}
1031	} else if (obj == ifAdminStatus) {
1032		/* ifAdminStatus up(1), down(2), testing(3) */
1033		i = (kif->if_flags & IFF_UP) ? 1 : 2;
1034		agentx_varbind_integer(vb, i);
1035	} else if (obj == ifOperStatus) {
1036		if ((kif->if_flags & IFF_UP) == 0)
1037			i = 2;	/* down(2) */
1038		else if (kif->if_link_state == LINK_STATE_UNKNOWN)
1039			i = 4;	/* unknown(4) */
1040		else if (LINK_STATE_IS_UP(kif->if_link_state))
1041			i = 1;	/* up(1) */
1042		else
1043			i = 7;	/* lowerLayerDown(7) or dormant(5)? */
1044		agentx_varbind_integer(vb, i);
1045	} else if (obj == ifLastChange)
1046		agentx_varbind_timeticks(vb, kif->if_ticks);
1047	else if (obj == ifInOctets)
1048		agentx_varbind_counter32(vb, (uint32_t)kif->if_ibytes);
1049	else if (obj == ifInUcastPkts)
1050		agentx_varbind_counter32(vb, (uint32_t)kif->if_ipackets);
1051	else if (obj == ifInNUcastPkts)
1052		agentx_varbind_counter32(vb, (uint32_t)kif->if_imcasts);
1053	else if (obj == ifInDiscards)
1054		agentx_varbind_counter32(vb, (uint32_t)kif->if_iqdrops);
1055	else if (obj == ifInErrors)
1056		agentx_varbind_counter32(vb, (uint32_t)kif->if_ierrors);
1057	else if (obj == ifInUnknownProtos)
1058		agentx_varbind_counter32(vb, (uint32_t)kif->if_noproto);
1059	else if (obj == ifOutOctets)
1060		agentx_varbind_counter32(vb, (uint32_t)kif->if_obytes);
1061	else if (obj == ifOutUcastPkts)
1062		agentx_varbind_counter32(vb, (uint32_t)kif->if_opackets);
1063	else if (obj == ifOutNUcastPkts)
1064		agentx_varbind_counter32(vb, (uint32_t)kif->if_omcasts);
1065	else if (obj == ifOutDiscards)
1066		agentx_varbind_counter32(vb, (uint32_t)kif->if_oqdrops);
1067	else if (obj == ifOutErrors)
1068		agentx_varbind_counter32(vb, (uint32_t)kif->if_oerrors);
1069	else if (obj == ifOutQLen)
1070		agentx_varbind_gauge32(vb, 0);
1071	else if (obj == ifSpecific)
1072		agentx_varbind_oid(vb, AGENTX_OID(0, 0));
1073	else
1074		fatal("%s: Unexpected object", __func__);
1075}
1076
1077void
1078mib_ifxtable(struct agentx_varbind *vb)
1079{
1080	struct agentx_object		*obj;
1081	enum agentx_request_type	 req;
1082	int32_t				 idx = 0;
1083	struct kif			*kif;
1084	int				 i = 0;
1085
1086	obj = agentx_varbind_get_object(vb);
1087	idx = agentx_varbind_get_index_integer(vb, ifIdx);
1088	req = agentx_varbind_request(vb);
1089	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
1090		if (idx == INT32_MAX) {
1091			agentx_varbind_notfound(vb);
1092			return;
1093		}
1094		idx++;
1095	}
1096	if ((kif = mib_ifget(idx)) == NULL) {
1097		agentx_varbind_notfound(vb);
1098		return;
1099	}
1100	if (req == AGENTX_REQUEST_TYPE_GET) {
1101		if (idx != kif->if_index) {
1102			agentx_varbind_notfound(vb);
1103			return;
1104		}
1105	}
1106	agentx_varbind_set_index_integer(vb, ifIdx, kif->if_index);
1107
1108	if (obj == ifName)
1109		agentx_varbind_string(vb, kif->if_name);
1110	else if (obj == ifInMulticastPkts)
1111		agentx_varbind_counter32(vb, (uint32_t)kif->if_imcasts);
1112	else if (obj == ifInBroadcastPkts)
1113		agentx_varbind_counter32(vb, 0);
1114	else if (obj == ifOutMulticastPkts)
1115		agentx_varbind_counter32(vb, (uint32_t)kif->if_omcasts);
1116	else if (obj == ifOutBroadcastPkts)
1117		agentx_varbind_counter32(vb, 0);
1118	else if (obj == ifHCInOctets)
1119		agentx_varbind_counter64(vb, (uint64_t)kif->if_ibytes);
1120	else if (obj == ifHCInUcastPkts)
1121		agentx_varbind_counter64(vb, (uint64_t)kif->if_ipackets);
1122	else if (obj == ifHCInMulticastPkts)
1123		agentx_varbind_counter64(vb, (uint64_t)kif->if_imcasts);
1124	else if (obj == ifHCInBroadcastPkts)
1125		agentx_varbind_counter64(vb, 0);
1126	else if (obj == ifHCOutOctets)
1127		agentx_varbind_counter64(vb, (uint64_t)kif->if_obytes);
1128	else if (obj == ifHCOutUcastPkts)
1129		agentx_varbind_counter64(vb, (uint64_t)kif->if_opackets);
1130	else if (obj == ifHCOutMulticastPkts)
1131		agentx_varbind_counter64(vb, (uint64_t)kif->if_omcasts);
1132	else if (obj == ifHCOutBroadcastPkts)
1133		agentx_varbind_counter64(vb, 0);
1134	else if (obj == ifLinkUpDownTrapEnable)
1135		agentx_varbind_integer(vb, 0);	/* enabled(1), disabled(2) */
1136	else if (obj == ifHighSpeed) {
1137		i = kif->if_baudrate >= 1000000 ?
1138		    kif->if_baudrate / 1000000 : 0;
1139		agentx_varbind_gauge32(vb, i);
1140	} else if (obj == ifPromiscuousMode) {
1141		/* ifPromiscuousMode: true(1), false(2) */
1142		i = kif->if_flags & IFF_PROMISC ? 1 : 2;
1143		agentx_varbind_integer(vb, i);
1144	} else if (obj == ifConnectorPresent) {
1145		/* ifConnectorPresent: false(2), true(1) */
1146		i = kif->if_type == IFT_ETHER ? 1 : 2;
1147		agentx_varbind_integer(vb, i);
1148	} else if (obj == ifAlias)
1149		agentx_varbind_string(vb, kif->if_descr);
1150	else if (obj == ifCounterDiscontinuityTime)
1151		agentx_varbind_timeticks(vb, 0);
1152	else
1153		fatal("%s: Unexpected object", __func__);
1154}
1155
1156void
1157mib_ifstacklast(struct agentx_varbind *vb)
1158{
1159	agentx_varbind_timeticks(vb, kr_iflastchange());
1160}
1161
1162void
1163mib_ifrcvtable(struct agentx_varbind *vb)
1164{
1165	struct agentx_object		*obj;
1166	enum agentx_request_type	 req;
1167	int32_t				 idx = 0;
1168	const uint8_t			*lladdr;
1169	struct kif			*kif;
1170	int				 i = 0, llcmp, impl;
1171	size_t				 slen;
1172
1173	obj = agentx_varbind_get_object(vb);
1174	idx = agentx_varbind_get_index_integer(vb, ifIdx);
1175	lladdr = (const uint8_t *)agentx_varbind_get_index_string(vb,
1176	    ifRcvAddressAddress, &slen, &impl);
1177	if (lladdr == NULL)
1178		lladdr = ether_zeroaddr;
1179	req = agentx_varbind_request(vb);
1180
1181	if ((kif = mib_ifget(idx)) == NULL) {
1182		agentx_varbind_notfound(vb);
1183		return;
1184	}
1185	/*
1186	 * The lladdr of the interface will be encoded in the returned OID
1187	 * ifRcvAddressX.ifindex.6.x.x.x.x.x.x = val
1188	 * Thanks to the virtual cloner interfaces, it is an easy 1:1
1189	 * mapping in OpenBSD; only one lladdr (MAC) address per interface.
1190	 */
1191	if (slen == 6)
1192		llcmp = bcmp(lladdr, kif->if_lladdr, sizeof(kif->if_lladdr));
1193	if (req == AGENTX_REQUEST_TYPE_GET) {
1194		if (idx != kif->if_index || slen != 6 || llcmp != 0) {
1195			agentx_varbind_notfound(vb);
1196			return;
1197		}
1198	} else if (idx == kif->if_index) {
1199		if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
1200			if (slen > 6 || llcmp >= 0)
1201				kif = kr_getnextif(kif->if_index);
1202		} else {
1203			if (slen > 6 || llcmp > 0)
1204				kif = kr_getnextif(kif->if_index);
1205		}
1206		if (kif == NULL) {
1207			agentx_varbind_notfound(vb);
1208			return;
1209		}
1210	}
1211	agentx_varbind_set_index_integer(vb, ifIdx, kif->if_index);
1212	agentx_varbind_set_index_nstring(vb, ifRcvAddressAddress,
1213	    kif->if_lladdr, sizeof(kif->if_lladdr));
1214
1215	if (obj == ifRcvAddressStatus) {
1216		/* ifRcvAddressStatus: RowStatus active(1), notInService(2) */
1217		i = kif->if_flags & IFF_UP ? 1 : 2;
1218		agentx_varbind_integer(vb, i);
1219	} else if (obj == ifRcvAddressType) {
1220		/* ifRcvAddressType: other(1), volatile(2), nonVolatile(3) */
1221		agentx_varbind_integer(vb, 1);
1222	} else
1223		fatal("%s: Unexpected object", __func__);
1224}
1225
1226/*
1227 * Defined in
1228 * - OPENBSD-PF-MIB.txt
1229 * - OPENBSD-SENSORS-MIB.txt
1230 * - OPENBSD-CARP-MIB.txt
1231 * (http://www.packetmischief.ca/openbsd-snmp-mibs/)
1232 */
1233#define OIDVER_OPENBSD_MEM		1
1234
1235struct carpif {
1236	struct carpreq	 carpr;
1237	struct kif	 kif;
1238};
1239
1240void	 mib_close_pftrans(struct agentx_varbind *, u_int32_t);
1241
1242void	 mib_pfinfo(struct agentx_varbind *);
1243void	 mib_pfcounters(struct agentx_varbind *);
1244void	 mib_pfscounters(struct agentx_varbind *);
1245void	 mib_pflogif(struct agentx_varbind *);
1246void	 mib_pfsrctrack(struct agentx_varbind *);
1247void	 mib_pflimits(struct agentx_varbind *);
1248void	 mib_pftimeouts(struct agentx_varbind *);
1249void	 mib_pfifnum(struct agentx_varbind *);
1250void	 mib_pfiftable(struct agentx_varbind *);
1251void	 mib_pftablenum(struct agentx_varbind *);
1252void	 mib_pftables(struct agentx_varbind *);
1253void	 mib_pftableaddrs(struct agentx_varbind *);
1254void	 mib_pflabelnum(struct agentx_varbind *);
1255void	 mib_pflabels(struct agentx_varbind *);
1256void	 mib_pfsyncstats(struct agentx_varbind *);
1257
1258void	 mib_sensornum(struct agentx_varbind *);
1259void	 mib_sensors(struct agentx_varbind *);
1260const char *mib_sensorunit(struct sensor *);
1261char	*mib_sensorvalue(struct sensor *);
1262
1263void	 mib_carpsysctl(struct agentx_varbind *);
1264void	 mib_carpstats(struct agentx_varbind *);
1265void	 mib_carpiftable(struct agentx_varbind *);
1266void	 mib_carpgrouptable(struct agentx_varbind *);
1267void	 mib_carpifnum(struct agentx_varbind *);
1268struct carpif
1269	*mib_carpifget(u_int);
1270void	 mib_memversion(struct agentx_varbind *);
1271void	 mib_memiftable(struct agentx_varbind *);
1272
1273void
1274mib_pfinfo(struct agentx_varbind *vb)
1275{
1276	struct agentx_object	*obj;
1277	struct pf_status	 s;
1278	time_t			 runtime = 0;
1279	struct timespec		 uptime;
1280
1281	if (pf_get_stats(&s)) {
1282		agentx_varbind_error(vb);
1283		return;
1284	}
1285
1286	obj = agentx_varbind_get_object(vb);
1287	if (obj == pfRunning)
1288		agentx_varbind_integer(vb, s.running);
1289	else if (obj == pfRuntime) {
1290		if (!clock_gettime(CLOCK_BOOTTIME, &uptime))
1291			runtime = uptime.tv_sec - s.since;
1292		runtime *= 100;
1293		agentx_varbind_timeticks(vb, runtime);
1294	} else if (obj == pfDebug)
1295		agentx_varbind_integer(vb, s.debug);
1296	else if (obj == pfHostid)
1297		agentx_varbind_printf(vb, "0x%08x", ntohl(s.hostid));
1298	else
1299		fatal("%s: Unexpected object", __func__);
1300}
1301
1302void
1303mib_pfcounters(struct agentx_varbind *vb)
1304{
1305	struct agentx_object	*obj;
1306	struct pf_status	 s;
1307
1308	if (pf_get_stats(&s)) {
1309		agentx_varbind_error(vb);
1310		return;
1311	}
1312
1313	obj = agentx_varbind_get_object(vb);
1314	if (obj == pfCntMatch)
1315		agentx_varbind_counter64(vb, s.counters[PFRES_MATCH]);
1316	else if (obj == pfCntBadOffset)
1317		agentx_varbind_counter64(vb, s.counters[PFRES_BADOFF]);
1318	else if (obj == pfCntFragment)
1319		agentx_varbind_counter64(vb, s.counters[PFRES_FRAG]);
1320	else if (obj == pfCntShort)
1321		agentx_varbind_counter64(vb, s.counters[PFRES_SHORT]);
1322	else if (obj == pfCntNormalize)
1323		agentx_varbind_counter64(vb, s.counters[PFRES_NORM]);
1324	else if (obj == pfCntMemory)
1325		agentx_varbind_counter64(vb, s.counters[PFRES_MEMORY]);
1326	else if (obj == pfCntTimestamp)
1327		agentx_varbind_counter64(vb, s.counters[PFRES_TS]);
1328	else if (obj == pfCntCongestion)
1329		agentx_varbind_counter64(vb, s.counters[PFRES_CONGEST]);
1330	else if (obj == pfCntIpOption)
1331		agentx_varbind_counter64(vb, s.counters[PFRES_IPOPTIONS]);
1332	else if (obj == pfCntProtoCksum)
1333		agentx_varbind_counter64(vb, s.counters[PFRES_PROTCKSUM]);
1334	else if (obj == pfCntStateMismatch)
1335		agentx_varbind_counter64(vb, s.counters[PFRES_BADSTATE]);
1336	else if (obj == pfCntStateInsert)
1337		agentx_varbind_counter64(vb, s.counters[PFRES_STATEINS]);
1338	else if (obj == pfCntStateLimit)
1339		agentx_varbind_counter64(vb, s.counters[PFRES_MAXSTATES]);
1340	else if (obj == pfCntSrcLimit)
1341		agentx_varbind_counter64(vb, s.counters[PFRES_SRCLIMIT]);
1342	else if (obj == pfCntSynproxy)
1343		agentx_varbind_counter64(vb, s.counters[PFRES_SYNPROXY]);
1344	else if (obj == pfCntTranslate)
1345		agentx_varbind_counter64(vb, s.counters[PFRES_TRANSLATE]);
1346	else if (obj == pfCntNoRoute)
1347		agentx_varbind_counter64(vb, s.counters[PFRES_NOROUTE]);
1348	else
1349		fatal("%s: Unexpected object", __func__);
1350}
1351
1352void
1353mib_pfscounters(struct agentx_varbind *vb)
1354{
1355	struct agentx_object	*obj;
1356	struct pf_status	 s;
1357
1358	if (pf_get_stats(&s)) {
1359		agentx_varbind_error(vb);
1360		return;
1361	}
1362
1363	obj = agentx_varbind_get_object(vb);
1364	if (obj == pfStateCount)
1365		agentx_varbind_unsigned32(vb, s.states);
1366	else if (obj == pfStateSearches)
1367		agentx_varbind_counter64(vb, s.fcounters[FCNT_STATE_SEARCH]);
1368	else if (obj == pfStateInserts)
1369		agentx_varbind_counter64(vb, s.fcounters[FCNT_STATE_INSERT]);
1370	else if (obj == pfStateRemovals)
1371		agentx_varbind_counter64(vb, s.fcounters[FCNT_STATE_REMOVALS]);
1372	else
1373		fatal("%s: Unexpected object", __func__);
1374}
1375
1376void
1377mib_pflogif(struct agentx_varbind *vb)
1378{
1379	struct agentx_object	*obj;
1380	struct pf_status	 s;
1381
1382	if (pf_get_stats(&s)) {
1383		agentx_varbind_error(vb);
1384		return;
1385	}
1386
1387	obj = agentx_varbind_get_object(vb);
1388	if (obj == pfLogIfName)
1389		agentx_varbind_string(vb, s.ifname);
1390	else if (obj == pfLogIfIpBytesIn)
1391		agentx_varbind_counter64(vb, s.bcounters[IPV4][IN]);
1392	else if (obj == pfLogIfIpBytesOut)
1393		agentx_varbind_counter64(vb, s.bcounters[IPV4][OUT]);
1394	else if (obj == pfLogIfIpPktsInPass)
1395		agentx_varbind_counter64(vb, s.pcounters[IPV4][IN][PF_PASS]);
1396	else if (obj == pfLogIfIpPktsInDrop)
1397		agentx_varbind_counter64(vb, s.pcounters[IPV4][IN][PF_DROP]);
1398	else if (obj == pfLogIfIpPktsOutPass)
1399		agentx_varbind_counter64(vb, s.pcounters[IPV4][OUT][PF_PASS]);
1400	else if (obj == pfLogIfIpPktsOutDrop)
1401		agentx_varbind_counter64(vb, s.pcounters[IPV4][OUT][PF_DROP]);
1402	else if (obj == pfLogIfIp6BytesIn)
1403		agentx_varbind_counter64(vb, s.bcounters[IPV6][IN]);
1404	else if (obj == pfLogIfIp6BytesOut)
1405		agentx_varbind_counter64(vb, s.bcounters[IPV6][OUT]);
1406	else if (obj == pfLogIfIp6PktsInPass)
1407		agentx_varbind_counter64(vb, s.pcounters[IPV6][IN][PF_PASS]);
1408	else if (obj == pfLogIfIp6PktsInDrop)
1409		agentx_varbind_counter64(vb, s.pcounters[IPV6][IN][PF_DROP]);
1410	else if (obj == pfLogIfIp6PktsOutPass)
1411		agentx_varbind_counter64(vb, s.pcounters[IPV6][OUT][PF_PASS]);
1412	else if (obj == pfLogIfIp6PktsOutDrop)
1413		agentx_varbind_counter64(vb, s.pcounters[IPV6][OUT][PF_DROP]);
1414	else
1415		fatal("%s: Unexpected object", __func__);
1416}
1417
1418void
1419mib_pfsrctrack(struct agentx_varbind *vb)
1420{
1421	struct agentx_object	*obj;
1422	struct pf_status	 s;
1423
1424	if (pf_get_stats(&s)) {
1425		agentx_varbind_error(vb);
1426		return;
1427	}
1428
1429	obj = agentx_varbind_get_object(vb);
1430	if (obj == pfSrcTrackCount)
1431		agentx_varbind_unsigned32(vb, s.src_nodes);
1432	else if (obj == pfSrcTrackSearches)
1433		agentx_varbind_counter64(vb, s.scounters[SCNT_SRC_NODE_SEARCH]);
1434	else if (obj == pfSrcTrackInserts)
1435		agentx_varbind_counter64(vb, s.scounters[SCNT_SRC_NODE_INSERT]);
1436	else if (obj == pfSrcTrackRemovals)
1437		agentx_varbind_counter64(vb,
1438		    s.scounters[SCNT_SRC_NODE_REMOVALS]);
1439	else
1440		fatal("%s: Unexpected object", __func__);
1441}
1442
1443void
1444mib_pflimits(struct agentx_varbind *vb)
1445{
1446	struct agentx_object	*obj;
1447	struct pfioc_limit	 pl;
1448	extern int		 devpf;
1449
1450	obj = agentx_varbind_get_object(vb);
1451	memset(&pl, 0, sizeof(pl));
1452	if (obj == pfLimitStates)
1453		pl.index = PF_LIMIT_STATES;
1454	else if (obj == pfLimitSourceNodes)
1455		pl.index = PF_LIMIT_SRC_NODES;
1456	else if (obj == pfLimitFragments)
1457		pl.index = PF_LIMIT_FRAGS;
1458	else if (obj == pfLimitMaxTables)
1459		pl.index = PF_LIMIT_TABLES;
1460	else if (obj == pfLimitMaxTableEntries)
1461		pl.index = PF_LIMIT_TABLE_ENTRIES;
1462	else
1463		fatal("%s: Unexpected object", __func__);
1464
1465	if (ioctl(devpf, DIOCGETLIMIT, &pl) == -1) {
1466		log_warn("DIOCGETLIMIT");
1467		agentx_varbind_error(vb);
1468		return;
1469	}
1470
1471	agentx_varbind_unsigned32(vb, pl.limit);
1472}
1473
1474void
1475mib_pftimeouts(struct agentx_varbind *vb)
1476{
1477	struct agentx_object	*obj;
1478	struct pfioc_tm		 pt;
1479	extern int		 devpf;
1480
1481	obj = agentx_varbind_get_object(vb);
1482	memset(&pt, 0, sizeof(pt));
1483	if (obj == pfTimeoutTcpFirst)
1484		pt.timeout = PFTM_TCP_FIRST_PACKET;
1485	else if (obj == pfTimeoutTcpOpening)
1486		pt.timeout = PFTM_TCP_OPENING;
1487	else if (obj == pfTimeoutTcpEstablished)
1488		pt.timeout = PFTM_TCP_ESTABLISHED;
1489	else if (obj == pfTimeoutTcpClosing)
1490		pt.timeout = PFTM_TCP_CLOSING;
1491	else if (obj == pfTimeoutTcpFinWait)
1492		pt.timeout = PFTM_TCP_FIN_WAIT;
1493	else if (obj == pfTimeoutTcpClosed)
1494		pt.timeout = PFTM_TCP_CLOSED;
1495	else if (obj == pfTimeoutUdpFirst)
1496		pt.timeout = PFTM_UDP_FIRST_PACKET;
1497	else if (obj == pfTimeoutUdpSingle)
1498		pt.timeout = PFTM_UDP_SINGLE;
1499	else if (obj == pfTimeoutUdpMultiple)
1500		pt.timeout = PFTM_UDP_MULTIPLE;
1501	else if (obj == pfTimeoutIcmpFirst)
1502		pt.timeout = PFTM_ICMP_FIRST_PACKET;
1503	else if (obj == pfTimeoutIcmpError)
1504		pt.timeout = PFTM_ICMP_ERROR_REPLY;
1505	else if (obj == pfTimeoutOtherFirst)
1506		pt.timeout = PFTM_OTHER_FIRST_PACKET;
1507	else if (obj == pfTimeoutOtherSingle)
1508		pt.timeout = PFTM_OTHER_SINGLE;
1509	else if (obj == pfTimeoutOtherMultiple)
1510		pt.timeout = PFTM_OTHER_MULTIPLE;
1511	else if (obj == pfTimeoutFragment)
1512		pt.timeout = PFTM_FRAG;
1513	else if (obj == pfTimeoutInterval)
1514		pt.timeout = PFTM_INTERVAL;
1515	else if (obj == pfTimeoutAdaptiveStart)
1516		pt.timeout = PFTM_ADAPTIVE_START;
1517	else if (obj == pfTimeoutAdaptiveEnd)
1518		pt.timeout = PFTM_ADAPTIVE_END;
1519	else if (obj == pfTimeoutSrcTrack)
1520		pt.timeout = PFTM_SRC_NODE;
1521	else
1522		fatal("%s: Unexpected object", __func__);
1523
1524	if (ioctl(devpf, DIOCGETTIMEOUT, &pt) == -1) {
1525		log_warn("DIOCGETTIMEOUT");
1526		agentx_varbind_error(vb);
1527		return;
1528	}
1529
1530	agentx_varbind_integer(vb, pt.seconds);
1531}
1532
1533void
1534mib_pfifnum(struct agentx_varbind *vb)
1535{
1536	int	 c;
1537
1538	if ((c = pfi_count()) == -1)
1539		agentx_varbind_error(vb);
1540	else
1541		agentx_varbind_integer(vb, c);
1542}
1543
1544void
1545mib_pfiftable(struct agentx_varbind *vb)
1546{
1547	struct agentx_object		*obj;
1548	enum agentx_request_type	 req;
1549	struct pfi_kif			 pif;
1550	int				 idx, iftype;
1551
1552	obj = agentx_varbind_get_object(vb);
1553	idx = agentx_varbind_get_index_integer(vb, pfIfIdx);
1554	req = agentx_varbind_request(vb);
1555
1556	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
1557		if (idx < 1)
1558			idx = 1;
1559		else if (idx == INT32_MAX) {
1560			agentx_varbind_notfound(vb);
1561			return;
1562		} else
1563			idx++;
1564	} else if (req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
1565		if (idx < 1)
1566			idx = 1;
1567	}
1568	if (pfi_get_if(&pif, idx)) {
1569		agentx_varbind_notfound(vb);
1570		return;
1571	}
1572	agentx_varbind_set_index_integer(vb, pfIfIdx, idx);
1573
1574	if (obj == pfIfIndex)
1575		agentx_varbind_integer(vb, idx);
1576	else if (obj == pfIfDescr)
1577		agentx_varbind_string(vb, pif.pfik_name);
1578	else if (obj == pfIfType) {
1579		iftype = (pif.pfik_ifp == NULL ? PFI_IFTYPE_GROUP
1580		    : PFI_IFTYPE_INSTANCE);
1581		agentx_varbind_integer(vb, iftype);
1582	} else if (obj == pfIfRefs)
1583		agentx_varbind_unsigned32(vb, pif.pfik_states);
1584	else if (obj == pfIfRules)
1585		agentx_varbind_unsigned32(vb, pif.pfik_rules);
1586	else if (obj == pfIfIn4PassPkts)
1587		agentx_varbind_counter64(vb, pif.pfik_packets[IPV4][IN][PASS]);
1588	else if (obj == pfIfIn4PassBytes)
1589		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV4][IN][PASS]);
1590	else if (obj == pfIfIn4BlockPkts)
1591		agentx_varbind_counter64(vb, pif.pfik_packets[IPV4][IN][BLOCK]);
1592	else if (obj == pfIfIn4BlockBytes)
1593		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV4][IN][BLOCK]);
1594	else if (obj == pfIfOut4PassPkts)
1595		agentx_varbind_counter64(vb, pif.pfik_packets[IPV4][OUT][PASS]);
1596	else if (obj == pfIfOut4PassBytes)
1597		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV4][OUT][PASS]);
1598	else if (obj == pfIfOut4BlockPkts)
1599		agentx_varbind_counter64(vb, pif.pfik_packets[IPV4][OUT][BLOCK]);
1600	else if (obj == pfIfOut4BlockBytes)
1601		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV4][OUT][BLOCK]);
1602	else if (obj == pfIfIn6PassPkts)
1603		agentx_varbind_counter64(vb, pif.pfik_packets[IPV6][IN][PASS]);
1604	else if (obj == pfIfIn6PassBytes)
1605		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV6][IN][PASS]);
1606	else if (obj == pfIfIn6BlockPkts)
1607		agentx_varbind_counter64(vb, pif.pfik_packets[IPV6][IN][BLOCK]);
1608	else if (obj == pfIfIn6BlockBytes)
1609		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV6][IN][BLOCK]);
1610	else if (obj == pfIfOut6PassPkts)
1611		agentx_varbind_counter64(vb, pif.pfik_packets[IPV6][OUT][PASS]);
1612	else if (obj == pfIfOut6PassBytes)
1613		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV6][OUT][PASS]);
1614	else if (obj == pfIfOut6BlockPkts)
1615		agentx_varbind_counter64(vb, pif.pfik_packets[IPV6][OUT][BLOCK]);
1616	else if (obj == pfIfOut6BlockBytes)
1617		agentx_varbind_counter64(vb, pif.pfik_bytes[IPV6][OUT][BLOCK]);
1618	else
1619		fatal("%s: Unexpected object", __func__);
1620}
1621
1622void
1623mib_pftablenum(struct agentx_varbind *vb)
1624{
1625	int	 c;
1626
1627	if ((c = pft_count()) == -1)
1628		agentx_varbind_error(vb);
1629	else
1630		agentx_varbind_integer(vb, c);
1631}
1632
1633void
1634mib_pftables(struct agentx_varbind *vb)
1635{
1636	struct agentx_object		*obj;
1637	enum agentx_request_type	 req;
1638	struct pfr_tstats		 ts;
1639	time_t				 tzero;
1640	int				 idx;
1641
1642	obj = agentx_varbind_get_object(vb);
1643	idx = agentx_varbind_get_index_integer(vb, pfTblIdx);
1644	req = agentx_varbind_request(vb);
1645
1646	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
1647		if (idx < 1)
1648			idx = 1;
1649		else if (idx == INT32_MAX) {
1650			agentx_varbind_notfound(vb);
1651			return;
1652		} else
1653			idx++;
1654	} else if (req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
1655		if (idx < 1)
1656			idx = 1;
1657	}
1658	if (pft_get_table(&ts, idx)) {
1659		agentx_varbind_notfound(vb);
1660		return;
1661	}
1662	agentx_varbind_set_index_integer(vb, pfTblIdx, idx);
1663
1664	if (obj == pfTblIndex)
1665		agentx_varbind_integer(vb, idx);
1666	else if (obj == pfTblName)
1667		agentx_varbind_string(vb, ts.pfrts_name);
1668	else if (obj == pfTblAddresses)
1669		agentx_varbind_integer(vb, ts.pfrts_cnt);
1670	else if (obj == pfTblAnchorRefs)
1671		agentx_varbind_integer(vb, ts.pfrts_refcnt[PFR_REFCNT_ANCHOR]);
1672	else if (obj == pfTblRuleRefs)
1673		agentx_varbind_integer(vb, ts.pfrts_refcnt[PFR_REFCNT_RULE]);
1674	else if (obj == pfTblEvalsMatch)
1675		agentx_varbind_counter64(vb, ts.pfrts_match);
1676	else if (obj == pfTblEvalsNoMatch)
1677		agentx_varbind_counter64(vb, ts.pfrts_nomatch);
1678	else if (obj == pfTblInPassPkts)
1679		agentx_varbind_counter64(vb, ts.pfrts_packets[IN][PFR_OP_PASS]);
1680	else if (obj == pfTblInPassBytes)
1681		agentx_varbind_counter64(vb, ts.pfrts_bytes[IN][PFR_OP_PASS]);
1682	else if (obj == pfTblInBlockPkts)
1683		agentx_varbind_counter64(vb, ts.pfrts_packets[IN][PFR_OP_BLOCK]);
1684	else if (obj == pfTblInBlockBytes)
1685		agentx_varbind_counter64(vb, ts.pfrts_bytes[IN][PFR_OP_BLOCK]);
1686	else if (obj == pfTblInXPassPkts)
1687		agentx_varbind_counter64(vb, ts.pfrts_packets[IN][PFR_OP_XPASS]);
1688	else if (obj == pfTblInXPassBytes)
1689		agentx_varbind_counter64(vb, ts.pfrts_bytes[IN][PFR_OP_XPASS]);
1690	else if (obj == pfTblOutPassPkts)
1691		agentx_varbind_counter64(vb, ts.pfrts_packets[OUT][PFR_OP_PASS]);
1692	else if (obj == pfTblOutPassBytes)
1693		agentx_varbind_counter64(vb, ts.pfrts_bytes[OUT][PFR_OP_PASS]);
1694	else if (obj == pfTblOutBlockPkts)
1695		agentx_varbind_counter64(vb, ts.pfrts_packets[OUT][PFR_OP_BLOCK]);
1696	else if (obj == pfTblOutBlockBytes)
1697		agentx_varbind_counter64(vb, ts.pfrts_bytes[OUT][PFR_OP_BLOCK]);
1698	else if (obj == pfTblOutXPassPkts)
1699		agentx_varbind_counter64(vb, ts.pfrts_packets[OUT][PFR_OP_XPASS]);
1700	else if (obj == pfTblOutXPassBytes)
1701		agentx_varbind_counter64(vb, ts.pfrts_bytes[OUT][PFR_OP_XPASS]);
1702	else if (obj == pfTblStatsCleared) {
1703		tzero = (time(NULL) - ts.pfrts_tzero) * 100;
1704		agentx_varbind_timeticks(vb, tzero);
1705	} else if (obj == pfTblInMatchPkts)
1706		agentx_varbind_counter64(vb, ts.pfrts_packets[IN][PFR_OP_MATCH]);
1707	else if (obj == pfTblInMatchBytes)
1708		agentx_varbind_counter64(vb, ts.pfrts_bytes[IN][PFR_OP_MATCH]);
1709	else if (obj == pfTblOutMatchPkts)
1710		agentx_varbind_counter64(vb, ts.pfrts_packets[OUT][PFR_OP_MATCH]);
1711	else if (obj == pfTblOutMatchBytes)
1712		agentx_varbind_counter64(vb, ts.pfrts_bytes[OUT][PFR_OP_MATCH]);
1713	else
1714		fatal("%s: Unexpected object", __func__);
1715}
1716
1717void
1718mib_pftableaddrs(struct agentx_varbind *vb)
1719{
1720	struct agentx_object		*obj;
1721	enum agentx_request_type	 req;
1722	struct pfr_astats		 as;
1723	int				 tblidx;
1724
1725	obj = agentx_varbind_get_object(vb);
1726	tblidx = agentx_varbind_get_index_integer(vb, pfTblAddrTblIdx);
1727	req = agentx_varbind_request(vb);
1728
1729	/*
1730	 * XXX No consistent way to differentiate between not found and error
1731	 * Treat everything as not found.
1732	 */
1733	if (req == AGENTX_REQUEST_TYPE_GET ||
1734	    req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
1735		as.pfras_a.pfra_ip4addr = *agentx_varbind_get_index_ipaddress(
1736		    vb, pfTblAddrNetIdx);
1737		as.pfras_a.pfra_net = agentx_varbind_get_index_integer(vb,
1738		    pfTblAddrMaskIdx);
1739
1740		if (pfta_get_addr(&as, tblidx)) {
1741			if (req == AGENTX_REQUEST_TYPE_GET) {
1742				agentx_varbind_notfound(vb);
1743				return;
1744			}
1745			req = AGENTX_REQUEST_TYPE_GETNEXT;
1746		}
1747	}
1748	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
1749		if (tblidx < 1)
1750			tblidx = 1;
1751		as.pfras_a.pfra_ip4addr = *agentx_varbind_get_index_ipaddress(
1752		    vb, pfTblAddrNetIdx);
1753		as.pfras_a.pfra_net = agentx_varbind_get_index_integer(vb,
1754		    pfTblAddrMaskIdx);
1755
1756		if (pfta_get_nextaddr(&as, &tblidx)){
1757			agentx_varbind_notfound(vb);
1758			return;
1759		}
1760	}
1761	agentx_varbind_set_index_integer(vb, pfTblAddrTblIdx, tblidx);
1762	agentx_varbind_set_index_ipaddress(vb, pfTblAddrNetIdx,
1763	    &as.pfras_a.pfra_ip4addr);
1764	agentx_varbind_set_index_integer(vb, pfTblAddrMaskIdx,
1765	    as.pfras_a.pfra_net);
1766
1767	if (obj == pfTblAddrTblIndex)
1768		agentx_varbind_integer(vb, tblidx);
1769	else if (obj == pfTblAddrNet)
1770		agentx_varbind_ipaddress(vb, &as.pfras_a.pfra_ip4addr);
1771	else if (obj == pfTblAddrMask)
1772		agentx_varbind_integer(vb, as.pfras_a.pfra_net);
1773	else if (obj == pfTblAddrCleared)
1774		agentx_varbind_timeticks(vb, (time(NULL) - as.pfras_tzero) * 100);
1775	else if (obj == pfTblAddrInBlockPkts)
1776		agentx_varbind_counter64(vb, as.pfras_packets[IN][PFR_OP_BLOCK]);
1777	else if (obj == pfTblAddrInBlockBytes)
1778		agentx_varbind_counter64(vb, as.pfras_bytes[IN][PFR_OP_BLOCK]);
1779	else if (obj == pfTblAddrInPassPkts)
1780		agentx_varbind_counter64(vb, as.pfras_packets[IN][PFR_OP_PASS]);
1781	else if (obj == pfTblAddrInPassBytes)
1782		agentx_varbind_counter64(vb, as.pfras_bytes[IN][PFR_OP_PASS]);
1783	else if (obj == pfTblAddrOutBlockPkts)
1784		agentx_varbind_counter64(vb, as.pfras_packets[OUT][PFR_OP_BLOCK]);
1785	else if (obj == pfTblAddrOutBlockBytes)
1786		agentx_varbind_counter64(vb, as.pfras_bytes[OUT][PFR_OP_BLOCK]);
1787	else if (obj == pfTblAddrOutPassPkts)
1788		agentx_varbind_counter64(vb, as.pfras_packets[OUT][PFR_OP_PASS]);
1789	else if (obj == pfTblAddrOutPassBytes)
1790		agentx_varbind_counter64(vb, as.pfras_bytes[OUT][PFR_OP_PASS]);
1791	else if (obj == pfTblAddrInMatchPkts)
1792		agentx_varbind_counter64(vb, as.pfras_packets[IN][PFR_OP_MATCH]);
1793	else if (obj == pfTblAddrInMatchBytes)
1794		agentx_varbind_counter64(vb, as.pfras_bytes[IN][PFR_OP_MATCH]);
1795	else if (obj == pfTblAddrOutMatchPkts)
1796		agentx_varbind_counter64(vb, as.pfras_packets[OUT][PFR_OP_MATCH]);
1797	else if (obj == pfTblAddrOutMatchBytes)
1798		agentx_varbind_counter64(vb, as.pfras_bytes[OUT][PFR_OP_MATCH]);
1799	else
1800		fatal("%s: Unexpected object", __func__);
1801}
1802
1803void
1804mib_close_pftrans(struct agentx_varbind *vb, u_int32_t ticket)
1805{
1806	extern int		devpf;
1807
1808	if (ioctl(devpf, DIOCXEND, &ticket) == -1) {
1809		log_warn("DIOCXEND");
1810		agentx_varbind_error(vb);
1811	}
1812}
1813
1814void
1815mib_pflabelnum(struct agentx_varbind *vb)
1816{
1817	struct pfioc_rule	 pr;
1818	u_int32_t		 nr, mnr, lnr;
1819	extern int		 devpf;
1820
1821	memset(&pr, 0, sizeof(pr));
1822	if (ioctl(devpf, DIOCGETRULES, &pr) == -1) {
1823		log_warn("DIOCGETRULES");
1824		agentx_varbind_error(vb);
1825		return;
1826	}
1827
1828	mnr = pr.nr;
1829	lnr = 0;
1830	for (nr = 0; nr < mnr; ++nr) {
1831		pr.nr = nr;
1832		if (ioctl(devpf, DIOCGETRULE, &pr) == -1) {
1833			log_warn("DIOCGETRULE");
1834			agentx_varbind_error(vb);
1835			mib_close_pftrans(vb, pr.ticket);
1836			return;
1837		}
1838
1839		if (pr.rule.label[0])
1840			lnr++;
1841	}
1842
1843	agentx_varbind_integer(vb, lnr);
1844
1845	mib_close_pftrans(vb, pr.ticket);
1846}
1847
1848void
1849mib_pflabels(struct agentx_varbind *vb)
1850{
1851	struct agentx_object		*obj;
1852	enum agentx_request_type	 req;
1853	struct pfioc_rule		 pr;
1854	struct pf_rule			*r = NULL;
1855	u_int32_t			 nr, mnr, lnr;
1856	u_int32_t			 idx;
1857	extern int			 devpf;
1858
1859	memset(&pr, 0, sizeof(pr));
1860	if (ioctl(devpf, DIOCGETRULES, &pr) == -1) {
1861		log_warn("DIOCGETRULES");
1862		agentx_varbind_error(vb);
1863		return;
1864	}
1865
1866	obj = agentx_varbind_get_object(vb);
1867	idx = agentx_varbind_get_index_integer(vb, pfLabelIdx);
1868	req = agentx_varbind_request(vb);
1869
1870	if (idx < 1) {
1871		if (req == AGENTX_REQUEST_TYPE_GET) {
1872			agentx_varbind_notfound(vb);
1873			return;
1874		}
1875		idx = 1;
1876	} else if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
1877		if (idx == INT32_MAX) {
1878			agentx_varbind_notfound(vb);
1879			return;
1880		}
1881		idx++;
1882	}
1883
1884	mnr = pr.nr;
1885	lnr = 0;
1886	for (nr = 0; nr < mnr; ++nr) {
1887		pr.nr = nr;
1888		if (ioctl(devpf, DIOCGETRULE, &pr) == -1) {
1889			log_warn("DIOCGETRULE");
1890			agentx_varbind_error(vb);
1891			mib_close_pftrans(vb, pr.ticket);
1892			return;
1893		}
1894
1895		if (pr.rule.label[0] && ++lnr == idx) {
1896			r = &pr.rule;
1897			break;
1898		}
1899	}
1900
1901	mib_close_pftrans(vb, pr.ticket);
1902
1903	if (r == NULL) {
1904		agentx_varbind_notfound(vb);
1905		return;
1906	}
1907	agentx_varbind_set_index_integer(vb, pfLabelIdx, idx);
1908
1909	if (obj == pfLabelIndex)
1910		agentx_varbind_integer(vb, lnr);
1911	else if (obj == pfLabelName)
1912		agentx_varbind_string(vb, r->label);
1913	else if (obj == pfLabelEvals)
1914		agentx_varbind_counter64(vb, r->evaluations);
1915	else if (obj == pfLabelPkts)
1916		agentx_varbind_counter64(vb, r->packets[IN] + r->packets[OUT]);
1917	else if (obj == pfLabelBytes)
1918		agentx_varbind_counter64(vb, r->bytes[IN] + r->bytes[OUT]);
1919	else if (obj == pfLabelInPkts)
1920		agentx_varbind_counter64(vb, r->packets[IN]);
1921	else if (obj == pfLabelInBytes)
1922		agentx_varbind_counter64(vb, r->bytes[IN]);
1923	else if (obj == pfLabelOutPkts)
1924		agentx_varbind_counter64(vb, r->packets[OUT]);
1925	else if (obj == pfLabelOutBytes)
1926		agentx_varbind_counter64(vb, r->bytes[OUT]);
1927	else if (obj == pfLabelTotalStates)
1928		agentx_varbind_counter32(vb, r->states_tot);
1929	else
1930		fatal("%s: Unexpected object", __func__);
1931}
1932
1933void
1934mib_pfsyncstats(struct agentx_varbind *vb)
1935{
1936	struct agentx_object	*obj;
1937	int			 mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC,
1938				    PFSYNCCTL_STATS };
1939	size_t			 len = sizeof(struct pfsyncstats);
1940	struct pfsyncstats	 s;
1941
1942	if (sysctl(mib, 4, &s, &len, NULL, 0) == -1) {
1943		log_warn("sysctl");
1944		agentx_varbind_error(vb);
1945		return;
1946	}
1947
1948	obj = agentx_varbind_get_object(vb);
1949	if (obj == pfsyncIpPktsRecv)
1950		agentx_varbind_counter64(vb, s.pfsyncs_ipackets);
1951	else if (obj == pfsyncIp6PktsRecv)
1952		agentx_varbind_counter64(vb, s.pfsyncs_ipackets6);
1953	else if (obj == pfsyncPktDiscardsForBadInterface)
1954		agentx_varbind_counter64(vb, s.pfsyncs_badif);
1955	else if (obj == pfsyncPktDiscardsForBadTtl)
1956		agentx_varbind_counter64(vb, s.pfsyncs_badttl);
1957	else if (obj == pfsyncPktShorterThanHeader)
1958		agentx_varbind_counter64(vb, s.pfsyncs_hdrops);
1959	else if (obj == pfsyncPktDiscardsForBadVersion)
1960		agentx_varbind_counter64(vb, s.pfsyncs_badver);
1961	else if (obj == pfsyncPktDiscardsForBadAction)
1962		agentx_varbind_counter64(vb, s.pfsyncs_badact);
1963	else if (obj == pfsyncPktDiscardsForBadLength)
1964		agentx_varbind_counter64(vb, s.pfsyncs_badlen);
1965	else if (obj == pfsyncPktDiscardsForBadAuth)
1966		agentx_varbind_counter64(vb, s.pfsyncs_badauth);
1967	else if (obj == pfsyncPktDiscardsForStaleState)
1968		agentx_varbind_counter64(vb, s.pfsyncs_stale);
1969	else if (obj == pfsyncPktDiscardsForBadValues)
1970		agentx_varbind_counter64(vb, s.pfsyncs_badval);
1971	else if (obj == pfsyncPktDiscardsForBadState)
1972		agentx_varbind_counter64(vb, s.pfsyncs_badstate);
1973	else if (obj == pfsyncIpPktsSent)
1974		agentx_varbind_counter64(vb, s.pfsyncs_opackets);
1975	else if (obj == pfsyncIp6PktsSent)
1976		agentx_varbind_counter64(vb, s.pfsyncs_opackets6);
1977	else if (obj == pfsyncNoMemory)
1978		agentx_varbind_counter64(vb, s.pfsyncs_onomem);
1979	else if (obj == pfsyncOutputErrors)
1980		agentx_varbind_counter64(vb, s.pfsyncs_oerrors);
1981	else
1982		fatal("%s: Unexpected object", __func__);
1983}
1984
1985/* OPENBSD-SENSORS-MIB */
1986void
1987mib_sensornum(struct agentx_varbind *vb)
1988{
1989	struct sensordev	 sensordev;
1990	size_t			 len = sizeof(sensordev);
1991	int			 mib[] = { CTL_HW, HW_SENSORS, 0 };
1992	int			 i, c;
1993
1994	for (i = c = 0; ; i++) {
1995		mib[2] = i;
1996		if (sysctl(mib, nitems(mib),
1997		    &sensordev, &len, NULL, 0) == -1) {
1998			if (errno == ENXIO)
1999				continue;
2000			if (errno == ENOENT)
2001				break;
2002			log_warn("sysctl");
2003			agentx_varbind_error(vb);
2004			return;
2005		}
2006		c += sensordev.sensors_count;
2007	}
2008
2009	agentx_varbind_integer(vb, c);
2010}
2011
2012void
2013mib_sensors(struct agentx_varbind *vb)
2014{
2015	struct agentx_object		*obj;
2016	enum agentx_request_type	 req;
2017	struct sensordev		 sensordev;
2018	size_t				 len = sizeof(sensordev);
2019	struct sensor			 sensor;
2020	size_t				 slen = sizeof(sensor);
2021	char				 desc[32];
2022	int				 mib[] =
2023	    { CTL_HW, HW_SENSORS, 0, 0, 0 };
2024	int				 i, j, k;
2025	u_int32_t			 idx = 0, n;
2026	char				*s;
2027
2028	obj = agentx_varbind_get_object(vb);
2029	idx = agentx_varbind_get_index_integer(vb, sensorIdx);
2030	req = agentx_varbind_request(vb);
2031
2032	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
2033		if (idx == INT32_MAX) {
2034			agentx_varbind_notfound(vb);
2035			return;
2036		}
2037		idx++;
2038	}
2039	if (idx < 1 &&
2040	    (req == AGENTX_REQUEST_TYPE_GETNEXT ||
2041	    req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE))
2042		idx = 1;
2043
2044	for (i = 0, n = 1; ; i++) {
2045		mib[2] = i;
2046		if (sysctl(mib, 3, &sensordev, &len, NULL, 0) == -1) {
2047			if (errno == ENXIO)
2048				continue;
2049			if (errno == ENOENT)
2050				break;
2051			log_warn("sysctl");
2052			agentx_varbind_error(vb);
2053			return;
2054		}
2055		for (j = 0; j < SENSOR_MAX_TYPES; j++) {
2056			mib[3] = j;
2057			for (k = 0; k < sensordev.maxnumt[j]; k++) {
2058				mib[4] = k;
2059				if (sysctl(mib, 5,
2060				    &sensor, &slen, NULL, 0) == -1) {
2061					if (errno == ENXIO)
2062						continue;
2063					if (errno == ENOENT)
2064						break;
2065					log_warn("sysctl");
2066					agentx_varbind_error(vb);
2067					return;
2068				}
2069				if (sensor.flags & SENSOR_FINVALID)
2070					continue;
2071				if (n == idx)
2072					goto found;
2073				n++;
2074			}
2075		}
2076	}
2077	agentx_varbind_notfound(vb);
2078	return;
2079
2080 found:
2081	agentx_varbind_set_index_integer(vb, sensorIdx, idx);
2082	if (obj == sensorIndex)
2083		agentx_varbind_integer(vb, (int32_t)n);
2084	else if (obj == sensorDescr) {
2085		if (sensor.desc[0] == '\0') {
2086			snprintf(desc, sizeof(desc), "%s%d",
2087			    sensor_type_s[sensor.type],
2088			    sensor.numt);
2089			agentx_varbind_string(vb, desc);
2090		} else
2091			agentx_varbind_string(vb, sensor.desc);
2092	} else if (obj == sensorType)
2093		agentx_varbind_integer(vb, sensor.type);
2094	else if (obj == sensorDevice)
2095		agentx_varbind_string(vb, sensordev.xname);
2096	else if (obj == sensorValue) {
2097		if ((s = mib_sensorvalue(&sensor)) == NULL) {
2098			log_warn("asprintf");
2099			agentx_varbind_error(vb);
2100			return;
2101		}
2102		agentx_varbind_string(vb, s);
2103		free(s);
2104	} else if (obj == sensorUnits)
2105		agentx_varbind_string(vb, mib_sensorunit(&sensor));
2106	else if (obj == sensorStatus)
2107		agentx_varbind_integer(vb, sensor.status);
2108	else
2109		fatal("%s: Unexpected object", __func__);
2110}
2111
2112#define SENSOR_DRIVE_STATES	(SENSOR_DRIVE_PFAIL + 1)
2113static const char * const sensor_drive_s[SENSOR_DRIVE_STATES] = {
2114	NULL, "empty", "ready", "powerup", "online", "idle", "active",
2115	"rebuild", "powerdown", "fail", "pfail"
2116};
2117
2118static const char * const sensor_unit_s[SENSOR_MAX_TYPES + 1] = {
2119	"degC",	"RPM", "V DC", "V AC", "Ohm", "W", "A", "Wh", "Ah",
2120	"", "", "%", "lx", "", "sec", "%RH", "Hz", "degree",
2121	"m", "Pa", "m/s^2", "m/s", ""
2122};
2123
2124const char *
2125mib_sensorunit(struct sensor *s)
2126{
2127	u_int	 idx;
2128	idx = s->type > SENSOR_MAX_TYPES ?
2129	    SENSOR_MAX_TYPES : s->type;
2130	return (sensor_unit_s[idx]);
2131}
2132
2133char *
2134mib_sensorvalue(struct sensor *s)
2135{
2136	char	*v;
2137	int	 ret = -1;
2138
2139	switch (s->type) {
2140	case SENSOR_TEMP:
2141		ret = asprintf(&v, "%.2f",
2142		    (s->value - 273150000) / 1000000.0);
2143		break;
2144	case SENSOR_VOLTS_DC:
2145	case SENSOR_VOLTS_AC:
2146	case SENSOR_WATTS:
2147	case SENSOR_AMPS:
2148	case SENSOR_WATTHOUR:
2149	case SENSOR_AMPHOUR:
2150	case SENSOR_LUX:
2151	case SENSOR_FREQ:
2152	case SENSOR_ACCEL:
2153	case SENSOR_VELOCITY:
2154	case SENSOR_DISTANCE:
2155		ret = asprintf(&v, "%.2f", s->value / 1000000.0);
2156		break;
2157	case SENSOR_INDICATOR:
2158		ret = asprintf(&v, "%s", s->value ? "on" : "off");
2159		break;
2160	case SENSOR_PERCENT:
2161	case SENSOR_HUMIDITY:
2162		ret = asprintf(&v, "%.2f", s->value / 1000.0);
2163		break;
2164	case SENSOR_PRESSURE:
2165		ret = asprintf(&v, "%.2f", s->value / 1000.0);
2166		break;
2167	case SENSOR_TIMEDELTA:
2168		ret = asprintf(&v, "%.6f", s->value / 1000000000.0);
2169		break;
2170	case SENSOR_DRIVE:
2171		if (s->value > 0 && s->value < SENSOR_DRIVE_STATES) {
2172			ret = asprintf(&v, "%s", sensor_drive_s[s->value]);
2173			break;
2174		}
2175		/* FALLTHROUGH */
2176	case SENSOR_FANRPM:
2177	case SENSOR_OHMS:
2178	case SENSOR_INTEGER:
2179	default:
2180		ret = asprintf(&v, "%lld", s->value);
2181		break;
2182	}
2183
2184	if (ret == -1)
2185		return (NULL);
2186	return (v);
2187}
2188
2189void
2190mib_carpsysctl(struct agentx_varbind *vb)
2191{
2192	struct agentx_object	*obj;
2193	size_t			 len;
2194	int			 mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, 0 };
2195	int			 v;
2196
2197	obj = agentx_varbind_get_object(vb);
2198	if (obj == carpAllow)
2199		mib[3] = CARPCTL_ALLOW;
2200	else if (obj == carpPreempt)
2201		mib[3] = CARPCTL_PREEMPT;
2202	else if (obj == carpLog)
2203		mib[3] = CARPCTL_LOG;
2204	else
2205		fatal("%s: Unexpected object", __func__);
2206	len = sizeof(v);
2207
2208	if (sysctl(mib, 4, &v, &len, NULL, 0) == -1) {
2209		log_warn("sysctl");
2210		agentx_varbind_error(vb);
2211		return;
2212	}
2213
2214	agentx_varbind_integer(vb, v);
2215}
2216
2217void
2218mib_carpstats(struct agentx_varbind *vb)
2219{
2220	struct agentx_object	*obj;
2221	int			 mib[] = { CTL_NET, PF_INET, IPPROTO_CARP,
2222				    CARPCTL_STATS };
2223	size_t			 len;
2224	struct			 carpstats stats;
2225
2226	len = sizeof(stats);
2227
2228	if (sysctl(mib, 4, &stats, &len, NULL, 0) == -1) {
2229		log_warn("sysctl");
2230		agentx_varbind_error(vb);
2231		return;
2232	}
2233
2234	obj = agentx_varbind_get_object(vb);
2235	if (obj == carpIpPktsRecv)
2236		agentx_varbind_counter64(vb, stats.carps_ipackets);
2237	else if (obj == carpIp6PktsRecv)
2238		agentx_varbind_counter64(vb, stats.carps_ipackets6);
2239	else if (obj == carpPktDiscardsForBadInterface)
2240		agentx_varbind_counter64(vb, stats.carps_badif);
2241	else if (obj == carpPktDiscardsForWrongTtl)
2242		agentx_varbind_counter64(vb, stats.carps_badttl);
2243	else if (obj == carpPktShorterThanHeader)
2244		agentx_varbind_counter64(vb, stats.carps_hdrops);
2245	else if (obj == carpPktDiscardsForBadChecksum)
2246		agentx_varbind_counter64(vb, stats.carps_badsum);
2247	else if (obj == carpPktDiscardsForBadVersion)
2248		agentx_varbind_counter64(vb, stats.carps_badver);
2249	else if (obj == carpPktDiscardsForTooShort)
2250		agentx_varbind_counter64(vb, stats.carps_badlen);
2251	else if (obj == carpPktDiscardsForBadAuth)
2252		agentx_varbind_counter64(vb, stats.carps_badauth);
2253	else if (obj == carpPktDiscardsForBadVhid)
2254		agentx_varbind_counter64(vb, stats.carps_badvhid);
2255	else if (obj == carpPktDiscardsForBadAddressList)
2256		agentx_varbind_counter64(vb, stats.carps_badaddrs);
2257	else if (obj == carpIpPktsSent)
2258		agentx_varbind_counter64(vb, stats.carps_opackets);
2259	else if (obj == carpIp6PktsSent)
2260		agentx_varbind_counter64(vb, stats.carps_opackets6);
2261	else if (obj == carpNoMemory)
2262		agentx_varbind_counter64(vb, stats.carps_onomem);
2263	else if (obj == carpTransitionsToMaster)
2264		agentx_varbind_counter64(vb, stats.carps_preempt);
2265	else
2266		fatal("%s: Unexpected object", __func__);
2267}
2268
2269void
2270mib_carpifnum(struct agentx_varbind *vb)
2271{
2272	struct kif	*kif;
2273	int		 c = 0;
2274
2275	for (kif = kr_getif(0); kif != NULL;
2276	    kif = kr_getnextif(kif->if_index))
2277		if (kif->if_type == IFT_CARP)
2278			c++;
2279
2280	agentx_varbind_integer(vb, c);
2281}
2282
2283struct carpif *
2284mib_carpifget(u_int idx)
2285{
2286	struct kif	*kif;
2287	struct carpif	*cif;
2288	int		 s;
2289	struct ifreq	 ifr;
2290	struct carpreq	 carpr;
2291
2292	if ((kif = kr_getif(idx)) == NULL || kif->if_type != IFT_CARP) {
2293		/*
2294		 * It may happen that an interface with a specific index
2295		 * does not exist, has been removed, or is not a carp(4)
2296		 * interface. Jump to the next available carp(4) interface
2297		 * index.
2298		 */
2299		for (kif = kr_getif(0); kif != NULL;
2300		    kif = kr_getnextif(kif->if_index)) {
2301			if (kif->if_type != IFT_CARP)
2302				continue;
2303			if (kif->if_index > idx)
2304				break;
2305
2306		}
2307		if (kif == NULL)
2308			return (NULL);
2309	}
2310	idx = kif->if_index;
2311
2312	/* Update interface information */
2313	kr_updateif(idx);
2314	if ((kif = kr_getif(idx)) == NULL) {
2315		log_debug("mib_carpifget: interface %d disappeared?", idx);
2316		return (NULL);
2317	}
2318
2319	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2320		return (NULL);
2321
2322	memset(&ifr, 0, sizeof(ifr));
2323	strlcpy(ifr.ifr_name, kif->if_name, sizeof(ifr.ifr_name));
2324	memset((char *)&carpr, 0, sizeof(carpr));
2325	ifr.ifr_data = (caddr_t)&carpr;
2326
2327	if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) {
2328		close(s);
2329		return (NULL);
2330	}
2331
2332	cif = calloc(1, sizeof(struct carpif));
2333	if (cif != NULL) {
2334		memcpy(&cif->carpr, &carpr, sizeof(struct carpreq));
2335		memcpy(&cif->kif, kif, sizeof(struct kif));
2336	}
2337
2338	close(s);
2339
2340	return (cif);
2341}
2342
2343void
2344mib_carpiftable(struct agentx_varbind *vb)
2345{
2346	struct agentx_object		*obj;
2347	enum agentx_request_type	 req;
2348	u_int32_t			 idx;
2349	struct carpif			*cif;
2350
2351	obj = agentx_varbind_get_object(vb);
2352	idx = agentx_varbind_get_index_integer(vb, carpIfIdx);
2353	req = agentx_varbind_request(vb);
2354
2355	if (idx < 1) {
2356		if (req == AGENTX_REQUEST_TYPE_GET) {
2357			agentx_varbind_notfound(vb);
2358			return;
2359		}
2360		idx = 1;
2361	} else if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
2362		if (idx == INT32_MAX) {
2363			agentx_varbind_notfound(vb);
2364			return;
2365		}
2366		idx++;
2367	}
2368
2369	/*
2370	 * XXX No consistent way to differentiate between not found and error
2371	 * Treat everything as not found.
2372	 */
2373	if ((cif = mib_carpifget(idx)) == NULL) {
2374		agentx_varbind_notfound(vb);
2375		return;
2376	}
2377
2378	if (req == AGENTX_REQUEST_TYPE_GET && cif->kif.if_index != idx) {
2379		agentx_varbind_notfound(vb);
2380		return;
2381	}
2382	agentx_varbind_set_index_integer(vb, carpIfIdx, cif->kif.if_index);
2383
2384	if (obj == carpIfIndex)
2385		agentx_varbind_integer(vb, cif->kif.if_index);
2386	else if (obj == carpIfDescr)
2387		agentx_varbind_string(vb, cif->kif.if_name);
2388	else if (obj == carpIfVhid)
2389		agentx_varbind_integer(vb, cif->carpr.carpr_vhids[0]);
2390	else if (obj == carpIfDev)
2391		agentx_varbind_string(vb, cif->carpr.carpr_carpdev);
2392	else if (obj == carpIfAdvbase)
2393		agentx_varbind_integer(vb, cif->carpr.carpr_advbase);
2394	else if (obj == carpIfAdvskew)
2395		agentx_varbind_integer(vb, cif->carpr.carpr_advskews[0]);
2396	else if (obj == carpIfState)
2397		agentx_varbind_integer(vb, cif->carpr.carpr_states[0]);
2398	else
2399		fatal("%s: Unexpected object", __func__);
2400	free(cif);
2401}
2402
2403static struct ifg_req *
2404mib_carpgroupget(u_int idx)
2405{
2406	struct ifgroupreq	 ifgr;
2407	struct ifg_req		*ifg = NULL;
2408	u_int			 len;
2409	int			 s = -1;
2410
2411	bzero(&ifgr, sizeof(ifgr));
2412
2413	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
2414		log_warn("socket");
2415		return (NULL);
2416	}
2417
2418	if (ioctl(s, SIOCGIFGLIST, (caddr_t)&ifgr) == -1) {
2419		log_warn("SIOCGIFGLIST");
2420		goto err;
2421	}
2422	len = ifgr.ifgr_len;
2423
2424	if (len / sizeof(*ifgr.ifgr_groups) <= idx-1)
2425		goto err;
2426
2427	if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) {
2428		log_warn("alloc");
2429		goto err;
2430	}
2431	if (ioctl(s, SIOCGIFGLIST, (caddr_t)&ifgr) == -1) {
2432		log_warn("SIOCGIFGLIST");
2433		goto err;
2434	}
2435	close(s);
2436
2437	if ((ifg = calloc(1, sizeof *ifg)) == NULL) {
2438		log_warn("alloc");
2439		goto err;
2440	}
2441
2442	memcpy(ifg, &ifgr.ifgr_groups[idx-1], sizeof *ifg);
2443	free(ifgr.ifgr_groups);
2444	return ifg;
2445 err:
2446	free(ifgr.ifgr_groups);
2447	close(s);
2448	return (NULL);
2449}
2450
2451void
2452mib_carpgrouptable(struct agentx_varbind *vb)
2453{
2454	struct agentx_object		*obj;
2455	enum agentx_request_type	 req;
2456	struct ifgroupreq		 ifgr;
2457	struct ifg_req			*ifg;
2458	uint32_t			 idx;
2459	int				 s;
2460
2461	obj = agentx_varbind_get_object(vb);
2462	idx = agentx_varbind_get_index_integer(vb, carpGroupIdx);
2463	req = agentx_varbind_request(vb);
2464
2465	if (idx < 1) {
2466		if (req == AGENTX_REQUEST_TYPE_GET) {
2467			agentx_varbind_notfound(vb);
2468			return;
2469		}
2470		idx = 1;
2471	} else if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
2472		if (idx == INT32_MAX) {
2473			agentx_varbind_notfound(vb);
2474			return;
2475		}
2476		idx++;
2477	}
2478
2479	/*
2480	 * XXX No consistent way to differentiate between not found and error
2481	 * Treat everything as not found.
2482	 */
2483	if ((ifg = mib_carpgroupget(idx)) == NULL) {
2484		agentx_varbind_notfound(vb);
2485		return;
2486	}
2487	agentx_varbind_set_index_integer(vb, carpGroupIdx, idx);
2488
2489	if (obj == carpGroupName)
2490		agentx_varbind_string(vb, ifg->ifgrq_group);
2491	else if (obj == carpGroupDemote) {
2492		if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
2493			log_warn("socket");
2494			free(ifg);
2495			agentx_varbind_error(vb);
2496			return;
2497		}
2498
2499		bzero(&ifgr, sizeof(ifgr));
2500		strlcpy(ifgr.ifgr_name, ifg->ifgrq_group, sizeof(ifgr.ifgr_name));
2501		if (ioctl(s, SIOCGIFGATTR, (caddr_t)&ifgr) == -1) {
2502			log_warn("SIOCGIFGATTR");
2503			close(s);
2504			free(ifg);
2505			agentx_varbind_error(vb);
2506			return;
2507		}
2508
2509		close(s);
2510		agentx_varbind_integer(vb, ifgr.ifgr_attrib.ifg_carp_demoted);
2511	} else
2512		fatal("%s: Unexpected object", __func__);
2513
2514	free(ifg);
2515}
2516
2517void
2518mib_memversion(struct agentx_varbind *vb)
2519{
2520	agentx_varbind_integer(vb, 1);
2521}
2522
2523void
2524mib_memiftable(struct agentx_varbind *vb)
2525{
2526	struct agentx_object		*obj;
2527	enum agentx_request_type	 req;
2528	u_int32_t			 idx = 0;
2529	struct kif			*kif;
2530
2531	obj = agentx_varbind_get_object(vb);
2532	idx = agentx_varbind_get_index_integer(vb, ifIdx);
2533	req = agentx_varbind_request(vb);
2534	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
2535		if (idx == INT32_MAX) {
2536			agentx_varbind_notfound(vb);
2537			return;
2538		}
2539		idx++;
2540	}
2541	if ((kif = mib_ifget(idx)) == NULL) {
2542		agentx_varbind_notfound(vb);
2543		return;
2544	}
2545	if (req == AGENTX_REQUEST_TYPE_GET) {
2546		if (idx != kif->if_index) {
2547			agentx_varbind_notfound(vb);
2548			return;
2549		}
2550	}
2551	agentx_varbind_set_index_integer(vb, ifIdx, kif->if_index);
2552
2553	if (obj == memIfName)
2554		agentx_varbind_string(vb, kif->if_name);
2555	else if (obj == memIfLiveLocks)
2556		agentx_varbind_counter64(vb, 0);
2557	else
2558		fatal("%s: Unexpected object", __func__);
2559}
2560
2561/*
2562 * Defined in IP-MIB.txt
2563 */
2564int mib_getipstat(struct ipstat *);
2565void mib_ipstat(struct agentx_varbind *);
2566void mib_ipforwarding(struct agentx_varbind *);
2567void mib_ipdefaultttl(struct agentx_varbind *);
2568void mib_ipinhdrerrs(struct agentx_varbind *);
2569void mib_ipinaddrerrs(struct agentx_varbind *);
2570void mib_ipforwdgrams(struct agentx_varbind *);
2571void mib_ipreasmtimeout(struct agentx_varbind *);
2572void mib_ipreasmfails(struct agentx_varbind *);
2573void mib_ipfragfails(struct agentx_varbind *);
2574void mib_ipaddr(struct agentx_varbind *);
2575void mib_physaddr(struct agentx_varbind *);
2576
2577void
2578mib_ipforwarding(struct agentx_varbind *vb)
2579{
2580	int	mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_FORWARDING };
2581	int	v;
2582	size_t	len = sizeof(v);
2583
2584	if (sysctl(mib, nitems(mib), &v, &len, NULL, 0) == -1) {
2585		log_warn("sysctl");
2586		agentx_varbind_error(vb);
2587		return;
2588	}
2589
2590	/* ipForwarding: forwarding(1), notForwarding(2) */
2591	agentx_varbind_integer(vb, (v == 0) ? 2 : 1);
2592}
2593
2594void
2595mib_ipdefaultttl(struct agentx_varbind *vb)
2596{
2597	int	mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
2598	int	v;
2599	size_t	len = sizeof(v);
2600
2601	if (sysctl(mib, nitems(mib), &v, &len, NULL, 0) == -1) {
2602		log_warn("sysctl");
2603		agentx_varbind_error(vb);
2604		return;
2605	}
2606
2607	agentx_varbind_integer(vb, v);
2608}
2609
2610int
2611mib_getipstat(struct ipstat *ipstat)
2612{
2613	int	 mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS };
2614	size_t	 len = sizeof(*ipstat);
2615
2616	return (sysctl(mib, nitems(mib), ipstat, &len, NULL, 0));
2617}
2618
2619void
2620mib_ipstat(struct agentx_varbind *vb)
2621{
2622	struct agentx_object	*obj;
2623	struct ipstat		 ipstat;
2624
2625	if (mib_getipstat(&ipstat) == -1) {
2626		log_warn("sysctl");
2627		agentx_varbind_error(vb);
2628		return;
2629	}
2630
2631	obj = agentx_varbind_get_object(vb);
2632	if (obj == ipInReceives)
2633		agentx_varbind_counter32(vb, ipstat.ips_total);
2634	else if (obj == ipInUnknownProtos)
2635		agentx_varbind_counter32(vb, ipstat.ips_noproto);
2636	else if (obj == ipInDelivers)
2637		agentx_varbind_counter32(vb, ipstat.ips_delivered);
2638	else if (obj == ipOutRequests)
2639		agentx_varbind_counter32(vb, ipstat.ips_localout);
2640	else if (obj == ipOutDiscards)
2641		agentx_varbind_counter32(vb, ipstat.ips_odropped);
2642	else if (obj == ipOutNoRoutes)
2643		agentx_varbind_counter32(vb, ipstat.ips_noroute);
2644	else if (obj == ipReasmReqds)
2645		agentx_varbind_counter32(vb, ipstat.ips_fragments);
2646	else if (obj == ipReasmOKs)
2647		agentx_varbind_counter32(vb, ipstat.ips_reassembled);
2648	else if (obj == ipFragOKs)
2649		agentx_varbind_counter32(vb, ipstat.ips_fragmented);
2650	else if (obj == ipFragCreates)
2651		agentx_varbind_counter32(vb, ipstat.ips_ofragments);
2652	else
2653		fatal("%s: Unexpected object", __func__);
2654}
2655
2656void
2657mib_ipinhdrerrs(struct agentx_varbind *vb)
2658{
2659	u_int32_t	errors;
2660	struct ipstat	ipstat;
2661
2662	if (mib_getipstat(&ipstat) == -1) {
2663		log_warn("sysctl");
2664		agentx_varbind_error(vb);
2665		return;
2666	}
2667
2668	errors = ipstat.ips_badsum + ipstat.ips_badvers +
2669	    ipstat.ips_tooshort + ipstat.ips_toosmall +
2670	    ipstat.ips_badhlen +  ipstat.ips_badlen +
2671	    ipstat.ips_badoptions + ipstat.ips_toolong +
2672	    ipstat.ips_badaddr;
2673
2674	agentx_varbind_counter32(vb, errors);
2675}
2676
2677void
2678mib_ipinaddrerrs(struct agentx_varbind *vb)
2679{
2680	u_int32_t	errors;
2681	struct ipstat	ipstat;
2682
2683	if (mib_getipstat(&ipstat) == -1) {
2684		log_warn("sysctl");
2685		agentx_varbind_error(vb);
2686		return;
2687	}
2688
2689	errors = ipstat.ips_cantforward + ipstat.ips_badaddr;
2690
2691	agentx_varbind_counter32(vb, errors);
2692}
2693
2694void
2695mib_ipforwdgrams(struct agentx_varbind *vb)
2696{
2697	u_int32_t	counter;
2698	struct ipstat	ipstat;
2699
2700	if (mib_getipstat(&ipstat) == -1) {
2701		log_warn("sysctl");
2702		agentx_varbind_error(vb);
2703		return;
2704	}
2705
2706	counter = ipstat.ips_forward + ipstat.ips_redirectsent;
2707
2708	agentx_varbind_counter32(vb, counter);
2709}
2710
2711void
2712mib_ipreasmtimeout(struct agentx_varbind *vb)
2713{
2714	agentx_varbind_integer(vb, IPFRAGTTL);
2715}
2716
2717void
2718mib_ipreasmfails(struct agentx_varbind *vb)
2719{
2720	u_int32_t	counter;
2721	struct ipstat	ipstat;
2722
2723	if (mib_getipstat(&ipstat) == -1) {
2724		log_warn("sysctl");
2725		agentx_varbind_error(vb);
2726		return;
2727	}
2728
2729	counter = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
2730
2731	agentx_varbind_counter32(vb, counter);
2732}
2733
2734void
2735mib_ipfragfails(struct agentx_varbind *vb)
2736{
2737	u_int32_t	counter;
2738	struct ipstat	ipstat;
2739
2740	if (mib_getipstat(&ipstat) == -1) {
2741		log_warn("sysctl");
2742		agentx_varbind_error(vb);
2743		return;
2744	}
2745
2746	counter = ipstat.ips_badfrags + ipstat.ips_cantfrag;
2747	agentx_varbind_counter32(vb, counter);
2748}
2749
2750void
2751mib_ipaddr(struct agentx_varbind *vb)
2752{
2753	struct agentx_object		*obj;
2754	enum agentx_request_type	 req;
2755	struct sockaddr_in		 addr;
2756	struct kif_addr			*ka;
2757
2758	obj = agentx_varbind_get_object(vb);
2759	req = agentx_varbind_request(vb);
2760	bzero(&addr, sizeof(addr));
2761	addr.sin_family = AF_INET;
2762	addr.sin_len = sizeof(addr);
2763	addr.sin_addr = *agentx_varbind_get_index_ipaddress(vb, ipAdEntAddrIdx);
2764
2765	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
2766		if (addr.sin_addr.s_addr == UINT32_MAX) {
2767			agentx_varbind_notfound(vb);
2768			return;
2769		}
2770		addr.sin_addr.s_addr = htonl(ntohl(addr.sin_addr.s_addr) + 1);
2771	}
2772	/*
2773	 * XXX No consistent way to differentiate between not found and error
2774	 * Treat everything as not found.
2775	 */
2776	ka = kr_getnextaddr((struct sockaddr *)&addr);
2777	if (ka == NULL || ka->addr.sa.sa_family != AF_INET) {
2778		agentx_varbind_notfound(vb);
2779		return;
2780	}
2781	if (req == AGENTX_REQUEST_TYPE_GET) {
2782		if (addr.sin_addr.s_addr !=
2783		    ((struct sockaddr_in *)&ka->addr.sa)->sin_addr.s_addr) {
2784			agentx_varbind_notfound(vb);
2785			return;
2786		}
2787	}
2788	agentx_varbind_set_index_ipaddress(vb, ipAdEntAddrIdx,
2789	    &((struct sockaddr_in *)&ka->addr.sa)->sin_addr);
2790
2791	if (obj == ipAdEntAddr)
2792		agentx_varbind_ipaddress(vb,
2793		    &((struct sockaddr_in *)&ka->addr.sa)->sin_addr);
2794	else if (obj == ipAdEntIfIndex)
2795		agentx_varbind_integer(vb, ka->if_index);
2796	else if (obj == ipAdEntNetMask)
2797		agentx_varbind_ipaddress(vb, &ka->mask.sin.sin_addr);
2798	else if (obj == ipAdEntBcastAddr)
2799		agentx_varbind_integer(vb, ka->dstbrd.sa.sa_len ? 1 : 0);
2800	else if (obj == ipAdEntReasmMaxSize)
2801		agentx_varbind_integer(vb, IP_MAXPACKET);
2802	else
2803		fatal("%s: Unexpected object", __func__);
2804}
2805
2806void
2807mib_physaddr(struct agentx_varbind *vb)
2808{
2809	struct agentx_object		*obj;
2810	enum agentx_request_type	 req;
2811	struct sockaddr_in		 addr;
2812	struct kif			*kif;
2813	struct kif_arp			*ka;
2814	u_int32_t			 idx = 0;
2815
2816	obj = agentx_varbind_get_object(vb);
2817	idx = agentx_varbind_get_index_integer(vb, ipNetToMediaIfIdx);
2818	req = agentx_varbind_request(vb);
2819
2820	/* Get the IP address */
2821	bzero(&addr, sizeof(addr));
2822	addr.sin_family = AF_INET;
2823	addr.sin_len = sizeof(addr);
2824	addr.sin_addr = *agentx_varbind_get_index_ipaddress(vb,
2825	    ipNetToMediaNetAddressIdx);
2826
2827	if (req == AGENTX_REQUEST_TYPE_GET ||
2828	    req == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
2829		if ((ka = karp_getaddr((struct sockaddr *)&addr, idx, 0)) == NULL) {
2830			if (req == AGENTX_REQUEST_TYPE_GET) {
2831				agentx_varbind_notfound(vb);
2832				return;
2833			}
2834			req = AGENTX_REQUEST_TYPE_GETNEXT;
2835		} else {
2836			if (req == AGENTX_REQUEST_TYPE_GET &&
2837			    (idx != ka->if_index ||
2838			    addr.sin_addr.s_addr !=
2839			    ka->addr.sin.sin_addr.s_addr)) {
2840				agentx_varbind_notfound(vb);
2841				return;
2842			}
2843		}
2844	}
2845	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
2846		if ((kif = kr_getif(idx)) == NULL) {
2847			/* No configured interfaces */
2848			if (idx == 0) {
2849				agentx_varbind_notfound(vb);
2850				return;
2851			}
2852			/*
2853			 * It may happen that an interface with a specific index
2854			 * does not exist or has been removed.  Jump to the next
2855			 * available interface.
2856			 */
2857			kif = kr_getif(0);
2858 nextif:
2859			for (; kif != NULL; kif = kr_getnextif(kif->if_index))
2860				if (kif->if_index > idx &&
2861				    (ka = karp_first(kif->if_index)) != NULL)
2862					break;
2863			if (kif == NULL) {
2864				/* No more interfaces with addresses on them */
2865				agentx_varbind_notfound(vb);
2866				return;
2867			}
2868		} else {
2869			if (idx == 0 || addr.sin_addr.s_addr == 0)
2870				ka = karp_first(kif->if_index);
2871			else {
2872				/* XXX This only works on a walk. */
2873				ka = karp_getaddr((struct sockaddr *)&addr, idx, 1);
2874			}
2875			if (ka == NULL) {
2876				/* Try next interface */
2877				goto nextif;
2878			}
2879		}
2880	}
2881	agentx_varbind_set_index_integer(vb, ipNetToMediaIfIdx, ka->if_index);
2882	agentx_varbind_set_index_ipaddress(vb, ipNetToMediaNetAddressIdx,
2883	    &ka->addr.sin.sin_addr);
2884
2885	if (obj == ipNetToMediaIfIndex)
2886		agentx_varbind_integer(vb, ka->if_index);
2887	else if (obj == ipNetToMediaPhysAddress) {
2888		if (bcmp(LLADDR(&ka->target.sdl), ether_zeroaddr,
2889		    sizeof(ether_zeroaddr)) == 0)
2890			agentx_varbind_nstring(vb, ether_zeroaddr,
2891			    sizeof(ether_zeroaddr));
2892		else
2893			agentx_varbind_nstring(vb, LLADDR(&ka->target.sdl),
2894			    ka->target.sdl.sdl_alen);
2895	} else if (obj == ipNetToMediaNetAddress)
2896		agentx_varbind_ipaddress(vb, &ka->addr.sin.sin_addr);
2897	else if (obj == ipNetToMediaType) {
2898		if (ka->flags & F_STATIC)
2899			agentx_varbind_integer(vb, 4); /* static */
2900		else
2901			agentx_varbind_integer(vb, 3); /* dynamic */
2902	} else
2903		fatal("%s: Unexpected object", __func__);
2904}
2905
2906/*
2907 * Defined in IP-FORWARD-MIB.txt (rfc4292)
2908 */
2909
2910void mib_ipfnroutes(struct agentx_varbind *);
2911//struct ber_oid *
2912//mib_ipfroutetable(struct oid *oid, struct ber_oid *o, struct ber_oid *no);
2913void mib_ipfroute(struct agentx_varbind *);
2914
2915void
2916mib_ipfnroutes(struct agentx_varbind *vb)
2917{
2918	agentx_varbind_gauge32(vb, kr_routenumber());
2919}
2920
2921#define INETADDRESSTYPE_IPV4	1
2922void
2923mib_ipfroute(struct agentx_varbind *vb)
2924{
2925	struct agentx_object		*obj;
2926	enum agentx_request_type	 req;
2927	struct kroute			*kr;
2928	const in_addr_t			*addr, *nhaddr;
2929	const uint32_t			*policy;
2930	size_t				 alen, plen, nlen;
2931	int				 af;
2932	int				 implied;
2933	u_int8_t			 prefixlen, prio, type, proto;
2934
2935
2936	obj = agentx_varbind_get_object(vb);
2937	req = agentx_varbind_request(vb);
2938	af = agentx_varbind_get_index_integer(vb, inetCidrRouteDestTypeIdx);
2939	addr = (const in_addr_t *)agentx_varbind_get_index_string(vb,
2940	    inetCidrRouteDestIdx, &alen, &implied);
2941	prefixlen = agentx_varbind_get_index_integer(vb,
2942	    inetCidrRoutePfxLenIdx);
2943	policy = agentx_varbind_get_index_oid(vb, inetCidrRoutePolicyIdx,
2944	    &plen, &implied);
2945	nhaddr = ((const in_addr_t *)agentx_varbind_get_index_string(vb,
2946	    inetCidrRouteNextHopIdx, &nlen, &implied));
2947
2948	if (plen >= 2)
2949		prio = policy[1];
2950	/* Initial 2 sub-identifiers should always be the same for us */
2951	if (af < INETADDRESSTYPE_IPV4 ||
2952	    (af == INETADDRESSTYPE_IPV4 && alen < 4)) {
2953		if (req == AGENTX_REQUEST_TYPE_GET) {
2954			agentx_varbind_notfound(vb);
2955			return;
2956		}
2957		kr = kroute_first();
2958	} else if (af > INETADDRESSTYPE_IPV4 ||
2959		   (af == INETADDRESSTYPE_IPV4 && alen > 4)) {
2960		agentx_varbind_notfound(vb);
2961		return;
2962	} else {
2963		/* XXX This only works when requesting known values. */
2964		kr = kroute_getaddr(*addr, prefixlen, prio,
2965		    req == AGENTX_REQUEST_TYPE_GETNEXT);
2966		if (kr == NULL) {
2967			agentx_varbind_notfound(vb);
2968			return;
2969		}
2970		if (req == AGENTX_REQUEST_TYPE_GETNEXT)
2971			goto done;
2972		if (nlen < 4) {
2973			if (req == AGENTX_REQUEST_TYPE_GET) {
2974				agentx_varbind_notfound(vb);
2975				return;
2976			}
2977		} else if (nlen > 4) {
2978			kr = kroute_getaddr(*addr, prefixlen, prio, 1);
2979			if (req == AGENTX_REQUEST_TYPE_GET || kr == NULL) {
2980				agentx_varbind_notfound(vb);
2981				return;
2982			}
2983		} else {
2984			if (ntohl(kr->nexthop.s_addr) < ntohl(*nhaddr)) {
2985				if (req == AGENTX_REQUEST_TYPE_GET) {
2986					agentx_varbind_notfound(vb);
2987					return;
2988				}
2989			} else if (ntohl(kr->nexthop.s_addr) > ntohl(*nhaddr)) {
2990				kr = kroute_getaddr(*addr, prefixlen, prio, 1);
2991				if (req == AGENTX_REQUEST_TYPE_GET ||
2992				    kr == NULL) {
2993					agentx_varbind_notfound(vb);
2994					return;
2995				}
2996			}
2997
2998		}
2999	}
3000 done:
3001	agentx_varbind_set_index_integer(vb, inetCidrRouteDestTypeIdx,
3002	    INETADDRESSTYPE_IPV4);
3003	agentx_varbind_set_index_nstring(vb, inetCidrRouteDestIdx,
3004	    (unsigned char *)&kr->prefix.s_addr, 4);
3005	agentx_varbind_set_index_integer(vb, inetCidrRoutePfxLenIdx,
3006	    kr->prefixlen);
3007	agentx_varbind_set_index_oid(vb, inetCidrRoutePolicyIdx,
3008	    AGENTX_OID(0, kr->priority));
3009	agentx_varbind_set_index_integer(vb, inetCidrRouteNextHopTypeIdx,
3010	    INETADDRESSTYPE_IPV4);
3011	agentx_varbind_set_index_nstring(vb, inetCidrRouteNextHopIdx,
3012	    (unsigned char *)&kr->nexthop.s_addr, 4);
3013
3014	if (obj == inetCidrRouteIfIndex)
3015		agentx_varbind_integer(vb, kr->if_index);
3016	else if (obj == inetCidrRouteType) {
3017		if (kr->flags & F_REJECT)
3018			type = 2;
3019		else if (kr->flags & F_BLACKHOLE)
3020			type = 5;
3021		else if (kr->flags & F_CONNECTED)
3022			type = 3;
3023		else
3024			type = 4;
3025		agentx_varbind_integer(vb, type);
3026	} else if (obj == inetCidrRouteProto) {
3027		switch (kr->priority) {
3028		case RTP_CONNECTED:
3029			proto = 2;
3030			break;
3031		case RTP_STATIC:
3032			proto = 3;
3033			break;
3034		case RTP_OSPF:
3035			proto = 13;
3036			break;
3037		case RTP_ISIS:
3038			proto = 9;
3039			break;
3040		case RTP_RIP:
3041			proto = 8;
3042			break;
3043		case RTP_BGP:
3044			proto = 14;
3045			break;
3046		default:
3047			if (kr->flags & F_DYNAMIC)
3048				proto = 4;
3049			else
3050				proto = 1; /* not specified */
3051			break;
3052		}
3053		agentx_varbind_integer(vb, proto);
3054	} else if (obj == inetCidrRouteAge)
3055		agentx_varbind_gauge32(vb, 0);
3056	else if (obj == inetCidrRouteNextHopAS)
3057		agentx_varbind_unsigned32(vb, 0); /* unknown */
3058	else if (obj == inetCidrRouteMetric1)
3059		agentx_varbind_integer(vb, -1);
3060	else if (obj == inetCidrRouteMetric2)
3061		agentx_varbind_integer(vb, -1);
3062	else if (obj == inetCidrRouteMetric3)
3063		agentx_varbind_integer(vb, -1);
3064	else if (obj == inetCidrRouteMetric4)
3065		agentx_varbind_integer(vb, -1);
3066	else if (obj == inetCidrRouteMetric5)
3067		agentx_varbind_integer(vb, -1);
3068	else if (obj == inetCidrRouteStatus)
3069		agentx_varbind_integer(vb, 1);	/* XXX */
3070	else
3071		fatal("%s: Unexpected object", __func__);
3072}
3073
3074/*
3075 * Defined in UCD-DISKIO-MIB.txt.
3076 */
3077
3078void	mib_diskio(struct agentx_varbind *vb);
3079
3080void
3081mib_diskio(struct agentx_varbind *vb)
3082{
3083	struct agentx_object		*obj;
3084	enum agentx_request_type	 req;
3085	u_int32_t			 idx;
3086	int				 mib[] = { CTL_HW, 0 };
3087	unsigned int			 diskcount;
3088	struct diskstats		*stats;
3089	size_t				 len;
3090
3091	len = sizeof(diskcount);
3092	mib[1] = HW_DISKCOUNT;
3093	if (sysctl(mib, nitems(mib), &diskcount, &len, NULL, 0) == -1) {
3094		log_warn("sysctl");
3095		agentx_varbind_error(vb);
3096		return;
3097	}
3098
3099	obj = agentx_varbind_get_object(vb);
3100	req = agentx_varbind_request(vb);
3101	idx = agentx_varbind_get_index_integer(vb, diskIOIdx);
3102
3103	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
3104		if (idx == INT32_MAX) {
3105			agentx_varbind_notfound(vb);
3106			return;
3107		}
3108		idx++;
3109	}
3110	if(idx < 1) {
3111		if (req == AGENTX_REQUEST_TYPE_GET) {
3112			agentx_varbind_notfound(vb);
3113			return;
3114		}
3115		idx = 1;
3116	} else if (idx > diskcount) {
3117		agentx_varbind_notfound(vb);
3118		return;
3119	}
3120	agentx_varbind_set_index_integer(vb, diskIOIdx, idx);
3121
3122	stats = calloc(diskcount, sizeof(*stats));
3123	if (stats == NULL) {
3124		log_warn("malloc");
3125		agentx_varbind_error(vb);
3126		return;
3127	}
3128	/* We know len won't overflow, otherwise calloc() would have failed. */
3129	len = diskcount * sizeof(*stats);
3130	mib[1] = HW_DISKSTATS;
3131	if (sysctl(mib, nitems(mib), stats, &len, NULL, 0) == -1) {
3132		log_warn("sysctl");
3133		free(stats);
3134		agentx_varbind_error(vb);
3135		return;
3136	}
3137
3138	if (obj == diskIOIndex)
3139		agentx_varbind_integer(vb, idx);
3140	else if (obj == diskIODevice)
3141		agentx_varbind_string(vb, stats[idx - 1].ds_name);
3142	else if (obj == diskIONRead)
3143		agentx_varbind_counter32(vb,
3144		    (u_int32_t)stats[idx - 1].ds_rbytes);
3145	else if (obj == diskIONWritten)
3146		agentx_varbind_counter32(vb,
3147		    (u_int32_t)stats[idx - 1].ds_wbytes);
3148	else if (obj == diskIOReads)
3149		agentx_varbind_counter32(vb,
3150		    (u_int32_t)stats[idx - 1].ds_rxfer);
3151	else if (obj == diskIOWrites)
3152		agentx_varbind_counter32(vb,
3153		    (u_int32_t)stats[idx - 1].ds_wxfer);
3154	else if (obj == diskIONReadX)
3155		agentx_varbind_counter64(vb, stats[idx - 1].ds_rbytes);
3156	else if (obj == diskIONWrittenX)
3157		agentx_varbind_counter64(vb, stats[idx - 1].ds_wbytes);
3158	else
3159		fatal("%s: Unexpected object", __func__);
3160	free(stats);
3161}
3162
3163/*
3164 * Defined in BRIDGE-MIB.txt (rfc1493)
3165 *
3166 * This MIB is required by some NMS to accept the device because
3167 * the RFC says that mostly any network device has to provide this MIB... :(
3168 */
3169
3170void	 mib_dot1basetype(struct agentx_varbind *);
3171void	 mib_dot1dtable(struct agentx_varbind *);
3172
3173void
3174mib_dot1basetype(struct agentx_varbind *vb)
3175{
3176	/* srt (sourceroute + transparent) */
3177	agentx_varbind_integer(vb, 4);
3178}
3179
3180void
3181mib_dot1dtable(struct agentx_varbind *vb)
3182{
3183	struct agentx_object		*obj;
3184	enum agentx_request_type	 req;
3185	u_int32_t			 idx = 0;
3186	struct kif			*kif;
3187
3188	obj = agentx_varbind_get_object(vb);
3189	req = agentx_varbind_request(vb);
3190	idx = agentx_varbind_get_index_integer(vb, dot1dBasePortIdx);
3191
3192	if (req == AGENTX_REQUEST_TYPE_GETNEXT) {
3193		if (idx == INT32_MAX) {
3194			agentx_varbind_notfound(vb);
3195			return;
3196		}
3197		idx++;
3198	}
3199	if ((kif = mib_ifget(idx)) == NULL) {
3200		agentx_varbind_notfound(vb);
3201		return;
3202	}
3203	if (req == AGENTX_REQUEST_TYPE_GET) {
3204		if (idx != kif->if_index) {
3205			agentx_varbind_notfound(vb);
3206			return;
3207		}
3208	}
3209	agentx_varbind_set_index_integer(vb, dot1dBasePortIdx, kif->if_index);
3210
3211	if (obj == dot1dBasePort)
3212		agentx_varbind_integer(vb, kif->if_index);
3213	else if (obj == dot1dBasePortIfIndex)
3214		agentx_varbind_integer(vb, kif->if_index);
3215	else if (obj == dot1dBasePortCircuit)
3216		agentx_varbind_oid(vb, AGENTX_OID(0, 0));
3217	else if (obj == dot1dBasePortDelayExceededDiscards)
3218		agentx_varbind_counter32(vb, 0);
3219	else if (obj == dot1dBasePortMtuExceededDiscards)
3220		agentx_varbind_counter32(vb, 0);
3221	else
3222		fatal("%s: Unexpected object", __func__);
3223}
3224
3225/*
3226 * Import all MIBs
3227 */
3228
3229int
3230main(int argc, char *argv[])
3231{
3232	static struct snmpd conf;
3233	struct agentx *sa;
3234	struct agentx_session *sas;
3235	struct agentx_index *indices[6];
3236	struct passwd *pw;
3237	struct group *gr;
3238	char agentxsocketdir[PATH_MAX];
3239	int ch;
3240	int verbose = 0, daemonize = 1, debug = 0;
3241	char *context = NULL;
3242	const char *errstr;
3243	/* HOST-RESOURCES-MIB */
3244	struct agentx_region *host;
3245	struct agentx_object *hrSystemUptime, *hrSystemDate, *hrMemorySize;
3246	/* IF-MIB */
3247	struct agentx_region *ifMIB, *interfaces;
3248	/* OPENBSD-PF-MIB */
3249	struct agentx_region *pfMIBObjects;
3250	/* OPENBSD-SENSOR-MIB */
3251	struct agentx_region *sensorsMIBObjects;
3252	/* OPENBSD-CARP-MIB */
3253	struct agentx_region *carpMIBObjects;
3254	/* OPENBSD-MEM-MIB */
3255	struct agentx_region *memMIBObjects;
3256	/* IP-MIB */
3257	struct agentx_region *ip;
3258	/* IP-FORWARD-MIB */
3259	struct agentx_region *ipForward;
3260	/* UCD-DISKIO-MIB */
3261	struct agentx_region *ucdDiskIOMIB;
3262	/* BRIDGE-MIB */
3263	struct agentx_region *dot1dBridge;
3264
3265	snmpd_env = &conf;
3266	log_init(2, LOG_DAEMON);
3267
3268	agentx_log_fatal = fatalx;
3269	agentx_log_warn = log_warnx;
3270	agentx_log_info = log_info;
3271	agentx_log_debug = log_debug;
3272
3273	while ((ch = getopt(argc, argv, "C:c:ds:vx:")) != -1) {
3274		switch (ch) {
3275		case 'C':
3276			if (strcmp(optarg, "filter-routes") == 0) {
3277				conf.sc_rtfilter = ROUTE_FILTER(RTM_NEWADDR) |
3278				    ROUTE_FILTER(RTM_DELADDR) |
3279				    ROUTE_FILTER(RTM_IFINFO) |
3280				    ROUTE_FILTER(RTM_IFANNOUNCE);
3281
3282			}
3283			break;
3284		case 'c':
3285			context = optarg;
3286			break;
3287		case 'd':
3288			daemonize = 0;
3289			debug = 1;
3290			break;
3291		case 's':
3292			if (optarg[0] != '/')
3293				fatalx("agentx socket path must be absolute");
3294			agentxsocket = optarg;
3295			break;
3296		case 'v':
3297			verbose++;
3298			break;
3299		case 'x':
3300			/* Undocumented flag for snmpd(8) spawning */
3301			agentxfd = strtonum(optarg, 0, INT_MAX, &errstr);
3302			if (errstr != NULL)
3303				fatalx("invalid agentx fd: %s", errstr);
3304			daemonize = 0;
3305			break;
3306		default:
3307			fatalx("usage: snmpd_metrics [-dv] [-C option] "
3308			    "[-c context] [-s master]\n");
3309		}
3310	}
3311
3312	if (agentxfd != -1 && !debug)
3313		/* Initialize syslog logging asap for snmpd */
3314		log_init(0, LOG_DAEMON);
3315
3316	if ((pw = getpwnam("_snmpd")) == NULL)
3317		fatal("can't find _snmpd user");
3318	if ((gr = getgrnam("_agentx")) == NULL)
3319		fatal("can't find _agentx group");
3320
3321	if (agentxfd != -1 && agentxsocket != NULL)
3322		fatalx("-s and -x are mutually exclusive");
3323	if (agentxfd == -1 && agentxsocket == NULL)
3324		agentxsocket = AGENTX_MASTER_PATH;
3325
3326	event_init();
3327
3328	if ((sa = agentx(snmp_connect, NULL)) == NULL)
3329		fatal("agentx");
3330	if ((sas = agentx_session(sa, NULL, 0, "OpenSNMPd metrics", 0)) == NULL)
3331		fatal("agentx_session");
3332	if ((sac = agentx_context(sas, context)) == NULL)
3333		fatal("agentx_context");
3334
3335	/* kr_init requires sac */
3336	kr_init();
3337	pf_init();
3338	timer_init();
3339	pageshift_init();
3340
3341	if (agentxsocket != NULL) {
3342		if (strlcpy(agentxsocketdir, agentxsocket,
3343		    sizeof(agentxsocketdir)) >= sizeof(agentxsocketdir)) {
3344			errno = ENAMETOOLONG;
3345			fatal("-s");
3346		}
3347		if (unveil(dirname(agentxsocketdir), "r") == -1)
3348			fatal("unveil");
3349	}
3350
3351	/* Can't pledge: kvm_getfiles */
3352	if (unveil(NULL, NULL) == -1)
3353		fatal("unveil");
3354
3355	if (setgid(gr->gr_gid) == -1)
3356		fatal("setgid");
3357	if (setuid(pw->pw_uid) == -1)
3358		fatal("setuid");
3359
3360	/* HOST-RESOURCES-MIB */
3361	if ((host = agentx_region(sac, AGENTX_OID(HOST), 0)) == NULL)
3362		fatal("agentx_region");
3363
3364	if ((hrSystemUptime = agentx_object(host, AGENTX_OID(HRSYSTEMUPTIME),
3365	    NULL, 0, 0, mib_hrsystemuptime)) == NULL ||
3366	    (hrSystemDate = agentx_object(host, AGENTX_OID(HRSYSTEMDATE),
3367	    NULL, 0, 0, mib_hrsystemdate)) == NULL ||
3368	    (hrSystemProcesses = agentx_object(host,
3369	    AGENTX_OID(HRSYSTEMPROCESSES), NULL, 0, 0,
3370	    mib_hrsystemprocs)) == NULL ||
3371	    (hrSystemMaxProcesses = agentx_object(host,
3372	    AGENTX_OID(HRSYSTEMMAXPROCESSES), NULL, 0, 0,
3373	    mib_hrsystemprocs)) == NULL ||
3374	    (hrMemorySize = agentx_object(host, AGENTX_OID(HRMEMORYSIZE),
3375	    NULL, 0, 0, mib_hrmemory)) == NULL)
3376		fatal("agentx_object");
3377
3378	if ((hrStorageIdx = agentx_index_integer_dynamic(host,
3379	    AGENTX_OID(HRSTORAGEINDEX))) == NULL)
3380		fatal("agentx_index_integer_dynamic");
3381	if ((hrStorageIndex = agentx_object(host, AGENTX_OID(HRSTORAGEINDEX),
3382	    &hrStorageIdx, 1, 0, mib_hrstorage)) == NULL ||
3383	    (hrStorageType = agentx_object(host, AGENTX_OID(HRSTORAGETYPE),
3384	    &hrStorageIdx, 1, 0, mib_hrstorage)) == NULL ||
3385	    (hrStorageDescr = agentx_object(host, AGENTX_OID(HRSTORAGEDESCR),
3386	    &hrStorageIdx, 1, 0, mib_hrstorage)) == NULL ||
3387	    (hrStorageAllocationUnits = agentx_object(host,
3388	    AGENTX_OID(HRSTORAGEALLOCATIONUNITS), &hrStorageIdx, 1, 0,
3389	    mib_hrstorage)) == NULL ||
3390	    (hrStorageSize = agentx_object(host, AGENTX_OID(HRSTORAGESIZE),
3391	    &hrStorageIdx, 1, 0, mib_hrstorage)) == NULL ||
3392	    (hrStorageUsed = agentx_object(host, AGENTX_OID(HRSTORAGEUSED),
3393	    &hrStorageIdx, 1, 0, mib_hrstorage)) == NULL ||
3394	    (hrStorageAllocationFailures = agentx_object(host,
3395	    AGENTX_OID(HRSTORAGEALLOCATIONFAILURES), &hrStorageIdx, 1, 0,
3396	    mib_hrstorage)) == NULL)
3397		fatal("agentx_object");
3398
3399	if ((hrDeviceIdx = agentx_index_integer_dynamic(host,
3400	    AGENTX_OID(HRDEVICEINDEX))) == NULL)
3401		fatal("agentx_index_integer_dynamic");
3402	if ((hrDeviceIndex = agentx_object(host, AGENTX_OID(HRDEVICEINDEX),
3403	    &hrDeviceIdx, 1, 0, mib_hrdevice)) == NULL ||
3404	    (hrDeviceType = agentx_object(host, AGENTX_OID(HRDEVICETYPE),
3405	    &hrDeviceIdx, 1, 0, mib_hrdevice)) == NULL ||
3406	    (hrDeviceDescr = agentx_object(host, AGENTX_OID(HRDEVICEDESCR),
3407	    &hrDeviceIdx, 1, 0, mib_hrdevice)) == NULL ||
3408	    (hrDeviceID = agentx_object(host, AGENTX_OID(HRDEVICEID),
3409	    &hrDeviceIdx, 1, 0, mib_hrdevice)) == NULL ||
3410	    (hrDeviceStatus = agentx_object(host, AGENTX_OID(HRDEVICESTATUS),
3411	    &hrDeviceIdx, 1, 0, mib_hrdevice)) == NULL ||
3412	    (hrDeviceErrors = agentx_object(host, AGENTX_OID(HRDEVICEERRORS),
3413	    &hrDeviceIdx, 1, 0, mib_hrdevice)) == NULL)
3414		fatal("agentx_object");
3415	if ((hrProcessorFrwID = agentx_object(host, AGENTX_OID(HRPROCESSORFRWID),
3416	    &hrDeviceIdx, 1, 0, mib_hrprocessor)) == NULL ||
3417	    (hrProcessorLoad = agentx_object(host, AGENTX_OID(HRPROCESSORLOAD),
3418	    &hrDeviceIdx, 1, 0, mib_hrprocessor)) == NULL)
3419		fatal("agentx_object");
3420	if ((hrSWRunIdx = agentx_index_integer_dynamic(host,
3421	    AGENTX_OID(HRSWRUNINDEX))) == NULL)
3422		fatal("agentx_index_integer_dynamic");
3423	if ((hrSWRunIndex = agentx_object(host, AGENTX_OID(HRSWRUNINDEX),
3424	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3425	    (hrSWRunName = agentx_object(host, AGENTX_OID(HRSWRUNNAME),
3426	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3427	    (hrSWRunID = agentx_object(host, AGENTX_OID(HRSWRUNID),
3428	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3429	    (hrSWRunPath = agentx_object(host, AGENTX_OID(HRSWRUNPATH),
3430	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3431	    (hrSWRunParameters = agentx_object(host,
3432	    AGENTX_OID(HRSWRUNPARAMETERS), &hrSWRunIdx, 1, 0,
3433	    mib_hrswrun)) == NULL ||
3434	    (hrSWRunType = agentx_object(host, AGENTX_OID(HRSWRUNTYPE),
3435	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3436	    (hrSWRunStatus = agentx_object(host, AGENTX_OID(HRSWRUNSTATUS),
3437	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3438	    (hrSWRunPerfCPU = agentx_object(host, AGENTX_OID(HRSWRUNPERFCPU),
3439	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL ||
3440	    (hrSWRunPerfMem = agentx_object(host, AGENTX_OID(HRSWRUNPERFMEM),
3441	    &hrSWRunIdx, 1, 0, mib_hrswrun)) == NULL)
3442		fatal("agentx_object");
3443
3444	/* IF-MIB */
3445	if ((ifMIB = agentx_region(sac, AGENTX_OID(IFMIB), 0)) == NULL ||
3446	    (interfaces = agentx_region(sac,
3447	    AGENTX_OID(INTERFACES), 0)) == NULL)
3448		fatal("agentx_region");
3449
3450	if ((ifIdx = agentx_index_integer_dynamic(interfaces,
3451	    AGENTX_OID(IFINDEX))) == NULL)
3452		fatal("agentx_index_integer_dynamic");
3453	if ((ifName = agentx_object(ifMIB, AGENTX_OID(IFNAME),
3454	    &ifIdx, 1, 0, mib_ifxtable)) == NULL ||
3455	    (ifInMulticastPkts = agentx_object(ifMIB,
3456	    AGENTX_OID(IFINMULTICASTPKTS), &ifIdx, 1, 0,
3457	    mib_ifxtable)) == NULL ||
3458	    (ifInBroadcastPkts = agentx_object(ifMIB,
3459	    AGENTX_OID(IFINBROADCASTPKTS), &ifIdx, 1, 0,
3460	    mib_ifxtable)) == NULL ||
3461	    (ifOutMulticastPkts = agentx_object(ifMIB,
3462	    AGENTX_OID(IFOUTMULTICASTPKTS), &ifIdx, 1, 0,
3463	    mib_ifxtable)) == NULL ||
3464	    (ifOutBroadcastPkts = agentx_object(ifMIB,
3465	    AGENTX_OID(IFOUTBROADCASTPKTS), &ifIdx, 1, 0,
3466	    mib_ifxtable)) == NULL ||
3467	    (ifHCInOctets = agentx_object(ifMIB, AGENTX_OID(IFHCINOCTETS),
3468	    &ifIdx, 1, 0, mib_ifxtable)) == NULL ||
3469	    (ifHCInUcastPkts = agentx_object(ifMIB, AGENTX_OID(IFHCINUCASTPKTS),
3470	    &ifIdx, 1, 0, mib_ifxtable)) == NULL ||
3471	    (ifHCInMulticastPkts = agentx_object(ifMIB,
3472	    AGENTX_OID(IFHCINMULTICASTPKTS), &ifIdx, 1, 0,
3473	    mib_ifxtable)) == NULL ||
3474	    (ifHCInBroadcastPkts = agentx_object(ifMIB,
3475	    AGENTX_OID(IFHCINBROADCASTPKTS), &ifIdx, 1, 0,
3476	    mib_ifxtable)) == NULL ||
3477	    (ifHCOutOctets = agentx_object(ifMIB, AGENTX_OID(IFHCOUTOCTETS),
3478	    &ifIdx, 1, 0, mib_ifxtable)) == NULL ||
3479	    (ifHCOutUcastPkts = agentx_object(ifMIB,
3480	    AGENTX_OID(IFHCOUTUCASTPKTS), &ifIdx, 1, 0,
3481	    mib_ifxtable)) == NULL ||
3482	    (ifHCOutMulticastPkts = agentx_object(ifMIB,
3483	    AGENTX_OID(IFHCOUTMULTICASTPKTS), &ifIdx, 1, 0,
3484	    mib_ifxtable)) == NULL ||
3485	    (ifHCOutBroadcastPkts = agentx_object(ifMIB,
3486	    AGENTX_OID(IFHCOUTBROADCASTPKTS), &ifIdx, 1, 0,
3487	    mib_ifxtable)) == NULL ||
3488	    (ifLinkUpDownTrapEnable = agentx_object(ifMIB,
3489	    AGENTX_OID(IFLINKUPDOWNTRAPENABLE), &ifIdx, 1, 0,
3490	    mib_ifxtable)) == NULL ||
3491	    (ifHighSpeed = agentx_object(ifMIB, AGENTX_OID(IFHIGHSPEED),
3492	    &ifIdx, 1, 0, mib_ifxtable)) == NULL ||
3493	    (ifPromiscuousMode = agentx_object(ifMIB,
3494	    AGENTX_OID(IFPROMISCUOUSMODE), &ifIdx, 1, 0,
3495	    mib_ifxtable)) == NULL ||
3496	    (ifConnectorPresent = agentx_object(ifMIB,
3497	    AGENTX_OID(IFCONNECTORPRESENT), &ifIdx, 1, 0,
3498	    mib_ifxtable)) == NULL ||
3499	    (ifAlias = agentx_object(ifMIB, AGENTX_OID(IFALIAS),
3500	    &ifIdx, 1, 0, mib_ifxtable)) == NULL ||
3501	    (ifCounterDiscontinuityTime = agentx_object(ifMIB,
3502	    AGENTX_OID(IFCOUNTERDISCONTINUITYTIME), &ifIdx, 1, 0,
3503	    mib_ifxtable)) == NULL)
3504		fatal("agentx_object");
3505
3506	if ((ifRcvAddressAddress = agentx_index_string_dynamic(ifMIB,
3507	    AGENTX_OID(IFRCVADDRESSADDRESS))) == NULL)
3508		fatal("agentx_index_string_dynamic");
3509	indices[0] = ifIdx;
3510	indices[1] = ifRcvAddressAddress;
3511	if ((ifRcvAddressStatus = agentx_object(ifMIB,
3512	    AGENTX_OID(IFRCVADDRESSSTATUS), indices, 2, 0,
3513	    mib_ifrcvtable)) == NULL ||
3514	    (ifRcvAddressType = agentx_object(ifMIB,
3515	    AGENTX_OID(IFRCVADDRESSTYPE), indices, 2, 0,
3516	    mib_ifrcvtable)) == NULL)
3517		fatal("agentx_object");
3518
3519	if ((ifStackLastChange = agentx_object(ifMIB,
3520	    AGENTX_OID(IFSTACKLASTCHANGE), NULL, 0, 0,
3521	    mib_ifstacklast)) == NULL)
3522		fatal("agentx_object");
3523
3524	if ((ifNumber = agentx_object(interfaces, AGENTX_OID(IFNUMBER),
3525	    NULL, 0, 0, mib_ifnumber)) == NULL)
3526		fatal("agentx_object");
3527
3528	if ((ifIndex = agentx_object(interfaces, AGENTX_OID(IFINDEX),
3529	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3530	    (ifDescr = agentx_object(interfaces, AGENTX_OID(IFDESCR),
3531	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3532	    (ifType = agentx_object(interfaces, AGENTX_OID(IFTYPE),
3533	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3534	    (ifMtu = agentx_object(interfaces, AGENTX_OID(IFMTU),
3535	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3536	    (ifSpeed = agentx_object(interfaces, AGENTX_OID(IFSPEED),
3537	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3538	    (ifPhysAddress = agentx_object(interfaces,
3539	    AGENTX_OID(IFPHYSADDRESS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3540	    (ifAdminStatus = agentx_object(interfaces,
3541	    AGENTX_OID(IFADMINSTATUS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3542	    (ifOperStatus = agentx_object(interfaces,
3543	    AGENTX_OID(IFOPERSTATUS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3544	    (ifLastChange = agentx_object(interfaces,
3545	    AGENTX_OID(IFLASTCHANGE), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3546	    (ifInOctets = agentx_object(interfaces, AGENTX_OID(IFINOCTETS),
3547	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3548	    (ifInUcastPkts = agentx_object(interfaces,
3549	    AGENTX_OID(IFINUCASTPKTS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3550	    (ifInNUcastPkts = agentx_object(interfaces,
3551	    AGENTX_OID(IFINNUCASTPKTS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3552	    (ifInDiscards = agentx_object(interfaces,
3553	    AGENTX_OID(IFINDISCARDS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3554	    (ifInErrors = agentx_object(interfaces, AGENTX_OID(IFINERRORS),
3555	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3556	    (ifInUnknownProtos = agentx_object(interfaces,
3557	    AGENTX_OID(IFINUNKNOWNPROTOS), &ifIdx, 1, 0,
3558	    mib_iftable)) == NULL ||
3559	    (ifOutOctets = agentx_object(interfaces, AGENTX_OID(IFOUTOCTETS),
3560	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3561	    (ifOutUcastPkts = agentx_object(interfaces,
3562	    AGENTX_OID(IFOUTUCASTPKTS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3563	    (ifOutNUcastPkts = agentx_object(interfaces,
3564	    AGENTX_OID(IFOUTNUCASTPKTS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3565	    (ifOutDiscards = agentx_object(interfaces,
3566	    AGENTX_OID(IFOUTDISCARDS), &ifIdx, 1, 0, mib_iftable)) == NULL ||
3567	    (ifOutErrors = agentx_object(interfaces, AGENTX_OID(IFOUTERRORS),
3568	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3569	    (ifOutQLen = agentx_object(interfaces, AGENTX_OID(IFOUTQLEN),
3570	    &ifIdx, 1, 0, mib_iftable)) == NULL ||
3571	    (ifSpecific = agentx_object(interfaces, AGENTX_OID(IFSPECIFIC),
3572	    &ifIdx, 1, 0, mib_iftable)) == NULL)
3573		fatal("agentx_object");
3574
3575	/* OPENBSD-PF-MIB */
3576	if ((pfMIBObjects = agentx_region(sac,
3577	    AGENTX_OID(PFMIBOBJECTS), 0)) == NULL)
3578		fatal("agentx_region");
3579	if ((pfRunning = agentx_object(pfMIBObjects, AGENTX_OID(PFRUNNING),
3580	    NULL, 0, 0, mib_pfinfo)) == NULL ||
3581	    (pfRuntime = agentx_object(pfMIBObjects, AGENTX_OID(PFRUNTIME),
3582	    NULL, 0, 0, mib_pfinfo)) == NULL ||
3583	    (pfDebug = agentx_object(pfMIBObjects, AGENTX_OID(PFDEBUG),
3584	    NULL, 0, 0, mib_pfinfo)) == NULL ||
3585	    (pfHostid = agentx_object(pfMIBObjects, AGENTX_OID(PFHOSTID),
3586	    NULL, 0, 0, mib_pfinfo)) == NULL)
3587		fatal("agentx_object");
3588
3589	if ((pfCntMatch = agentx_object(pfMIBObjects, AGENTX_OID(PFCNTMATCH),
3590	    NULL, 0, 0, mib_pfcounters)) == NULL ||
3591	    (pfCntBadOffset = agentx_object(pfMIBObjects,
3592	    AGENTX_OID(PFCNTBADOFFSET), NULL, 0, 0, mib_pfcounters)) == NULL ||
3593	    (pfCntFragment = agentx_object(pfMIBObjects,
3594	    AGENTX_OID(PFCNTFRAGMENT), NULL, 0, 0, mib_pfcounters)) == NULL ||
3595	    (pfCntShort = agentx_object(pfMIBObjects, AGENTX_OID(PFCNTSHORT),
3596	    NULL, 0, 0, mib_pfcounters)) == NULL ||
3597	    (pfCntNormalize = agentx_object(pfMIBObjects,
3598	    AGENTX_OID(PFCNTNORMALIZE), NULL, 0, 0, mib_pfcounters)) == NULL ||
3599	    (pfCntMemory = agentx_object(pfMIBObjects, AGENTX_OID(PFCNTMEMORY),
3600	    NULL, 0, 0, mib_pfcounters)) == NULL ||
3601	    (pfCntTimestamp = agentx_object(pfMIBObjects,
3602	    AGENTX_OID(PFCNTTIMESTAMP), NULL, 0, 0, mib_pfcounters)) == NULL ||
3603	    (pfCntCongestion = agentx_object(pfMIBObjects,
3604	    AGENTX_OID(PFCNTCONGESTION), NULL, 0, 0, mib_pfcounters)) == NULL ||
3605	    (pfCntIpOption = agentx_object(pfMIBObjects,
3606	    AGENTX_OID(PFCNTIPOPTION), NULL, 0, 0, mib_pfcounters)) == NULL ||
3607	    (pfCntProtoCksum = agentx_object(pfMIBObjects,
3608	    AGENTX_OID(PFCNTPROTOCKSUM), NULL, 0, 0, mib_pfcounters)) == NULL ||
3609	    (pfCntStateMismatch = agentx_object(pfMIBObjects,
3610	    AGENTX_OID(PFCNTSTATEMISMATCH), NULL, 0, 0,
3611	    mib_pfcounters)) == NULL ||
3612	    (pfCntStateInsert = agentx_object(pfMIBObjects,
3613	    AGENTX_OID(PFCNTSTATEINSERT), NULL, 0, 0,
3614	    mib_pfcounters)) == NULL ||
3615	    (pfCntStateLimit = agentx_object(pfMIBObjects,
3616	    AGENTX_OID(PFCNTSTATELIMIT), NULL, 0, 0, mib_pfcounters)) == NULL ||
3617	    (pfCntSrcLimit = agentx_object(pfMIBObjects,
3618	    AGENTX_OID(PFCNTSRCLIMIT), NULL, 0, 0, mib_pfcounters)) == NULL ||
3619	    (pfCntSynproxy = agentx_object(pfMIBObjects,
3620	    AGENTX_OID(PFCNTSYNPROXY), NULL, 0, 0, mib_pfcounters)) == NULL ||
3621	    (pfCntTranslate = agentx_object(pfMIBObjects,
3622	    AGENTX_OID(PFCNTTRANSLATE), NULL, 0, 0, mib_pfcounters)) == NULL ||
3623	    (pfCntNoRoute = agentx_object(pfMIBObjects,
3624	    AGENTX_OID(PFCNTNOROUTE), NULL, 0, 0, mib_pfcounters)) == NULL)
3625		fatal("agentx_object");
3626
3627	if ((pfStateCount = agentx_object(pfMIBObjects,
3628	    AGENTX_OID(PFSTATECOUNT), NULL, 0, 0, mib_pfscounters)) == NULL ||
3629	    (pfStateSearches = agentx_object(pfMIBObjects,
3630	    AGENTX_OID(PFSTATESEARCHES), NULL, 0, 0,
3631	    mib_pfscounters)) == NULL ||
3632	    (pfStateInserts = agentx_object(pfMIBObjects,
3633	    AGENTX_OID(PFSTATEINSERTS), NULL, 0, 0, mib_pfscounters)) == NULL ||
3634	    (pfStateRemovals = agentx_object(pfMIBObjects,
3635	    AGENTX_OID(PFSTATEREMOVALS), NULL, 0, 0, mib_pfscounters)) == NULL)
3636		fatal("agentx_object");
3637
3638	if ((pfLogIfName = agentx_object(pfMIBObjects, AGENTX_OID(PFLOGIFNAME),
3639	    NULL, 0, 0, mib_pflogif)) == NULL ||
3640	    (pfLogIfIpBytesIn = agentx_object(pfMIBObjects,
3641	    AGENTX_OID(PFLOGIFIPBYTESIN), NULL, 0, 0, mib_pflogif)) == NULL ||
3642	    (pfLogIfIpBytesOut = agentx_object(pfMIBObjects,
3643	    AGENTX_OID(PFLOGIFIPBYTESOUT), NULL, 0, 0, mib_pflogif)) == NULL ||
3644	    (pfLogIfIpPktsInPass = agentx_object(pfMIBObjects,
3645	    AGENTX_OID(PFLOGIFIPPKTSINPASS), NULL, 0, 0,
3646	    mib_pflogif)) == NULL ||
3647	    (pfLogIfIpPktsInDrop = agentx_object(pfMIBObjects,
3648	    AGENTX_OID(PFLOGIFIPPKTSINDROP), NULL, 0, 0,
3649	    mib_pflogif)) == NULL ||
3650	    (pfLogIfIpPktsOutPass = agentx_object(pfMIBObjects,
3651	    AGENTX_OID(PFLOGIFIPPKTSOUTPASS), NULL, 0, 0,
3652	    mib_pflogif)) == NULL ||
3653	    (pfLogIfIpPktsOutDrop = agentx_object(pfMIBObjects,
3654	    AGENTX_OID(PFLOGIFIPPKTSOUTDROP), NULL, 0, 0,
3655	    mib_pflogif)) == NULL ||
3656	    (pfLogIfIp6BytesIn = agentx_object(pfMIBObjects,
3657	    AGENTX_OID(PFLOGIFIP6BYTESIN), NULL, 0, 0, mib_pflogif)) == NULL ||
3658	    (pfLogIfIp6BytesOut = agentx_object(pfMIBObjects,
3659	    AGENTX_OID(PFLOGIFIP6BYTESOUT), NULL, 0, 0, mib_pflogif)) == NULL ||
3660	    (pfLogIfIp6PktsInPass = agentx_object(pfMIBObjects,
3661	    AGENTX_OID(PFLOGIFIP6PKTSINPASS), NULL, 0, 0,
3662	    mib_pflogif)) == NULL ||
3663	    (pfLogIfIp6PktsInDrop = agentx_object(pfMIBObjects,
3664	    AGENTX_OID(PFLOGIFIP6PKTSINDROP), NULL, 0, 0,
3665	    mib_pflogif)) == NULL ||
3666	    (pfLogIfIp6PktsOutPass = agentx_object(pfMIBObjects,
3667	    AGENTX_OID(PFLOGIFIP6PKTSOUTPASS), NULL, 0, 0,
3668	    mib_pflogif)) == NULL ||
3669	    (pfLogIfIp6PktsOutDrop = agentx_object(pfMIBObjects,
3670	    AGENTX_OID(PFLOGIFIP6PKTSOUTDROP), NULL, 0, 0,
3671	    mib_pflogif)) == NULL)
3672		fatal("agentx_object");
3673
3674	if ((pfSrcTrackCount = agentx_object(pfMIBObjects,
3675	    AGENTX_OID(PFSRCTRACKCOUNT), NULL, 0, 0, mib_pfsrctrack)) == NULL ||
3676	    (pfSrcTrackSearches = agentx_object(pfMIBObjects,
3677	    AGENTX_OID(PFSRCTRACKSEARCHES), NULL, 0, 0,
3678	    mib_pfsrctrack)) == NULL ||
3679	    (pfSrcTrackInserts = agentx_object(pfMIBObjects,
3680	    AGENTX_OID(PFSRCTRACKINSERTS), NULL, 0, 0,
3681	    mib_pfsrctrack)) == NULL ||
3682	    (pfSrcTrackRemovals = agentx_object(pfMIBObjects,
3683	    AGENTX_OID(PFSRCTRACKREMOVALS), NULL, 0, 0,
3684	    mib_pfsrctrack)) == NULL)
3685		fatal("agentx_object");
3686
3687	if ((pfLimitStates = agentx_object(pfMIBObjects,
3688	    AGENTX_OID(PFLIMITSTATES), NULL, 0, 0, mib_pflimits)) == NULL ||
3689	    (pfLimitSourceNodes = agentx_object(pfMIBObjects,
3690	    AGENTX_OID(PFLIMITSOURCENODES), NULL, 0, 0,
3691	    mib_pflimits)) == NULL ||
3692	    (pfLimitFragments = agentx_object(pfMIBObjects,
3693	    AGENTX_OID(PFLIMITFRAGMENTS), NULL, 0, 0, mib_pflimits)) == NULL ||
3694	    (pfLimitMaxTables = agentx_object(pfMIBObjects,
3695	    AGENTX_OID(PFLIMITMAXTABLES), NULL, 0, 0, mib_pflimits)) == NULL ||
3696	    (pfLimitMaxTableEntries = agentx_object(pfMIBObjects,
3697	    AGENTX_OID(PFLIMITMAXTABLEENTRIES), NULL, 0, 0,
3698	    mib_pflimits)) == NULL)
3699		fatal("agentx_object");
3700
3701	if ((pfTimeoutTcpFirst = agentx_object(pfMIBObjects,
3702	    AGENTX_OID(PFTIMEOUTTCPFIRST), NULL, 0, 0,
3703	    mib_pftimeouts)) == NULL ||
3704	    (pfTimeoutTcpOpening = agentx_object(pfMIBObjects,
3705	    AGENTX_OID(PFTIMEOUTTCPOPENING), NULL, 0, 0,
3706	    mib_pftimeouts)) == NULL ||
3707	    (pfTimeoutTcpEstablished = agentx_object(pfMIBObjects,
3708	    AGENTX_OID(PFTIMEOUTTCPESTABLISHED), NULL, 0, 0,
3709	    mib_pftimeouts)) == NULL ||
3710	    (pfTimeoutTcpClosing = agentx_object(pfMIBObjects,
3711	    AGENTX_OID(PFTIMEOUTTCPCLOSING), NULL, 0, 0,
3712	    mib_pftimeouts)) == NULL ||
3713	    (pfTimeoutTcpFinWait = agentx_object(pfMIBObjects,
3714	    AGENTX_OID(PFTIMEOUTTCPFINWAIT), NULL, 0, 0,
3715	    mib_pftimeouts)) == NULL ||
3716	    (pfTimeoutTcpClosed = agentx_object(pfMIBObjects,
3717	    AGENTX_OID(PFTIMEOUTTCPCLOSED), NULL, 0, 0,
3718	    mib_pftimeouts)) == NULL ||
3719	    (pfTimeoutUdpFirst = agentx_object(pfMIBObjects,
3720	    AGENTX_OID(PFTIMEOUTUDPFIRST), NULL, 0, 0,
3721	    mib_pftimeouts)) == NULL ||
3722	    (pfTimeoutUdpSingle = agentx_object(pfMIBObjects,
3723	    AGENTX_OID(PFTIMEOUTUDPSINGLE), NULL, 0, 0,
3724	    mib_pftimeouts)) == NULL ||
3725	    (pfTimeoutUdpMultiple = agentx_object(pfMIBObjects,
3726	    AGENTX_OID(PFTIMEOUTUDPMULTIPLE), NULL, 0, 0,
3727	    mib_pftimeouts)) == NULL ||
3728	    (pfTimeoutIcmpFirst = agentx_object(pfMIBObjects,
3729	    AGENTX_OID(PFTIMEOUTICMPFIRST), NULL, 0, 0,
3730	    mib_pftimeouts)) == NULL ||
3731	    (pfTimeoutIcmpError = agentx_object(pfMIBObjects,
3732	    AGENTX_OID(PFTIMEOUTICMPERROR), NULL, 0, 0,
3733	    mib_pftimeouts)) == NULL ||
3734	    (pfTimeoutOtherFirst = agentx_object(pfMIBObjects,
3735	    AGENTX_OID(PFTIMEOUTOTHERFIRST), NULL, 0, 0,
3736	    mib_pftimeouts)) == NULL ||
3737	    (pfTimeoutOtherSingle = agentx_object(pfMIBObjects,
3738	    AGENTX_OID(PFTIMEOUTOTHERSINGLE), NULL, 0, 0,
3739	    mib_pftimeouts)) == NULL ||
3740	    (pfTimeoutOtherMultiple = agentx_object(pfMIBObjects,
3741	    AGENTX_OID(PFTIMEOUTOTHERMULTIPLE), NULL, 0, 0,
3742	    mib_pftimeouts)) == NULL ||
3743	    (pfTimeoutFragment = agentx_object(pfMIBObjects,
3744	    AGENTX_OID(PFTIMEOUTFRAGMENT), NULL, 0, 0,
3745	    mib_pftimeouts)) == NULL ||
3746	    (pfTimeoutInterval = agentx_object(pfMIBObjects,
3747	    AGENTX_OID(PFTIMEOUTINTERVAL), NULL, 0, 0,
3748	    mib_pftimeouts)) == NULL ||
3749	    (pfTimeoutAdaptiveStart = agentx_object(pfMIBObjects,
3750	    AGENTX_OID(PFTIMEOUTADAPTIVESTART), NULL, 0, 0,
3751	    mib_pftimeouts)) == NULL ||
3752	    (pfTimeoutAdaptiveEnd = agentx_object(pfMIBObjects,
3753	    AGENTX_OID(PFTIMEOUTADAPTIVEEND), NULL, 0, 0,
3754	    mib_pftimeouts)) == NULL ||
3755	    (pfTimeoutSrcTrack = agentx_object(pfMIBObjects,
3756	    AGENTX_OID(PFTIMEOUTSRCTRACK), NULL, 0, 0,
3757	    mib_pftimeouts)) == NULL)
3758		fatal("agentx_object");
3759
3760	if ((pfIfNumber = agentx_object(pfMIBObjects, AGENTX_OID(PFIFNUMBER),
3761	    NULL, 0, 0, mib_pfifnum)) == NULL)
3762		fatal("agentx_object");
3763	if ((pfIfIdx = agentx_index_integer_dynamic(pfMIBObjects,
3764	    AGENTX_OID(PFIFINDEX))) == NULL)
3765		fatal("agentx_index_integer_dynamic");
3766	if ((pfIfIndex = agentx_object(pfMIBObjects, AGENTX_OID(PFIFINDEX),
3767	    &pfIfIdx, 1, 0, mib_pfiftable)) == NULL ||
3768	    (pfIfDescr = agentx_object(pfMIBObjects, AGENTX_OID(PFIFDESCR),
3769	    &pfIfIdx, 1, 0, mib_pfiftable)) == NULL ||
3770	    (pfIfType = agentx_object(pfMIBObjects, AGENTX_OID(PFIFTYPE),
3771	    &pfIfIdx, 1, 0, mib_pfiftable)) == NULL ||
3772	    (pfIfRefs = agentx_object(pfMIBObjects, AGENTX_OID(PFIFREFS),
3773	    &pfIfIdx, 1, 0, mib_pfiftable)) == NULL ||
3774	    (pfIfRules = agentx_object(pfMIBObjects, AGENTX_OID(PFIFRULES),
3775	    &pfIfIdx, 1, 0, mib_pfiftable)) == NULL ||
3776	    (pfIfIn4PassPkts = agentx_object(pfMIBObjects,
3777	    AGENTX_OID(PFIFIN4PASSPKTS), &pfIfIdx, 1, 0,
3778	    mib_pfiftable)) == NULL ||
3779	    (pfIfIn4PassBytes = agentx_object(pfMIBObjects,
3780	    AGENTX_OID(PFIFIN4PASSBYTES), &pfIfIdx, 1, 0,
3781	    mib_pfiftable)) == NULL ||
3782	    (pfIfIn4BlockPkts = agentx_object(pfMIBObjects,
3783	    AGENTX_OID(PFIFIN4BLOCKPKTS), &pfIfIdx, 1, 0,
3784	    mib_pfiftable)) == NULL ||
3785	    (pfIfIn4BlockBytes = agentx_object(pfMIBObjects,
3786	    AGENTX_OID(PFIFIN4BLOCKBYTES), &pfIfIdx, 1, 0,
3787	    mib_pfiftable)) == NULL ||
3788	    (pfIfOut4PassPkts = agentx_object(pfMIBObjects,
3789	    AGENTX_OID(PFIFOUT4PASSPKTS), &pfIfIdx, 1, 0,
3790	    mib_pfiftable)) == NULL ||
3791	    (pfIfOut4PassBytes = agentx_object(pfMIBObjects,
3792	    AGENTX_OID(PFIFOUT4PASSBYTES), &pfIfIdx, 1, 0,
3793	    mib_pfiftable)) == NULL ||
3794	    (pfIfOut4BlockPkts = agentx_object(pfMIBObjects,
3795	    AGENTX_OID(PFIFOUT4BLOCKPKTS), &pfIfIdx, 1, 0,
3796	    mib_pfiftable)) == NULL ||
3797	    (pfIfOut4BlockBytes = agentx_object(pfMIBObjects,
3798	    AGENTX_OID(PFIFOUT4BLOCKBYTES), &pfIfIdx, 1, 0,
3799	    mib_pfiftable)) == NULL ||
3800	    (pfIfIn6PassPkts = agentx_object(pfMIBObjects,
3801	    AGENTX_OID(PFIFIN6PASSPKTS), &pfIfIdx, 1, 0,
3802	    mib_pfiftable)) == NULL ||
3803	    (pfIfIn6PassBytes = agentx_object(pfMIBObjects,
3804	    AGENTX_OID(PFIFIN6PASSBYTES), &pfIfIdx, 1, 0,
3805	    mib_pfiftable)) == NULL ||
3806	    (pfIfIn6BlockPkts = agentx_object(pfMIBObjects,
3807	    AGENTX_OID(PFIFIN6BLOCKPKTS), &pfIfIdx, 1, 0,
3808	    mib_pfiftable)) == NULL ||
3809	    (pfIfIn6BlockBytes = agentx_object(pfMIBObjects,
3810	    AGENTX_OID(PFIFIN6BLOCKBYTES), &pfIfIdx, 1, 0,
3811	    mib_pfiftable)) == NULL ||
3812	    (pfIfOut6PassPkts = agentx_object(pfMIBObjects,
3813	    AGENTX_OID(PFIFOUT6PASSPKTS), &pfIfIdx, 1, 0,
3814	    mib_pfiftable)) == NULL ||
3815	    (pfIfOut6PassBytes = agentx_object(pfMIBObjects,
3816	    AGENTX_OID(PFIFOUT6PASSBYTES), &pfIfIdx, 1, 0,
3817	    mib_pfiftable)) == NULL ||
3818	    (pfIfOut6BlockPkts = agentx_object(pfMIBObjects,
3819	    AGENTX_OID(PFIFOUT6BLOCKPKTS), &pfIfIdx, 1, 0,
3820	    mib_pfiftable)) == NULL ||
3821	    (pfIfOut6BlockBytes = agentx_object(pfMIBObjects,
3822	    AGENTX_OID(PFIFOUT6BLOCKBYTES), &pfIfIdx, 1, 0,
3823	    mib_pfiftable)) == NULL)
3824		fatal("agentx_object");
3825
3826	if ((pfTblNumber = agentx_object(pfMIBObjects, AGENTX_OID(PFTBLNUMBER),
3827	    NULL, 0, 0, mib_pftablenum)) == NULL)
3828		fatal("agentx_object");
3829	if ((pfTblIdx = agentx_index_integer_dynamic(pfMIBObjects,
3830	    AGENTX_OID(PFTBLINDEX))) == NULL)
3831		fatal("agentx_index_integer_dynamic");
3832	if ((pfTblIndex = agentx_object(pfMIBObjects, AGENTX_OID(PFTBLINDEX),
3833	    &pfTblIdx, 1, 0, mib_pftables)) == NULL ||
3834	    (pfTblName = agentx_object(pfMIBObjects, AGENTX_OID(PFTBLNAME),
3835	    &pfTblIdx, 1, 0, mib_pftables)) == NULL ||
3836	    (pfTblAddresses = agentx_object(pfMIBObjects,
3837	    AGENTX_OID(PFTBLADDRESSES), &pfTblIdx, 1, 0,
3838	    mib_pftables)) == NULL ||
3839	    (pfTblAnchorRefs = agentx_object(pfMIBObjects,
3840	    AGENTX_OID(PFTBLANCHORREFS), &pfTblIdx, 1, 0,
3841	    mib_pftables)) == NULL ||
3842	    (pfTblRuleRefs = agentx_object(pfMIBObjects,
3843	    AGENTX_OID(PFTBLRULEREFS), &pfTblIdx, 1, 0,
3844	    mib_pftables)) == NULL ||
3845	    (pfTblEvalsMatch = agentx_object(pfMIBObjects,
3846	    AGENTX_OID(PFTBLEVALSMATCH), &pfTblIdx, 1, 0,
3847	    mib_pftables)) == NULL ||
3848	    (pfTblEvalsNoMatch = agentx_object(pfMIBObjects,
3849	    AGENTX_OID(PFTBLEVALSNOMATCH), &pfTblIdx, 1, 0,
3850	    mib_pftables)) == NULL ||
3851	    (pfTblInPassPkts = agentx_object(pfMIBObjects,
3852	    AGENTX_OID(PFTBLINPASSPKTS), &pfTblIdx, 1, 0,
3853	    mib_pftables)) == NULL ||
3854	    (pfTblInPassBytes = agentx_object(pfMIBObjects,
3855	    AGENTX_OID(PFTBLINPASSBYTES), &pfTblIdx, 1, 0,
3856	    mib_pftables)) == NULL ||
3857	    (pfTblInBlockPkts = agentx_object(pfMIBObjects,
3858	    AGENTX_OID(PFTBLINBLOCKPKTS), &pfTblIdx, 1, 0,
3859	    mib_pftables)) == NULL ||
3860	    (pfTblInBlockBytes = agentx_object(pfMIBObjects,
3861	    AGENTX_OID(PFTBLINBLOCKBYTES), &pfTblIdx, 1, 0,
3862	    mib_pftables)) == NULL ||
3863	    (pfTblInXPassPkts = agentx_object(pfMIBObjects,
3864	    AGENTX_OID(PFTBLINXPASSPKTS), &pfTblIdx, 1, 0,
3865	    mib_pftables)) == NULL ||
3866	    (pfTblInXPassBytes = agentx_object(pfMIBObjects,
3867	    AGENTX_OID(PFTBLINXPASSBYTES), &pfTblIdx, 1, 0,
3868	    mib_pftables)) == NULL ||
3869	    (pfTblOutPassPkts = agentx_object(pfMIBObjects,
3870	    AGENTX_OID(PFTBLOUTPASSPKTS), &pfTblIdx, 1, 0,
3871	    mib_pftables)) == NULL ||
3872	    (pfTblOutPassBytes = agentx_object(pfMIBObjects,
3873	    AGENTX_OID(PFTBLOUTPASSBYTES), &pfTblIdx, 1, 0,
3874	    mib_pftables)) == NULL ||
3875	    (pfTblOutBlockPkts = agentx_object(pfMIBObjects,
3876	    AGENTX_OID(PFTBLOUTBLOCKPKTS), &pfTblIdx, 1, 0,
3877	    mib_pftables)) == NULL ||
3878	    (pfTblOutBlockBytes = agentx_object(pfMIBObjects,
3879	    AGENTX_OID(PFTBLOUTBLOCKBYTES), &pfTblIdx, 1, 0,
3880	    mib_pftables)) == NULL ||
3881	    (pfTblOutXPassPkts = agentx_object(pfMIBObjects,
3882	    AGENTX_OID(PFTBLOUTXPASSPKTS), &pfTblIdx, 1, 0,
3883	    mib_pftables)) == NULL ||
3884	    (pfTblOutXPassBytes = agentx_object(pfMIBObjects,
3885	    AGENTX_OID(PFTBLOUTXPASSBYTES), &pfTblIdx, 1, 0,
3886	    mib_pftables)) == NULL ||
3887	    (pfTblStatsCleared = agentx_object(pfMIBObjects,
3888	    AGENTX_OID(PFTBLSTATSCLEARED), &pfTblIdx, 1, 0,
3889	    mib_pftables)) == NULL ||
3890	    (pfTblInMatchPkts = agentx_object(pfMIBObjects,
3891	    AGENTX_OID(PFTBLINMATCHPKTS), &pfTblIdx, 1, 0,
3892	    mib_pftables)) == NULL ||
3893	    (pfTblInMatchBytes = agentx_object(pfMIBObjects,
3894	    AGENTX_OID(PFTBLINMATCHBYTES), &pfTblIdx, 1, 0,
3895	    mib_pftables)) == NULL ||
3896	    (pfTblOutMatchPkts = agentx_object(pfMIBObjects,
3897	    AGENTX_OID(PFTBLOUTMATCHPKTS), &pfTblIdx, 1, 0,
3898	    mib_pftables)) == NULL ||
3899	    (pfTblOutMatchBytes = agentx_object(pfMIBObjects,
3900	    AGENTX_OID(PFTBLOUTMATCHBYTES), &pfTblIdx, 1, 0,
3901	    mib_pftables)) == NULL)
3902		fatal("agentx_object");
3903
3904	if ((pfTblAddrTblIdx = agentx_index_integer_dynamic(pfMIBObjects,
3905	    AGENTX_OID(PFTBLADDRTBLINDEX))) == NULL ||
3906	    (pfTblAddrNetIdx = agentx_index_ipaddress_dynamic(pfMIBObjects,
3907	    AGENTX_OID(PFTBLADDRNET))) == NULL ||
3908	    (pfTblAddrMaskIdx = agentx_index_integer_dynamic(pfMIBObjects,
3909	    AGENTX_OID(PFTBLADDRMASK))) == NULL)
3910		fatal("agentx_index_integer_dynamic");
3911	indices[0] = pfTblAddrTblIdx;
3912	indices[1] = pfTblAddrNetIdx;
3913	indices[2] = pfTblAddrMaskIdx;
3914	if ((pfTblAddrTblIndex = agentx_object(pfMIBObjects,
3915	    AGENTX_OID(PFTBLADDRTBLINDEX), indices, 3, 0,
3916	    mib_pftableaddrs)) == NULL ||
3917	    (pfTblAddrNet = agentx_object(pfMIBObjects,
3918	    AGENTX_OID(PFTBLADDRNET), indices, 3, 0,
3919	    mib_pftableaddrs)) == NULL ||
3920	    (pfTblAddrMask = agentx_object(pfMIBObjects,
3921	    AGENTX_OID(PFTBLADDRMASK), indices, 3, 0,
3922	    mib_pftableaddrs)) == NULL ||
3923	    (pfTblAddrCleared = agentx_object(pfMIBObjects,
3924	    AGENTX_OID(PFTBLADDRCLEARED), indices, 3, 0,
3925	    mib_pftableaddrs)) == NULL ||
3926	    (pfTblAddrInBlockPkts = agentx_object(pfMIBObjects,
3927	    AGENTX_OID(PFTBLADDRINBLOCKPKTS), indices, 3, 0,
3928	    mib_pftableaddrs)) == NULL ||
3929	    (pfTblAddrInBlockBytes = agentx_object(pfMIBObjects,
3930	    AGENTX_OID(PFTBLADDRINBLOCKBYTES), indices, 3, 0,
3931	    mib_pftableaddrs)) == NULL ||
3932	    (pfTblAddrInPassPkts = agentx_object(pfMIBObjects,
3933	    AGENTX_OID(PFTBLADDRINPASSPKTS), indices, 3, 0,
3934	    mib_pftableaddrs)) == NULL ||
3935	    (pfTblAddrInPassBytes = agentx_object(pfMIBObjects,
3936	    AGENTX_OID(PFTBLADDRINPASSBYTES), indices, 3, 0,
3937	    mib_pftableaddrs)) == NULL ||
3938	    (pfTblAddrOutBlockPkts = agentx_object(pfMIBObjects,
3939	    AGENTX_OID(PFTBLADDROUTBLOCKPKTS), indices, 3, 0,
3940	    mib_pftableaddrs)) == NULL ||
3941	    (pfTblAddrOutBlockBytes = agentx_object(pfMIBObjects,
3942	    AGENTX_OID(PFTBLADDROUTBLOCKBYTES), indices, 3, 0,
3943	    mib_pftableaddrs)) == NULL ||
3944	    (pfTblAddrOutPassPkts = agentx_object(pfMIBObjects,
3945	    AGENTX_OID(PFTBLADDROUTPASSPKTS), indices, 3, 0,
3946	    mib_pftableaddrs)) == NULL ||
3947	    (pfTblAddrOutPassBytes = agentx_object(pfMIBObjects,
3948	    AGENTX_OID(PFTBLADDROUTPASSBYTES), indices, 3, 0,
3949	    mib_pftableaddrs)) == NULL ||
3950	    (pfTblAddrInMatchPkts = agentx_object(pfMIBObjects,
3951	    AGENTX_OID(PFTBLADDRINMATCHPKTS), indices, 3, 0,
3952	    mib_pftableaddrs)) == NULL ||
3953	    (pfTblAddrInMatchBytes = agentx_object(pfMIBObjects,
3954	    AGENTX_OID(PFTBLADDRINMATCHBYTES), indices, 3, 0,
3955	    mib_pftableaddrs)) == NULL ||
3956	    (pfTblAddrOutMatchPkts = agentx_object(pfMIBObjects,
3957	    AGENTX_OID(PFTBLADDROUTMATCHPKTS), indices, 3, 0,
3958	    mib_pftableaddrs)) == NULL ||
3959	    (pfTblAddrOutMatchBytes = agentx_object(pfMIBObjects,
3960	    AGENTX_OID(PFTBLADDROUTMATCHBYTES), indices, 3, 0,
3961	    mib_pftableaddrs)) == NULL)
3962		fatal("agentx_object");
3963
3964	if ((pfLabelNumber = agentx_object(pfMIBObjects,
3965	    AGENTX_OID(PFLABELNUMBER), NULL, 0, 0, mib_pflabelnum)) == NULL)
3966		fatal("agentx_object");
3967	if ((pfLabelIdx = agentx_index_integer_dynamic(pfMIBObjects,
3968	    AGENTX_OID(PFLABELINDEX))) == NULL)
3969		fatal("agentx_index_integer_dynamic");
3970	if ((pfLabelIndex = agentx_object(pfMIBObjects,
3971	    AGENTX_OID(PFLABELINDEX), &pfLabelIdx, 1, 0,
3972	    mib_pflabels)) == NULL ||
3973	    (pfLabelName = agentx_object(pfMIBObjects, AGENTX_OID(PFLABELNAME),
3974	    &pfLabelIdx, 1, 0, mib_pflabels)) == NULL ||
3975	    (pfLabelEvals = agentx_object(pfMIBObjects,
3976	    AGENTX_OID(PFLABELEVALS), &pfLabelIdx, 1, 0,
3977	    mib_pflabels)) == NULL ||
3978	    (pfLabelPkts = agentx_object(pfMIBObjects, AGENTX_OID(PFLABELPKTS),
3979	    &pfLabelIdx, 1, 0, mib_pflabels)) == NULL ||
3980	    (pfLabelBytes = agentx_object(pfMIBObjects,
3981	    AGENTX_OID(PFLABELBYTES), &pfLabelIdx, 1, 0,
3982	    mib_pflabels)) == NULL ||
3983	    (pfLabelInPkts = agentx_object(pfMIBObjects,
3984	    AGENTX_OID(PFLABELINPKTS), &pfLabelIdx, 1, 0,
3985	    mib_pflabels)) == NULL ||
3986	    (pfLabelInBytes = agentx_object(pfMIBObjects,
3987	    AGENTX_OID(PFLABELINBYTES), &pfLabelIdx, 1, 0,
3988	    mib_pflabels)) == NULL ||
3989	    (pfLabelOutPkts = agentx_object(pfMIBObjects,
3990	    AGENTX_OID(PFLABELOUTPKTS), &pfLabelIdx, 1, 0,
3991	    mib_pflabels)) == NULL ||
3992	    (pfLabelOutBytes = agentx_object(pfMIBObjects,
3993	    AGENTX_OID(PFLABELOUTBYTES), &pfLabelIdx, 1, 0,
3994	    mib_pflabels)) == NULL ||
3995	    (pfLabelTotalStates = agentx_object(pfMIBObjects,
3996	    AGENTX_OID(PFLABELTOTALSTATES), &pfLabelIdx, 1, 0,
3997	    mib_pflabels)) == NULL)
3998		fatal("agentx_object");
3999
4000	if ((pfsyncIpPktsRecv = agentx_object(pfMIBObjects,
4001	    AGENTX_OID(PFSYNCIPPKTSRECV), NULL, 0, 0,
4002	    mib_pfsyncstats)) == NULL ||
4003	    (pfsyncIp6PktsRecv = agentx_object(pfMIBObjects,
4004	    AGENTX_OID(PFSYNCIP6PKTSRECV), NULL, 0, 0,
4005	    mib_pfsyncstats)) == NULL ||
4006	    (pfsyncPktDiscardsForBadInterface = agentx_object(pfMIBObjects,
4007	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADINTERFACE), NULL, 0, 0,
4008	    mib_pfsyncstats)) == NULL ||
4009	    (pfsyncPktDiscardsForBadTtl = agentx_object(pfMIBObjects,
4010	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADTTL), NULL, 0, 0,
4011	    mib_pfsyncstats)) == NULL ||
4012	    (pfsyncPktShorterThanHeader = agentx_object(pfMIBObjects,
4013	    AGENTX_OID(PFSYNCPKTSHORTERTHANHEADER), NULL, 0, 0,
4014	    mib_pfsyncstats)) == NULL ||
4015	    (pfsyncPktDiscardsForBadVersion = agentx_object(pfMIBObjects,
4016	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADVERSION), NULL, 0, 0,
4017	    mib_pfsyncstats)) == NULL ||
4018	    (pfsyncPktDiscardsForBadAction = agentx_object(pfMIBObjects,
4019	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADACTION), NULL, 0, 0,
4020	    mib_pfsyncstats)) == NULL ||
4021	    (pfsyncPktDiscardsForBadLength = agentx_object(pfMIBObjects,
4022	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADLENGTH), NULL, 0, 0,
4023	    mib_pfsyncstats)) == NULL ||
4024	    (pfsyncPktDiscardsForBadAuth = agentx_object(pfMIBObjects,
4025	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADAUTH), NULL, 0, 0,
4026	    mib_pfsyncstats)) == NULL ||
4027	    (pfsyncPktDiscardsForStaleState = agentx_object(pfMIBObjects,
4028	    AGENTX_OID(PFSYNCPKTDISCARDSFORSTALESTATE), NULL, 0, 0,
4029	    mib_pfsyncstats)) == NULL ||
4030	    (pfsyncPktDiscardsForBadValues = agentx_object(pfMIBObjects,
4031	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADVALUES), NULL, 0, 0,
4032	    mib_pfsyncstats)) == NULL ||
4033	    (pfsyncPktDiscardsForBadState = agentx_object(pfMIBObjects,
4034	    AGENTX_OID(PFSYNCPKTDISCARDSFORBADSTATE), NULL, 0, 0,
4035	    mib_pfsyncstats)) == NULL ||
4036	    (pfsyncIpPktsSent = agentx_object(pfMIBObjects,
4037	    AGENTX_OID(PFSYNCIPPKTSSENT), NULL, 0, 0,
4038	    mib_pfsyncstats)) == NULL ||
4039	    (pfsyncIp6PktsSent = agentx_object(pfMIBObjects,
4040	    AGENTX_OID(PFSYNCIP6PKTSSENT), NULL, 0, 0,
4041	    mib_pfsyncstats)) == NULL ||
4042	    (pfsyncNoMemory = agentx_object(pfMIBObjects,
4043	    AGENTX_OID(PFSYNCNOMEMORY), NULL, 0, 0,
4044	    mib_pfsyncstats)) == NULL ||
4045	    (pfsyncOutputErrors = agentx_object(pfMIBObjects,
4046	    AGENTX_OID(PFSYNCOUTPUTERRORS), NULL, 0, 0,
4047	    mib_pfsyncstats)) == NULL)
4048		fatal("agentx_object");
4049
4050	if ((sensorsMIBObjects = agentx_region(sac,
4051	    AGENTX_OID(SENSORSMIBOBJECTS), 0)) == NULL)
4052		fatal("agentx_region");
4053	if ((sensorNumber = agentx_object(sensorsMIBObjects,
4054	    AGENTX_OID(SENSORNUMBER), NULL, 0, 0, mib_sensornum)) == NULL)
4055		fatal("agentx_object");
4056	if ((sensorIdx = agentx_index_integer_dynamic(sensorsMIBObjects,
4057	    AGENTX_OID(SENSORINDEX))) == NULL)
4058		fatal("agentx_index_integer_dynamic");
4059	if ((sensorIndex = agentx_object(sensorsMIBObjects,
4060	    AGENTX_OID(SENSORINDEX), &sensorIdx, 1, 0, mib_sensors)) == NULL ||
4061	    (sensorDescr = agentx_object(sensorsMIBObjects,
4062	    AGENTX_OID(SENSORDESCR), &sensorIdx, 1, 0, mib_sensors)) == NULL ||
4063	    (sensorType = agentx_object(sensorsMIBObjects,
4064	    AGENTX_OID(SENSORTYPE), &sensorIdx, 1, 0, mib_sensors)) == NULL ||
4065	    (sensorDevice = agentx_object(sensorsMIBObjects,
4066	    AGENTX_OID(SENSORDEVICE), &sensorIdx, 1, 0, mib_sensors)) == NULL ||
4067	    (sensorValue = agentx_object(sensorsMIBObjects,
4068	    AGENTX_OID(SENSORVALUE), &sensorIdx, 1, 0, mib_sensors)) == NULL ||
4069	    (sensorUnits = agentx_object(sensorsMIBObjects,
4070	    AGENTX_OID(SENSORUNITS), &sensorIdx, 1, 0, mib_sensors)) == NULL ||
4071	    (sensorStatus = agentx_object(sensorsMIBObjects,
4072	    AGENTX_OID(SENSORSTATUS), &sensorIdx, 1, 0, mib_sensors)) == NULL)
4073		fatal("agentx_object");
4074
4075	if ((carpMIBObjects = agentx_region(sac,
4076	    AGENTX_OID(CARPMIBOBJECTS), 0)) == NULL)
4077		fatal("agentx_region");
4078	if ((carpAllow = agentx_object(carpMIBObjects, AGENTX_OID(CARPALLOW),
4079	    NULL, 0, 0, mib_carpsysctl)) == NULL ||
4080	    (carpPreempt = agentx_object(carpMIBObjects,
4081	    AGENTX_OID(CARPPREEMPT), NULL, 0, 0, mib_carpsysctl)) == NULL ||
4082	    (carpLog = agentx_object(carpMIBObjects, AGENTX_OID(CARPLOG),
4083	    NULL, 0, 0, mib_carpsysctl)) == NULL)
4084		fatal("agentx_object");
4085
4086	if ((carpIfNumber = agentx_object(carpMIBObjects,
4087	    AGENTX_OID(CARPIFNUMBER), NULL, 0, 0, mib_carpifnum)) == NULL)
4088		fatal("agentx_object");
4089	if ((carpIfIdx = agentx_index_integer_dynamic(carpMIBObjects,
4090	    AGENTX_OID(CARPIFINDEX))) == NULL)
4091		fatal("agentx_index_integer_dynamic");
4092	if ((carpIfIndex = agentx_object(carpMIBObjects,
4093	    AGENTX_OID(CARPIFINDEX), &carpIfIdx, 1, 0,
4094	    mib_carpiftable)) == NULL ||
4095	    (carpIfDescr = agentx_object(carpMIBObjects,
4096	    AGENTX_OID(CARPIFDESCR), &carpIfIdx, 1, 0,
4097	    mib_carpiftable)) == NULL ||
4098	    (carpIfVhid = agentx_object(carpMIBObjects, AGENTX_OID(CARPIFVHID),
4099	    &carpIfIdx, 1, 0, mib_carpiftable)) == NULL ||
4100	    (carpIfDev = agentx_object(carpMIBObjects, AGENTX_OID(CARPIFDEV),
4101	    &carpIfIdx, 1, 0, mib_carpiftable)) == NULL ||
4102	    (carpIfAdvbase = agentx_object(carpMIBObjects,
4103	    AGENTX_OID(CARPIFADVBASE), &carpIfIdx, 1, 0,
4104	    mib_carpiftable)) == NULL ||
4105	    (carpIfAdvskew = agentx_object(carpMIBObjects,
4106	    AGENTX_OID(CARPIFADVSKEW), &carpIfIdx, 1, 0,
4107	    mib_carpiftable)) == NULL ||
4108	    (carpIfState = agentx_object(carpMIBObjects,
4109	    AGENTX_OID(CARPIFSTATE), &carpIfIdx, 1, 0,
4110	    mib_carpiftable)) == NULL)
4111		fatal("agentx_object");
4112
4113	if ((carpGroupIdx = agentx_index_integer_dynamic(carpMIBObjects,
4114	    AGENTX_OID(CARPGROUPINDEX))) == NULL)
4115		fatal("agentx_index_integer_dynamic");
4116	if ((carpGroupName = agentx_object(carpMIBObjects,
4117	    AGENTX_OID(CARPGROUPNAME), &carpGroupIdx, 1, 0,
4118	    mib_carpgrouptable)) == NULL ||
4119	    (carpGroupDemote = agentx_object(carpMIBObjects,
4120	    AGENTX_OID(CARPGROUPDEMOTE), &carpGroupIdx, 1, 0,
4121	    mib_carpgrouptable)) == NULL)
4122		fatal("agentx_object");
4123
4124	if ((carpIpPktsRecv = agentx_object(carpMIBObjects,
4125	    AGENTX_OID(CARPIPPKTSRECV), NULL, 0, 0, mib_carpstats)) == NULL ||
4126	    (carpIp6PktsRecv = agentx_object(carpMIBObjects,
4127	    AGENTX_OID(CARPIP6PKTSRECV), NULL, 0, 0, mib_carpstats)) == NULL ||
4128	    (carpPktDiscardsForBadInterface = agentx_object(carpMIBObjects,
4129	    AGENTX_OID(CARPPKTDISCARDSFORBADINTERFACE), NULL, 0, 0,
4130	    mib_carpstats)) == NULL ||
4131	    (carpPktDiscardsForWrongTtl = agentx_object(carpMIBObjects,
4132	    AGENTX_OID(CARPPKTDISCARDSFORWRONGTTL), NULL, 0, 0,
4133	    mib_carpstats)) == NULL ||
4134	    (carpPktShorterThanHeader = agentx_object(carpMIBObjects,
4135	    AGENTX_OID(CARPPKTSHORTERTHANHEADER), NULL, 0, 0,
4136	    mib_carpstats)) == NULL ||
4137	    (carpPktDiscardsForBadChecksum = agentx_object(carpMIBObjects,
4138	    AGENTX_OID(CARPPKTDISCARDSFORBADCHECKSUM), NULL, 0, 0,
4139	    mib_carpstats)) == NULL ||
4140	    (carpPktDiscardsForBadVersion = agentx_object(carpMIBObjects,
4141	    AGENTX_OID(CARPPKTDISCARDSFORBADVERSION), NULL, 0, 0,
4142	    mib_carpstats)) == NULL ||
4143	    (carpPktDiscardsForTooShort = agentx_object(carpMIBObjects,
4144	    AGENTX_OID(CARPPKTDISCARDSFORTOOSHORT), NULL, 0, 0,
4145	    mib_carpstats)) == NULL ||
4146	    (carpPktDiscardsForBadAuth = agentx_object(carpMIBObjects,
4147	    AGENTX_OID(CARPPKTDISCARDSFORBADAUTH), NULL, 0, 0,
4148	    mib_carpstats)) == NULL ||
4149	    (carpPktDiscardsForBadVhid = agentx_object(carpMIBObjects,
4150	    AGENTX_OID(CARPPKTDISCARDSFORBADVHID), NULL, 0, 0,
4151	    mib_carpstats)) == NULL ||
4152	    (carpPktDiscardsForBadAddressList = agentx_object(carpMIBObjects,
4153	    AGENTX_OID(CARPPKTDISCARDSFORBADADDRESSLIST), NULL, 0, 0,
4154	    mib_carpstats)) == NULL ||
4155	    (carpIpPktsSent = agentx_object(carpMIBObjects,
4156	    AGENTX_OID(CARPIPPKTSSENT), NULL, 0, 0,
4157	    mib_carpstats)) == NULL ||
4158	    (carpIp6PktsSent = agentx_object(carpMIBObjects,
4159	    AGENTX_OID(CARPIP6PKTSSENT), NULL, 0, 0,
4160	    mib_carpstats)) == NULL ||
4161	    (carpNoMemory = agentx_object(carpMIBObjects,
4162	    AGENTX_OID(CARPNOMEMORY), NULL, 0, 0,
4163	    mib_carpstats)) == NULL ||
4164	    (carpTransitionsToMaster = agentx_object(carpMIBObjects,
4165	    AGENTX_OID(CARPTRANSITIONSTOMASTER), NULL, 0, 0,
4166	    mib_carpstats)) == NULL)
4167		fatal("agentx_object");
4168
4169	/* OPENBSD-MEM-MIB */
4170	if ((memMIBObjects = agentx_region(sac,
4171	    AGENTX_OID(MEMMIBOBJECTS), 0)) == NULL)
4172		fatal("agentx_region");
4173	if ((memMIBVersion = agentx_object(memMIBObjects,
4174	    AGENTX_OID(MEMMIBVERSION), NULL, 0, 0, mib_memversion)) == NULL)
4175		fatal("agentx_object");
4176	if ((memIfName = agentx_object(memMIBObjects, AGENTX_OID(MEMIFNAME),
4177	    &ifIdx, 1, 0, mib_memiftable)) == NULL ||
4178	    (memIfLiveLocks = agentx_object(memMIBObjects,
4179	    AGENTX_OID(MEMIFLIVELOCKS), &ifIdx, 1, 0,
4180	    mib_memiftable)) == NULL)
4181		fatal("agentx_object");
4182
4183	/* IP-MIB */
4184	if ((ip = agentx_region(sac, AGENTX_OID(IP), 0)) == NULL)
4185		fatal("agentx_region");
4186	if ((ipForwarding = agentx_object(ip, AGENTX_OID(IPFORWARDING),
4187	    NULL, 0, 0, mib_ipforwarding)) == NULL ||
4188	    (ipDefaultTTL = agentx_object(ip, AGENTX_OID(IPDEFAULTTTL),
4189	    NULL, 0, 0, mib_ipdefaultttl)) == NULL ||
4190	    (ipInReceives = agentx_object(ip, AGENTX_OID(IPINRECEIVES),
4191	    NULL, 0, 0, mib_ipstat)) == NULL ||
4192	    (ipInHdrErrors = agentx_object(ip, AGENTX_OID(IPINHDRERRORS),
4193	    NULL, 0, 0, mib_ipinhdrerrs)) == NULL ||
4194	    (ipInAddrErrors = agentx_object(ip, AGENTX_OID(IPINADDRERRORS),
4195	    NULL, 0, 0, mib_ipinaddrerrs)) == NULL ||
4196	    (ipForwDatagrams = agentx_object(ip, AGENTX_OID(IPFORWDATAGRAMS),
4197	    NULL, 0, 0, mib_ipforwdgrams)) == NULL ||
4198	    (ipInUnknownProtos = agentx_object(ip,
4199	    AGENTX_OID(IPINUNKNOWNPROTOS), NULL, 0, 0, mib_ipstat)) == NULL ||
4200	    (ipInDelivers = agentx_object(ip, AGENTX_OID(IPINDELIVERS),
4201	    NULL, 0, 0, mib_ipstat)) == NULL ||
4202	    (ipOutRequests = agentx_object(ip, AGENTX_OID(IPOUTREQUESTS),
4203	    NULL, 0, 0, mib_ipstat)) == NULL ||
4204	    (ipOutDiscards = agentx_object(ip, AGENTX_OID(IPOUTDISCARDS),
4205	    NULL, 0, 0, mib_ipstat)) == NULL ||
4206	    (ipOutNoRoutes = agentx_object(ip, AGENTX_OID(IPOUTNOROUTES),
4207	    NULL, 0, 0, mib_ipstat)) == NULL ||
4208	    (ipReasmTimeout = agentx_object(ip, AGENTX_OID(IPREASMTIMEOUT),
4209	    NULL, 0, 0, mib_ipreasmtimeout)) == NULL ||
4210	    (ipReasmReqds = agentx_object(ip, AGENTX_OID(IPREASMREQDS),
4211	    NULL, 0, 0, mib_ipstat)) == NULL ||
4212	    (ipReasmOKs = agentx_object(ip, AGENTX_OID(IPREASMOKS),
4213	    NULL, 0, 0, mib_ipstat)) == NULL ||
4214	    (ipReasmFails = agentx_object(ip, AGENTX_OID(IPREASMFAILS),
4215	    NULL, 0, 0, mib_ipreasmfails)) == NULL ||
4216	    (ipFragOKs = agentx_object(ip, AGENTX_OID(IPFRAGOKS),
4217	    NULL, 0, 0, mib_ipstat)) == NULL ||
4218	    (ipFragFails = agentx_object(ip, AGENTX_OID(IPFRAGFAILS),
4219	    NULL, 0, 0, mib_ipfragfails)) == NULL ||
4220	    (ipFragCreates = agentx_object(ip, AGENTX_OID(IPFRAGCREATES),
4221	    NULL, 0, 0, mib_ipstat)) == NULL)
4222		fatal("agentx_object");
4223
4224	if ((ipAdEntAddrIdx = agentx_index_ipaddress_dynamic(ip,
4225	    AGENTX_OID(IPADENTADDR))) == NULL)
4226		fatal("agentx_index_integer_dynamic");
4227	if ((ipAdEntAddr = agentx_object(ip, AGENTX_OID(IPADENTADDR),
4228	    &ipAdEntAddrIdx, 1, 0, mib_ipaddr)) == NULL ||
4229	    (ipAdEntIfIndex = agentx_object(ip, AGENTX_OID(IPADENTIFINDEX),
4230	    &ipAdEntAddrIdx, 1, 0, mib_ipaddr)) == NULL ||
4231	    (ipAdEntNetMask = agentx_object(ip, AGENTX_OID(IPADENTNETMASK),
4232	    &ipAdEntAddrIdx, 1, 0, mib_ipaddr)) == NULL ||
4233	    (ipAdEntBcastAddr = agentx_object(ip, AGENTX_OID(IPADENTBCASTADDR),
4234	    &ipAdEntAddrIdx, 1, 0, mib_ipaddr)) == NULL ||
4235	    (ipAdEntReasmMaxSize = agentx_object(ip,
4236	    AGENTX_OID(IPADENTREASMMAXSIZE), &ipAdEntAddrIdx, 1, 0,
4237	    mib_ipaddr)) == NULL)
4238		fatal("agentx_object");
4239
4240	if ((ipNetToMediaIfIdx = agentx_index_integer_dynamic(ip,
4241	    AGENTX_OID(IPNETTOMEDIAIFINDEX))) == NULL)
4242		fatal("agentx_index_integer_dynamic");
4243	if ((ipNetToMediaNetAddressIdx = agentx_index_ipaddress_dynamic(ip,
4244	    AGENTX_OID(IPNETTOMEDIANETADDRESS))) == NULL)
4245		fatal("agentx_index_string_dynamic");
4246	indices[0] = ipNetToMediaIfIdx;
4247	indices[1] = ipNetToMediaNetAddressIdx;
4248	if ((ipNetToMediaIfIndex = agentx_object(ip,
4249	    AGENTX_OID(IPNETTOMEDIAIFINDEX), indices, 2, 0,
4250	    mib_physaddr)) == NULL ||
4251	    (ipNetToMediaPhysAddress = agentx_object(ip,
4252	    AGENTX_OID(IPNETTOMEDIAPHYSADDRESS), indices, 2, 0,
4253	    mib_physaddr)) == NULL ||
4254	    (ipNetToMediaNetAddress = agentx_object(ip,
4255	    AGENTX_OID(IPNETTOMEDIANETADDRESS), indices, 2, 0,
4256	    mib_physaddr)) == NULL ||
4257	    (ipNetToMediaType = agentx_object(ip, AGENTX_OID(IPNETTOMEDIATYPE),
4258	    indices, 2, 0, mib_physaddr)) == NULL)
4259		fatal("agentx_object");
4260
4261	if ((ipForward = agentx_region(sac, AGENTX_OID(IPFORWARD), 0)) == NULL)
4262		fatal("agentx_region");
4263	if ((inetCidrRouteNumber = agentx_object(ipForward,
4264	    AGENTX_OID(INETCIDRROUTENUMBER), NULL, 0, 0,
4265	    mib_ipfnroutes)) == NULL)
4266		fatal("agentx_object");
4267	if ((inetCidrRouteDestTypeIdx = agentx_index_integer_dynamic(ipForward,
4268	    AGENTX_OID(INETCIDRROUTEDESTTYPE))) == NULL ||
4269	    (inetCidrRouteDestIdx = agentx_index_string_dynamic(ipForward,
4270	    AGENTX_OID(INETCIDRROUTEDEST))) == NULL ||
4271	    (inetCidrRoutePfxLenIdx = agentx_index_integer_dynamic(ipForward,
4272	    AGENTX_OID(INETCIDRROUTEPFXLEN))) == NULL ||
4273	    (inetCidrRoutePolicyIdx = agentx_index_oid_dynamic(ipForward,
4274	    AGENTX_OID(INETCIDRROUTEPOLICY))) == NULL ||
4275	    (inetCidrRouteNextHopTypeIdx = agentx_index_integer_dynamic(
4276	    ipForward, AGENTX_OID(INETCIDRROUTENEXTHOPTYPE))) == NULL ||
4277	    (inetCidrRouteNextHopIdx = agentx_index_string_dynamic(ipForward,
4278	    AGENTX_OID(INETCIDRROUTENEXTHOP))) == NULL)
4279		fatal("agentx_index_*_dynamic");
4280	indices[0] = inetCidrRouteDestTypeIdx;
4281	indices[1] = inetCidrRouteDestIdx;
4282	indices[2] = inetCidrRoutePfxLenIdx;
4283	indices[3] = inetCidrRoutePolicyIdx;
4284	indices[4] = inetCidrRouteNextHopTypeIdx;
4285	indices[5] = inetCidrRouteNextHopIdx;
4286	if ((inetCidrRouteIfIndex = agentx_object(ipForward,
4287	    AGENTX_OID(INETCIDRROUTEIFINDEX), indices, 6, 0,
4288	    mib_ipfroute)) == NULL ||
4289	    (inetCidrRouteType = agentx_object(ipForward,
4290	    AGENTX_OID(INETCIDRROUTETYPE), indices, 6, 0,
4291	    mib_ipfroute)) == NULL ||
4292	    (inetCidrRouteProto = agentx_object(ipForward,
4293	    AGENTX_OID(INETCIDRROUTEPROTO), indices, 6, 0,
4294	    mib_ipfroute)) == NULL ||
4295	    (inetCidrRouteAge = agentx_object(ipForward,
4296	    AGENTX_OID(INETCIDRROUTEAGE), indices, 6, 0,
4297	    mib_ipfroute)) == NULL ||
4298	    (inetCidrRouteNextHopAS = agentx_object(ipForward,
4299	    AGENTX_OID(INETCIDRROUTENEXTHOPAS), indices, 6, 0,
4300	    mib_ipfroute)) == NULL ||
4301	    (inetCidrRouteMetric1 = agentx_object(ipForward,
4302	    AGENTX_OID(INETCIDRROUTEMETRIC1), indices, 6, 0,
4303	    mib_ipfroute)) == NULL ||
4304	    (inetCidrRouteMetric2 = agentx_object(ipForward,
4305	    AGENTX_OID(INETCIDRROUTEMETRIC2), indices, 6, 0,
4306	    mib_ipfroute)) == NULL ||
4307	    (inetCidrRouteMetric3 = agentx_object(ipForward,
4308	    AGENTX_OID(INETCIDRROUTEMETRIC3), indices, 6, 0,
4309	    mib_ipfroute)) == NULL ||
4310	    (inetCidrRouteMetric4 = agentx_object(ipForward,
4311	    AGENTX_OID(INETCIDRROUTEMETRIC4), indices, 6, 0,
4312	    mib_ipfroute)) == NULL ||
4313	    (inetCidrRouteMetric5 = agentx_object(ipForward,
4314	    AGENTX_OID(INETCIDRROUTEMETRIC5), indices, 6, 0,
4315	    mib_ipfroute)) == NULL ||
4316	    (inetCidrRouteStatus = agentx_object(ipForward,
4317	    AGENTX_OID(INETCIDRROUTESTATUS), indices, 6, 0,
4318	    mib_ipfroute)) == NULL)
4319		fatal("agentx_object");
4320
4321	/* UCD-DISKIO-MIB */
4322	if ((ucdDiskIOMIB = agentx_region(sac, AGENTX_OID(UCDDISKIOMIB),
4323	    0)) == NULL)
4324		fatal("agentx_region");
4325	if ((diskIOIdx = agentx_index_integer_dynamic(ucdDiskIOMIB,
4326	    AGENTX_OID(DISKIOINDEX))) == NULL)
4327		fatal("agentx_index_integer_dynamic");
4328	if ((diskIOIndex = agentx_object(ucdDiskIOMIB, AGENTX_OID(DISKIOINDEX),
4329	    &diskIOIdx, 1, 0, mib_diskio)) == NULL ||
4330	    (diskIODevice = agentx_object(ucdDiskIOMIB,
4331	    AGENTX_OID(DISKIODEVICE), &diskIOIdx, 1, 0, mib_diskio)) == NULL ||
4332	    (diskIONRead = agentx_object(ucdDiskIOMIB, AGENTX_OID(DISKIONREAD),
4333	    &diskIOIdx, 1, 0, mib_diskio)) == NULL ||
4334	    (diskIONWritten = agentx_object(ucdDiskIOMIB,
4335	    AGENTX_OID(DISKIONWRITTEN), &diskIOIdx, 1, 0,
4336	    mib_diskio)) == NULL ||
4337	    (diskIOReads = agentx_object(ucdDiskIOMIB,
4338	    AGENTX_OID(DISKIOREADS), &diskIOIdx, 1, 0, mib_diskio)) == NULL ||
4339	    (diskIOWrites = agentx_object(ucdDiskIOMIB,
4340	    AGENTX_OID(DISKIOWRITES), &diskIOIdx, 1, 0, mib_diskio)) == NULL ||
4341	    (diskIONReadX = agentx_object(ucdDiskIOMIB,
4342	    AGENTX_OID(DISKIONREADX), &diskIOIdx, 1, 0, mib_diskio)) == NULL ||
4343	    (diskIONWrittenX = agentx_object(ucdDiskIOMIB,
4344	    AGENTX_OID(DISKIONWRITTENX), &diskIOIdx, 1, 0,
4345	    mib_diskio)) == NULL)
4346		fatal("agentx_object");
4347
4348	if ((dot1dBridge = agentx_region(sac, AGENTX_OID(DOT1DBRIDGE),
4349	    0)) == NULL)
4350		fatal("agentx_region");
4351	if ((dot1dBaseNumPorts = agentx_object(dot1dBridge,
4352	    AGENTX_OID(DOT1DBASENUMPORTS), NULL, 0, 0, mib_ifnumber)) == NULL ||
4353	    (dot1dBaseType = agentx_object(dot1dBridge,
4354	    AGENTX_OID(DOT1DBASETYPE), NULL, 0, 0, mib_dot1basetype)) == NULL)
4355		fatal("agentx_object");
4356
4357	if ((dot1dBasePortIdx = agentx_index_integer_dynamic(dot1dBridge,
4358	    AGENTX_OID(DOT1DBASEPORT))) == NULL)
4359		fatal("agentx_index_integer_dynamic");
4360	if ((dot1dBasePort = agentx_object(dot1dBridge,
4361	    AGENTX_OID(DOT1DBASEPORT), &dot1dBasePortIdx, 1, 0,
4362	    mib_dot1dtable)) == NULL ||
4363	    (dot1dBasePortIfIndex = agentx_object(dot1dBridge,
4364	    AGENTX_OID(DOT1DBASEPORTIFINDEX), &dot1dBasePortIdx, 1, 0,
4365	    mib_dot1dtable)) == NULL ||
4366	    (dot1dBasePortCircuit = agentx_object(dot1dBridge,
4367	    AGENTX_OID(DOT1DBASEPORTCIRCUIT), &dot1dBasePortIdx, 1, 0,
4368	    mib_dot1dtable)) == NULL ||
4369	    (dot1dBasePortDelayExceededDiscards = agentx_object(dot1dBridge,
4370	    AGENTX_OID(DOT1DBASEPORTDELAYEXCEEDEDDISCARDS), &dot1dBasePortIdx,
4371	    1, 0, mib_dot1dtable)) == NULL ||
4372	    (dot1dBasePortMtuExceededDiscards = agentx_object(dot1dBridge,
4373	    AGENTX_OID(DOT1DBASEPORTMTUEXCEEDEDDISCARDS), &dot1dBasePortIdx,
4374	    1, 0, mib_dot1dtable)) == NULL)
4375		fatal("agentx_object");
4376
4377	if (daemonize) {
4378		log_init(0, LOG_DAEMON);
4379		daemon(0, 0);
4380	}
4381	log_setverbose(verbose);
4382
4383	event_dispatch();
4384}
4385
4386#define LOG1024		 10
4387void
4388pageshift_init(void)
4389{
4390	long pagesize;
4391
4392	if ((pagesize = sysconf(_SC_PAGESIZE)) == -1)
4393		fatal("sysconf(_SC_PAGESIZE)");
4394	while (pagesize > 1) {
4395		pageshift++;
4396		pagesize >>= 1;
4397	}
4398	/* we only need the amount of log(2)1024 for our conversion */
4399	pageshift -= LOG1024;
4400}
4401
4402void
4403snmp_connect(struct agentx *sa, void *cookie, int close)
4404{
4405	static int init = 0;
4406
4407	if (close) {
4408		event_del(&connev);
4409		return;
4410	}
4411
4412	if (agentxfd != -1) {
4413		/* Exit if snmpd(8) leaves */
4414		if (init)
4415			exit(0);
4416		agentx_connect(sa, agentxfd);
4417		event_set(&connev, agentxfd, EV_READ | EV_PERSIST,
4418		    snmp_read, sa);
4419		event_add(&connev, NULL);
4420		init = 1;
4421	} else
4422		snmp_tryconnect(-1, 0, sa);
4423}
4424
4425void
4426snmp_tryconnect(int fd, short event, void *cookie)
4427{
4428	struct timeval timeout = {3, 0};
4429	struct agentx *sa = cookie;
4430	struct sockaddr_un sun;
4431
4432	sun.sun_len = sizeof(sun);
4433	sun.sun_family = AF_UNIX;
4434	strlcpy(sun.sun_path, AGENTX_MASTER_PATH, sizeof(sun.sun_path));
4435
4436	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ||
4437	    connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
4438		if (fd != -1)
4439			close(fd);
4440		log_warn("Failed to connect to snmpd");
4441		evtimer_set(&connev, snmp_tryconnect, sa);
4442		evtimer_add(&connev, &timeout);
4443		return;
4444	}
4445
4446	event_set(&connev, fd, EV_READ | EV_PERSIST, snmp_read, sa);
4447	event_add(&connev, NULL);
4448
4449	agentx_connect(sa, fd);
4450}
4451
4452void
4453snmp_read(int fd, short event, void *cookie)
4454{
4455	struct agentx *sa = cookie;
4456
4457	agentx_read(sa);
4458}
4459
4460u_long
4461smi_getticks(void)
4462{
4463	return agentx_context_uptime(sac);
4464}
4465