1122394Sharti/*
2122394Sharti * Copyright (c) 2001-2003
3122394Sharti *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4122394Sharti *	All rights reserved.
5122394Sharti *
6122394Sharti * Author: Harti Brandt <harti@freebsd.org>
7133211Sharti *
8133211Sharti * Redistribution and use in source and binary forms, with or without
9133211Sharti * modification, are permitted provided that the following conditions
10133211Sharti * are met:
11133211Sharti * 1. Redistributions of source code must retain the above copyright
12133211Sharti *    notice, this list of conditions and the following disclaimer.
13122394Sharti * 2. Redistributions in binary form must reproduce the above copyright
14122394Sharti *    notice, this list of conditions and the following disclaimer in the
15122394Sharti *    documentation and/or other materials provided with the distribution.
16133211Sharti *
17133211Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20133211Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21133211Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25133211Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26133211Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27133211Sharti * SUCH DAMAGE.
28122394Sharti *
29156066Sharti * $Begemot: bsnmp/snmp_mibII/mibII_interfaces.c,v 1.17 2006/02/14 09:04:19 brandt_h Exp $
30122394Sharti *
31122394Sharti * Interfaces group.
32122394Sharti */
33122394Sharti#include "mibII.h"
34122394Sharti#include "mibII_oid.h"
35122394Sharti
36122394Sharti/*
37122394Sharti * This structure catches all changes to a interface entry
38122394Sharti */
39122394Shartistruct ifchange {
40122394Sharti	struct snmp_dependency dep;
41122394Sharti
42122394Sharti	u_int		ifindex;
43122394Sharti
44133211Sharti	uint32_t	set;
45122394Sharti	int		promisc;
46122394Sharti	int		admin;
47122394Sharti	int		traps;
48122394Sharti
49133211Sharti	uint32_t	rb;
50122394Sharti	int		rb_flags;
51122394Sharti	int		rb_traps;
52122394Sharti};
53122394Sharti#define IFC_PROMISC	0x0001
54122394Sharti#define IFC_ADMIN	0x0002
55122394Sharti#define IFC_TRAPS	0x0004
56122394Sharti#define IFRB_FLAGS	0x0001
57122394Sharti#define IFRB_TRAPS	0x0002
58122394Sharti
59122394Shartistatic const struct asn_oid
60122394Sharti	oid_ifTable = OIDX_ifTable;
61122394Sharti
62122394Sharti/*
63122394Sharti * This function handles all changes to the interface table and interface
64122394Sharti * extension table.
65122394Sharti */
66122394Shartistatic int
67122394Shartiifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
68122394Sharti    enum snmp_depop op)
69122394Sharti{
70122394Sharti	struct ifchange *ifc = (struct ifchange *)dep;
71122394Sharti	struct mibif *ifp;
72122394Sharti	struct ifreq ifr, ifr1;
73122394Sharti
74122394Sharti	if ((ifp = mib_find_if(ifc->ifindex)) == NULL)
75122394Sharti		return (SNMP_ERR_NO_CREATION);
76122394Sharti
77122394Sharti	switch (op) {
78122394Sharti
79122394Sharti	  case SNMP_DEPOP_COMMIT:
80122394Sharti		strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
81122394Sharti		if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) {
82122394Sharti			syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
83122394Sharti			return (SNMP_ERR_GENERR);
84122394Sharti		}
85122394Sharti		if (ifc->set & IFC_PROMISC) {
86122394Sharti			ifr.ifr_flags &= ~IFF_PROMISC;
87122394Sharti			if (ifc->promisc)
88122394Sharti				ifr.ifr_flags |= IFF_PROMISC;
89122394Sharti			ifc->rb |= IFRB_FLAGS;
90122394Sharti		}
91122394Sharti		if (ifc->set & IFC_ADMIN) {
92122394Sharti			ifr.ifr_flags &= ~IFF_UP;
93122394Sharti			if (ifc->admin)
94122394Sharti				ifr.ifr_flags |= IFF_UP;
95122394Sharti			ifc->rb |= IFRB_FLAGS;
96122394Sharti		}
97122394Sharti		if (ifc->rb & IFRB_FLAGS) {
98122394Sharti			strncpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name));
99122394Sharti			if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr1) == -1) {
100122394Sharti				syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
101122394Sharti				return (SNMP_ERR_GENERR);
102122394Sharti			}
103122394Sharti			ifc->rb_flags = ifr1.ifr_flags;
104122394Sharti			if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
105122394Sharti				syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
106122394Sharti				return (SNMP_ERR_GENERR);
107122394Sharti			}
108122394Sharti			(void)mib_fetch_ifmib(ifp);
109122394Sharti		}
110122394Sharti		if (ifc->set & IFC_TRAPS) {
111122394Sharti			ifc->rb |= IFRB_TRAPS;
112122394Sharti			ifc->rb_traps = ifp->trap_enable;
113122394Sharti			ifp->trap_enable = ifc->traps;
114122394Sharti		}
115122394Sharti		return (SNMP_ERR_NOERROR);
116122394Sharti
117122394Sharti	  case SNMP_DEPOP_ROLLBACK:
118122394Sharti		if (ifc->rb & IFRB_FLAGS) {
119122394Sharti			strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
120122394Sharti			ifr.ifr_flags = ifc->rb_flags;
121122394Sharti			if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
122122394Sharti				syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
123122394Sharti				return (SNMP_ERR_UNDO_FAILED);
124122394Sharti			}
125122394Sharti			(void)mib_fetch_ifmib(ifp);
126122394Sharti		}
127122394Sharti		if (ifc->rb & IFRB_TRAPS)
128122394Sharti			ifp->trap_enable = ifc->rb_traps;
129122394Sharti		return (SNMP_ERR_NOERROR);
130122394Sharti
131128237Sharti	  case SNMP_DEPOP_FINISH:
132128237Sharti		return (SNMP_ERR_NOERROR);
133128237Sharti
134122394Sharti	}
135122394Sharti	abort();
136122394Sharti}
137122394Sharti
138146525Sharti/*
139146525Sharti * Return difference to daemon start time in ticks truncated to a
140146525Sharti * 32-bit value. If the timeval is 0 then return 0.
141146525Sharti */
142133211Shartistatic uint32_t
143122394Shartiticks_get_timeval(struct timeval *tv)
144122394Sharti{
145146525Sharti	uint64_t v;
146122394Sharti
147122394Sharti	if (tv->tv_sec != 0 || tv->tv_usec != 0) {
148146525Sharti		v = 100ULL * tv->tv_sec + tv->tv_usec / 10000ULL;
149122394Sharti		if (v > start_tick)
150122394Sharti			return (v - start_tick);
151122394Sharti	}
152122394Sharti	return (0);
153122394Sharti}
154122394Sharti
155122394Sharti/*
156122394Sharti * Scalars
157122394Sharti */
158122394Shartiint
159122394Shartiop_interfaces(struct snmp_context *ctx __unused, struct snmp_value *value,
160122394Sharti    u_int sub, u_int idx __unused, enum snmp_op op)
161122394Sharti{
162122394Sharti	switch (op) {
163122394Sharti
164122394Sharti	  case SNMP_OP_GETNEXT:
165122394Sharti		abort();
166122394Sharti
167122394Sharti	  case SNMP_OP_GET:
168122394Sharti		break;
169122394Sharti
170122394Sharti	  case SNMP_OP_SET:
171122394Sharti		return (SNMP_ERR_NOT_WRITEABLE);
172122394Sharti
173122394Sharti	  case SNMP_OP_ROLLBACK:
174122394Sharti	  case SNMP_OP_COMMIT:
175122394Sharti		abort();
176122394Sharti	}
177122394Sharti
178122394Sharti	switch (value->var.subs[sub - 1]) {
179122394Sharti
180122394Sharti	  case LEAF_ifNumber:
181122394Sharti		value->v.integer = mib_if_number;
182122394Sharti		break;
183122394Sharti	}
184122394Sharti	return (SNMP_ERR_NOERROR);
185122394Sharti}
186122394Sharti
187122394Sharti/*
188122394Sharti * Iftable entry
189122394Sharti */
190122394Shartiint
191122394Shartiop_ifentry(struct snmp_context *ctx, struct snmp_value *value,
192122394Sharti    u_int sub, u_int iidx __unused, enum snmp_op op)
193122394Sharti{
194122394Sharti	struct mibif *ifp = NULL;
195122394Sharti	int ret;
196122394Sharti	struct ifchange *ifc;
197122394Sharti	struct asn_oid idx;
198122394Sharti
199122394Sharti	switch (op) {
200122394Sharti
201122394Sharti	  case SNMP_OP_GETNEXT:
202122394Sharti		if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
203122394Sharti			return (SNMP_ERR_NOSUCHNAME);
204122394Sharti		value->var.len = sub + 1;
205122394Sharti		value->var.subs[sub] = ifp->index;
206122394Sharti		break;
207122394Sharti
208122394Sharti	  case SNMP_OP_GET:
209122394Sharti		if (value->var.len - sub != 1)
210122394Sharti			return (SNMP_ERR_NOSUCHNAME);
211122394Sharti		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
212122394Sharti			return (SNMP_ERR_NOSUCHNAME);
213122394Sharti		break;
214122394Sharti
215122394Sharti	  case SNMP_OP_SET:
216122394Sharti		if (value->var.len - sub != 1)
217122394Sharti			return (SNMP_ERR_NO_CREATION);
218122394Sharti		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
219122394Sharti			return (SNMP_ERR_NO_CREATION);
220122394Sharti		if (value->var.subs[sub - 1] != LEAF_ifAdminStatus)
221122394Sharti			return (SNMP_ERR_NOT_WRITEABLE);
222122394Sharti
223122394Sharti		idx.len = 1;
224122394Sharti		idx.subs[0] = ifp->index;
225122394Sharti
226122394Sharti		if (value->v.integer != 1 && value->v.integer != 2)
227122394Sharti			return (SNMP_ERR_WRONG_VALUE);
228122394Sharti
229122394Sharti		if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
230122394Sharti		    &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
231122394Sharti			return (SNMP_ERR_RES_UNAVAIL);
232122394Sharti		ifc->ifindex = ifp->index;
233122394Sharti
234122394Sharti		if (ifc->set & IFC_ADMIN)
235122394Sharti			return (SNMP_ERR_INCONS_VALUE);
236122394Sharti		ifc->set |= IFC_ADMIN;
237122394Sharti		ifc->admin = (value->v.integer == 1) ? 1 : 0;
238122394Sharti
239122394Sharti		return (SNMP_ERR_NOERROR);
240122394Sharti
241122394Sharti	  case SNMP_OP_ROLLBACK:
242122394Sharti	  case SNMP_OP_COMMIT:
243122394Sharti		return (SNMP_ERR_NOERROR);
244122394Sharti	}
245122394Sharti
246122394Sharti	if (ifp->mibtick < this_tick)
247122394Sharti		(void)mib_fetch_ifmib(ifp);
248122394Sharti
249122394Sharti	ret = SNMP_ERR_NOERROR;
250122394Sharti	switch (value->var.subs[sub - 1]) {
251122394Sharti
252122394Sharti	  case LEAF_ifIndex:
253122394Sharti		value->v.integer = ifp->index;
254122394Sharti		break;
255122394Sharti
256122394Sharti	  case LEAF_ifDescr:
257122394Sharti		ret = string_get(value, ifp->descr, -1);
258122394Sharti		break;
259122394Sharti
260122394Sharti	  case LEAF_ifType:
261122394Sharti		value->v.integer = ifp->mib.ifmd_data.ifi_type;
262122394Sharti		break;
263122394Sharti
264122394Sharti	  case LEAF_ifMtu:
265122394Sharti		value->v.integer = ifp->mib.ifmd_data.ifi_mtu;
266122394Sharti		break;
267122394Sharti
268122394Sharti	  case LEAF_ifSpeed:
269122394Sharti		value->v.integer = ifp->mib.ifmd_data.ifi_baudrate;
270122394Sharti		break;
271122394Sharti
272122394Sharti	  case LEAF_ifPhysAddress:
273122394Sharti		ret = string_get(value, ifp->physaddr,
274122394Sharti		    ifp->physaddrlen);
275122394Sharti		break;
276122394Sharti
277122394Sharti	  case LEAF_ifAdminStatus:
278122394Sharti		value->v.integer =
279122394Sharti		    (ifp->mib.ifmd_flags & IFF_UP) ? 1 : 2;
280122394Sharti		break;
281122394Sharti
282122394Sharti	  case LEAF_ifOperStatus:
283151970Sharti		/*
284151970Sharti		 * According to RFC 2863 the state should be Up if the
285151970Sharti		 * interface is ready to transmit packets. We takes this to
286151970Sharti		 * mean that the interface should be running and should have
287151970Sharti		 * a carrier. If it is running and has no carrier we interpret
288151970Sharti		 * this as 'waiting for an external event' (plugging in the
289151970Sharti		 * cable) and hence return 'dormant'.
290151970Sharti		 */
291151970Sharti		if (ifp->mib.ifmd_flags & IFF_RUNNING) {
292221373Sru			if (ifp->mib.ifmd_data.ifi_link_state != LINK_STATE_UP)
293151970Sharti				value->v.integer = 5;   /* state dormant */
294151970Sharti			else
295151970Sharti				value->v.integer = 1;   /* state up */
296151970Sharti		} else
297151970Sharti			value->v.integer = 2;   /* state down */
298122394Sharti		break;
299122394Sharti
300122394Sharti	  case LEAF_ifLastChange:
301122394Sharti		value->v.uint32 =
302122394Sharti		    ticks_get_timeval(&ifp->mib.ifmd_data.ifi_lastchange);
303122394Sharti		break;
304122394Sharti
305122394Sharti	  case LEAF_ifInOctets:
306122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_ibytes;
307122394Sharti		break;
308122394Sharti
309122394Sharti	  case LEAF_ifInUcastPkts:
310122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_ipackets -
311122394Sharti		    ifp->mib.ifmd_data.ifi_imcasts;
312122394Sharti		break;
313122394Sharti
314122394Sharti	  case LEAF_ifInNUcastPkts:
315122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
316122394Sharti		break;
317122394Sharti
318122394Sharti	  case LEAF_ifInDiscards:
319122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_iqdrops;
320122394Sharti		break;
321122394Sharti
322122394Sharti	  case LEAF_ifInErrors:
323122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_ierrors;
324122394Sharti		break;
325122394Sharti
326122394Sharti	  case LEAF_ifInUnknownProtos:
327122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_noproto;
328122394Sharti		break;
329122394Sharti
330122394Sharti	  case LEAF_ifOutOctets:
331122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_obytes;
332122394Sharti		break;
333122394Sharti
334122394Sharti	  case LEAF_ifOutUcastPkts:
335122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_opackets -
336122394Sharti		    ifp->mib.ifmd_data.ifi_omcasts;
337122394Sharti		break;
338122394Sharti
339122394Sharti	  case LEAF_ifOutNUcastPkts:
340122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
341122394Sharti		break;
342122394Sharti
343122394Sharti	  case LEAF_ifOutDiscards:
344122394Sharti		value->v.uint32 = ifp->mib.ifmd_snd_drops;
345122394Sharti		break;
346122394Sharti
347122394Sharti	  case LEAF_ifOutErrors:
348122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_oerrors;
349122394Sharti		break;
350122394Sharti
351122394Sharti	  case LEAF_ifOutQLen:
352122394Sharti		value->v.uint32 = ifp->mib.ifmd_snd_len;
353122394Sharti		break;
354122394Sharti
355122394Sharti	  case LEAF_ifSpecific:
356142810Sharti		value->v.oid = ifp->spec_oid;
357122394Sharti		break;
358122394Sharti	}
359122394Sharti	return (SNMP_ERR_NOERROR);
360122394Sharti}
361122394Sharti
362122394Sharti/*
363122394Sharti * IfXtable entry
364122394Sharti */
365122394Shartiint
366122394Shartiop_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
367122394Sharti    u_int sub, u_int iidx __unused, enum snmp_op op)
368122394Sharti{
369122394Sharti	struct mibif *ifp = NULL;
370122394Sharti	int ret;
371122394Sharti	struct ifchange *ifc;
372122394Sharti	struct asn_oid idx;
373122394Sharti
374122394Sharti	switch (op) {
375122394Sharti
376122394Sharti  again:
377122394Sharti		if (op != SNMP_OP_GETNEXT)
378122394Sharti			return (SNMP_ERR_NOSUCHNAME);
379122394Sharti		/* FALLTHROUGH */
380122394Sharti
381122394Sharti	  case SNMP_OP_GETNEXT:
382122394Sharti		if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
383122394Sharti			return (SNMP_ERR_NOSUCHNAME);
384122394Sharti		value->var.len = sub + 1;
385122394Sharti		value->var.subs[sub] = ifp->index;
386122394Sharti		break;
387122394Sharti
388122394Sharti	  case SNMP_OP_GET:
389122394Sharti		if (value->var.len - sub != 1)
390122394Sharti			return (SNMP_ERR_NOSUCHNAME);
391122394Sharti		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
392122394Sharti			return (SNMP_ERR_NOSUCHNAME);
393122394Sharti		break;
394122394Sharti
395122394Sharti	  case SNMP_OP_SET:
396122394Sharti		if (value->var.len - sub != 1)
397122394Sharti			return (SNMP_ERR_NO_CREATION);
398122394Sharti		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
399122394Sharti			return (SNMP_ERR_NO_CREATION);
400122394Sharti
401122394Sharti		idx.len = 1;
402122394Sharti		idx.subs[0] = ifp->index;
403122394Sharti
404122394Sharti		if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
405122394Sharti		    &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
406122394Sharti			return (SNMP_ERR_RES_UNAVAIL);
407122394Sharti		ifc->ifindex = ifp->index;
408122394Sharti
409122394Sharti		switch (value->var.subs[sub - 1]) {
410122394Sharti
411122394Sharti		  case LEAF_ifLinkUpDownTrapEnable:
412122394Sharti			if (value->v.integer != 1 && value->v.integer != 2)
413122394Sharti				return (SNMP_ERR_WRONG_VALUE);
414122394Sharti			if (ifc->set & IFC_TRAPS)
415122394Sharti				return (SNMP_ERR_INCONS_VALUE);
416122394Sharti			ifc->set |= IFC_TRAPS;
417122394Sharti			ifc->traps = (value->v.integer == 1) ? 1 : 0;
418122394Sharti			return (SNMP_ERR_NOERROR);
419122394Sharti
420122394Sharti		  case LEAF_ifPromiscuousMode:
421122394Sharti			if (value->v.integer != 1 && value->v.integer != 2)
422122394Sharti				return (SNMP_ERR_WRONG_VALUE);
423122394Sharti			if (ifc->set & IFC_PROMISC)
424122394Sharti				return (SNMP_ERR_INCONS_VALUE);
425122394Sharti			ifc->set |= IFC_PROMISC;
426122394Sharti			ifc->promisc = (value->v.integer == 1) ? 1 : 0;
427122394Sharti			return (SNMP_ERR_NOERROR);
428122394Sharti		}
429122394Sharti		return (SNMP_ERR_NOT_WRITEABLE);
430122394Sharti
431122394Sharti	  case SNMP_OP_ROLLBACK:
432122394Sharti	  case SNMP_OP_COMMIT:
433122394Sharti		return (SNMP_ERR_NOERROR);
434122394Sharti	}
435122394Sharti
436122394Sharti	if (ifp->mibtick < this_tick)
437122394Sharti		(void)mib_fetch_ifmib(ifp);
438122394Sharti
439122394Sharti	ret = SNMP_ERR_NOERROR;
440122394Sharti	switch (value->var.subs[sub - 1]) {
441122394Sharti
442122394Sharti	  case LEAF_ifName:
443122394Sharti		ret = string_get(value, ifp->name, -1);
444122394Sharti		break;
445122394Sharti
446122394Sharti	  case LEAF_ifInMulticastPkts:
447122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
448122394Sharti		break;
449122394Sharti
450122394Sharti	  case LEAF_ifInBroadcastPkts:
451122394Sharti		value->v.uint32 = 0;
452122394Sharti		break;
453122394Sharti
454122394Sharti	  case LEAF_ifOutMulticastPkts:
455122394Sharti		value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
456122394Sharti		break;
457122394Sharti
458122394Sharti	  case LEAF_ifOutBroadcastPkts:
459122394Sharti		value->v.uint32 = 0;
460122394Sharti		break;
461122394Sharti
462122394Sharti	  case LEAF_ifHCInOctets:
463122394Sharti		if (!(ifp->flags & MIBIF_HIGHSPEED))
464122394Sharti			goto again;
465155602Sharti		value->v.counter64 = MIBIF_PRIV(ifp)->hc_inoctets;
466122394Sharti		break;
467122394Sharti
468122394Sharti	  case LEAF_ifHCInUcastPkts:
469122394Sharti		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
470122394Sharti			goto again;
471155602Sharti		value->v.counter64 = MIBIF_PRIV(ifp)->hc_ipackets -
472155602Sharti		    MIBIF_PRIV(ifp)->hc_imcasts;
473122394Sharti		break;
474122394Sharti
475122394Sharti	  case LEAF_ifHCInMulticastPkts:
476122394Sharti		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
477122394Sharti			goto again;
478155602Sharti		value->v.counter64 = MIBIF_PRIV(ifp)->hc_imcasts;
479122394Sharti		break;
480122394Sharti
481122394Sharti	  case LEAF_ifHCInBroadcastPkts:
482122394Sharti		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
483122394Sharti			goto again;
484122394Sharti		value->v.counter64 = 0;
485122394Sharti		break;
486122394Sharti
487122394Sharti	  case LEAF_ifHCOutOctets:
488122394Sharti		if (!(ifp->flags & MIBIF_HIGHSPEED))
489122394Sharti			goto again;
490155602Sharti		value->v.counter64 = MIBIF_PRIV(ifp)->hc_outoctets;
491122394Sharti		break;
492122394Sharti
493122394Sharti	  case LEAF_ifHCOutUcastPkts:
494122394Sharti		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
495122394Sharti			goto again;
496155602Sharti		value->v.counter64 = MIBIF_PRIV(ifp)->hc_opackets -
497155602Sharti		    MIBIF_PRIV(ifp)->hc_omcasts;
498122394Sharti		break;
499122394Sharti
500122394Sharti	  case LEAF_ifHCOutMulticastPkts:
501122394Sharti		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
502122394Sharti			goto again;
503155602Sharti		value->v.counter64 = MIBIF_PRIV(ifp)->hc_omcasts;
504122394Sharti		break;
505122394Sharti
506122394Sharti	  case LEAF_ifHCOutBroadcastPkts:
507122394Sharti		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
508122394Sharti			goto again;
509122394Sharti		value->v.counter64 = 0;
510122394Sharti		break;
511122394Sharti
512122394Sharti	  case LEAF_ifLinkUpDownTrapEnable:
513122394Sharti		value->v.integer = ifp->trap_enable ? 1 : 2;
514122394Sharti		break;
515122394Sharti
516122394Sharti	  case LEAF_ifHighSpeed:
517122394Sharti		value->v.integer =
518122394Sharti		    (ifp->mib.ifmd_data.ifi_baudrate + 499999) / 1000000;
519122394Sharti		break;
520122394Sharti
521122394Sharti	  case LEAF_ifPromiscuousMode:
522122394Sharti		value->v.integer =
523122394Sharti		    (ifp->mib.ifmd_flags & IFF_PROMISC) ? 1 : 2;
524122394Sharti		break;
525122394Sharti
526122394Sharti	  case LEAF_ifConnectorPresent:
527122394Sharti		value->v.integer = ifp->has_connector ? 1 : 2;
528122394Sharti		break;
529122394Sharti
530122394Sharti	  case LEAF_ifAlias:
531122394Sharti		ret = string_get(value, "", -1);
532122394Sharti		break;
533122394Sharti
534122394Sharti	  case LEAF_ifCounterDiscontinuityTime:
535122394Sharti		if (ifp->counter_disc > start_tick)
536122394Sharti			value->v.uint32 = ifp->counter_disc - start_tick;
537122394Sharti		else
538122394Sharti			value->v.uint32 = 0;
539122394Sharti		break;
540122394Sharti	}
541122394Sharti	return (ret);
542122394Sharti}
543