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