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 * 29748b5b1eSHartmut Brandt * $Begemot: bsnmp/snmp_mibII/mibII_interfaces.c,v 1.17 2006/02/14 09:04:19 brandt_h 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 13869292cedSHartmut Brandt /* 13969292cedSHartmut Brandt * Return difference to daemon start time in ticks truncated to a 14069292cedSHartmut Brandt * 32-bit value. If the timeval is 0 then return 0. 14169292cedSHartmut Brandt */ 142896052c1SHartmut Brandt static uint32_t 143f06ca4afSHartmut Brandt ticks_get_timeval(struct timeval *tv) 144f06ca4afSHartmut Brandt { 14569292cedSHartmut Brandt uint64_t v; 146f06ca4afSHartmut Brandt 147f06ca4afSHartmut Brandt if (tv->tv_sec != 0 || tv->tv_usec != 0) { 14869292cedSHartmut Brandt v = 100ULL * tv->tv_sec + tv->tv_usec / 10000ULL; 149f06ca4afSHartmut Brandt if (v > start_tick) 150f06ca4afSHartmut Brandt return (v - start_tick); 151f06ca4afSHartmut Brandt } 152f06ca4afSHartmut Brandt return (0); 153f06ca4afSHartmut Brandt } 154f06ca4afSHartmut Brandt 155f06ca4afSHartmut Brandt /* 156f06ca4afSHartmut Brandt * Scalars 157f06ca4afSHartmut Brandt */ 158f06ca4afSHartmut Brandt int 159f06ca4afSHartmut Brandt op_interfaces(struct snmp_context *ctx __unused, struct snmp_value *value, 160f06ca4afSHartmut Brandt u_int sub, u_int idx __unused, enum snmp_op op) 161f06ca4afSHartmut Brandt { 162f06ca4afSHartmut Brandt switch (op) { 163f06ca4afSHartmut Brandt 164f06ca4afSHartmut Brandt case SNMP_OP_GETNEXT: 165f06ca4afSHartmut Brandt abort(); 166f06ca4afSHartmut Brandt 167f06ca4afSHartmut Brandt case SNMP_OP_GET: 168f06ca4afSHartmut Brandt break; 169f06ca4afSHartmut Brandt 170f06ca4afSHartmut Brandt case SNMP_OP_SET: 171f06ca4afSHartmut Brandt return (SNMP_ERR_NOT_WRITEABLE); 172f06ca4afSHartmut Brandt 173f06ca4afSHartmut Brandt case SNMP_OP_ROLLBACK: 174f06ca4afSHartmut Brandt case SNMP_OP_COMMIT: 175f06ca4afSHartmut Brandt abort(); 176f06ca4afSHartmut Brandt } 177f06ca4afSHartmut Brandt 178f06ca4afSHartmut Brandt switch (value->var.subs[sub - 1]) { 179f06ca4afSHartmut Brandt 180f06ca4afSHartmut Brandt case LEAF_ifNumber: 181f06ca4afSHartmut Brandt value->v.integer = mib_if_number; 182f06ca4afSHartmut Brandt break; 183f06ca4afSHartmut Brandt } 184f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 185f06ca4afSHartmut Brandt } 186f06ca4afSHartmut Brandt 187f06ca4afSHartmut Brandt /* 188f06ca4afSHartmut Brandt * Iftable entry 189f06ca4afSHartmut Brandt */ 190f06ca4afSHartmut Brandt int 191f06ca4afSHartmut Brandt op_ifentry(struct snmp_context *ctx, struct snmp_value *value, 192f06ca4afSHartmut Brandt u_int sub, u_int iidx __unused, enum snmp_op op) 193f06ca4afSHartmut Brandt { 194f06ca4afSHartmut Brandt struct mibif *ifp = NULL; 195f06ca4afSHartmut Brandt int ret; 196f06ca4afSHartmut Brandt struct ifchange *ifc; 197f06ca4afSHartmut Brandt struct asn_oid idx; 198f06ca4afSHartmut Brandt 199f06ca4afSHartmut Brandt switch (op) { 200f06ca4afSHartmut Brandt 201f06ca4afSHartmut Brandt case SNMP_OP_GETNEXT: 202f06ca4afSHartmut Brandt if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL) 203f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 204f06ca4afSHartmut Brandt value->var.len = sub + 1; 205f06ca4afSHartmut Brandt value->var.subs[sub] = ifp->index; 206f06ca4afSHartmut Brandt break; 207f06ca4afSHartmut Brandt 208f06ca4afSHartmut Brandt case SNMP_OP_GET: 209f06ca4afSHartmut Brandt if (value->var.len - sub != 1) 210f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 211f06ca4afSHartmut Brandt if ((ifp = mib_find_if(value->var.subs[sub])) == NULL) 212f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 213f06ca4afSHartmut Brandt break; 214f06ca4afSHartmut Brandt 215f06ca4afSHartmut Brandt case SNMP_OP_SET: 216f06ca4afSHartmut Brandt if (value->var.len - sub != 1) 217f06ca4afSHartmut Brandt return (SNMP_ERR_NO_CREATION); 218f06ca4afSHartmut Brandt if ((ifp = mib_find_if(value->var.subs[sub])) == NULL) 219f06ca4afSHartmut Brandt return (SNMP_ERR_NO_CREATION); 220f06ca4afSHartmut Brandt if (value->var.subs[sub - 1] != LEAF_ifAdminStatus) 221f06ca4afSHartmut Brandt return (SNMP_ERR_NOT_WRITEABLE); 222f06ca4afSHartmut Brandt 223f06ca4afSHartmut Brandt idx.len = 1; 224f06ca4afSHartmut Brandt idx.subs[0] = ifp->index; 225f06ca4afSHartmut Brandt 226f06ca4afSHartmut Brandt if (value->v.integer != 1 && value->v.integer != 2) 227f06ca4afSHartmut Brandt return (SNMP_ERR_WRONG_VALUE); 228f06ca4afSHartmut Brandt 229f06ca4afSHartmut Brandt if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx, 230f06ca4afSHartmut Brandt &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL) 231f06ca4afSHartmut Brandt return (SNMP_ERR_RES_UNAVAIL); 232f06ca4afSHartmut Brandt ifc->ifindex = ifp->index; 233f06ca4afSHartmut Brandt 234f06ca4afSHartmut Brandt if (ifc->set & IFC_ADMIN) 235f06ca4afSHartmut Brandt return (SNMP_ERR_INCONS_VALUE); 236f06ca4afSHartmut Brandt ifc->set |= IFC_ADMIN; 237f06ca4afSHartmut Brandt ifc->admin = (value->v.integer == 1) ? 1 : 0; 238f06ca4afSHartmut Brandt 239f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 240f06ca4afSHartmut Brandt 241f06ca4afSHartmut Brandt case SNMP_OP_ROLLBACK: 242f06ca4afSHartmut Brandt case SNMP_OP_COMMIT: 243f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 244f06ca4afSHartmut Brandt } 245f06ca4afSHartmut Brandt 246f06ca4afSHartmut Brandt if (ifp->mibtick < this_tick) 247f06ca4afSHartmut Brandt (void)mib_fetch_ifmib(ifp); 248f06ca4afSHartmut Brandt 249f06ca4afSHartmut Brandt ret = SNMP_ERR_NOERROR; 250f06ca4afSHartmut Brandt switch (value->var.subs[sub - 1]) { 251f06ca4afSHartmut Brandt 252f06ca4afSHartmut Brandt case LEAF_ifIndex: 253f06ca4afSHartmut Brandt value->v.integer = ifp->index; 254f06ca4afSHartmut Brandt break; 255f06ca4afSHartmut Brandt 256f06ca4afSHartmut Brandt case LEAF_ifDescr: 257f06ca4afSHartmut Brandt ret = string_get(value, ifp->descr, -1); 258f06ca4afSHartmut Brandt break; 259f06ca4afSHartmut Brandt 260f06ca4afSHartmut Brandt case LEAF_ifType: 261f06ca4afSHartmut Brandt value->v.integer = ifp->mib.ifmd_data.ifi_type; 262f06ca4afSHartmut Brandt break; 263f06ca4afSHartmut Brandt 264f06ca4afSHartmut Brandt case LEAF_ifMtu: 265f06ca4afSHartmut Brandt value->v.integer = ifp->mib.ifmd_data.ifi_mtu; 266f06ca4afSHartmut Brandt break; 267f06ca4afSHartmut Brandt 268f06ca4afSHartmut Brandt case LEAF_ifSpeed: 269f06ca4afSHartmut Brandt value->v.integer = ifp->mib.ifmd_data.ifi_baudrate; 270f06ca4afSHartmut Brandt break; 271f06ca4afSHartmut Brandt 272f06ca4afSHartmut Brandt case LEAF_ifPhysAddress: 273f06ca4afSHartmut Brandt ret = string_get(value, ifp->physaddr, 274f06ca4afSHartmut Brandt ifp->physaddrlen); 275f06ca4afSHartmut Brandt break; 276f06ca4afSHartmut Brandt 277f06ca4afSHartmut Brandt case LEAF_ifAdminStatus: 278f06ca4afSHartmut Brandt value->v.integer = 279f06ca4afSHartmut Brandt (ifp->mib.ifmd_flags & IFF_UP) ? 1 : 2; 280f06ca4afSHartmut Brandt break; 281f06ca4afSHartmut Brandt 282f06ca4afSHartmut Brandt case LEAF_ifOperStatus: 283361b40a3SHartmut Brandt /* 284361b40a3SHartmut Brandt * According to RFC 2863 the state should be Up if the 285361b40a3SHartmut Brandt * interface is ready to transmit packets. We takes this to 286361b40a3SHartmut Brandt * mean that the interface should be running and should have 287361b40a3SHartmut Brandt * a carrier. If it is running and has no carrier we interpret 288361b40a3SHartmut Brandt * this as 'waiting for an external event' (plugging in the 289361b40a3SHartmut Brandt * cable) and hence return 'dormant'. 290361b40a3SHartmut Brandt */ 291361b40a3SHartmut Brandt if (ifp->mib.ifmd_flags & IFF_RUNNING) { 292361b40a3SHartmut Brandt if (ifp->mib.ifmd_data.ifi_link_state == 293361b40a3SHartmut Brandt LINK_STATE_DOWN) 294361b40a3SHartmut Brandt value->v.integer = 5; /* state dormant */ 295361b40a3SHartmut Brandt else 296361b40a3SHartmut Brandt value->v.integer = 1; /* state up */ 297361b40a3SHartmut Brandt } else 298361b40a3SHartmut Brandt value->v.integer = 2; /* state down */ 299f06ca4afSHartmut Brandt break; 300f06ca4afSHartmut Brandt 301f06ca4afSHartmut Brandt case LEAF_ifLastChange: 302f06ca4afSHartmut Brandt value->v.uint32 = 303f06ca4afSHartmut Brandt ticks_get_timeval(&ifp->mib.ifmd_data.ifi_lastchange); 304f06ca4afSHartmut Brandt break; 305f06ca4afSHartmut Brandt 306f06ca4afSHartmut Brandt case LEAF_ifInOctets: 307f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_ibytes; 308f06ca4afSHartmut Brandt break; 309f06ca4afSHartmut Brandt 310f06ca4afSHartmut Brandt case LEAF_ifInUcastPkts: 311f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_ipackets - 312f06ca4afSHartmut Brandt ifp->mib.ifmd_data.ifi_imcasts; 313f06ca4afSHartmut Brandt break; 314f06ca4afSHartmut Brandt 315f06ca4afSHartmut Brandt case LEAF_ifInNUcastPkts: 316f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts; 317f06ca4afSHartmut Brandt break; 318f06ca4afSHartmut Brandt 319f06ca4afSHartmut Brandt case LEAF_ifInDiscards: 320f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_iqdrops; 321f06ca4afSHartmut Brandt break; 322f06ca4afSHartmut Brandt 323f06ca4afSHartmut Brandt case LEAF_ifInErrors: 324f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_ierrors; 325f06ca4afSHartmut Brandt break; 326f06ca4afSHartmut Brandt 327f06ca4afSHartmut Brandt case LEAF_ifInUnknownProtos: 328f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_noproto; 329f06ca4afSHartmut Brandt break; 330f06ca4afSHartmut Brandt 331f06ca4afSHartmut Brandt case LEAF_ifOutOctets: 332f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_obytes; 333f06ca4afSHartmut Brandt break; 334f06ca4afSHartmut Brandt 335f06ca4afSHartmut Brandt case LEAF_ifOutUcastPkts: 336f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_opackets - 337f06ca4afSHartmut Brandt ifp->mib.ifmd_data.ifi_omcasts; 338f06ca4afSHartmut Brandt break; 339f06ca4afSHartmut Brandt 340f06ca4afSHartmut Brandt case LEAF_ifOutNUcastPkts: 341f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts; 342f06ca4afSHartmut Brandt break; 343f06ca4afSHartmut Brandt 344f06ca4afSHartmut Brandt case LEAF_ifOutDiscards: 345f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_snd_drops; 346f06ca4afSHartmut Brandt break; 347f06ca4afSHartmut Brandt 348f06ca4afSHartmut Brandt case LEAF_ifOutErrors: 349f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_oerrors; 350f06ca4afSHartmut Brandt break; 351f06ca4afSHartmut Brandt 352f06ca4afSHartmut Brandt case LEAF_ifOutQLen: 353f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_snd_len; 354f06ca4afSHartmut Brandt break; 355f06ca4afSHartmut Brandt 356f06ca4afSHartmut Brandt case LEAF_ifSpecific: 35794caccb3SHartmut Brandt value->v.oid = ifp->spec_oid; 358f06ca4afSHartmut Brandt break; 359f06ca4afSHartmut Brandt } 360f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 361f06ca4afSHartmut Brandt } 362f06ca4afSHartmut Brandt 363f06ca4afSHartmut Brandt /* 364f06ca4afSHartmut Brandt * IfXtable entry 365f06ca4afSHartmut Brandt */ 366f06ca4afSHartmut Brandt int 367f06ca4afSHartmut Brandt op_ifxtable(struct snmp_context *ctx, struct snmp_value *value, 368f06ca4afSHartmut Brandt u_int sub, u_int iidx __unused, enum snmp_op op) 369f06ca4afSHartmut Brandt { 370f06ca4afSHartmut Brandt struct mibif *ifp = NULL; 371f06ca4afSHartmut Brandt int ret; 372f06ca4afSHartmut Brandt struct ifchange *ifc; 373f06ca4afSHartmut Brandt struct asn_oid idx; 374f06ca4afSHartmut Brandt 375f06ca4afSHartmut Brandt switch (op) { 376f06ca4afSHartmut Brandt 377f06ca4afSHartmut Brandt again: 378f06ca4afSHartmut Brandt if (op != SNMP_OP_GETNEXT) 379f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 380f06ca4afSHartmut Brandt /* FALLTHROUGH */ 381f06ca4afSHartmut Brandt 382f06ca4afSHartmut Brandt case SNMP_OP_GETNEXT: 383f06ca4afSHartmut Brandt if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL) 384f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 385f06ca4afSHartmut Brandt value->var.len = sub + 1; 386f06ca4afSHartmut Brandt value->var.subs[sub] = ifp->index; 387f06ca4afSHartmut Brandt break; 388f06ca4afSHartmut Brandt 389f06ca4afSHartmut Brandt case SNMP_OP_GET: 390f06ca4afSHartmut Brandt if (value->var.len - sub != 1) 391f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 392f06ca4afSHartmut Brandt if ((ifp = mib_find_if(value->var.subs[sub])) == NULL) 393f06ca4afSHartmut Brandt return (SNMP_ERR_NOSUCHNAME); 394f06ca4afSHartmut Brandt break; 395f06ca4afSHartmut Brandt 396f06ca4afSHartmut Brandt case SNMP_OP_SET: 397f06ca4afSHartmut Brandt if (value->var.len - sub != 1) 398f06ca4afSHartmut Brandt return (SNMP_ERR_NO_CREATION); 399f06ca4afSHartmut Brandt if ((ifp = mib_find_if(value->var.subs[sub])) == NULL) 400f06ca4afSHartmut Brandt return (SNMP_ERR_NO_CREATION); 401f06ca4afSHartmut Brandt 402f06ca4afSHartmut Brandt idx.len = 1; 403f06ca4afSHartmut Brandt idx.subs[0] = ifp->index; 404f06ca4afSHartmut Brandt 405f06ca4afSHartmut Brandt if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx, 406f06ca4afSHartmut Brandt &oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL) 407f06ca4afSHartmut Brandt return (SNMP_ERR_RES_UNAVAIL); 408f06ca4afSHartmut Brandt ifc->ifindex = ifp->index; 409f06ca4afSHartmut Brandt 410f06ca4afSHartmut Brandt switch (value->var.subs[sub - 1]) { 411f06ca4afSHartmut Brandt 412f06ca4afSHartmut Brandt case LEAF_ifLinkUpDownTrapEnable: 413f06ca4afSHartmut Brandt if (value->v.integer != 1 && value->v.integer != 2) 414f06ca4afSHartmut Brandt return (SNMP_ERR_WRONG_VALUE); 415f06ca4afSHartmut Brandt if (ifc->set & IFC_TRAPS) 416f06ca4afSHartmut Brandt return (SNMP_ERR_INCONS_VALUE); 417f06ca4afSHartmut Brandt ifc->set |= IFC_TRAPS; 418f06ca4afSHartmut Brandt ifc->traps = (value->v.integer == 1) ? 1 : 0; 419f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 420f06ca4afSHartmut Brandt 421f06ca4afSHartmut Brandt case LEAF_ifPromiscuousMode: 422f06ca4afSHartmut Brandt if (value->v.integer != 1 && value->v.integer != 2) 423f06ca4afSHartmut Brandt return (SNMP_ERR_WRONG_VALUE); 424f06ca4afSHartmut Brandt if (ifc->set & IFC_PROMISC) 425f06ca4afSHartmut Brandt return (SNMP_ERR_INCONS_VALUE); 426f06ca4afSHartmut Brandt ifc->set |= IFC_PROMISC; 427f06ca4afSHartmut Brandt ifc->promisc = (value->v.integer == 1) ? 1 : 0; 428f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 429f06ca4afSHartmut Brandt } 430f06ca4afSHartmut Brandt return (SNMP_ERR_NOT_WRITEABLE); 431f06ca4afSHartmut Brandt 432f06ca4afSHartmut Brandt case SNMP_OP_ROLLBACK: 433f06ca4afSHartmut Brandt case SNMP_OP_COMMIT: 434f06ca4afSHartmut Brandt return (SNMP_ERR_NOERROR); 435f06ca4afSHartmut Brandt } 436f06ca4afSHartmut Brandt 437f06ca4afSHartmut Brandt if (ifp->mibtick < this_tick) 438f06ca4afSHartmut Brandt (void)mib_fetch_ifmib(ifp); 439f06ca4afSHartmut Brandt 440f06ca4afSHartmut Brandt ret = SNMP_ERR_NOERROR; 441f06ca4afSHartmut Brandt switch (value->var.subs[sub - 1]) { 442f06ca4afSHartmut Brandt 443f06ca4afSHartmut Brandt case LEAF_ifName: 444f06ca4afSHartmut Brandt ret = string_get(value, ifp->name, -1); 445f06ca4afSHartmut Brandt break; 446f06ca4afSHartmut Brandt 447f06ca4afSHartmut Brandt case LEAF_ifInMulticastPkts: 448f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts; 449f06ca4afSHartmut Brandt break; 450f06ca4afSHartmut Brandt 451f06ca4afSHartmut Brandt case LEAF_ifInBroadcastPkts: 452f06ca4afSHartmut Brandt value->v.uint32 = 0; 453f06ca4afSHartmut Brandt break; 454f06ca4afSHartmut Brandt 455f06ca4afSHartmut Brandt case LEAF_ifOutMulticastPkts: 456f06ca4afSHartmut Brandt value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts; 457f06ca4afSHartmut Brandt break; 458f06ca4afSHartmut Brandt 459f06ca4afSHartmut Brandt case LEAF_ifOutBroadcastPkts: 460f06ca4afSHartmut Brandt value->v.uint32 = 0; 461f06ca4afSHartmut Brandt break; 462f06ca4afSHartmut Brandt 463f06ca4afSHartmut Brandt case LEAF_ifHCInOctets: 464f06ca4afSHartmut Brandt if (!(ifp->flags & MIBIF_HIGHSPEED)) 465f06ca4afSHartmut Brandt goto again; 466c6a4e658SHartmut Brandt value->v.counter64 = MIBIF_PRIV(ifp)->hc_inoctets; 467f06ca4afSHartmut Brandt break; 468f06ca4afSHartmut Brandt 469f06ca4afSHartmut Brandt case LEAF_ifHCInUcastPkts: 470f06ca4afSHartmut Brandt if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED))) 471f06ca4afSHartmut Brandt goto again; 472c6a4e658SHartmut Brandt value->v.counter64 = MIBIF_PRIV(ifp)->hc_ipackets - 473c6a4e658SHartmut Brandt MIBIF_PRIV(ifp)->hc_imcasts; 474f06ca4afSHartmut Brandt break; 475f06ca4afSHartmut Brandt 476f06ca4afSHartmut Brandt case LEAF_ifHCInMulticastPkts: 477f06ca4afSHartmut Brandt if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED))) 478f06ca4afSHartmut Brandt goto again; 479c6a4e658SHartmut Brandt value->v.counter64 = MIBIF_PRIV(ifp)->hc_imcasts; 480f06ca4afSHartmut Brandt break; 481f06ca4afSHartmut Brandt 482f06ca4afSHartmut Brandt case LEAF_ifHCInBroadcastPkts: 483f06ca4afSHartmut Brandt if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED))) 484f06ca4afSHartmut Brandt goto again; 485f06ca4afSHartmut Brandt value->v.counter64 = 0; 486f06ca4afSHartmut Brandt break; 487f06ca4afSHartmut Brandt 488f06ca4afSHartmut Brandt case LEAF_ifHCOutOctets: 489f06ca4afSHartmut Brandt if (!(ifp->flags & MIBIF_HIGHSPEED)) 490f06ca4afSHartmut Brandt goto again; 491c6a4e658SHartmut Brandt value->v.counter64 = MIBIF_PRIV(ifp)->hc_outoctets; 492f06ca4afSHartmut Brandt break; 493f06ca4afSHartmut Brandt 494f06ca4afSHartmut Brandt case LEAF_ifHCOutUcastPkts: 495f06ca4afSHartmut Brandt if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED))) 496f06ca4afSHartmut Brandt goto again; 497c6a4e658SHartmut Brandt value->v.counter64 = MIBIF_PRIV(ifp)->hc_opackets - 498c6a4e658SHartmut Brandt MIBIF_PRIV(ifp)->hc_omcasts; 499f06ca4afSHartmut Brandt break; 500f06ca4afSHartmut Brandt 501f06ca4afSHartmut Brandt case LEAF_ifHCOutMulticastPkts: 502f06ca4afSHartmut Brandt if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED))) 503f06ca4afSHartmut Brandt goto again; 504c6a4e658SHartmut Brandt value->v.counter64 = MIBIF_PRIV(ifp)->hc_omcasts; 505f06ca4afSHartmut Brandt break; 506f06ca4afSHartmut Brandt 507f06ca4afSHartmut Brandt case LEAF_ifHCOutBroadcastPkts: 508f06ca4afSHartmut Brandt if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED))) 509f06ca4afSHartmut Brandt goto again; 510f06ca4afSHartmut Brandt value->v.counter64 = 0; 511f06ca4afSHartmut Brandt break; 512f06ca4afSHartmut Brandt 513f06ca4afSHartmut Brandt case LEAF_ifLinkUpDownTrapEnable: 514f06ca4afSHartmut Brandt value->v.integer = ifp->trap_enable ? 1 : 2; 515f06ca4afSHartmut Brandt break; 516f06ca4afSHartmut Brandt 517f06ca4afSHartmut Brandt case LEAF_ifHighSpeed: 518f06ca4afSHartmut Brandt value->v.integer = 519f06ca4afSHartmut Brandt (ifp->mib.ifmd_data.ifi_baudrate + 499999) / 1000000; 520f06ca4afSHartmut Brandt break; 521f06ca4afSHartmut Brandt 522f06ca4afSHartmut Brandt case LEAF_ifPromiscuousMode: 523f06ca4afSHartmut Brandt value->v.integer = 524f06ca4afSHartmut Brandt (ifp->mib.ifmd_flags & IFF_PROMISC) ? 1 : 2; 525f06ca4afSHartmut Brandt break; 526f06ca4afSHartmut Brandt 527f06ca4afSHartmut Brandt case LEAF_ifConnectorPresent: 528f06ca4afSHartmut Brandt value->v.integer = ifp->has_connector ? 1 : 2; 529f06ca4afSHartmut Brandt break; 530f06ca4afSHartmut Brandt 531f06ca4afSHartmut Brandt case LEAF_ifAlias: 532f06ca4afSHartmut Brandt ret = string_get(value, "", -1); 533f06ca4afSHartmut Brandt break; 534f06ca4afSHartmut Brandt 535f06ca4afSHartmut Brandt case LEAF_ifCounterDiscontinuityTime: 536f06ca4afSHartmut Brandt if (ifp->counter_disc > start_tick) 537f06ca4afSHartmut Brandt value->v.uint32 = ifp->counter_disc - start_tick; 538f06ca4afSHartmut Brandt else 539f06ca4afSHartmut Brandt value->v.uint32 = 0; 540f06ca4afSHartmut Brandt break; 541f06ca4afSHartmut Brandt } 542f06ca4afSHartmut Brandt return (ret); 543f06ca4afSHartmut Brandt } 544