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