mibII_interfaces.c revision 156066
1191618Sedwin/*
2153761Swollman * Copyright (c) 2001-2003
367578Swollman *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
42742Swollman *	All rights reserved.
52742Swollman *
62742Swollman * Author: Harti Brandt <harti@freebsd.org>
72742Swollman *
8158421Swollman * Redistribution and use in source and binary forms, with or without
92742Swollman * modification, are permitted provided that the following conditions
102742Swollman * are met:
11158421Swollman * 1. Redistributions of source code must retain the above copyright
12158421Swollman *    notice, this list of conditions and the following disclaimer.
132742Swollman * 2. Redistributions in binary form must reproduce the above copyright
1486222Swollman *    notice, this list of conditions and the following disclaimer in the
1520094Swollman *    documentation and/or other materials provided with the distribution.
1620094Swollman *
1720094Swollman * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1820094Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1920094Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20158421Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21158421Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2220094Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
232742Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
242742Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
252742Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
262742Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2714343Swollman * SUCH DAMAGE.
2858787Sru *
2914343Swollman * $Begemot: bsnmp/snmp_mibII/mibII_interfaces.c,v 1.17 2006/02/14 09:04:19 brandt_h Exp $
3030711Swollman *
3130711Swollman * Interfaces group.
32149514Swollman */
3330711Swollman#include "mibII.h"
3430711Swollman#include "mibII_oid.h"
3530711Swollman
3630711Swollman/*
3730711Swollman * This structure catches all changes to a interface entry
382742Swollman */
3930711Swollmanstruct ifchange {
4030711Swollman	struct snmp_dependency dep;
4130711Swollman
4230711Swollman	u_int		ifindex;
4330711Swollman
442742Swollman	uint32_t	set;
4530711Swollman	int		promisc;
4630711Swollman	int		admin;
4730711Swollman	int		traps;
4830711Swollman
4930711Swollman	uint32_t	rb;
5030711Swollman	int		rb_flags;
5130711Swollman	int		rb_traps;
5230711Swollman};
5330711Swollman#define IFC_PROMISC	0x0001
5430711Swollman#define IFC_ADMIN	0x0002
552742Swollman#define IFC_TRAPS	0x0004
5630711Swollman#define IFRB_FLAGS	0x0001
5730711Swollman#define IFRB_TRAPS	0x0002
5830711Swollman
5986222Swollmanstatic const struct asn_oid
6030711Swollman	oid_ifTable = OIDX_ifTable;
6130711Swollman
622742Swollman/*
6330711Swollman * This function handles all changes to the interface table and interface
642742Swollman * extension table.
652742Swollman */
662742Swollmanstatic int
6719878Swollmanifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
68158421Swollman    enum snmp_depop op)
6919878Swollman{
7019878Swollman	struct ifchange *ifc = (struct ifchange *)dep;
7119878Swollman	struct mibif *ifp;
7219878Swollman	struct ifreq ifr, ifr1;
732742Swollman
7419878Swollman	if ((ifp = mib_find_if(ifc->ifindex)) == NULL)
752742Swollman		return (SNMP_ERR_NO_CREATION);
7619878Swollman
772742Swollman	switch (op) {
78158421Swollman
792742Swollman	  case SNMP_DEPOP_COMMIT:
802742Swollman		strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
8119878Swollman		if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) {
822742Swollman			syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
8319878Swollman			return (SNMP_ERR_GENERR);
842742Swollman		}
8519878Swollman		if (ifc->set & IFC_PROMISC) {
862742Swollman			ifr.ifr_flags &= ~IFF_PROMISC;
8719878Swollman			if (ifc->promisc)
882742Swollman				ifr.ifr_flags |= IFF_PROMISC;
89158421Swollman			ifc->rb |= IFRB_FLAGS;
90158421Swollman		}
912742Swollman		if (ifc->set & IFC_ADMIN) {
922742Swollman			ifr.ifr_flags &= ~IFF_UP;
9314343Swollman			if (ifc->admin)
9419878Swollman				ifr.ifr_flags |= IFF_UP;
9519878Swollman			ifc->rb |= IFRB_FLAGS;
962742Swollman		}
9719878Swollman		if (ifc->rb & IFRB_FLAGS) {
9819878Swollman			strncpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name));
9919878Swollman			if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr1) == -1) {
10019878Swollman				syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
10119878Swollman				return (SNMP_ERR_GENERR);
1022742Swollman			}
1032742Swollman			ifc->rb_flags = ifr1.ifr_flags;
1042742Swollman			if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
1052742Swollman				syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
10686222Swollman				return (SNMP_ERR_GENERR);
10730711Swollman			}
1082742Swollman			(void)mib_fetch_ifmib(ifp);
1092742Swollman		}
110158421Swollman		if (ifc->set & IFC_TRAPS) {
111158421Swollman			ifc->rb |= IFRB_TRAPS;
1122742Swollman			ifc->rb_traps = ifp->trap_enable;
1132742Swollman			ifp->trap_enable = ifc->traps;
11430711Swollman		}
11530711Swollman		return (SNMP_ERR_NOERROR);
1162742Swollman
1172742Swollman	  case SNMP_DEPOP_ROLLBACK:
1182742Swollman		if (ifc->rb & IFRB_FLAGS) {
1192742Swollman			strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
12030711Swollman			ifr.ifr_flags = ifc->rb_flags;
12130711Swollman			if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
12230711Swollman				syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
1232742Swollman				return (SNMP_ERR_UNDO_FAILED);
1242742Swollman			}
1252742Swollman			(void)mib_fetch_ifmib(ifp);
1262742Swollman		}
12730711Swollman		if (ifc->rb & IFRB_TRAPS)
1282742Swollman			ifp->trap_enable = ifc->rb_traps;
1292742Swollman		return (SNMP_ERR_NOERROR);
1302742Swollman
1312742Swollman	  case SNMP_DEPOP_FINISH:
13230711Swollman		return (SNMP_ERR_NOERROR);
1332742Swollman
1342742Swollman	}
135158421Swollman	abort();
1362742Swollman}
1372742Swollman
13830711Swollman/*
1392742Swollman * Return difference to daemon start time in ticks truncated to a
1402742Swollman * 32-bit value. If the timeval is 0 then return 0.
1412742Swollman */
1422742Swollmanstatic uint32_t
1432742Swollmanticks_get_timeval(struct timeval *tv)
1442742Swollman{
1452742Swollman	uint64_t v;
14619878Swollman
1472742Swollman	if (tv->tv_sec != 0 || tv->tv_usec != 0) {
1482742Swollman		v = 100ULL * tv->tv_sec + tv->tv_usec / 10000ULL;
1492742Swollman		if (v > start_tick)
1502742Swollman			return (v - start_tick);
15130711Swollman	}
1522742Swollman	return (0);
1532742Swollman}
1542742Swollman
1552742Swollman/*
15630711Swollman * Scalars
15730711Swollman */
15830711Swollmanint
1592742Swollmanop_interfaces(struct snmp_context *ctx __unused, struct snmp_value *value,
1602742Swollman    u_int sub, u_int idx __unused, enum snmp_op op)
1612742Swollman{
1622742Swollman	switch (op) {
1632742Swollman
1642742Swollman	  case SNMP_OP_GETNEXT:
16530711Swollman		abort();
1662742Swollman
16730711Swollman	  case SNMP_OP_GET:
16830711Swollman		break;
16930711Swollman
17030711Swollman	  case SNMP_OP_SET:
17130711Swollman		return (SNMP_ERR_NOT_WRITEABLE);
17230711Swollman
17330711Swollman	  case SNMP_OP_ROLLBACK:
1742742Swollman	  case SNMP_OP_COMMIT:
17530711Swollman		abort();
1762742Swollman	}
1772742Swollman
1782742Swollman	switch (value->var.subs[sub - 1]) {
1792742Swollman
18030711Swollman	  case LEAF_ifNumber:
1812742Swollman		value->v.integer = mib_if_number;
1822742Swollman		break;
1832742Swollman	}
1842742Swollman	return (SNMP_ERR_NOERROR);
1852742Swollman}
1862742Swollman
1872742Swollman/*
1882742Swollman * Iftable entry
1892742Swollman */
1902742Swollmanint
1912742Swollmanop_ifentry(struct snmp_context *ctx, struct snmp_value *value,
19219878Swollman    u_int sub, u_int iidx __unused, enum snmp_op op)
1932742Swollman{
19419878Swollman	struct mibif *ifp = NULL;
1952742Swollman	int ret;
19619878Swollman	struct ifchange *ifc;
1972742Swollman	struct asn_oid idx;
1982742Swollman
19919878Swollman	switch (op) {
20019878Swollman
2012742Swollman	  case SNMP_OP_GETNEXT:
20219878Swollman		if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
20319878Swollman			return (SNMP_ERR_NOSUCHNAME);
2042742Swollman		value->var.len = sub + 1;
20530711Swollman		value->var.subs[sub] = ifp->index;
20619878Swollman		break;
20719878Swollman
20819878Swollman	  case SNMP_OP_GET:
20919878Swollman		if (value->var.len - sub != 1)
21030711Swollman			return (SNMP_ERR_NOSUCHNAME);
21143014Swollman		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
21243543Swollman			return (SNMP_ERR_NOSUCHNAME);
21358787Sru		break;
214163302Sru
215163302Sru	  case SNMP_OP_SET:
216163302Sru		if (value->var.len - sub != 1)
217163302Sru			return (SNMP_ERR_NO_CREATION);
218163302Sru		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
219163302Sru			return (SNMP_ERR_NO_CREATION);
220163302Sru		if (value->var.subs[sub - 1] != LEAF_ifAdminStatus)
221171948Sedwin			return (SNMP_ERR_NOT_WRITEABLE);
222171948Sedwin
223171948Sedwin		idx.len = 1;
224171948Sedwin		idx.subs[0] = ifp->index;
225171948Sedwin
226171948Sedwin		if (value->v.integer != 1 && value->v.integer != 2)
227172479Sedwin			return (SNMP_ERR_WRONG_VALUE);
228172479Sedwin
229172479Sedwin		if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
230172479Sedwin		    &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
231172479Sedwin			return (SNMP_ERR_RES_UNAVAIL);
232172479Sedwin		ifc->ifindex = ifp->index;
233172479Sedwin
234172479Sedwin		if (ifc->set & IFC_ADMIN)
235172479Sedwin			return (SNMP_ERR_INCONS_VALUE);
236172479Sedwin		ifc->set |= IFC_ADMIN;
237171948Sedwin		ifc->admin = (value->v.integer == 1) ? 1 : 0;
238172479Sedwin
23920094Swollman		return (SNMP_ERR_NOERROR);
240191618Sedwin
241191618Sedwin	  case SNMP_OP_ROLLBACK:
242191618Sedwin	  case SNMP_OP_COMMIT:
243191618Sedwin		return (SNMP_ERR_NOERROR);
244191618Sedwin	}
245191618Sedwin
246191618Sedwin	if (ifp->mibtick < this_tick)
247191618Sedwin		(void)mib_fetch_ifmib(ifp);
248191618Sedwin
249191618Sedwin	ret = SNMP_ERR_NOERROR;
250191618Sedwin	switch (value->var.subs[sub - 1]) {
251191618Sedwin
252191618Sedwin	  case LEAF_ifIndex:
253191618Sedwin		value->v.integer = ifp->index;
254191618Sedwin		break;
255191618Sedwin
256191618Sedwin	  case LEAF_ifDescr:
257191618Sedwin		ret = string_get(value, ifp->descr, -1);
258191618Sedwin		break;
259191618Sedwin
260191618Sedwin	  case LEAF_ifType:
261191618Sedwin		value->v.integer = ifp->mib.ifmd_data.ifi_type;
262191618Sedwin		break;
263191618Sedwin
264191618Sedwin	  case LEAF_ifMtu:
265191618Sedwin		value->v.integer = ifp->mib.ifmd_data.ifi_mtu;
266191618Sedwin		break;
267191618Sedwin
268191618Sedwin	  case LEAF_ifSpeed:
269191618Sedwin		value->v.integer = ifp->mib.ifmd_data.ifi_baudrate;
270191618Sedwin		break;
271191618Sedwin
272191618Sedwin	  case LEAF_ifPhysAddress:
273191618Sedwin		ret = string_get(value, ifp->physaddr,
274191618Sedwin		    ifp->physaddrlen);
275191618Sedwin		break;
276191618Sedwin
277191618Sedwin	  case LEAF_ifAdminStatus:
278191618Sedwin		value->v.integer =
279191618Sedwin		    (ifp->mib.ifmd_flags & IFF_UP) ? 1 : 2;
2802742Swollman		break;
2812742Swollman
28219878Swollman	  case LEAF_ifOperStatus:
2832742Swollman		/*
2842742Swollman		 * According to RFC 2863 the state should be Up if the
2852742Swollman		 * interface is ready to transmit packets. We takes this to
2862742Swollman		 * mean that the interface should be running and should have
28730711Swollman		 * a carrier. If it is running and has no carrier we interpret
28830711Swollman		 * this as 'waiting for an external event' (plugging in the
2892742Swollman		 * cable) and hence return 'dormant'.
2902742Swollman		 */
2912742Swollman		if (ifp->mib.ifmd_flags & IFF_RUNNING) {
292169811Swollman			if (ifp->mib.ifmd_data.ifi_link_state ==
293169811Swollman			    LINK_STATE_DOWN)
29430711Swollman				value->v.integer = 5;   /* state dormant */
2952742Swollman			else
2962742Swollman				value->v.integer = 1;   /* state up */
2972742Swollman		} else
298158421Swollman			value->v.integer = 2;   /* state down */
299158421Swollman		break;
300158421Swollman
30130711Swollman	  case LEAF_ifLastChange:
3022742Swollman		value->v.uint32 =
3032742Swollman		    ticks_get_timeval(&ifp->mib.ifmd_data.ifi_lastchange);
30430711Swollman		break;
3052742Swollman
3062742Swollman	  case LEAF_ifInOctets:
3072742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_ibytes;
3082742Swollman		break;
3092742Swollman
31030711Swollman	  case LEAF_ifInUcastPkts:
3112742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_ipackets -
3122742Swollman		    ifp->mib.ifmd_data.ifi_imcasts;
3132742Swollman		break;
3142742Swollman
31519878Swollman	  case LEAF_ifInNUcastPkts:
31630711Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
31730711Swollman		break;
3182742Swollman
3192742Swollman	  case LEAF_ifInDiscards:
3202742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_iqdrops;
321158421Swollman		break;
322158421Swollman
32330711Swollman	  case LEAF_ifInErrors:
32430711Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_ierrors;
3252742Swollman		break;
3262742Swollman
3272742Swollman	  case LEAF_ifInUnknownProtos:
3282742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_noproto;
3292742Swollman		break;
3302742Swollman
3312742Swollman	  case LEAF_ifOutOctets:
33230711Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_obytes;
33330711Swollman		break;
33430711Swollman
3352742Swollman	  case LEAF_ifOutUcastPkts:
3362742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_opackets -
3372742Swollman		    ifp->mib.ifmd_data.ifi_omcasts;
3382742Swollman		break;
33930711Swollman
34030711Swollman	  case LEAF_ifOutNUcastPkts:
3412742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
3422742Swollman		break;
3432742Swollman
3442742Swollman	  case LEAF_ifOutDiscards:
3452742Swollman		value->v.uint32 = ifp->mib.ifmd_snd_drops;
34630711Swollman		break;
34786222Swollman
3482742Swollman	  case LEAF_ifOutErrors:
3492742Swollman		value->v.uint32 = ifp->mib.ifmd_data.ifi_oerrors;
3502742Swollman		break;
3512742Swollman
3522742Swollman	  case LEAF_ifOutQLen:
35330711Swollman		value->v.uint32 = ifp->mib.ifmd_snd_len;
3542742Swollman		break;
35530711Swollman
3562742Swollman	  case LEAF_ifSpecific:
3572742Swollman		value->v.oid = ifp->spec_oid;
358158421Swollman		break;
3592742Swollman	}
36086222Swollman	return (SNMP_ERR_NOERROR);
36114343Swollman}
362158421Swollman
363158421Swollman/*
364158421Swollman * IfXtable entry
365158421Swollman */
3662742Swollmanint
3672742Swollmanop_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
3682742Swollman    u_int sub, u_int iidx __unused, enum snmp_op op)
36919878Swollman{
37030711Swollman	struct mibif *ifp = NULL;
3712742Swollman	int ret;
3722742Swollman	struct ifchange *ifc;
3732742Swollman	struct asn_oid idx;
3742742Swollman
3752742Swollman	switch (op) {
3762742Swollman
37719878Swollman  again:
3782742Swollman		if (op != SNMP_OP_GETNEXT)
37919878Swollman			return (SNMP_ERR_NOSUCHNAME);
3802742Swollman		/* FALLTHROUGH */
38119878Swollman
3822742Swollman	  case SNMP_OP_GETNEXT:
38319878Swollman		if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
3842742Swollman			return (SNMP_ERR_NOSUCHNAME);
38519878Swollman		value->var.len = sub + 1;
38619878Swollman		value->var.subs[sub] = ifp->index;
3872742Swollman		break;
38819878Swollman
389149514Swollman	  case SNMP_OP_GET:
3902742Swollman		if (value->var.len - sub != 1)
3912742Swollman			return (SNMP_ERR_NOSUCHNAME);
39219878Swollman		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
3932742Swollman			return (SNMP_ERR_NOSUCHNAME);
39458787Sru		break;
395158421Swollman
39658787Sru	  case SNMP_OP_SET:
39758787Sru		if (value->var.len - sub != 1)
39858787Sru			return (SNMP_ERR_NO_CREATION);
39958787Sru		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
40043014Swollman			return (SNMP_ERR_NO_CREATION);
4012742Swollman
4022742Swollman		idx.len = 1;
4032742Swollman		idx.subs[0] = ifp->index;
4042742Swollman
4052742Swollman		if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
4062742Swollman		    &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
4072742Swollman			return (SNMP_ERR_RES_UNAVAIL);
4082742Swollman		ifc->ifindex = ifp->index;
4092742Swollman
4102742Swollman		switch (value->var.subs[sub - 1]) {
4112742Swollman
41230711Swollman		  case LEAF_ifLinkUpDownTrapEnable:
4132742Swollman			if (value->v.integer != 1 && value->v.integer != 2)
4142742Swollman				return (SNMP_ERR_WRONG_VALUE);
4152742Swollman			if (ifc->set & IFC_TRAPS)
4162742Swollman				return (SNMP_ERR_INCONS_VALUE);
41730711Swollman			ifc->set |= IFC_TRAPS;
41830711Swollman			ifc->traps = (value->v.integer == 1) ? 1 : 0;
41930711Swollman			return (SNMP_ERR_NOERROR);
4202742Swollman
4212742Swollman		  case LEAF_ifPromiscuousMode:
4222742Swollman			if (value->v.integer != 1 && value->v.integer != 2)
4232742Swollman				return (SNMP_ERR_WRONG_VALUE);
42430711Swollman			if (ifc->set & IFC_PROMISC)
42530711Swollman				return (SNMP_ERR_INCONS_VALUE);
42630711Swollman			ifc->set |= IFC_PROMISC;
4272742Swollman			ifc->promisc = (value->v.integer == 1) ? 1 : 0;
4282742Swollman			return (SNMP_ERR_NOERROR);
429181421Sedwin		}
430181421Sedwin		return (SNMP_ERR_NOT_WRITEABLE);
431181421Sedwin
432181421Sedwin	  case SNMP_OP_ROLLBACK:
433181421Sedwin	  case SNMP_OP_COMMIT:
434181421Sedwin		return (SNMP_ERR_NOERROR);
435181421Sedwin	}
436181424Sedwin
437181421Sedwin	if (ifp->mibtick < this_tick)
438181421Sedwin		(void)mib_fetch_ifmib(ifp);
439181424Sedwin
440181421Sedwin	ret = SNMP_ERR_NOERROR;
441181421Sedwin	switch (value->var.subs[sub - 1]) {
442181421Sedwin
443181421Sedwin	  case LEAF_ifName:
444181424Sedwin		ret = string_get(value, ifp->name, -1);
445181421Sedwin		break;
446181421Sedwin
447181421Sedwin	  case LEAF_ifInMulticastPkts:
448181424Sedwin		value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
449181424Sedwin		break;
450181424Sedwin
451181424Sedwin	  case LEAF_ifInBroadcastPkts:
452181424Sedwin		value->v.uint32 = 0;
453181424Sedwin		break;
454181424Sedwin
455181424Sedwin	  case LEAF_ifOutMulticastPkts:
456181424Sedwin		value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
457181424Sedwin		break;
458181424Sedwin
459181424Sedwin	  case LEAF_ifOutBroadcastPkts:
460181424Sedwin		value->v.uint32 = 0;
461181424Sedwin		break;
462181424Sedwin
463181424Sedwin	  case LEAF_ifHCInOctets:
464181424Sedwin		if (!(ifp->flags & MIBIF_HIGHSPEED))
465181424Sedwin			goto again;
466181424Sedwin		value->v.counter64 = MIBIF_PRIV(ifp)->hc_inoctets;
467181424Sedwin		break;
468181424Sedwin
469181424Sedwin	  case LEAF_ifHCInUcastPkts:
470181424Sedwin		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
471181424Sedwin			goto again;
472181424Sedwin		value->v.counter64 = MIBIF_PRIV(ifp)->hc_ipackets -
473181424Sedwin		    MIBIF_PRIV(ifp)->hc_imcasts;
474181424Sedwin		break;
475181424Sedwin
476181424Sedwin	  case LEAF_ifHCInMulticastPkts:
477181424Sedwin		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
478183066Sedwin			goto again;
479183066Sedwin		value->v.counter64 = MIBIF_PRIV(ifp)->hc_imcasts;
480183066Sedwin		break;
481183066Sedwin
482183066Sedwin	  case LEAF_ifHCInBroadcastPkts:
483183066Sedwin		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
484183066Sedwin			goto again;
485183066Sedwin		value->v.counter64 = 0;
486183066Sedwin		break;
487183066Sedwin
488183066Sedwin	  case LEAF_ifHCOutOctets:
489183066Sedwin		if (!(ifp->flags & MIBIF_HIGHSPEED))
490183066Sedwin			goto again;
491183066Sedwin		value->v.counter64 = MIBIF_PRIV(ifp)->hc_outoctets;
492183066Sedwin		break;
493183066Sedwin
494183066Sedwin	  case LEAF_ifHCOutUcastPkts:
495183864Sedwin		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
496183864Sedwin			goto again;
497183864Sedwin		value->v.counter64 = MIBIF_PRIV(ifp)->hc_opackets -
498183864Sedwin		    MIBIF_PRIV(ifp)->hc_omcasts;
499183864Sedwin		break;
500183864Sedwin
501183864Sedwin	  case LEAF_ifHCOutMulticastPkts:
502183864Sedwin		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
503181421Sedwin			goto again;
504181421Sedwin		value->v.counter64 = MIBIF_PRIV(ifp)->hc_omcasts;
505181421Sedwin		break;
506183864Sedwin
507183864Sedwin	  case LEAF_ifHCOutBroadcastPkts:
5082742Swollman		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
5092742Swollman			goto again;
510181421Sedwin		value->v.counter64 = 0;
5112742Swollman		break;
5122742Swollman
5132742Swollman	  case LEAF_ifLinkUpDownTrapEnable:
5142742Swollman		value->v.integer = ifp->trap_enable ? 1 : 2;
5152742Swollman		break;
51614343Swollman
5172742Swollman	  case LEAF_ifHighSpeed:
5182742Swollman		value->v.integer =
5192742Swollman		    (ifp->mib.ifmd_data.ifi_baudrate + 499999) / 1000000;
52030711Swollman		break;
521181418Sedwin
522181418Sedwin	  case LEAF_ifPromiscuousMode:
523181418Sedwin		value->v.integer =
524181418Sedwin		    (ifp->mib.ifmd_flags & IFF_PROMISC) ? 1 : 2;
525181418Sedwin		break;
526181418Sedwin
527181418Sedwin	  case LEAF_ifConnectorPresent:
528181418Sedwin		value->v.integer = ifp->has_connector ? 1 : 2;
529181418Sedwin		break;
530181418Sedwin
531181418Sedwin	  case LEAF_ifAlias:
532181418Sedwin		ret = string_get(value, "", -1);
533181418Sedwin		break;
534181418Sedwin
535181418Sedwin	  case LEAF_ifCounterDiscontinuityTime:
536181418Sedwin		if (ifp->counter_disc > start_tick)
537181418Sedwin			value->v.uint32 = ifp->counter_disc - start_tick;
538181418Sedwin		else
539181418Sedwin			value->v.uint32 = 0;
540181418Sedwin		break;
541181418Sedwin	}
542181418Sedwin	return (ret);
543181418Sedwin}
544181418Sedwin