snmp_atm.c revision 133488
16059Samurai/* 26059Samurai * Copyright (c) 2001-2002 36059Samurai * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 46059Samurai * All rights reserved. 56059Samurai * Copyright (c) 2003-2004 66059Samurai * Hartmut Brandt. 76059Samurai * All rights reserved. 86059Samurai * 96059Samurai * Author: Hartmut Brandt <harti@freebsd.org> 106059Samurai * 116059Samurai * Redistribution and use in source and binary forms, with or without 126059Samurai * modification, are permitted provided that the following conditions 136059Samurai * are met: 146059Samurai * 1. Redistributions of source code must retain the above copyright 156059Samurai * notice, this list of conditions and the following disclaimer. 166059Samurai * 2. Redistributions in binary form must reproduce the above copyright 176059Samurai * notice, this list of conditions and the following disclaimer in the 186059Samurai * documentation and/or other materials provided with the distribution. 198857Srgrimes * 2031962Sbrian * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 218857Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 226059Samurai * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 236059Samurai * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 246059Samurai * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 256059Samurai * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2630715Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2731195Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2831195Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2931195Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3030715Sbrian * SUCH DAMAGE. 316059Samurai * 326059Samurai * $Begemot: libunimsg/snmp_atm/snmp_atm.c,v 1.2 2004/08/06 17:30:40 brandt Exp $ 336059Samurai * 346059Samurai * SNMP module for ATM hardware interfaces. 356059Samurai */ 3613389Sphk 3731195Sbrian#include "atm.h" 3831343Sbrian#include "atm_tree.h" 3931195Sbrian#include "atm_oid.h" 4031343Sbrian 4131195Sbrian#include <sys/ioctl.h> 4230715Sbrian 4331343Sbrian#include <stdio.h> 4426031Sbrian#include <stdlib.h> 4531343Sbrian#include <string.h> 4630092Sbrian#include <errno.h> 4730715Sbrian#include <syslog.h> 4830715Sbrian#include <net/if_types.h> 4930715Sbrian#include <net/if_media.h> 5030733Sbrian#include <net/if_atm.h> 5130715Sbrian 5230715Sbrianstruct lmodule *module; 5331343Sbrian 5430715Sbrian/* list of all (known) ATM interfaces */ 5530715Sbrianstruct atmif_list atmif_list = TAILQ_HEAD_INITIALIZER(atmif_list); 5630715Sbrian 5730715Sbrian/* whether we are started or not */ 5830715Sbrianstatic int started; 5930715Sbrian 6030715Sbrian/* last time table was changed */ 6126142Sbrianstatic uint32_t last_change; 626059Samurai 636059Samurai/* for the registration */ 6429043Sbrianstatic const struct asn_oid oid_begemotAtm = OIDX_begemotAtm; 6530715Sbrian 6630715Sbrian/* the registration */ 6730715Sbrianstatic u_int reg_atm; 6830733Sbrian 6931195Sbrian/* 7030715Sbrian * Find an ATM interface by name 716059Samurai */ 726059Samuraistruct atmif * 736059Samuraiatm_find_if_name(const char *name) 7428679Sbrian{ 7531343Sbrian struct atmif_priv *aif; 766059Samurai 7726516Sbrian TAILQ_FOREACH(aif, &atmif_list, link) 7826098Sbrian if (strcmp(aif->pub.ifp->name, name) == 0) 796059Samurai return (&aif->pub); 806059Samurai return (NULL); 816059Samurai} 826059Samurai 836059Samurai/* 846059Samurai * get the interface from the interface index 856059Samurai */ 866059Samuraistruct atmif * 876059Samuraiatm_find_if(u_int ifindex) 886059Samurai{ 8928679Sbrian struct atmif_priv *aif; 906059Samurai 916059Samurai TAILQ_FOREACH(aif, &atmif_list, link) 926059Samurai if (aif->index == ifindex) 936059Samurai return (&aif->pub); 946059Samurai return (NULL); 956059Samurai} 966059Samurai 976059Samurai/* 986059Samurai * Send notification to all listeners. 9926516Sbrian */ 10026516Sbrianvoid 10129043Sbrianatmif_send_notification(struct atmif_priv *aif, enum atmif_notify code, 10226516Sbrian uintptr_t arg) 10326516Sbrian{ 10426516Sbrian struct atmif_reg *r0, *r1; 10526516Sbrian 1066059Samurai r0 = TAILQ_FIRST(&aif->notify); 1076059Samurai while (r0 != NULL) { 1086059Samurai r1 = TAILQ_NEXT(r0, link); 1096059Samurai r0->func(&aif->pub, code, arg, r0->data); 1106059Samurai r0 = r1; 1116059Samurai } 1126059Samurai} 1136059Samurai 1146059Samurai/* 11531343Sbrian * Destroy an interface 1166059Samurai */ 11728679Sbrianstatic void 1186059Samuraiatmif_destroy(struct atmif_priv *aif) 1196059Samurai{ 1206059Samurai struct atmif_reg *r0; 1216059Samurai 1226059Samurai atmif_send_notification(aif, ATMIF_NOTIFY_DESTROY, 12331343Sbrian (uintptr_t)0); 12428679Sbrian 12528679Sbrian atmif_sys_destroy(aif); 1266059Samurai 1276059Samurai if (aif->ifpreg != NULL) 12813733Sdfr mibif_unnotify(aif->ifpreg); 1296059Samurai 13031343Sbrian while ((r0 = TAILQ_FIRST(&aif->notify)) != NULL) { 1316059Samurai TAILQ_REMOVE(&aif->notify, r0, link); 13231343Sbrian free(r0); 13328679Sbrian } 1346059Samurai 1356059Samurai TAILQ_REMOVE(&atmif_list, aif, link); 13628679Sbrian free(aif); 1376059Samurai 1386059Samurai last_change = this_tick; 13928679Sbrian} 14028679Sbrian 1416059Samurai/* 14228679Sbrian * Function gets called from the MIB-II module for events on that interface 1436059Samurai */ 14428679Sbrianstatic void 1456059Samuraiatmif_notify(struct mibif *ifp __unused, enum mibif_notify event, void *data) 14628679Sbrian{ 1476059Samurai struct atmif_priv *aif = data; 1486059Samurai 1496059Samurai switch (event) { 1506059Samurai 1516059Samurai case MIBIF_NOTIFY_DESTROY: 1526059Samurai atmif_destroy(aif); 1536059Samurai break; 15428679Sbrian } 1556059Samurai} 1566059Samurai 1576059Samurai/* 1586059Samurai * Check the carrier state of the interface 1596059Samurai */ 1606059Samuraivoid 1616059Samuraiatmif_check_carrier(struct atmif_priv *aif) 1626059Samurai{ 1636059Samurai struct ifmediareq ifmr; 1646059Samurai enum atmif_carrier_state ost = aif->pub.carrier; 1656059Samurai 1666059Samurai memset(&ifmr, 0, sizeof(ifmr)); 1676059Samurai strcpy(ifmr.ifm_name, aif->pub.ifp->name); 1686059Samurai 16928679Sbrian if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) == -1) { 17028679Sbrian aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 17128679Sbrian return; 17228679Sbrian } 17328679Sbrian if (!ifmr.ifm_status & IFM_AVALID) { 17428679Sbrian aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 17531143Sbrian return; 17631143Sbrian } 17731143Sbrian if (ifmr.ifm_status & IFM_ACTIVE) 17831143Sbrian aif->pub.carrier = ATMIF_CARRIER_ON; 1796059Samurai else 1806059Samurai aif->pub.carrier = ATMIF_CARRIER_OFF; 18128679Sbrian 1826059Samurai if (ost != aif->pub.carrier) 1836059Samurai atmif_send_notification(aif, ATMIF_NOTIFY_CARRIER, 1846059Samurai (uintptr_t)ost); 18528679Sbrian} 18628679Sbrian 18728679Sbrian/* 18828679Sbrian * Retrieve the SUNI mode 1896059Samurai */ 1906059Samuraistatic int 19128679Sbrianatmif_get_mode(struct atmif_priv *aif) 19228679Sbrian{ 19328679Sbrian struct ifmediareq ifmr; 19428679Sbrian 1956059Samurai memset(&ifmr, 0, sizeof(ifmr)); 1966059Samurai strcpy(ifmr.ifm_name, aif->pub.ifp->name); 1976059Samurai 19828679Sbrian if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) < 0) { 19928679Sbrian syslog(LOG_ERR, "SIOCGIFMEDIA: %m"); 20028679Sbrian aif->pub.mode = ATMIF_SUNI_MODE_UNKNOWN; 20128679Sbrian return (SNMP_ERR_GENERR); 2026059Samurai } 20328679Sbrian if (ifmr.ifm_current & IFM_ATM_SDH) 20428679Sbrian aif->pub.mode = ATMIF_SUNI_MODE_SDH; 20528679Sbrian else 2066059Samurai aif->pub.mode = ATMIF_SUNI_MODE_SONET; 2076059Samurai 20828679Sbrian return (SNMP_ERR_NOERROR); 2096059Samurai} 2106059Samurai 21128679Sbrian/* 21228679Sbrian * Change the SUNI mod 21328679Sbrian */ 2146059Samuraistatic int 21526516Sbrianatmif_set_mode(struct atmif_priv *aif, int newmode) 21628679Sbrian{ 21726516Sbrian struct ifmediareq ifmr; 21826516Sbrian struct ifreq ifr; 2196059Samurai 2206059Samurai memset(&ifmr, 0, sizeof(ifmr)); 22128679Sbrian strcpy(ifmr.ifm_name, aif->pub.ifp->name); 22228679Sbrian 2236059Samurai /* get current mode */ 22428679Sbrian if (ioctl(mib_netsock, SIOCGIFMEDIA, &ifmr) < 0) { 22528679Sbrian syslog(LOG_ERR, "SIOCGIFMEDIA: %m"); 2266059Samurai return (SNMP_ERR_GENERR); 22728679Sbrian } 2286059Samurai 2296059Samurai memset(&ifr, 0, sizeof(ifr)); 2306059Samurai strcpy(ifr.ifr_name, aif->pub.ifp->name); 2316059Samurai 23226516Sbrian ifr.ifr_media = ifmr.ifm_current; 23328679Sbrian if (newmode == ATMIF_SUNI_MODE_SDH) 2346059Samurai ifr.ifr_media |= IFM_ATM_SDH; 2356059Samurai else 2366059Samurai ifr.ifr_media &= ~IFM_ATM_SDH; 2376059Samurai 2386059Samurai if (ioctl(mib_netsock, SIOCSIFMEDIA, &ifr) < 0) { 23928679Sbrian syslog(LOG_ERR, "SIOCSIFMEDIA: %m"); 2406059Samurai return (SNMP_ERR_GENERR); 24128679Sbrian } 2426059Samurai 2436059Samurai aif->pub.mode = newmode; 2446059Samurai return (SNMP_ERR_NOERROR); 24528679Sbrian} 2466059Samurai 2476059Samurai/* 2486059Samurai * Attach to an ATM interface 2496059Samurai */ 2506059Samuraistatic void 2516059Samuraiattach_if(struct mibif *ifp) 25230715Sbrian{ 25313733Sdfr struct atmif_priv *aif; 2546059Samurai 25531272Sbrian /* we should not know it */ 2566059Samurai TAILQ_FOREACH(aif, &atmif_list, link) 2576059Samurai if (aif->pub.ifp == ifp) { 2586059Samurai syslog(LOG_CRIT, "new ATM if already known '%s'", 2596059Samurai ifp->name); 2606059Samurai return; 2616059Samurai } 2626059Samurai 2636059Samurai /* 26428679Sbrian * tap it 2656059Samurai */ 2666059Samurai if ((aif = malloc(sizeof(*aif))) == NULL) { 2676059Samurai syslog(LOG_ERR, "new atmif: %m"); 2686059Samurai return; 2696059Samurai } 2706059Samurai memset(aif, 0, sizeof(*aif)); 2716059Samurai 2726059Samurai aif->pub.ifp = ifp; 27326692Sbrian aif->index = ifp->index; 27426692Sbrian 2756059Samurai if (atmif_sys_attach_if(aif)) { 27626516Sbrian free(aif); 27726692Sbrian return; 2786059Samurai } 27928679Sbrian 2808857Srgrimes aif->ifpreg = mibif_notify(ifp, module, atmif_notify, aif); 28126692Sbrian 28228679Sbrian aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; 28328679Sbrian atmif_check_carrier(aif); 28428679Sbrian (void)atmif_get_mode(aif); 28526692Sbrian 2866059Samurai INSERT_OBJECT_INT(aif, &atmif_list); 2876059Samurai 2886059Samurai last_change = this_tick; 2896059Samurai 29026692Sbrian return; 29128679Sbrian} 29228679Sbrian 29328679Sbrian/* 29428679Sbrian * Function gets called when a new interface is created. If this is an 29528679Sbrian * ATM interface, hook in. Claim the interface in any case even when 29628679Sbrian * the creation of our data structures fails. 29728679Sbrian */ 2986059Samuraistatic int 2996059Samurainew_if(struct mibif *ifp) 3006059Samurai{ 30126692Sbrian if (!started || ifp->mib.ifmd_data.ifi_type != IFT_ATM || 30228679Sbrian ifp->xnotify != NULL) 30328679Sbrian return (0); 30428679Sbrian 30528679Sbrian attach_if(ifp); 30628679Sbrian return (1); 30728679Sbrian} 30828679Sbrian 3096059Samurai/* 3106059Samurai * Start the module 3116059Samurai */ 31228679Sbrianstatic void 3136059Samuraiatm_start(void) 3146059Samurai{ 31513733Sdfr struct mibif *ifp; 3166059Samurai 31728679Sbrian reg_atm = or_register(&oid_begemotAtm, 3186059Samurai "The Begemot MIB for ATM interfaces.", module); 31926692Sbrian 3206059Samurai started = 1; 32128679Sbrian for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp)) 32228679Sbrian if (ifp->mib.ifmd_data.ifi_type == IFT_ATM && 32328679Sbrian ifp->xnotify == NULL) 32428679Sbrian attach_if(ifp); 32528679Sbrian} 32628679Sbrian 3276059Samurai/* 3286059Samurai * Called when modules is loaded 32926692Sbrian */ 33028679Sbrianstatic int 33128679Sbrianatm_init(struct lmodule *mod, int argc __unused, char *argv[] __unused) 33228679Sbrian{ 3336059Samurai module = mod; 3346059Samurai 33528679Sbrian /* register to get creation messages for ATM interfaces */ 33628679Sbrian if (mib_register_newif(new_if, module)) { 33728679Sbrian syslog(LOG_ERR, "cannot register newif function: %m"); 33828679Sbrian return (-1); 3396059Samurai } 34028679Sbrian 3416059Samurai return (0); 3426059Samurai} 34328679Sbrian 34426692Sbrian/* 34528679Sbrian * Called when module gets unloaded - free all resources 34628679Sbrian */ 34728679Sbrianstatic int 34828679Sbrianatm_fini(void) 3496059Samurai{ 3506059Samurai struct atmif_priv *aif; 3516059Samurai 3526059Samurai while ((aif = TAILQ_FIRST(&atmif_list)) != NULL) 35326692Sbrian atmif_destroy(aif); 35413733Sdfr 35531142Sbrian mib_unregister_newif(module); 35631142Sbrian or_unregister(reg_atm); 35728679Sbrian 35828679Sbrian return (0); 35928679Sbrian} 3606059Samurai 36128679Sbrian/* 36231142Sbrian * Other module unloaded/loaded 36331142Sbrian */ 36430715Sbrianstatic void 3656735Samuraiatm_loading(const struct lmodule *mod, int loading) 36631142Sbrian{ 36731142Sbrian struct atmif_priv *aif; 36830715Sbrian struct atmif_reg *r0, *r1; 3696735Samurai 37028679Sbrian if (!loading) { 3716059Samurai /* remove notifications for this module */ 3726059Samurai TAILQ_FOREACH(aif, &atmif_list, link) 3736059Samurai TAILQ_FOREACH_SAFE(r0, &aif->notify, link, r1) { 3746059Samurai if (r0->mod == mod) { 37528679Sbrian TAILQ_REMOVE(&aif->notify, r0, link); 37628679Sbrian free(r0); 3776059Samurai } 3786059Samurai } 3796059Samurai } 38031343Sbrian} 3816059Samurai 38231195Sbrianconst struct snmp_module config = { 38331195Sbrian .comment = "This module implements a private MIB for ATM interfaces.", 3846059Samurai .init = atm_init, 38528679Sbrian .fini = atm_fini, 38630715Sbrian .start = atm_start, 3876059Samurai .tree = atm_ctree, 3886059Samurai .tree_size = atm_CTREE_SIZE, 3896059Samurai .loading = atm_loading 3906059Samurai}; 39131343Sbrian 39220365Sjkh/* 39331343Sbrian * Get the interface point for a table access 39426031Sbrian */ 39526031Sbrianint 39626031Sbrianatmif_get_aif(struct snmp_value *value, u_int sub, enum snmp_op op, 39731195Sbrian struct atmif_priv **aifp) 39831195Sbrian{ 39926031Sbrian switch (op) { 40026031Sbrian 40126516Sbrian case SNMP_OP_GETNEXT: 40226031Sbrian if ((*aifp = NEXT_OBJECT_INT(&atmif_list, 40326031Sbrian &value->var, sub)) == NULL) 40426031Sbrian return (SNMP_ERR_NOSUCHNAME); 40526031Sbrian value->var.len = sub + 1; 40628679Sbrian value->var.subs[sub] = (*aifp)->index; 40731195Sbrian break; 40828679Sbrian 40928679Sbrian case SNMP_OP_GET: 41026031Sbrian if ((*aifp = FIND_OBJECT_INT(&atmif_list, 41131272Sbrian &value->var, sub)) == NULL) 41226031Sbrian return (SNMP_ERR_NOSUCHNAME); 41331195Sbrian break; 41431962Sbrian 41531195Sbrian case SNMP_OP_SET: 41626031Sbrian if ((*aifp = FIND_OBJECT_INT(&atmif_list, 41730092Sbrian &value->var, sub)) == NULL) 41830092Sbrian return (SNMP_ERR_NO_CREATION); 41930092Sbrian break; 42030092Sbrian 42130092Sbrian case SNMP_OP_ROLLBACK: 42226031Sbrian case SNMP_OP_COMMIT: 42326031Sbrian if ((*aifp = FIND_OBJECT_INT(&atmif_list, 42431195Sbrian &value->var, sub)) == NULL) 42531195Sbrian abort(); 42628679Sbrian return (SNMP_ERR_NOERROR); 42731962Sbrian } 42831962Sbrian 42931962Sbrian if ((*aifp)->pub.mib->pcr == 0) { 43031195Sbrian mib_fetch_ifmib((*aifp)->pub.ifp); 43128679Sbrian atmif_sys_fill_mib(*aifp); 43230092Sbrian atmif_check_carrier(*aifp); 43330092Sbrian } 43430092Sbrian 43530092Sbrian return (SNMP_ERR_NOERROR); 43630092Sbrian} 43731195Sbrian 43828679Sbrian/* 43926031Sbrian * Table of all ATM interfaces 44028679Sbrian */ 44131195Sbrianint 44231962Sbrianop_atmif(struct snmp_context *ctx __unused, struct snmp_value *value, 44331195Sbrian u_int sub, u_int vindex __unused, enum snmp_op op) 44431195Sbrian{ 44528679Sbrian struct atmif_priv *aif; 44626031Sbrian int err; 44731195Sbrian 44831962Sbrian if ((err = atmif_get_aif(value, sub, op, &aif)) != SNMP_ERR_NOERROR) 44931195Sbrian return (err); 45026031Sbrian 45126031Sbrian if (op == SNMP_OP_SET) { 45231343Sbrian switch (value->var.subs[sub - 1]) { 45331343Sbrian 45431343Sbrian default: 45531195Sbrian return (SNMP_ERR_NOT_WRITEABLE); 45626031Sbrian 45726031Sbrian case LEAF_begemotAtmIfMode: 45826031Sbrian if ((err = atmif_get_mode(aif)) != SNMP_ERR_NOERROR) 45931272Sbrian return (err); 46031962Sbrian if (aif->pub.mode == ATMIF_SUNI_MODE_UNKNOWN) 46131195Sbrian return (SNMP_ERR_INCONS_VALUE); 46226031Sbrian if (value->v.integer != ATMIF_SUNI_MODE_SONET && 46330092Sbrian value->v.integer != ATMIF_SUNI_MODE_SDH) 46430092Sbrian return (SNMP_ERR_WRONG_VALUE); 46530092Sbrian if ((u_int)value->v.integer == aif->pub.mode) 46630092Sbrian return (SNMP_ERR_NOERROR); 4676059Samurai return (atmif_set_mode(aif, value->v.integer)); 4686059Samurai } 4696059Samurai abort(); 4706059Samurai } 4716059Samurai 4726059Samurai switch (value->var.subs[sub - 1]) { 47328679Sbrian 4746059Samurai case LEAF_begemotAtmIfName: 4756059Samurai return (string_get(value, aif->pub.ifp->name, -1)); 47628679Sbrian 4776059Samurai case LEAF_begemotAtmIfPcr: 4786059Samurai value->v.uint32 = aif->pub.mib->pcr; 4796059Samurai return (SNMP_ERR_NOERROR); 4806059Samurai 48130715Sbrian case LEAF_begemotAtmIfMedia: 4826059Samurai value->v.integer = aif->pub.mib->media; 4836059Samurai return (SNMP_ERR_NOERROR); 4846059Samurai 48530715Sbrian case LEAF_begemotAtmIfVpiBits: 4868857Srgrimes value->v.uint32 = aif->pub.mib->vpi_bits; 4877001Samurai return (SNMP_ERR_NOERROR); 4887001Samurai 4897001Samurai case LEAF_begemotAtmIfVciBits: 49030715Sbrian value->v.uint32 = aif->pub.mib->vci_bits; 49128679Sbrian return (SNMP_ERR_NOERROR); 49213733Sdfr 49328679Sbrian case LEAF_begemotAtmIfMaxVpcs: 49430715Sbrian value->v.uint32 = aif->pub.mib->max_vpcs; 49528679Sbrian return (SNMP_ERR_NOERROR); 49628679Sbrian 4977001Samurai case LEAF_begemotAtmIfMaxVccs: 49828679Sbrian value->v.uint32 = aif->pub.mib->max_vccs; 4997001Samurai return (SNMP_ERR_NOERROR); 50030715Sbrian 5017001Samurai case LEAF_begemotAtmIfEsi: 5026059Samurai return (string_get(value, aif->pub.mib->esi, 6)); 5036059Samurai 5046059Samurai case LEAF_begemotAtmIfCarrierStatus: 5056059Samurai value->v.integer = aif->pub.carrier; 5066059Samurai return (SNMP_ERR_NOERROR); 50725630Sbrian 5086059Samurai case LEAF_begemotAtmIfMode: 5096059Samurai if ((err = atmif_get_mode(aif)) != SNMP_ERR_NOERROR) 5106059Samurai return (err); 51113733Sdfr value->v.integer = aif->pub.mode; 5126059Samurai return (SNMP_ERR_NOERROR); 5136059Samurai } 5146059Samurai abort(); 5156059Samurai} 51613733Sdfr 5176059Samurai/* 51831272Sbrian * Hardware table 51913733Sdfr */ 52028679Sbrianint 5216059Samuraiop_atmhw(struct snmp_context *ctx __unused, struct snmp_value *value, 5226059Samurai u_int sub, u_int vindex __unused, enum snmp_op op) 5236059Samurai{ 524 struct atmif_priv *aif; 525 int err; 526 527 if ((err = atmif_get_aif(value, sub, op, &aif)) != SNMP_ERR_NOERROR) 528 return (err); 529 if (op == SNMP_OP_SET) 530 return (SNMP_ERR_NOT_WRITEABLE); 531 532 switch (value->var.subs[sub - 1]) { 533 534 case LEAF_begemotAtmHWVendor: 535 return (atm_sys_get_hw_vendor(aif, value)); 536 537 case LEAF_begemotAtmHWDevice: 538 return (atm_sys_get_hw_device(aif, value)); 539 540 case LEAF_begemotAtmHWSerial: 541 value->v.uint32 = aif->pub.mib->serial; 542 return (SNMP_ERR_NOERROR); 543 544 case LEAF_begemotAtmHWVersion: 545 value->v.uint32 = aif->pub.mib->hw_version; 546 return (SNMP_ERR_NOERROR); 547 548 case LEAF_begemotAtmHWSoftVersion: 549 value->v.uint32 = aif->pub.mib->sw_version; 550 return (SNMP_ERR_NOERROR); 551 552 } 553 abort(); 554} 555 556/* 557 * Scalars 558 */ 559int 560op_atm(struct snmp_context *ctx __unused, struct snmp_value *value, 561 u_int sub, u_int vindex __unused, enum snmp_op op) 562{ 563 switch (op) { 564 565 case SNMP_OP_GETNEXT: 566 abort(); 567 568 case SNMP_OP_GET: 569 switch (value->var.subs[sub - 1]) { 570 571 case LEAF_begemotAtmIfTableLastChange: 572 value->v.uint32 = 573 (last_change == 0 ? 0 : last_change - start_tick); 574 return (SNMP_ERR_NOERROR); 575 } 576 abort(); 577 578 case SNMP_OP_SET: 579 return (SNMP_ERR_NOT_WRITEABLE); 580 581 case SNMP_OP_ROLLBACK: 582 case SNMP_OP_COMMIT: 583 abort(); 584 } 585 abort(); 586} 587 588/* 589 * Register for interface notifications 590 */ 591void * 592atm_notify_aif(struct atmif *pub, const struct lmodule *mod, 593 atmif_event_f func, void *arg) 594{ 595 struct atmif_priv *aif = (struct atmif_priv *)pub; 596 struct atmif_reg *r0; 597 598 if ((r0 = malloc(sizeof(*r0))) == NULL) { 599 syslog(LOG_CRIT, "out of memory"); 600 return (NULL); 601 } 602 r0->func = func; 603 r0->mod = mod; 604 r0->data = arg; 605 r0->aif = aif; 606 607 TAILQ_INSERT_TAIL(&aif->notify, r0, link); 608 609 return (r0); 610} 611 612/* 613 * Unregister it 614 */ 615void 616atm_unnotify_aif(void *arg) 617{ 618 struct atmif_reg *r0 = arg; 619 620 TAILQ_REMOVE(&r0->aif->notify, r0, link); 621 free(r0); 622} 623