xref: /freebsd/contrib/bsnmp/snmp_mibII/mibII_interfaces.c (revision 896052c10f33c29a53b63fc67d4c8238b87f5b3e)
1f06ca4afSHartmut Brandt /*
2f06ca4afSHartmut Brandt  * Copyright (c) 2001-2003
3f06ca4afSHartmut Brandt  *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4f06ca4afSHartmut Brandt  *	All rights reserved.
5f06ca4afSHartmut Brandt  *
6f06ca4afSHartmut Brandt  * Author: Harti Brandt <harti@freebsd.org>
7f06ca4afSHartmut Brandt  *
8896052c1SHartmut Brandt  * Redistribution and use in source and binary forms, with or without
9896052c1SHartmut Brandt  * modification, are permitted provided that the following conditions
10896052c1SHartmut Brandt  * are met:
11896052c1SHartmut Brandt  * 1. Redistributions of source code must retain the above copyright
12896052c1SHartmut Brandt  *    notice, this list of conditions and the following disclaimer.
13f06ca4afSHartmut Brandt  * 2. Redistributions in binary form must reproduce the above copyright
14f06ca4afSHartmut Brandt  *    notice, this list of conditions and the following disclaimer in the
15f06ca4afSHartmut Brandt  *    documentation and/or other materials provided with the distribution.
16f06ca4afSHartmut Brandt  *
17896052c1SHartmut Brandt  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18896052c1SHartmut Brandt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19896052c1SHartmut Brandt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20896052c1SHartmut Brandt  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21896052c1SHartmut Brandt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22896052c1SHartmut Brandt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23896052c1SHartmut Brandt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24896052c1SHartmut Brandt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25896052c1SHartmut Brandt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26896052c1SHartmut Brandt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27896052c1SHartmut Brandt  * SUCH DAMAGE.
28f06ca4afSHartmut Brandt  *
29896052c1SHartmut Brandt  * $Begemot: bsnmp/snmp_mibII/mibII_interfaces.c,v 1.13 2004/08/06 08:47:01 brandt Exp $
30f06ca4afSHartmut Brandt  *
31f06ca4afSHartmut Brandt  * Interfaces group.
32f06ca4afSHartmut Brandt  */
33f06ca4afSHartmut Brandt #include "mibII.h"
34f06ca4afSHartmut Brandt #include "mibII_oid.h"
35f06ca4afSHartmut Brandt 
36f06ca4afSHartmut Brandt /*
37f06ca4afSHartmut Brandt  * This structure catches all changes to a interface entry
38f06ca4afSHartmut Brandt  */
39f06ca4afSHartmut Brandt struct ifchange {
40f06ca4afSHartmut Brandt 	struct snmp_dependency dep;
41f06ca4afSHartmut Brandt 
42f06ca4afSHartmut Brandt 	u_int		ifindex;
43f06ca4afSHartmut Brandt 
44896052c1SHartmut Brandt 	uint32_t	set;
45f06ca4afSHartmut Brandt 	int		promisc;
46f06ca4afSHartmut Brandt 	int		admin;
47f06ca4afSHartmut Brandt 	int		traps;
48f06ca4afSHartmut Brandt 
49896052c1SHartmut Brandt 	uint32_t	rb;
50f06ca4afSHartmut Brandt 	int		rb_flags;
51f06ca4afSHartmut Brandt 	int		rb_traps;
52f06ca4afSHartmut Brandt };
53f06ca4afSHartmut Brandt #define IFC_PROMISC	0x0001
54f06ca4afSHartmut Brandt #define IFC_ADMIN	0x0002
55f06ca4afSHartmut Brandt #define IFC_TRAPS	0x0004
56f06ca4afSHartmut Brandt #define IFRB_FLAGS	0x0001
57f06ca4afSHartmut Brandt #define IFRB_TRAPS	0x0002
58f06ca4afSHartmut Brandt 
59f06ca4afSHartmut Brandt static const struct asn_oid
60f06ca4afSHartmut Brandt 	oid_ifTable = OIDX_ifTable;
61f06ca4afSHartmut Brandt 
62f06ca4afSHartmut Brandt /*
63f06ca4afSHartmut Brandt  * This function handles all changes to the interface table and interface
64f06ca4afSHartmut Brandt  * extension table.
65f06ca4afSHartmut Brandt  */
66f06ca4afSHartmut Brandt static int
67f06ca4afSHartmut Brandt ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
68f06ca4afSHartmut Brandt     enum snmp_depop op)
69f06ca4afSHartmut Brandt {
70f06ca4afSHartmut Brandt 	struct ifchange *ifc = (struct ifchange *)dep;
71f06ca4afSHartmut Brandt 	struct mibif *ifp;
72f06ca4afSHartmut Brandt 	struct ifreq ifr, ifr1;
73f06ca4afSHartmut Brandt 
74f06ca4afSHartmut Brandt 	if ((ifp = mib_find_if(ifc->ifindex)) == NULL)
75f06ca4afSHartmut Brandt 		return (SNMP_ERR_NO_CREATION);
76f06ca4afSHartmut Brandt 
77f06ca4afSHartmut Brandt 	switch (op) {
78f06ca4afSHartmut Brandt 
79f06ca4afSHartmut Brandt 	  case SNMP_DEPOP_COMMIT:
80f06ca4afSHartmut Brandt 		strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
81f06ca4afSHartmut Brandt 		if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) {
82f06ca4afSHartmut Brandt 			syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
83f06ca4afSHartmut Brandt 			return (SNMP_ERR_GENERR);
84f06ca4afSHartmut Brandt 		}
85f06ca4afSHartmut Brandt 		if (ifc->set & IFC_PROMISC) {
86f06ca4afSHartmut Brandt 			ifr.ifr_flags &= ~IFF_PROMISC;
87f06ca4afSHartmut Brandt 			if (ifc->promisc)
88f06ca4afSHartmut Brandt 				ifr.ifr_flags |= IFF_PROMISC;
89f06ca4afSHartmut Brandt 			ifc->rb |= IFRB_FLAGS;
90f06ca4afSHartmut Brandt 		}
91f06ca4afSHartmut Brandt 		if (ifc->set & IFC_ADMIN) {
92f06ca4afSHartmut Brandt 			ifr.ifr_flags &= ~IFF_UP;
93f06ca4afSHartmut Brandt 			if (ifc->admin)
94f06ca4afSHartmut Brandt 				ifr.ifr_flags |= IFF_UP;
95f06ca4afSHartmut Brandt 			ifc->rb |= IFRB_FLAGS;
96f06ca4afSHartmut Brandt 		}
97f06ca4afSHartmut Brandt 		if (ifc->rb & IFRB_FLAGS) {
98f06ca4afSHartmut Brandt 			strncpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name));
99f06ca4afSHartmut Brandt 			if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr1) == -1) {
100f06ca4afSHartmut Brandt 				syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
101f06ca4afSHartmut Brandt 				return (SNMP_ERR_GENERR);
102f06ca4afSHartmut Brandt 			}
103f06ca4afSHartmut Brandt 			ifc->rb_flags = ifr1.ifr_flags;
104f06ca4afSHartmut Brandt 			if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
105f06ca4afSHartmut Brandt 				syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
106f06ca4afSHartmut Brandt 				return (SNMP_ERR_GENERR);
107f06ca4afSHartmut Brandt 			}
108f06ca4afSHartmut Brandt 			(void)mib_fetch_ifmib(ifp);
109f06ca4afSHartmut Brandt 		}
110f06ca4afSHartmut Brandt 		if (ifc->set & IFC_TRAPS) {
111f06ca4afSHartmut Brandt 			ifc->rb |= IFRB_TRAPS;
112f06ca4afSHartmut Brandt 			ifc->rb_traps = ifp->trap_enable;
113f06ca4afSHartmut Brandt 			ifp->trap_enable = ifc->traps;
114f06ca4afSHartmut Brandt 		}
115f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOERROR);
116f06ca4afSHartmut Brandt 
117f06ca4afSHartmut Brandt 	  case SNMP_DEPOP_ROLLBACK:
118f06ca4afSHartmut Brandt 		if (ifc->rb & IFRB_FLAGS) {
119f06ca4afSHartmut Brandt 			strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
120f06ca4afSHartmut Brandt 			ifr.ifr_flags = ifc->rb_flags;
121f06ca4afSHartmut Brandt 			if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
122f06ca4afSHartmut Brandt 				syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
123f06ca4afSHartmut Brandt 				return (SNMP_ERR_UNDO_FAILED);
124f06ca4afSHartmut Brandt 			}
125f06ca4afSHartmut Brandt 			(void)mib_fetch_ifmib(ifp);
126f06ca4afSHartmut Brandt 		}
127f06ca4afSHartmut Brandt 		if (ifc->rb & IFRB_TRAPS)
128f06ca4afSHartmut Brandt 			ifp->trap_enable = ifc->rb_traps;
129f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOERROR);
130f06ca4afSHartmut Brandt 
1318eecd77aSHartmut Brandt 	  case SNMP_DEPOP_FINISH:
1328eecd77aSHartmut Brandt 		return (SNMP_ERR_NOERROR);
1338eecd77aSHartmut Brandt 
134f06ca4afSHartmut Brandt 	}
135f06ca4afSHartmut Brandt 	abort();
136f06ca4afSHartmut Brandt }
137f06ca4afSHartmut Brandt 
138896052c1SHartmut Brandt static uint32_t
139f06ca4afSHartmut Brandt ticks_get_timeval(struct timeval *tv)
140f06ca4afSHartmut Brandt {
141896052c1SHartmut Brandt 	uint32_t v;
142f06ca4afSHartmut Brandt 
143f06ca4afSHartmut Brandt 	if (tv->tv_sec != 0 || tv->tv_usec != 0) {
144f06ca4afSHartmut Brandt 		v = 100 * tv->tv_sec + tv->tv_usec / 10000;
145f06ca4afSHartmut Brandt 		if (v > start_tick)
146f06ca4afSHartmut Brandt 			return (v - start_tick);
147f06ca4afSHartmut Brandt 	}
148f06ca4afSHartmut Brandt 	return (0);
149f06ca4afSHartmut Brandt }
150f06ca4afSHartmut Brandt 
151f06ca4afSHartmut Brandt /*
152f06ca4afSHartmut Brandt  * Scalars
153f06ca4afSHartmut Brandt  */
154f06ca4afSHartmut Brandt int
155f06ca4afSHartmut Brandt op_interfaces(struct snmp_context *ctx __unused, struct snmp_value *value,
156f06ca4afSHartmut Brandt     u_int sub, u_int idx __unused, enum snmp_op op)
157f06ca4afSHartmut Brandt {
158f06ca4afSHartmut Brandt 	switch (op) {
159f06ca4afSHartmut Brandt 
160f06ca4afSHartmut Brandt 	  case SNMP_OP_GETNEXT:
161f06ca4afSHartmut Brandt 		abort();
162f06ca4afSHartmut Brandt 
163f06ca4afSHartmut Brandt 	  case SNMP_OP_GET:
164f06ca4afSHartmut Brandt 		break;
165f06ca4afSHartmut Brandt 
166f06ca4afSHartmut Brandt 	  case SNMP_OP_SET:
167f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOT_WRITEABLE);
168f06ca4afSHartmut Brandt 
169f06ca4afSHartmut Brandt 	  case SNMP_OP_ROLLBACK:
170f06ca4afSHartmut Brandt 	  case SNMP_OP_COMMIT:
171f06ca4afSHartmut Brandt 		abort();
172f06ca4afSHartmut Brandt 	}
173f06ca4afSHartmut Brandt 
174f06ca4afSHartmut Brandt 	switch (value->var.subs[sub - 1]) {
175f06ca4afSHartmut Brandt 
176f06ca4afSHartmut Brandt 	  case LEAF_ifNumber:
177f06ca4afSHartmut Brandt 		value->v.integer = mib_if_number;
178f06ca4afSHartmut Brandt 		break;
179f06ca4afSHartmut Brandt 	}
180f06ca4afSHartmut Brandt 	return (SNMP_ERR_NOERROR);
181f06ca4afSHartmut Brandt }
182f06ca4afSHartmut Brandt 
183f06ca4afSHartmut Brandt /*
184f06ca4afSHartmut Brandt  * Iftable entry
185f06ca4afSHartmut Brandt  */
186f06ca4afSHartmut Brandt int
187f06ca4afSHartmut Brandt op_ifentry(struct snmp_context *ctx, struct snmp_value *value,
188f06ca4afSHartmut Brandt     u_int sub, u_int iidx __unused, enum snmp_op op)
189f06ca4afSHartmut Brandt {
190f06ca4afSHartmut Brandt 	struct mibif *ifp = NULL;
191f06ca4afSHartmut Brandt 	int ret;
192f06ca4afSHartmut Brandt 	struct ifchange *ifc;
193f06ca4afSHartmut Brandt 	struct asn_oid idx;
194f06ca4afSHartmut Brandt 
195f06ca4afSHartmut Brandt 	switch (op) {
196f06ca4afSHartmut Brandt 
197f06ca4afSHartmut Brandt 	  case SNMP_OP_GETNEXT:
198f06ca4afSHartmut Brandt 		if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
199f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
200f06ca4afSHartmut Brandt 		value->var.len = sub + 1;
201f06ca4afSHartmut Brandt 		value->var.subs[sub] = ifp->index;
202f06ca4afSHartmut Brandt 		break;
203f06ca4afSHartmut Brandt 
204f06ca4afSHartmut Brandt 	  case SNMP_OP_GET:
205f06ca4afSHartmut Brandt 		if (value->var.len - sub != 1)
206f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
207f06ca4afSHartmut Brandt 		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
208f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
209f06ca4afSHartmut Brandt 		break;
210f06ca4afSHartmut Brandt 
211f06ca4afSHartmut Brandt 	  case SNMP_OP_SET:
212f06ca4afSHartmut Brandt 		if (value->var.len - sub != 1)
213f06ca4afSHartmut Brandt 			return (SNMP_ERR_NO_CREATION);
214f06ca4afSHartmut Brandt 		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
215f06ca4afSHartmut Brandt 			return (SNMP_ERR_NO_CREATION);
216f06ca4afSHartmut Brandt 		if (value->var.subs[sub - 1] != LEAF_ifAdminStatus)
217f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOT_WRITEABLE);
218f06ca4afSHartmut Brandt 
219f06ca4afSHartmut Brandt 		idx.len = 1;
220f06ca4afSHartmut Brandt 		idx.subs[0] = ifp->index;
221f06ca4afSHartmut Brandt 
222f06ca4afSHartmut Brandt 		if (value->v.integer != 1 && value->v.integer != 2)
223f06ca4afSHartmut Brandt 			return (SNMP_ERR_WRONG_VALUE);
224f06ca4afSHartmut Brandt 
225f06ca4afSHartmut Brandt 		if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
226f06ca4afSHartmut Brandt 		    &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
227f06ca4afSHartmut Brandt 			return (SNMP_ERR_RES_UNAVAIL);
228f06ca4afSHartmut Brandt 		ifc->ifindex = ifp->index;
229f06ca4afSHartmut Brandt 
230f06ca4afSHartmut Brandt 		if (ifc->set & IFC_ADMIN)
231f06ca4afSHartmut Brandt 			return (SNMP_ERR_INCONS_VALUE);
232f06ca4afSHartmut Brandt 		ifc->set |= IFC_ADMIN;
233f06ca4afSHartmut Brandt 		ifc->admin = (value->v.integer == 1) ? 1 : 0;
234f06ca4afSHartmut Brandt 
235f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOERROR);
236f06ca4afSHartmut Brandt 
237f06ca4afSHartmut Brandt 	  case SNMP_OP_ROLLBACK:
238f06ca4afSHartmut Brandt 	  case SNMP_OP_COMMIT:
239f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOERROR);
240f06ca4afSHartmut Brandt 	}
241f06ca4afSHartmut Brandt 
242f06ca4afSHartmut Brandt 	if (ifp->mibtick < this_tick)
243f06ca4afSHartmut Brandt 		(void)mib_fetch_ifmib(ifp);
244f06ca4afSHartmut Brandt 
245f06ca4afSHartmut Brandt 	ret = SNMP_ERR_NOERROR;
246f06ca4afSHartmut Brandt 	switch (value->var.subs[sub - 1]) {
247f06ca4afSHartmut Brandt 
248f06ca4afSHartmut Brandt 	  case LEAF_ifIndex:
249f06ca4afSHartmut Brandt 		value->v.integer = ifp->index;
250f06ca4afSHartmut Brandt 		break;
251f06ca4afSHartmut Brandt 
252f06ca4afSHartmut Brandt 	  case LEAF_ifDescr:
253f06ca4afSHartmut Brandt 		ret = string_get(value, ifp->descr, -1);
254f06ca4afSHartmut Brandt 		break;
255f06ca4afSHartmut Brandt 
256f06ca4afSHartmut Brandt 	  case LEAF_ifType:
257f06ca4afSHartmut Brandt 		value->v.integer = ifp->mib.ifmd_data.ifi_type;
258f06ca4afSHartmut Brandt 		break;
259f06ca4afSHartmut Brandt 
260f06ca4afSHartmut Brandt 	  case LEAF_ifMtu:
261f06ca4afSHartmut Brandt 		value->v.integer = ifp->mib.ifmd_data.ifi_mtu;
262f06ca4afSHartmut Brandt 		break;
263f06ca4afSHartmut Brandt 
264f06ca4afSHartmut Brandt 	  case LEAF_ifSpeed:
265f06ca4afSHartmut Brandt 		value->v.integer = ifp->mib.ifmd_data.ifi_baudrate;
266f06ca4afSHartmut Brandt 		break;
267f06ca4afSHartmut Brandt 
268f06ca4afSHartmut Brandt 	  case LEAF_ifPhysAddress:
269f06ca4afSHartmut Brandt 		ret = string_get(value, ifp->physaddr,
270f06ca4afSHartmut Brandt 		    ifp->physaddrlen);
271f06ca4afSHartmut Brandt 		break;
272f06ca4afSHartmut Brandt 
273f06ca4afSHartmut Brandt 	  case LEAF_ifAdminStatus:
274f06ca4afSHartmut Brandt 		value->v.integer =
275f06ca4afSHartmut Brandt 		    (ifp->mib.ifmd_flags & IFF_UP) ? 1 : 2;
276f06ca4afSHartmut Brandt 		break;
277f06ca4afSHartmut Brandt 
278f06ca4afSHartmut Brandt 	  case LEAF_ifOperStatus:
279f06ca4afSHartmut Brandt 		value->v.integer =
280f06ca4afSHartmut Brandt 		    (ifp->mib.ifmd_flags & IFF_RUNNING) ? 1 : 2;
281f06ca4afSHartmut Brandt 		break;
282f06ca4afSHartmut Brandt 
283f06ca4afSHartmut Brandt 	  case LEAF_ifLastChange:
284f06ca4afSHartmut Brandt 		value->v.uint32 =
285f06ca4afSHartmut Brandt 		    ticks_get_timeval(&ifp->mib.ifmd_data.ifi_lastchange);
286f06ca4afSHartmut Brandt 		break;
287f06ca4afSHartmut Brandt 
288f06ca4afSHartmut Brandt 	  case LEAF_ifInOctets:
289f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_ibytes;
290f06ca4afSHartmut Brandt 		break;
291f06ca4afSHartmut Brandt 
292f06ca4afSHartmut Brandt 	  case LEAF_ifInUcastPkts:
293f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_ipackets -
294f06ca4afSHartmut Brandt 		    ifp->mib.ifmd_data.ifi_imcasts;
295f06ca4afSHartmut Brandt 		break;
296f06ca4afSHartmut Brandt 
297f06ca4afSHartmut Brandt 	  case LEAF_ifInNUcastPkts:
298f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
299f06ca4afSHartmut Brandt 		break;
300f06ca4afSHartmut Brandt 
301f06ca4afSHartmut Brandt 	  case LEAF_ifInDiscards:
302f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_iqdrops;
303f06ca4afSHartmut Brandt 		break;
304f06ca4afSHartmut Brandt 
305f06ca4afSHartmut Brandt 	  case LEAF_ifInErrors:
306f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_ierrors;
307f06ca4afSHartmut Brandt 		break;
308f06ca4afSHartmut Brandt 
309f06ca4afSHartmut Brandt 	  case LEAF_ifInUnknownProtos:
310f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_noproto;
311f06ca4afSHartmut Brandt 		break;
312f06ca4afSHartmut Brandt 
313f06ca4afSHartmut Brandt 	  case LEAF_ifOutOctets:
314f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_obytes;
315f06ca4afSHartmut Brandt 		break;
316f06ca4afSHartmut Brandt 
317f06ca4afSHartmut Brandt 	  case LEAF_ifOutUcastPkts:
318f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_opackets -
319f06ca4afSHartmut Brandt 		    ifp->mib.ifmd_data.ifi_omcasts;
320f06ca4afSHartmut Brandt 		break;
321f06ca4afSHartmut Brandt 
322f06ca4afSHartmut Brandt 	  case LEAF_ifOutNUcastPkts:
323f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
324f06ca4afSHartmut Brandt 		break;
325f06ca4afSHartmut Brandt 
326f06ca4afSHartmut Brandt 	  case LEAF_ifOutDiscards:
327f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_snd_drops;
328f06ca4afSHartmut Brandt 		break;
329f06ca4afSHartmut Brandt 
330f06ca4afSHartmut Brandt 	  case LEAF_ifOutErrors:
331f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_oerrors;
332f06ca4afSHartmut Brandt 		break;
333f06ca4afSHartmut Brandt 
334f06ca4afSHartmut Brandt 	  case LEAF_ifOutQLen:
335f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_snd_len;
336f06ca4afSHartmut Brandt 		break;
337f06ca4afSHartmut Brandt 
338f06ca4afSHartmut Brandt 	  case LEAF_ifSpecific:
339f06ca4afSHartmut Brandt 		value->v.oid = oid_zeroDotZero;
340f06ca4afSHartmut Brandt 		break;
341f06ca4afSHartmut Brandt 	}
342f06ca4afSHartmut Brandt 	return (SNMP_ERR_NOERROR);
343f06ca4afSHartmut Brandt }
344f06ca4afSHartmut Brandt 
345f06ca4afSHartmut Brandt /*
346f06ca4afSHartmut Brandt  * IfXtable entry
347f06ca4afSHartmut Brandt  */
348f06ca4afSHartmut Brandt int
349f06ca4afSHartmut Brandt op_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
350f06ca4afSHartmut Brandt     u_int sub, u_int iidx __unused, enum snmp_op op)
351f06ca4afSHartmut Brandt {
352f06ca4afSHartmut Brandt 	struct mibif *ifp = NULL;
353f06ca4afSHartmut Brandt 	int ret;
354f06ca4afSHartmut Brandt 	struct ifchange *ifc;
355f06ca4afSHartmut Brandt 	struct asn_oid idx;
356f06ca4afSHartmut Brandt 
357f06ca4afSHartmut Brandt 	switch (op) {
358f06ca4afSHartmut Brandt 
359f06ca4afSHartmut Brandt   again:
360f06ca4afSHartmut Brandt 		if (op != SNMP_OP_GETNEXT)
361f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
362f06ca4afSHartmut Brandt 		/* FALLTHROUGH */
363f06ca4afSHartmut Brandt 
364f06ca4afSHartmut Brandt 	  case SNMP_OP_GETNEXT:
365f06ca4afSHartmut Brandt 		if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
366f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
367f06ca4afSHartmut Brandt 		value->var.len = sub + 1;
368f06ca4afSHartmut Brandt 		value->var.subs[sub] = ifp->index;
369f06ca4afSHartmut Brandt 		break;
370f06ca4afSHartmut Brandt 
371f06ca4afSHartmut Brandt 	  case SNMP_OP_GET:
372f06ca4afSHartmut Brandt 		if (value->var.len - sub != 1)
373f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
374f06ca4afSHartmut Brandt 		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
375f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOSUCHNAME);
376f06ca4afSHartmut Brandt 		break;
377f06ca4afSHartmut Brandt 
378f06ca4afSHartmut Brandt 	  case SNMP_OP_SET:
379f06ca4afSHartmut Brandt 		if (value->var.len - sub != 1)
380f06ca4afSHartmut Brandt 			return (SNMP_ERR_NO_CREATION);
381f06ca4afSHartmut Brandt 		if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
382f06ca4afSHartmut Brandt 			return (SNMP_ERR_NO_CREATION);
383f06ca4afSHartmut Brandt 
384f06ca4afSHartmut Brandt 		idx.len = 1;
385f06ca4afSHartmut Brandt 		idx.subs[0] = ifp->index;
386f06ca4afSHartmut Brandt 
387f06ca4afSHartmut Brandt 		if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
388f06ca4afSHartmut Brandt 		    &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
389f06ca4afSHartmut Brandt 			return (SNMP_ERR_RES_UNAVAIL);
390f06ca4afSHartmut Brandt 		ifc->ifindex = ifp->index;
391f06ca4afSHartmut Brandt 
392f06ca4afSHartmut Brandt 		switch (value->var.subs[sub - 1]) {
393f06ca4afSHartmut Brandt 
394f06ca4afSHartmut Brandt 		  case LEAF_ifLinkUpDownTrapEnable:
395f06ca4afSHartmut Brandt 			if (value->v.integer != 1 && value->v.integer != 2)
396f06ca4afSHartmut Brandt 				return (SNMP_ERR_WRONG_VALUE);
397f06ca4afSHartmut Brandt 			if (ifc->set & IFC_TRAPS)
398f06ca4afSHartmut Brandt 				return (SNMP_ERR_INCONS_VALUE);
399f06ca4afSHartmut Brandt 			ifc->set |= IFC_TRAPS;
400f06ca4afSHartmut Brandt 			ifc->traps = (value->v.integer == 1) ? 1 : 0;
401f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOERROR);
402f06ca4afSHartmut Brandt 
403f06ca4afSHartmut Brandt 		  case LEAF_ifPromiscuousMode:
404f06ca4afSHartmut Brandt 			if (value->v.integer != 1 && value->v.integer != 2)
405f06ca4afSHartmut Brandt 				return (SNMP_ERR_WRONG_VALUE);
406f06ca4afSHartmut Brandt 			if (ifc->set & IFC_PROMISC)
407f06ca4afSHartmut Brandt 				return (SNMP_ERR_INCONS_VALUE);
408f06ca4afSHartmut Brandt 			ifc->set |= IFC_PROMISC;
409f06ca4afSHartmut Brandt 			ifc->promisc = (value->v.integer == 1) ? 1 : 0;
410f06ca4afSHartmut Brandt 			return (SNMP_ERR_NOERROR);
411f06ca4afSHartmut Brandt 		}
412f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOT_WRITEABLE);
413f06ca4afSHartmut Brandt 
414f06ca4afSHartmut Brandt 	  case SNMP_OP_ROLLBACK:
415f06ca4afSHartmut Brandt 	  case SNMP_OP_COMMIT:
416f06ca4afSHartmut Brandt 		return (SNMP_ERR_NOERROR);
417f06ca4afSHartmut Brandt 	}
418f06ca4afSHartmut Brandt 
419f06ca4afSHartmut Brandt 	if (ifp->mibtick < this_tick)
420f06ca4afSHartmut Brandt 		(void)mib_fetch_ifmib(ifp);
421f06ca4afSHartmut Brandt 
422f06ca4afSHartmut Brandt 	ret = SNMP_ERR_NOERROR;
423f06ca4afSHartmut Brandt 	switch (value->var.subs[sub - 1]) {
424f06ca4afSHartmut Brandt 
425f06ca4afSHartmut Brandt 	  case LEAF_ifName:
426f06ca4afSHartmut Brandt 		ret = string_get(value, ifp->name, -1);
427f06ca4afSHartmut Brandt 		break;
428f06ca4afSHartmut Brandt 
429f06ca4afSHartmut Brandt 	  case LEAF_ifInMulticastPkts:
430f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
431f06ca4afSHartmut Brandt 		break;
432f06ca4afSHartmut Brandt 
433f06ca4afSHartmut Brandt 	  case LEAF_ifInBroadcastPkts:
434f06ca4afSHartmut Brandt 		value->v.uint32 = 0;
435f06ca4afSHartmut Brandt 		break;
436f06ca4afSHartmut Brandt 
437f06ca4afSHartmut Brandt 	  case LEAF_ifOutMulticastPkts:
438f06ca4afSHartmut Brandt 		value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
439f06ca4afSHartmut Brandt 		break;
440f06ca4afSHartmut Brandt 
441f06ca4afSHartmut Brandt 	  case LEAF_ifOutBroadcastPkts:
442f06ca4afSHartmut Brandt 		value->v.uint32 = 0;
443f06ca4afSHartmut Brandt 		break;
444f06ca4afSHartmut Brandt 
445f06ca4afSHartmut Brandt 	  case LEAF_ifHCInOctets:
446f06ca4afSHartmut Brandt 		if (!(ifp->flags & MIBIF_HIGHSPEED))
447f06ca4afSHartmut Brandt 			goto again;
448f06ca4afSHartmut Brandt 		value->v.counter64 = ifp->hc_inoctets;
449f06ca4afSHartmut Brandt 		break;
450f06ca4afSHartmut Brandt 
451f06ca4afSHartmut Brandt 	  case LEAF_ifHCInUcastPkts:
452f06ca4afSHartmut Brandt 		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
453f06ca4afSHartmut Brandt 			goto again;
454f06ca4afSHartmut Brandt 		value->v.counter64 = ifp->hc_ipackets - ifp->hc_imcasts;
455f06ca4afSHartmut Brandt 		break;
456f06ca4afSHartmut Brandt 
457f06ca4afSHartmut Brandt 	  case LEAF_ifHCInMulticastPkts:
458f06ca4afSHartmut Brandt 		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
459f06ca4afSHartmut Brandt 			goto again;
460f06ca4afSHartmut Brandt 		value->v.counter64 = ifp->hc_imcasts;
461f06ca4afSHartmut Brandt 		break;
462f06ca4afSHartmut Brandt 
463f06ca4afSHartmut Brandt 	  case LEAF_ifHCInBroadcastPkts:
464f06ca4afSHartmut Brandt 		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
465f06ca4afSHartmut Brandt 			goto again;
466f06ca4afSHartmut Brandt 		value->v.counter64 = 0;
467f06ca4afSHartmut Brandt 		break;
468f06ca4afSHartmut Brandt 
469f06ca4afSHartmut Brandt 	  case LEAF_ifHCOutOctets:
470f06ca4afSHartmut Brandt 		if (!(ifp->flags & MIBIF_HIGHSPEED))
471f06ca4afSHartmut Brandt 			goto again;
4728eecd77aSHartmut Brandt 		value->v.counter64 = ifp->hc_outoctets;
473f06ca4afSHartmut Brandt 		break;
474f06ca4afSHartmut Brandt 
475f06ca4afSHartmut Brandt 	  case LEAF_ifHCOutUcastPkts:
476f06ca4afSHartmut Brandt 		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
477f06ca4afSHartmut Brandt 			goto again;
478f06ca4afSHartmut Brandt 		value->v.counter64 = ifp->hc_opackets - ifp->hc_omcasts;
479f06ca4afSHartmut Brandt 		break;
480f06ca4afSHartmut Brandt 
481f06ca4afSHartmut Brandt 	  case LEAF_ifHCOutMulticastPkts:
482f06ca4afSHartmut Brandt 		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
483f06ca4afSHartmut Brandt 			goto again;
484f06ca4afSHartmut Brandt 		value->v.counter64 = ifp->hc_omcasts;
485f06ca4afSHartmut Brandt 		break;
486f06ca4afSHartmut Brandt 
487f06ca4afSHartmut Brandt 	  case LEAF_ifHCOutBroadcastPkts:
488f06ca4afSHartmut Brandt 		if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
489f06ca4afSHartmut Brandt 			goto again;
490f06ca4afSHartmut Brandt 		value->v.counter64 = 0;
491f06ca4afSHartmut Brandt 		break;
492f06ca4afSHartmut Brandt 
493f06ca4afSHartmut Brandt 	  case LEAF_ifLinkUpDownTrapEnable:
494f06ca4afSHartmut Brandt 		value->v.integer = ifp->trap_enable ? 1 : 2;
495f06ca4afSHartmut Brandt 		break;
496f06ca4afSHartmut Brandt 
497f06ca4afSHartmut Brandt 	  case LEAF_ifHighSpeed:
498f06ca4afSHartmut Brandt 		value->v.integer =
499f06ca4afSHartmut Brandt 		    (ifp->mib.ifmd_data.ifi_baudrate + 499999) / 1000000;
500f06ca4afSHartmut Brandt 		break;
501f06ca4afSHartmut Brandt 
502f06ca4afSHartmut Brandt 	  case LEAF_ifPromiscuousMode:
503f06ca4afSHartmut Brandt 		value->v.integer =
504f06ca4afSHartmut Brandt 		    (ifp->mib.ifmd_flags & IFF_PROMISC) ? 1 : 2;
505f06ca4afSHartmut Brandt 		break;
506f06ca4afSHartmut Brandt 
507f06ca4afSHartmut Brandt 	  case LEAF_ifConnectorPresent:
508f06ca4afSHartmut Brandt 		value->v.integer = ifp->has_connector ? 1 : 2;
509f06ca4afSHartmut Brandt 		break;
510f06ca4afSHartmut Brandt 
511f06ca4afSHartmut Brandt 	  case LEAF_ifAlias:
512f06ca4afSHartmut Brandt 		ret = string_get(value, "", -1);
513f06ca4afSHartmut Brandt 		break;
514f06ca4afSHartmut Brandt 
515f06ca4afSHartmut Brandt 	  case LEAF_ifCounterDiscontinuityTime:
516f06ca4afSHartmut Brandt 		if (ifp->counter_disc > start_tick)
517f06ca4afSHartmut Brandt 			value->v.uint32 = ifp->counter_disc - start_tick;
518f06ca4afSHartmut Brandt 		else
519f06ca4afSHartmut Brandt 			value->v.uint32 = 0;
520f06ca4afSHartmut Brandt 		break;
521f06ca4afSHartmut Brandt 	}
522f06ca4afSHartmut Brandt 	return (ret);
523f06ca4afSHartmut Brandt }
524