15455Sdg/* 21541Srgrimes * Copyright (c) 2001-2002 31541Srgrimes * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 41549Srgrimes * All rights reserved. 51549Srgrimes * Copyright (c) 2003-2004 61549Srgrimes * Hartmut Brandt. 71549Srgrimes * All rights reserved. 81541Srgrimes * 91549Srgrimes * Author: Hartmut Brandt <harti@freebsd.org> 101541Srgrimes * 111541Srgrimes * Redistribution and use in source and binary forms, with or without 121541Srgrimes * modification, are permitted provided that the following conditions 131541Srgrimes * are met: 141541Srgrimes * 1. Redistributions of source code must retain the above copyright 151541Srgrimes * notice, this list of conditions and the following disclaimer. 161541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171541Srgrimes * notice, this list of conditions and the following disclaimer in the 181541Srgrimes * documentation and/or other materials provided with the distribution. 191541Srgrimes * 201541Srgrimes * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 211541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2258705Scharnier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 241541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301541Srgrimes * SUCH DAMAGE. 311541Srgrimes * 321541Srgrimes * $Begemot: libunimsg/snmp_atm/snmp_atm.c,v 1.3 2005/05/23 11:46:46 brandt_h Exp $ 331541Srgrimes * 341541Srgrimes * SNMP module for ATM hardware interfaces. 351541Srgrimes */ 361541Srgrimes 371541Srgrimes#include "atm.h" 381541Srgrimes#include "atm_tree.h" 391541Srgrimes#include "atm_oid.h" 401541Srgrimes 411817Sdg#include <sys/ioctl.h> 421541Srgrimes 431541Srgrimes#include <stdio.h> 441541Srgrimes#include <stdlib.h> 451541Srgrimes#include <string.h> 461541Srgrimes#include <errno.h> 471541Srgrimes#include <syslog.h> 485455Sdg#include <net/if_types.h> 491541Srgrimes#include <net/if_media.h> 501541Srgrimes#include <net/if_atm.h> 511541Srgrimes 521541Srgrimesstruct lmodule *module; 531541Srgrimes 545455Sdg/* list of all (known) ATM interfaces */ 555455Sdgstruct atmif_list atmif_list = TAILQ_HEAD_INITIALIZER(atmif_list); 565455Sdg 571541Srgrimes/* whether we are started or not */ 585455Sdgstatic int started; 591541Srgrimes 601541Srgrimes/* last time table was changed */ 611541Srgrimesstatic uint64_t last_change; 621541Srgrimes 631541Srgrimes/* for the registration */ 641541Srgrimesstatic const struct asn_oid oid_begemotAtm = OIDX_begemotAtm; 651541Srgrimes 661541Srgrimes/* the registration */ 671541Srgrimesstatic u_int reg_atm; 681817Sdg 6950477Speter/* 701541Srgrimes * Find an ATM interface by name 711541Srgrimes */ 721541Srgrimesstruct atmif * 731541Srgrimesatm_find_if_name(const char *name) 741541Srgrimes{ 751541Srgrimes struct atmif_priv *aif; 761541Srgrimes 771541Srgrimes TAILQ_FOREACH(aif, &atmif_list, link) 781549Srgrimes if (strcmp(aif->pub.ifp->name, name) == 0) 799507Sdg return (&aif->pub); 801549Srgrimes return (NULL); 8112662Sdg} 821541Srgrimes 831541Srgrimes/* 8412662Sdg * get the interface from the interface index 8522521Sdyson */ 8612662Sdgstruct atmif * 8712662Sdgatm_find_if(u_int ifindex) 8812662Sdg{ 891541Srgrimes struct atmif_priv *aif; 901541Srgrimes 914207Sdg TAILQ_FOREACH(aif, &atmif_list, link) 929507Sdg if (aif->index == ifindex) 939507Sdg return (&aif->pub); 9412662Sdg return (NULL); 951541Srgrimes} 9633181Seivind 9733181Seivind/* 981549Srgrimes * Send notification to all listeners. 9932585Sdyson */ 10032585Sdysonvoid 1011549Srgrimesatmif_send_notification(struct atmif_priv *aif, enum atmif_notify code, 1021549Srgrimes uintptr_t arg) 10334202Sdyson{ 10434202Sdyson struct atmif_reg *r0, *r1; 10534202Sdyson 10634202Sdyson r0 = TAILQ_FIRST(&aif->notify); 10734202Sdyson while (r0 != NULL) { 10834202Sdyson r1 = TAILQ_NEXT(r0, link); 10934202Sdyson r0->func(&aif->pub, code, arg, r0->data); 11034202Sdyson r0 = r1; 11134202Sdyson } 11234202Sdyson} 11334202Sdyson 11434202Sdyson/* 11534202Sdyson * Destroy an interface 11642957Sdillon */ 11734202Sdysonstatic void 11834202Sdysonatmif_destroy(struct atmif_priv *aif) 11938799Sdfr{ 12034202Sdyson struct atmif_reg *r0; 12134202Sdyson 12234202Sdyson atmif_send_notification(aif, ATMIF_NOTIFY_DESTROY, 12334202Sdyson (uintptr_t)0); 12442957Sdillon 12534202Sdyson atmif_sys_destroy(aif); 12634202Sdyson 12734202Sdyson if (aif->ifpreg != NULL) 12834202Sdyson mibif_unnotify(aif->ifpreg); 12934202Sdyson 13034202Sdyson while ((r0 = TAILQ_FIRST(&aif->notify)) != NULL) { 13134202Sdyson TAILQ_REMOVE(&aif->notify, r0, link); 13234202Sdyson free(r0); 13334202Sdyson } 13434202Sdyson 13534202Sdyson TAILQ_REMOVE(&atmif_list, aif, link); 13634202Sdyson free(aif); 13734202Sdyson 13834202Sdyson last_change = this_tick; 13934202Sdyson} 14034202Sdyson 14134202Sdyson/* 14234202Sdyson * Function gets called from the MIB-II module for events on that interface 14334202Sdyson */ 14434202Sdysonstatic void 14534202Sdysonatmif_notify(struct mibif *ifp __unused, enum mibif_notify event, void *data) 14634202Sdyson{ 14734202Sdyson struct atmif_priv *aif = data; 14834202Sdyson 14934202Sdyson switch (event) { 15034202Sdyson 15134202Sdyson case MIBIF_NOTIFY_DESTROY: 15234202Sdyson atmif_destroy(aif); 15334202Sdyson break; 15434202Sdyson } 1551541Srgrimes} 15651488Sdillon 15751488Sdillon/* 15851488Sdillon * Check the carrier state of the interface 15951488Sdillon */ 16051488Sdillonvoid 16151488Sdillonatmif_check_carrier(struct atmif_priv *aif) 16251488Sdillon{ 16351488Sdillon struct ifmediareq ifmr; 16451488Sdillon enum atmif_carrier_state ost = aif->pub.carrier; 16551488Sdillon 1661541Srgrimes memset(&ifmr, 0, sizeof(ifmr)); 1671541Srgrimes strcpy(ifmr.ifm_name, aif->pub.ifp->name); 16858634Scharnier 1691541Srgrimes if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) == -1) { 1701541Srgrimes aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 1711541Srgrimes return; 1721541Srgrimes } 1731541Srgrimes if (!(ifmr.ifm_status & IFM_AVALID)) { 1741541Srgrimes aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 1751541Srgrimes return; 1761541Srgrimes } 1771541Srgrimes if (ifmr.ifm_status & IFM_ACTIVE) 1781541Srgrimes aif->pub.carrier = ATMIF_CARRIER_ON; 1791541Srgrimes else 1801541Srgrimes aif->pub.carrier = ATMIF_CARRIER_OFF; 1811541Srgrimes 1821541Srgrimes if (ost != aif->pub.carrier) 1831541Srgrimes atmif_send_notification(aif, ATMIF_NOTIFY_CARRIER, 18428751Sbde (uintptr_t)ost); 1851541Srgrimes} 1865455Sdg 1875455Sdg/* 1885455Sdg * Retrieve the SUNI mode 18932702Sdyson */ 1905455Sdgstatic int 1915455Sdgatmif_get_mode(struct atmif_priv *aif) 19234202Sdyson{ 19332702Sdyson struct ifmediareq ifmr; 19434202Sdyson 1951541Srgrimes memset(&ifmr, 0, sizeof(ifmr)); 1965455Sdg strcpy(ifmr.ifm_name, aif->pub.ifp->name); 19734202Sdyson 1981541Srgrimes if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) < 0) { 1995455Sdg syslog(LOG_ERR, "SIOCGIFMEDIA: %m"); 2001541Srgrimes aif->pub.mode = ATMIF_SUNI_MODE_UNKNOWN; 2011541Srgrimes return (SNMP_ERR_GENERR); 2025455Sdg } 2035455Sdg if (ifmr.ifm_current & IFM_ATM_SDH) 2041541Srgrimes aif->pub.mode = ATMIF_SUNI_MODE_SDH; 20551488Sdillon else 20634202Sdyson aif->pub.mode = ATMIF_SUNI_MODE_SONET; 20734202Sdyson 20834202Sdyson return (SNMP_ERR_NOERROR); 20932585Sdyson} 21032585Sdyson 21132585Sdyson/* 21232585Sdyson * Change the SUNI mod 21332585Sdyson */ 21432585Sdysonstatic int 21532585Sdysonatmif_set_mode(struct atmif_priv *aif, int newmode) 21632585Sdyson{ 21732585Sdyson struct ifmediareq ifmr; 21832585Sdyson struct ifreq ifr; 21932585Sdyson 22032585Sdyson memset(&ifmr, 0, sizeof(ifmr)); 22134202Sdyson strcpy(ifmr.ifm_name, aif->pub.ifp->name); 22232585Sdyson 22334202Sdyson /* get current mode */ 22432585Sdyson if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) < 0) { 22532585Sdyson syslog(LOG_ERR, "SIOCGIFMEDIA: %m"); 22632585Sdyson return (SNMP_ERR_GENERR); 22732585Sdyson } 22832585Sdyson 22932585Sdyson memset(&ifr, 0, sizeof(ifr)); 23032585Sdyson strcpy(ifr.ifr_name, aif->pub.ifp->name); 23132585Sdyson 23232585Sdyson ifr.ifr_media = ifmr.ifm_current; 23334202Sdyson if (newmode == ATMIF_SUNI_MODE_SDH) 23434202Sdyson ifr.ifr_media |= IFM_ATM_SDH; 2351541Srgrimes else 2367695Sdg ifr.ifr_media &= ~IFM_ATM_SDH; 23734202Sdyson 23832702Sdyson if (ioctl(mib_netsock, SIOCSIFMEDIA, &ifr) < 0) { 23934202Sdyson syslog(LOG_ERR, "SIOCSIFMEDIA: %m"); 24020054Sdyson return (SNMP_ERR_GENERR); 24137563Sbde } 24220054Sdyson 24320054Sdyson aif->pub.mode = newmode; 24420449Sdyson return (SNMP_ERR_NOERROR); 24532286Sdyson} 24632286Sdyson 24732286Sdyson/* 24832286Sdyson * Attach to an ATM interface 24932286Sdyson */ 25034202Sdysonstatic void 25138135Sdfrattach_if(struct mibif *ifp) 25232286Sdyson{ 25334202Sdyson struct atmif_priv *aif; 25431853Sdyson 25534202Sdyson /* we should not know it */ 25634202Sdyson TAILQ_FOREACH(aif, &atmif_list, link) 25734202Sdyson if (aif->pub.ifp == ifp) { 25831853Sdyson syslog(LOG_CRIT, "new ATM if already known '%s'", 2597695Sdg ifp->name); 26034202Sdyson return; 2611541Srgrimes } 2621541Srgrimes 2631541Srgrimes /* 2641541Srgrimes * tap it 26534202Sdyson */ 2661541Srgrimes if ((aif = malloc(sizeof(*aif))) == NULL) { 2675455Sdg syslog(LOG_ERR, "new atmif: %m"); 2685455Sdg return; 2691541Srgrimes } 2701541Srgrimes memset(aif, 0, sizeof(*aif)); 27134202Sdyson 27234202Sdyson aif->pub.ifp = ifp; 2731541Srgrimes aif->index = ifp->index; 2741541Srgrimes TAILQ_INIT(&aif->notify); 27542957Sdillon 27642957Sdillon if (atmif_sys_attach_if(aif)) { 27742957Sdillon free(aif); 27832585Sdyson return; 27934202Sdyson } 28034202Sdyson 28132585Sdyson aif->ifpreg = mibif_notify(ifp, module, atmif_notify, aif); 28232585Sdyson 28342957Sdillon aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 28442957Sdillon atmif_check_carrier(aif); 28542957Sdillon (void)atmif_get_mode(aif); 28642957Sdillon 28732585Sdyson INSERT_OBJECT_INT(aif, &atmif_list); 28834202Sdyson 28934202Sdyson last_change = this_tick; 29041322Sdg 2911541Srgrimes return; 29242957Sdillon} 29342957Sdillon 29442957Sdillon/* 29542957Sdillon * Function gets called when a new interface is created. If this is an 29642957Sdillon * ATM interface, hook in. Claim the interface in any case even when 29758634Scharnier * the creation of our data structures fails. 29842957Sdillon */ 29942957Sdillonstatic int 30042957Sdillonnew_if(struct mibif *ifp) 30142957Sdillon{ 30242957Sdillon if (!started || ifp->mib.ifmd_data.ifi_type != IFT_ATM || 30342957Sdillon ifp->xnotify != NULL) 30442957Sdillon return (0); 30542957Sdillon 3061541Srgrimes attach_if(ifp); 30742957Sdillon return (1); 30834202Sdyson} 30942957Sdillon 31042957Sdillon/* 31134202Sdyson * Start the module 3121541Srgrimes */ 3131541Srgrimesstatic void 3147695Sdgatm_start(void) 31534202Sdyson{ 31641322Sdg struct mibif *ifp; 31734202Sdyson 31841322Sdg reg_atm = or_register(&oid_begemotAtm, 31916268Sdyson "The Begemot MIB for ATM interfaces.", module); 32051488Sdillon 32134202Sdyson started = 1; 32234202Sdyson for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp)) 3235455Sdg if (ifp->mib.ifmd_data.ifi_type == IFT_ATM && 3245455Sdg ifp->xnotify == NULL) 3255455Sdg attach_if(ifp); 32643086Sdillon} 32742957Sdillon 32842957Sdillon/* 32942957Sdillon * Called when modules is loaded 33042957Sdillon */ 33142957Sdillonstatic int 33242957Sdillonatm_init(struct lmodule *mod, int argc __unused, char *argv[] __unused) 3331541Srgrimes{ 33438799Sdfr module = mod; 33534202Sdyson 33634202Sdyson /* register to get creation messages for ATM interfaces */ 3375455Sdg if (mib_register_newif(new_if, module)) { 3385455Sdg syslog(LOG_ERR, "cannot register newif function: %m"); 33933936Sdyson return (-1); 3401541Srgrimes } 3411541Srgrimes 34242957Sdillon return (0); 34342957Sdillon} 34451488Sdillon 34551488Sdillon/* 34642957Sdillon * Called when module gets unloaded - free all resources 34742957Sdillon */ 34851488Sdillonstatic int 34934202Sdysonatm_fini(void) 35034202Sdyson{ 3518585Sdg struct atmif_priv *aif; 3528585Sdg 35310988Sdyson while ((aif = TAILQ_FIRST(&atmif_list)) != NULL) 3541541Srgrimes atmif_destroy(aif); 3555455Sdg 3561541Srgrimes mib_unregister_newif(module); 35751488Sdillon or_unregister(reg_atm); 35851488Sdillon 35951488Sdillon return (0); 36051488Sdillon} 36151488Sdillon 36234202Sdyson/* 36334202Sdyson * Other module unloaded/loaded 3641541Srgrimes */ 3651541Srgrimesstatic void 3661541Srgrimesatm_loading(const struct lmodule *mod, int loading) 3671541Srgrimes{ 36832585Sdyson struct atmif_priv *aif; 3695455Sdg struct atmif_reg *r0, *r1; 37042957Sdillon 37151488Sdillon if (!loading) { 37251488Sdillon /* remove notifications for this module */ 37351488Sdillon TAILQ_FOREACH(aif, &atmif_list, link) 37451488Sdillon TAILQ_FOREACH_SAFE(r0, &aif->notify, link, r1) { 37551488Sdillon if (r0->mod == mod) { 37651488Sdillon TAILQ_REMOVE(&aif->notify, r0, link); 37751488Sdillon free(r0); 37842957Sdillon } 37942957Sdillon } 38051488Sdillon } 3811541Srgrimes} 3821549Srgrimes 38315819Sdysonconst struct snmp_module config = { 38449338Salc .comment = "This module implements a private MIB for ATM interfaces.", 3851541Srgrimes .init = atm_init, 38649338Salc .fini = atm_fini, 38715819Sdyson .start = atm_start, 38815819Sdyson .tree = atm_ctree, 38932702Sdyson .tree_size = atm_CTREE_SIZE, 39034202Sdyson .loading = atm_loading 39132702Sdyson}; 39232702Sdyson 39332702Sdyson/* 39434202Sdyson * Get the interface point for a table access 39532702Sdyson */ 39632702Sdysonint 39715819Sdysonatmif_get_aif(struct snmp_value *value, u_int sub, enum snmp_op op, 39815819Sdyson struct atmif_priv **aifp) 39934202Sdyson{ 40051488Sdillon switch (op) { 40151488Sdillon 40251488Sdillon case SNMP_OP_GETNEXT: 40351488Sdillon if ((*aifp = NEXT_OBJECT_INT(&atmif_list, 40451488Sdillon &value->var, sub)) == NULL) 40515819Sdyson return (SNMP_ERR_NOSUCHNAME); 40651488Sdillon value->var.len = sub + 1; 40751488Sdillon value->var.subs[sub] = (*aifp)->index; 40815819Sdyson break; 40915819Sdyson 41051488Sdillon case SNMP_OP_GET: 41115819Sdyson if ((*aifp = FIND_OBJECT_INT(&atmif_list, 41246349Salc &value->var, sub)) == NULL) 41346349Salc return (SNMP_ERR_NOSUCHNAME); 41446349Salc break; 41546349Salc 41646349Salc case SNMP_OP_SET: 41746349Salc if ((*aifp = FIND_OBJECT_INT(&atmif_list, 41834202Sdyson &value->var, sub)) == NULL) 41924678Speter return (SNMP_ERR_NO_CREATION); 42015819Sdyson break; 42115819Sdyson 42234202Sdyson case SNMP_OP_ROLLBACK: 42315819Sdyson case SNMP_OP_COMMIT: 42415819Sdyson if ((*aifp = FIND_OBJECT_INT(&atmif_list, 42516058Sdyson &value->var, sub)) == NULL) 42661081Sdillon abort(); 42716058Sdyson return (SNMP_ERR_NOERROR); 42815819Sdyson } 42915819Sdyson 43015819Sdyson if ((*aifp)->pub.mib->pcr == 0) { 43115819Sdyson mib_fetch_ifmib((*aifp)->pub.ifp); 43215819Sdyson atmif_sys_fill_mib(*aifp); 43315819Sdyson atmif_check_carrier(*aifp); 43415819Sdyson } 43515819Sdyson 43615819Sdyson return (SNMP_ERR_NOERROR); 43715819Sdyson} 43815819Sdyson 43915819Sdyson/* 44015819Sdyson * Table of all ATM interfaces 44115819Sdyson */ 44215819Sdysonint 44315819Sdysonop_atmif(struct snmp_context *ctx __unused, struct snmp_value *value, 4441541Srgrimes u_int sub, u_int vindex __unused, enum snmp_op op) 4455455Sdg{ 4465455Sdg struct atmif_priv *aif; 4475455Sdg int err; 4485455Sdg 4495455Sdg if ((err = atmif_get_aif(value, sub, op, &aif)) != SNMP_ERR_NOERROR) 4505455Sdg return (err); 4515455Sdg 4525455Sdg if (op == SNMP_OP_SET) { 4535455Sdg switch (value->var.subs[sub - 1]) { 4545455Sdg 45542957Sdillon default: 45642957Sdillon return (SNMP_ERR_NOT_WRITEABLE); 4571549Srgrimes 4583449Sphk case LEAF_begemotAtmIfMode: 45934202Sdyson if ((err = atmif_get_mode(aif)) != SNMP_ERR_NOERROR) 4601541Srgrimes return (err); 4611541Srgrimes if (aif->pub.mode == ATMIF_SUNI_MODE_UNKNOWN) 46251488Sdillon return (SNMP_ERR_INCONS_VALUE); 46351488Sdillon if (value->v.integer != ATMIF_SUNI_MODE_SONET && 46451488Sdillon value->v.integer != ATMIF_SUNI_MODE_SDH) 46551488Sdillon return (SNMP_ERR_WRONG_VALUE); 46651488Sdillon if ((u_int)value->v.integer == aif->pub.mode) 46751488Sdillon return (SNMP_ERR_NOERROR); 4685455Sdg return (atmif_set_mode(aif, value->v.integer)); 46942957Sdillon } 47042957Sdillon abort(); 4711541Srgrimes } 47234202Sdyson 4731541Srgrimes switch (value->var.subs[sub - 1]) { 4741549Srgrimes 47534202Sdyson case LEAF_begemotAtmIfName: 4769507Sdg return (string_get(value, aif->pub.ifp->name, -1)); 47710988Sdyson 4781541Srgrimes case LEAF_begemotAtmIfPcr: 4791541Srgrimes value->v.uint32 = aif->pub.mib->pcr; 48017312Sdyson return (SNMP_ERR_NOERROR); 48117312Sdyson 48217312Sdyson case LEAF_begemotAtmIfMedia: 48317312Sdyson value->v.integer = aif->pub.mib->media; 48417312Sdyson return (SNMP_ERR_NOERROR); 4855455Sdg 4865455Sdg case LEAF_begemotAtmIfVpiBits: 4875455Sdg value->v.uint32 = aif->pub.mib->vpi_bits; 4881541Srgrimes return (SNMP_ERR_NOERROR); 48934202Sdyson 49034202Sdyson case LEAF_begemotAtmIfVciBits: 49134202Sdyson value->v.uint32 = aif->pub.mib->vci_bits; 49217312Sdyson return (SNMP_ERR_NOERROR); 4937695Sdg 4948876Srgrimes case LEAF_begemotAtmIfMaxVpcs: 4951549Srgrimes value->v.uint32 = aif->pub.mib->max_vpcs; 49642957Sdillon return (SNMP_ERR_NOERROR); 4971541Srgrimes 4981541Srgrimes case LEAF_begemotAtmIfMaxVccs: 4995455Sdg value->v.uint32 = aif->pub.mib->max_vccs; 5005455Sdg return (SNMP_ERR_NOERROR); 5015455Sdg 5028876Srgrimes case LEAF_begemotAtmIfEsi: 5039507Sdg return (string_get(value, aif->pub.mib->esi, 6)); 5045455Sdg 5058876Srgrimes case LEAF_begemotAtmIfCarrierStatus: 5065455Sdg value->v.integer = aif->pub.carrier; 5079507Sdg return (SNMP_ERR_NOERROR); 5085455Sdg 5095455Sdg case LEAF_begemotAtmIfMode: 5101541Srgrimes if ((err = atmif_get_mode(aif)) != SNMP_ERR_NOERROR) 5111549Srgrimes return (err); 5124207Sdg value->v.integer = aif->pub.mode; 51337843Sdg return (SNMP_ERR_NOERROR); 51437843Sdg } 5151549Srgrimes abort(); 5164207Sdg} 5171549Srgrimes 5184207Sdg/* 5195455Sdg * Hardware table 5205455Sdg */ 5215455Sdgint 5224207Sdgop_atmhw(struct snmp_context *ctx __unused, struct snmp_value *value, 52334202Sdyson u_int sub, u_int vindex __unused, enum snmp_op op) 52432585Sdyson{ 52534202Sdyson struct atmif_priv *aif; 52634202Sdyson int err; 52734202Sdyson 5284207Sdg if ((err = atmif_get_aif(value, sub, op, &aif)) != SNMP_ERR_NOERROR) 5291541Srgrimes return (err); 53034202Sdyson if (op == SNMP_OP_SET) 53134202Sdyson return (SNMP_ERR_NOT_WRITEABLE); 53234202Sdyson 5331549Srgrimes switch (value->var.subs[sub - 1]) { 5341549Srgrimes 5351549Srgrimes case LEAF_begemotAtmHWVendor: 5361549Srgrimes return (atm_sys_get_hw_vendor(aif, value)); 5371541Srgrimes 5381541Srgrimes case LEAF_begemotAtmHWDevice: 53951488Sdillon return (atm_sys_get_hw_device(aif, value)); 5401541Srgrimes 54142957Sdillon case LEAF_begemotAtmHWSerial: 54242957Sdillon value->v.uint32 = aif->pub.mib->serial; 5431541Srgrimes return (SNMP_ERR_NOERROR); 54434202Sdyson 54534202Sdyson case LEAF_begemotAtmHWVersion: 5461541Srgrimes value->v.uint32 = aif->pub.mib->hw_version; 5471541Srgrimes return (SNMP_ERR_NOERROR); 5485455Sdg 5495455Sdg case LEAF_begemotAtmHWSoftVersion: 5501541Srgrimes value->v.uint32 = aif->pub.mib->sw_version; 5511541Srgrimes return (SNMP_ERR_NOERROR); 55234202Sdyson 55334202Sdyson } 5541541Srgrimes abort(); 5551541Srgrimes} 5565455Sdg 5575455Sdg/* 5581541Srgrimes * Scalars 55934202Sdyson */ 56034202Sdysonint 5611541Srgrimesop_atm(struct snmp_context *ctx __unused, struct snmp_value *value, 56234202Sdyson u_int sub, u_int vindex __unused, enum snmp_op op) 56334202Sdyson{ 56434202Sdyson switch (op) { 5651541Srgrimes 56634202Sdyson case SNMP_OP_GETNEXT: 5671541Srgrimes abort(); 56846349Salc 56946349Salc case SNMP_OP_GET: 57046349Salc switch (value->var.subs[sub - 1]) { 57134202Sdyson 57234202Sdyson case LEAF_begemotAtmIfTableLastChange: 57346349Salc value->v.uint32 = 57446349Salc (last_change == 0 ? 0 : last_change - start_tick); 57544250Salc return (SNMP_ERR_NOERROR); 57617312Sdyson } 57746349Salc abort(); 57842957Sdillon 5795455Sdg case SNMP_OP_SET: 58034202Sdyson return (SNMP_ERR_NOT_WRITEABLE); 58134202Sdyson 5821549Srgrimes case SNMP_OP_ROLLBACK: 58342957Sdillon case SNMP_OP_COMMIT: 58434202Sdyson abort(); 58538135Sdfr } 5861541Srgrimes abort(); 5871541Srgrimes} 58842957Sdillon 58942408Seivind/* 59042408Seivind * Register for interface notifications 5911541Srgrimes */ 5921541Srgrimesvoid * 5935455Sdgatm_notify_aif(struct atmif *pub, const struct lmodule *mod, 5945455Sdg atmif_event_f func, void *arg) 5951541Srgrimes{ 5961541Srgrimes struct atmif_priv *aif = (struct atmif_priv *)pub; 5971541Srgrimes struct atmif_reg *r0; 5985455Sdg 5995455Sdg if ((r0 = malloc(sizeof(*r0))) == NULL) { 6005455Sdg syslog(LOG_CRIT, "out of memory"); 6011541Srgrimes return (NULL); 6021541Srgrimes } 60334202Sdyson r0->func = func; 6045455Sdg r0->mod = mod; 6055455Sdg r0->data = arg; 6061541Srgrimes r0->aif = aif; 6071541Srgrimes 6085455Sdg TAILQ_INSERT_TAIL(&aif->notify, r0, link); 6091541Srgrimes 61042957Sdillon return (r0); 61142957Sdillon} 61242957Sdillon 61342957Sdillon/* 61442957Sdillon * Unregister it 61542957Sdillon */ 61642957Sdillonvoid 61742957Sdillonatm_unnotify_aif(void *arg) 6181541Srgrimes{ 61934202Sdyson struct atmif_reg *r0 = arg; 62014316Sdyson 62114316Sdyson TAILQ_REMOVE(&r0->aif->notify, r0, link); 62214316Sdyson free(r0); 62334202Sdyson} 62414316Sdyson