1133488Sharti/* 2133488Sharti * Copyright (c) 2001-2002 3133488Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4133488Sharti * All rights reserved. 5133488Sharti * Copyright (c) 2003-2004 6133488Sharti * Hartmut Brandt. 7133488Sharti * All rights reserved. 8133488Sharti * 9133488Sharti * Author: Hartmut Brandt <harti@freebsd.org> 10133488Sharti * 11133488Sharti * Redistribution and use in source and binary forms, with or without 12133488Sharti * modification, are permitted provided that the following conditions 13133488Sharti * are met: 14133488Sharti * 1. Redistributions of source code must retain the above copyright 15133488Sharti * notice, this list of conditions and the following disclaimer. 16133488Sharti * 2. Redistributions in binary form must reproduce the above copyright 17133488Sharti * notice, this list of conditions and the following disclaimer in the 18133488Sharti * documentation and/or other materials provided with the distribution. 19133488Sharti * 20133488Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21133488Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22133488Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23133488Sharti * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 24133488Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25133488Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26133488Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27133488Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28133488Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29133488Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30133488Sharti * SUCH DAMAGE. 31133488Sharti * 32146532Sharti * $Begemot: libunimsg/snmp_atm/snmp_atm.c,v 1.3 2005/05/23 11:46:46 brandt_h Exp $ 33133488Sharti * 34133488Sharti * SNMP module for ATM hardware interfaces. 35133488Sharti */ 36133488Sharti 37133488Sharti#include "atm.h" 38133488Sharti#include "atm_tree.h" 39133488Sharti#include "atm_oid.h" 40133488Sharti 41133488Sharti#include <sys/ioctl.h> 42133488Sharti 43133488Sharti#include <stdio.h> 44133488Sharti#include <stdlib.h> 45133488Sharti#include <string.h> 46133488Sharti#include <errno.h> 47133488Sharti#include <syslog.h> 48133488Sharti#include <net/if_types.h> 49133488Sharti#include <net/if_media.h> 50133488Sharti#include <net/if_atm.h> 51133488Sharti 52133488Shartistruct lmodule *module; 53133488Sharti 54133488Sharti/* list of all (known) ATM interfaces */ 55133488Shartistruct atmif_list atmif_list = TAILQ_HEAD_INITIALIZER(atmif_list); 56133488Sharti 57133488Sharti/* whether we are started or not */ 58133488Shartistatic int started; 59133488Sharti 60133488Sharti/* last time table was changed */ 61146532Shartistatic uint64_t last_change; 62133488Sharti 63133488Sharti/* for the registration */ 64133488Shartistatic const struct asn_oid oid_begemotAtm = OIDX_begemotAtm; 65133488Sharti 66133488Sharti/* the registration */ 67133488Shartistatic u_int reg_atm; 68133488Sharti 69133488Sharti/* 70133488Sharti * Find an ATM interface by name 71133488Sharti */ 72133488Shartistruct atmif * 73133488Shartiatm_find_if_name(const char *name) 74133488Sharti{ 75133488Sharti struct atmif_priv *aif; 76133488Sharti 77133488Sharti TAILQ_FOREACH(aif, &atmif_list, link) 78133488Sharti if (strcmp(aif->pub.ifp->name, name) == 0) 79133488Sharti return (&aif->pub); 80133488Sharti return (NULL); 81133488Sharti} 82133488Sharti 83133488Sharti/* 84133488Sharti * get the interface from the interface index 85133488Sharti */ 86133488Shartistruct atmif * 87133488Shartiatm_find_if(u_int ifindex) 88133488Sharti{ 89133488Sharti struct atmif_priv *aif; 90133488Sharti 91133488Sharti TAILQ_FOREACH(aif, &atmif_list, link) 92133488Sharti if (aif->index == ifindex) 93133488Sharti return (&aif->pub); 94133488Sharti return (NULL); 95133488Sharti} 96133488Sharti 97133488Sharti/* 98133488Sharti * Send notification to all listeners. 99133488Sharti */ 100133488Shartivoid 101133488Shartiatmif_send_notification(struct atmif_priv *aif, enum atmif_notify code, 102133488Sharti uintptr_t arg) 103133488Sharti{ 104133488Sharti struct atmif_reg *r0, *r1; 105133488Sharti 106133488Sharti r0 = TAILQ_FIRST(&aif->notify); 107133488Sharti while (r0 != NULL) { 108133488Sharti r1 = TAILQ_NEXT(r0, link); 109133488Sharti r0->func(&aif->pub, code, arg, r0->data); 110133488Sharti r0 = r1; 111133488Sharti } 112133488Sharti} 113133488Sharti 114133488Sharti/* 115133488Sharti * Destroy an interface 116133488Sharti */ 117133488Shartistatic void 118133488Shartiatmif_destroy(struct atmif_priv *aif) 119133488Sharti{ 120133488Sharti struct atmif_reg *r0; 121133488Sharti 122133488Sharti atmif_send_notification(aif, ATMIF_NOTIFY_DESTROY, 123133488Sharti (uintptr_t)0); 124133488Sharti 125133488Sharti atmif_sys_destroy(aif); 126133488Sharti 127133488Sharti if (aif->ifpreg != NULL) 128133488Sharti mibif_unnotify(aif->ifpreg); 129133488Sharti 130133488Sharti while ((r0 = TAILQ_FIRST(&aif->notify)) != NULL) { 131133488Sharti TAILQ_REMOVE(&aif->notify, r0, link); 132133488Sharti free(r0); 133133488Sharti } 134133488Sharti 135133488Sharti TAILQ_REMOVE(&atmif_list, aif, link); 136133488Sharti free(aif); 137133488Sharti 138133488Sharti last_change = this_tick; 139133488Sharti} 140133488Sharti 141133488Sharti/* 142133488Sharti * Function gets called from the MIB-II module for events on that interface 143133488Sharti */ 144133488Shartistatic void 145133488Shartiatmif_notify(struct mibif *ifp __unused, enum mibif_notify event, void *data) 146133488Sharti{ 147133488Sharti struct atmif_priv *aif = data; 148133488Sharti 149133488Sharti switch (event) { 150133488Sharti 151133488Sharti case MIBIF_NOTIFY_DESTROY: 152133488Sharti atmif_destroy(aif); 153133488Sharti break; 154133488Sharti } 155133488Sharti} 156133488Sharti 157133488Sharti/* 158133488Sharti * Check the carrier state of the interface 159133488Sharti */ 160133488Shartivoid 161133488Shartiatmif_check_carrier(struct atmif_priv *aif) 162133488Sharti{ 163133488Sharti struct ifmediareq ifmr; 164133488Sharti enum atmif_carrier_state ost = aif->pub.carrier; 165133488Sharti 166133488Sharti memset(&ifmr, 0, sizeof(ifmr)); 167133488Sharti strcpy(ifmr.ifm_name, aif->pub.ifp->name); 168133488Sharti 169133488Sharti if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) == -1) { 170133488Sharti aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 171133488Sharti return; 172133488Sharti } 173133488Sharti if (!ifmr.ifm_status & IFM_AVALID) { 174133488Sharti aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 175133488Sharti return; 176133488Sharti } 177133488Sharti if (ifmr.ifm_status & IFM_ACTIVE) 178133488Sharti aif->pub.carrier = ATMIF_CARRIER_ON; 179133488Sharti else 180133488Sharti aif->pub.carrier = ATMIF_CARRIER_OFF; 181133488Sharti 182133488Sharti if (ost != aif->pub.carrier) 183133488Sharti atmif_send_notification(aif, ATMIF_NOTIFY_CARRIER, 184133488Sharti (uintptr_t)ost); 185133488Sharti} 186133488Sharti 187133488Sharti/* 188133488Sharti * Retrieve the SUNI mode 189133488Sharti */ 190133488Shartistatic int 191133488Shartiatmif_get_mode(struct atmif_priv *aif) 192133488Sharti{ 193133488Sharti struct ifmediareq ifmr; 194133488Sharti 195133488Sharti memset(&ifmr, 0, sizeof(ifmr)); 196133488Sharti strcpy(ifmr.ifm_name, aif->pub.ifp->name); 197133488Sharti 198133488Sharti if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) < 0) { 199133488Sharti syslog(LOG_ERR, "SIOCGIFMEDIA: %m"); 200133488Sharti aif->pub.mode = ATMIF_SUNI_MODE_UNKNOWN; 201133488Sharti return (SNMP_ERR_GENERR); 202133488Sharti } 203133488Sharti if (ifmr.ifm_current & IFM_ATM_SDH) 204133488Sharti aif->pub.mode = ATMIF_SUNI_MODE_SDH; 205133488Sharti else 206133488Sharti aif->pub.mode = ATMIF_SUNI_MODE_SONET; 207133488Sharti 208133488Sharti return (SNMP_ERR_NOERROR); 209133488Sharti} 210133488Sharti 211133488Sharti/* 212133488Sharti * Change the SUNI mod 213133488Sharti */ 214133488Shartistatic int 215133488Shartiatmif_set_mode(struct atmif_priv *aif, int newmode) 216133488Sharti{ 217133488Sharti struct ifmediareq ifmr; 218133488Sharti struct ifreq ifr; 219133488Sharti 220133488Sharti memset(&ifmr, 0, sizeof(ifmr)); 221133488Sharti strcpy(ifmr.ifm_name, aif->pub.ifp->name); 222133488Sharti 223133488Sharti /* get current mode */ 224133488Sharti if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) < 0) { 225133488Sharti syslog(LOG_ERR, "SIOCGIFMEDIA: %m"); 226133488Sharti return (SNMP_ERR_GENERR); 227133488Sharti } 228133488Sharti 229133488Sharti memset(&ifr, 0, sizeof(ifr)); 230133488Sharti strcpy(ifr.ifr_name, aif->pub.ifp->name); 231133488Sharti 232133488Sharti ifr.ifr_media = ifmr.ifm_current; 233133488Sharti if (newmode == ATMIF_SUNI_MODE_SDH) 234133488Sharti ifr.ifr_media |= IFM_ATM_SDH; 235133488Sharti else 236133488Sharti ifr.ifr_media &= ~IFM_ATM_SDH; 237133488Sharti 238133488Sharti if (ioctl(mib_netsock, SIOCSIFMEDIA, &ifr) < 0) { 239133488Sharti syslog(LOG_ERR, "SIOCSIFMEDIA: %m"); 240133488Sharti return (SNMP_ERR_GENERR); 241133488Sharti } 242133488Sharti 243133488Sharti aif->pub.mode = newmode; 244133488Sharti return (SNMP_ERR_NOERROR); 245133488Sharti} 246133488Sharti 247133488Sharti/* 248133488Sharti * Attach to an ATM interface 249133488Sharti */ 250133488Shartistatic void 251133488Shartiattach_if(struct mibif *ifp) 252133488Sharti{ 253133488Sharti struct atmif_priv *aif; 254133488Sharti 255133488Sharti /* we should not know it */ 256133488Sharti TAILQ_FOREACH(aif, &atmif_list, link) 257133488Sharti if (aif->pub.ifp == ifp) { 258133488Sharti syslog(LOG_CRIT, "new ATM if already known '%s'", 259133488Sharti ifp->name); 260133488Sharti return; 261133488Sharti } 262133488Sharti 263133488Sharti /* 264133488Sharti * tap it 265133488Sharti */ 266133488Sharti if ((aif = malloc(sizeof(*aif))) == NULL) { 267133488Sharti syslog(LOG_ERR, "new atmif: %m"); 268133488Sharti return; 269133488Sharti } 270133488Sharti memset(aif, 0, sizeof(*aif)); 271133488Sharti 272133488Sharti aif->pub.ifp = ifp; 273133488Sharti aif->index = ifp->index; 274146532Sharti TAILQ_INIT(&aif->notify); 275133488Sharti 276133488Sharti if (atmif_sys_attach_if(aif)) { 277133488Sharti free(aif); 278133488Sharti return; 279133488Sharti } 280133488Sharti 281133488Sharti aif->ifpreg = mibif_notify(ifp, module, atmif_notify, aif); 282133488Sharti 283133488Sharti aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 284133488Sharti atmif_check_carrier(aif); 285133488Sharti (void)atmif_get_mode(aif); 286133488Sharti 287133488Sharti INSERT_OBJECT_INT(aif, &atmif_list); 288133488Sharti 289133488Sharti last_change = this_tick; 290133488Sharti 291133488Sharti return; 292133488Sharti} 293133488Sharti 294133488Sharti/* 295133488Sharti * Function gets called when a new interface is created. If this is an 296133488Sharti * ATM interface, hook in. Claim the interface in any case even when 297133488Sharti * the creation of our data structures fails. 298133488Sharti */ 299133488Shartistatic int 300133488Shartinew_if(struct mibif *ifp) 301133488Sharti{ 302133488Sharti if (!started || ifp->mib.ifmd_data.ifi_type != IFT_ATM || 303133488Sharti ifp->xnotify != NULL) 304133488Sharti return (0); 305133488Sharti 306133488Sharti attach_if(ifp); 307133488Sharti return (1); 308133488Sharti} 309133488Sharti 310133488Sharti/* 311133488Sharti * Start the module 312133488Sharti */ 313133488Shartistatic void 314133488Shartiatm_start(void) 315133488Sharti{ 316133488Sharti struct mibif *ifp; 317133488Sharti 318133488Sharti reg_atm = or_register(&oid_begemotAtm, 319133488Sharti "The Begemot MIB for ATM interfaces.", module); 320133488Sharti 321133488Sharti started = 1; 322133488Sharti for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp)) 323133488Sharti if (ifp->mib.ifmd_data.ifi_type == IFT_ATM && 324133488Sharti ifp->xnotify == NULL) 325133488Sharti attach_if(ifp); 326133488Sharti} 327133488Sharti 328133488Sharti/* 329133488Sharti * Called when modules is loaded 330133488Sharti */ 331133488Shartistatic int 332133488Shartiatm_init(struct lmodule *mod, int argc __unused, char *argv[] __unused) 333133488Sharti{ 334133488Sharti module = mod; 335133488Sharti 336133488Sharti /* register to get creation messages for ATM interfaces */ 337133488Sharti if (mib_register_newif(new_if, module)) { 338133488Sharti syslog(LOG_ERR, "cannot register newif function: %m"); 339133488Sharti return (-1); 340133488Sharti } 341133488Sharti 342133488Sharti return (0); 343133488Sharti} 344133488Sharti 345133488Sharti/* 346133488Sharti * Called when module gets unloaded - free all resources 347133488Sharti */ 348133488Shartistatic int 349133488Shartiatm_fini(void) 350133488Sharti{ 351133488Sharti struct atmif_priv *aif; 352133488Sharti 353133488Sharti while ((aif = TAILQ_FIRST(&atmif_list)) != NULL) 354133488Sharti atmif_destroy(aif); 355133488Sharti 356133488Sharti mib_unregister_newif(module); 357133488Sharti or_unregister(reg_atm); 358133488Sharti 359133488Sharti return (0); 360133488Sharti} 361133488Sharti 362133488Sharti/* 363133488Sharti * Other module unloaded/loaded 364133488Sharti */ 365133488Shartistatic void 366133488Shartiatm_loading(const struct lmodule *mod, int loading) 367133488Sharti{ 368133488Sharti struct atmif_priv *aif; 369133488Sharti struct atmif_reg *r0, *r1; 370133488Sharti 371133488Sharti if (!loading) { 372133488Sharti /* remove notifications for this module */ 373133488Sharti TAILQ_FOREACH(aif, &atmif_list, link) 374133488Sharti TAILQ_FOREACH_SAFE(r0, &aif->notify, link, r1) { 375133488Sharti if (r0->mod == mod) { 376133488Sharti TAILQ_REMOVE(&aif->notify, r0, link); 377133488Sharti free(r0); 378133488Sharti } 379133488Sharti } 380133488Sharti } 381133488Sharti} 382133488Sharti 383133488Sharticonst struct snmp_module config = { 384133488Sharti .comment = "This module implements a private MIB for ATM interfaces.", 385133488Sharti .init = atm_init, 386133488Sharti .fini = atm_fini, 387133488Sharti .start = atm_start, 388133488Sharti .tree = atm_ctree, 389133488Sharti .tree_size = atm_CTREE_SIZE, 390133488Sharti .loading = atm_loading 391133488Sharti}; 392133488Sharti 393133488Sharti/* 394133488Sharti * Get the interface point for a table access 395133488Sharti */ 396133488Shartiint 397133488Shartiatmif_get_aif(struct snmp_value *value, u_int sub, enum snmp_op op, 398133488Sharti struct atmif_priv **aifp) 399133488Sharti{ 400133488Sharti switch (op) { 401133488Sharti 402133488Sharti case SNMP_OP_GETNEXT: 403133488Sharti if ((*aifp = NEXT_OBJECT_INT(&atmif_list, 404133488Sharti &value->var, sub)) == NULL) 405133488Sharti return (SNMP_ERR_NOSUCHNAME); 406133488Sharti value->var.len = sub + 1; 407133488Sharti value->var.subs[sub] = (*aifp)->index; 408133488Sharti break; 409133488Sharti 410133488Sharti case SNMP_OP_GET: 411133488Sharti if ((*aifp = FIND_OBJECT_INT(&atmif_list, 412133488Sharti &value->var, sub)) == NULL) 413133488Sharti return (SNMP_ERR_NOSUCHNAME); 414133488Sharti break; 415133488Sharti 416133488Sharti case SNMP_OP_SET: 417133488Sharti if ((*aifp = FIND_OBJECT_INT(&atmif_list, 418133488Sharti &value->var, sub)) == NULL) 419133488Sharti return (SNMP_ERR_NO_CREATION); 420133488Sharti break; 421133488Sharti 422133488Sharti case SNMP_OP_ROLLBACK: 423133488Sharti case SNMP_OP_COMMIT: 424133488Sharti if ((*aifp = FIND_OBJECT_INT(&atmif_list, 425133488Sharti &value->var, sub)) == NULL) 426133488Sharti abort(); 427133488Sharti return (SNMP_ERR_NOERROR); 428133488Sharti } 429133488Sharti 430133488Sharti if ((*aifp)->pub.mib->pcr == 0) { 431133488Sharti mib_fetch_ifmib((*aifp)->pub.ifp); 432133488Sharti atmif_sys_fill_mib(*aifp); 433133488Sharti atmif_check_carrier(*aifp); 434133488Sharti } 435133488Sharti 436133488Sharti return (SNMP_ERR_NOERROR); 437133488Sharti} 438133488Sharti 439133488Sharti/* 440133488Sharti * Table of all ATM interfaces 441133488Sharti */ 442133488Shartiint 443133488Shartiop_atmif(struct snmp_context *ctx __unused, struct snmp_value *value, 444133488Sharti u_int sub, u_int vindex __unused, enum snmp_op op) 445133488Sharti{ 446133488Sharti struct atmif_priv *aif; 447133488Sharti int err; 448133488Sharti 449133488Sharti if ((err = atmif_get_aif(value, sub, op, &aif)) != SNMP_ERR_NOERROR) 450133488Sharti return (err); 451133488Sharti 452133488Sharti if (op == SNMP_OP_SET) { 453133488Sharti switch (value->var.subs[sub - 1]) { 454133488Sharti 455133488Sharti default: 456133488Sharti return (SNMP_ERR_NOT_WRITEABLE); 457133488Sharti 458133488Sharti case LEAF_begemotAtmIfMode: 459133488Sharti if ((err = atmif_get_mode(aif)) != SNMP_ERR_NOERROR) 460133488Sharti return (err); 461133488Sharti if (aif->pub.mode == ATMIF_SUNI_MODE_UNKNOWN) 462133488Sharti return (SNMP_ERR_INCONS_VALUE); 463133488Sharti if (value->v.integer != ATMIF_SUNI_MODE_SONET && 464133488Sharti value->v.integer != ATMIF_SUNI_MODE_SDH) 465133488Sharti return (SNMP_ERR_WRONG_VALUE); 466133488Sharti if ((u_int)value->v.integer == aif->pub.mode) 467133488Sharti return (SNMP_ERR_NOERROR); 468133488Sharti return (atmif_set_mode(aif, value->v.integer)); 469133488Sharti } 470133488Sharti abort(); 471133488Sharti } 472133488Sharti 473133488Sharti switch (value->var.subs[sub - 1]) { 474133488Sharti 475133488Sharti case LEAF_begemotAtmIfName: 476133488Sharti return (string_get(value, aif->pub.ifp->name, -1)); 477133488Sharti 478133488Sharti case LEAF_begemotAtmIfPcr: 479133488Sharti value->v.uint32 = aif->pub.mib->pcr; 480133488Sharti return (SNMP_ERR_NOERROR); 481133488Sharti 482133488Sharti case LEAF_begemotAtmIfMedia: 483133488Sharti value->v.integer = aif->pub.mib->media; 484133488Sharti return (SNMP_ERR_NOERROR); 485133488Sharti 486133488Sharti case LEAF_begemotAtmIfVpiBits: 487133488Sharti value->v.uint32 = aif->pub.mib->vpi_bits; 488133488Sharti return (SNMP_ERR_NOERROR); 489133488Sharti 490133488Sharti case LEAF_begemotAtmIfVciBits: 491133488Sharti value->v.uint32 = aif->pub.mib->vci_bits; 492133488Sharti return (SNMP_ERR_NOERROR); 493133488Sharti 494133488Sharti case LEAF_begemotAtmIfMaxVpcs: 495133488Sharti value->v.uint32 = aif->pub.mib->max_vpcs; 496133488Sharti return (SNMP_ERR_NOERROR); 497133488Sharti 498133488Sharti case LEAF_begemotAtmIfMaxVccs: 499133488Sharti value->v.uint32 = aif->pub.mib->max_vccs; 500133488Sharti return (SNMP_ERR_NOERROR); 501133488Sharti 502133488Sharti case LEAF_begemotAtmIfEsi: 503133488Sharti return (string_get(value, aif->pub.mib->esi, 6)); 504133488Sharti 505133488Sharti case LEAF_begemotAtmIfCarrierStatus: 506133488Sharti value->v.integer = aif->pub.carrier; 507133488Sharti return (SNMP_ERR_NOERROR); 508133488Sharti 509133488Sharti case LEAF_begemotAtmIfMode: 510133488Sharti if ((err = atmif_get_mode(aif)) != SNMP_ERR_NOERROR) 511133488Sharti return (err); 512133488Sharti value->v.integer = aif->pub.mode; 513133488Sharti return (SNMP_ERR_NOERROR); 514133488Sharti } 515133488Sharti abort(); 516133488Sharti} 517133488Sharti 518133488Sharti/* 519133488Sharti * Hardware table 520133488Sharti */ 521133488Shartiint 522133488Shartiop_atmhw(struct snmp_context *ctx __unused, struct snmp_value *value, 523133488Sharti u_int sub, u_int vindex __unused, enum snmp_op op) 524133488Sharti{ 525133488Sharti struct atmif_priv *aif; 526133488Sharti int err; 527133488Sharti 528133488Sharti if ((err = atmif_get_aif(value, sub, op, &aif)) != SNMP_ERR_NOERROR) 529133488Sharti return (err); 530133488Sharti if (op == SNMP_OP_SET) 531133488Sharti return (SNMP_ERR_NOT_WRITEABLE); 532133488Sharti 533133488Sharti switch (value->var.subs[sub - 1]) { 534133488Sharti 535133488Sharti case LEAF_begemotAtmHWVendor: 536133488Sharti return (atm_sys_get_hw_vendor(aif, value)); 537133488Sharti 538133488Sharti case LEAF_begemotAtmHWDevice: 539133488Sharti return (atm_sys_get_hw_device(aif, value)); 540133488Sharti 541133488Sharti case LEAF_begemotAtmHWSerial: 542133488Sharti value->v.uint32 = aif->pub.mib->serial; 543133488Sharti return (SNMP_ERR_NOERROR); 544133488Sharti 545133488Sharti case LEAF_begemotAtmHWVersion: 546133488Sharti value->v.uint32 = aif->pub.mib->hw_version; 547133488Sharti return (SNMP_ERR_NOERROR); 548133488Sharti 549133488Sharti case LEAF_begemotAtmHWSoftVersion: 550133488Sharti value->v.uint32 = aif->pub.mib->sw_version; 551133488Sharti return (SNMP_ERR_NOERROR); 552133488Sharti 553133488Sharti } 554133488Sharti abort(); 555133488Sharti} 556133488Sharti 557133488Sharti/* 558133488Sharti * Scalars 559133488Sharti */ 560133488Shartiint 561133488Shartiop_atm(struct snmp_context *ctx __unused, struct snmp_value *value, 562133488Sharti u_int sub, u_int vindex __unused, enum snmp_op op) 563133488Sharti{ 564133488Sharti switch (op) { 565133488Sharti 566133488Sharti case SNMP_OP_GETNEXT: 567133488Sharti abort(); 568133488Sharti 569133488Sharti case SNMP_OP_GET: 570133488Sharti switch (value->var.subs[sub - 1]) { 571133488Sharti 572133488Sharti case LEAF_begemotAtmIfTableLastChange: 573133488Sharti value->v.uint32 = 574133488Sharti (last_change == 0 ? 0 : last_change - start_tick); 575133488Sharti return (SNMP_ERR_NOERROR); 576133488Sharti } 577133488Sharti abort(); 578133488Sharti 579133488Sharti case SNMP_OP_SET: 580133488Sharti return (SNMP_ERR_NOT_WRITEABLE); 581133488Sharti 582133488Sharti case SNMP_OP_ROLLBACK: 583133488Sharti case SNMP_OP_COMMIT: 584133488Sharti abort(); 585133488Sharti } 586133488Sharti abort(); 587133488Sharti} 588133488Sharti 589133488Sharti/* 590133488Sharti * Register for interface notifications 591133488Sharti */ 592133488Shartivoid * 593133488Shartiatm_notify_aif(struct atmif *pub, const struct lmodule *mod, 594133488Sharti atmif_event_f func, void *arg) 595133488Sharti{ 596133488Sharti struct atmif_priv *aif = (struct atmif_priv *)pub; 597133488Sharti struct atmif_reg *r0; 598133488Sharti 599133488Sharti if ((r0 = malloc(sizeof(*r0))) == NULL) { 600133488Sharti syslog(LOG_CRIT, "out of memory"); 601133488Sharti return (NULL); 602133488Sharti } 603133488Sharti r0->func = func; 604133488Sharti r0->mod = mod; 605133488Sharti r0->data = arg; 606133488Sharti r0->aif = aif; 607133488Sharti 608133488Sharti TAILQ_INSERT_TAIL(&aif->notify, r0, link); 609133488Sharti 610133488Sharti return (r0); 611133488Sharti} 612133488Sharti 613133488Sharti/* 614133488Sharti * Unregister it 615133488Sharti */ 616133488Shartivoid 617133488Shartiatm_unnotify_aif(void *arg) 618133488Sharti{ 619133488Sharti struct atmif_reg *r0 = arg; 620133488Sharti 621133488Sharti TAILQ_REMOVE(&r0->aif->notify, r0, link); 622133488Sharti free(r0); 623133488Sharti} 624