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