/* * Copyright 2006 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. */ /* if_mth.c - method routines for the interfaces group */ /* modification history -------------------- 01h,02feb16,rjq Incorrect calling ipnet API(VXW6-217). 01g,22nov11,h_x Fix WIND00209696 01f,30jul09,y_t fix for the warnings 01e,02may07,mdk merge from spr-dev for spin45A 01d,21sep06,jbl use ipcom_socketioctl() instead of ipnet_socketioctl_islocked() 01c,20sep06,jbl trivial sets to ifAdminStatus shouldn't do anything 01b,20sep06,jbl clear up build warnings and errors 01a,08sep06,jbl patch up interfaces method routines */ #include #include #include #include #include #include #include #include #include "ip_mibleaf.h" #include #include #include #include #include #define IPNET_CODE_LOCK(handle) \ handle = ipnet_suspend_stack(); \ if (handle == IP_NULL) \ return; #define IPNET_CODE_UNLOCK(handle) \ ipnet_resume_stack(handle); /* * Method routines for the ifTable: * * ifIndex -- read-only * A unique value for each interface. Its value * ranges between 1 and the value of ifNumber. The * value for each interface must remain constant at * least from one re-initialization of the entity's * network management system to the next re- * initialization. * * ifDescr -- read-only * A textual string containing information about the * interface. This string should include the name of * the manufacturer, the product name and the version * of the hardware interface. * * ifType -- read-only * The type of interface, distinguished according to * the physical/link protocol(s) immediately `below' * the network layer in the protocol stack. * * ifMtu -- read-only * The size of the largest datagram which can be * sent/received on the interface, specified in * octets. For interfaces that are used for * transmitting network datagrams, this is the size * of the largest network datagram that can be sent * on the interface. * * ifSpeed -- read-only * An estimate of the interface's current bandwidth * in bits per second. For interfaces which do not * vary in bandwidth or for those where no accurate * estimation can be made, this object should contain * the nominal bandwidth. * * ifPhysAddress -- read-only * The interface's address at the protocol layer * immediately `below' the network layer in the * protocol stack. For interfaces which do not have * such an address (e.g., a serial line), this object * should contain an octet string of zero length. * * ifAdminStatus -- read-write * The desired state of the interface. The * testing(3) state indicates that no operational * packets can be passed. * * ifOperStatus -- read-only * The current operational state of the interface. * The testing(3) state indicates that no operational * packets can be passed. * * ifLastChange -- read-only * The value of sysUpTime at the time the interface * entered its current operational state. If the * current state was entered prior to the last re- * initialization of the local network management * subsystem, then this object contains a zero * value. * * ifInOctets -- read-only * The total number of octets received on the * interface, including framing characters. * * ifInUcastPkts -- read-only * The number of subnetwork-unicast packets * delivered to a higher-layer protocol. * * ifInNUcastPkts -- read-only * The number of non-unicast (i.e., subnetwork- * broadcast or subnetwork-multicast) packets * delivered to a higher-layer protocol. * * ifInDiscards -- read-only * The number of inbound packets which were chosen * to be discarded even though no errors had been * detected to prevent their being deliverable to a * higher-layer protocol. One possible reason for * discarding such a packet could be to free up * buffer space. * * ifInErrors -- read-only * The number of inbound packets that contained * errors preventing them from being deliverable to a * higher-layer protocol. * * ifInUnknownProtos -- read-only * The number of packets received via the interface * which were discarded because of an unknown or * unsupported protocol. * * ifOutOctets -- read-only * The total number of octets transmitted out of the * interface, including framing characters. * * ifOutUcastPkts -- read-only * The total number of packets that higher-level * protocols requested be transmitted to a * subnetwork-unicast address, including those that * were discarded or not sent. * * ifOutNUcastPkts -- read-only * The total number of packets that higher-level * protocols requested be transmitted to a non- * unicast (i.e., a subnetwork-broadcast or * subnetwork-multicast) address, including those * that were discarded or not sent. * * ifOutDiscards -- read-only * The number of outbound packets which were chosen * to be discarded even though no errors had been * detected to prevent their being transmitted. One * possible reason for discarding such a packet could * be to free up buffer space. * * ifOutErrors -- read-only * The number of outbound packets that could not be * transmitted because of errors. * * Method routines for the ifXTable: * * ifName -- read-only * The textual name of the interface. The value of this * object should be the name of the interface as assigned by * the local device and should be suitable for use in commands * entered at the device's `console'. This might be a text * name, such as `le0' or a simple port number, such as `1', * depending on the interface naming syntax of the device. If * several entries in the ifTable together represent a single * interface as named by the device, then each will have the * same value of ifName. Note that for an agent which responds * to SNMP queries concerning an interface on some other * (proxied) device, then the value of ifName for such an * interface is the proxied device's local name for it. * * If there is no local name, or this object is otherwise not * applicable, then this object contains a zero-length string. * * ifInMulticastPkts -- read-only * The number of packets, delivered by this sub-layer to a * higher (sub-)layer, which were addressed to a multicast * address at this sub-layer. For a MAC layer protocol, this * includes both Group and Functional addresses. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifInBroadcastPkts -- read-only * The number of packets, delivered by this sub-layer to a * higher (sub-)layer, which were addressed to a broadcast * address at this sub-layer. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifOutMulticastPkts -- read-only * The total number of packets that higher-level protocols * requested be transmitted, and which were addressed to a * multicast address at this sub-layer, including those that * were discarded or not sent. For a MAC layer protocol, this * includes both Group and Functional addresses. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifOutBroadcastPkts -- read-only * The total number of packets that higher-level protocols * requested be transmitted, and which were addressed to a * broadcast address at this sub-layer, including those that * were discarded or not sent. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCInOctets -- read-only * The total number of octets received on the interface, * including framing characters. This object is a 64-bit * version of ifInOctets. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCInUcastPkts -- read-only * The number of packets, delivered by this sub-layer to a * higher (sub-)layer, which were not addressed to a multicast * or broadcast address at this sub-layer. This object is a * 64-bit version of ifInUcastPkts. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCInMulticastPkts -- read-only * The number of packets, delivered by this sub-layer to a * higher (sub-)layer, which were addressed to a multicast * address at this sub-layer. For a MAC layer protocol, this * includes both Group and Functional addresses. This object * is a 64-bit version of ifInMulticastPkts. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCInBroadcastPkts -- read-only * The number of packets, delivered by this sub-layer to a * higher (sub-)layer, which were addressed to a broadcast * address at this sub-layer. This object is a 64-bit version * of ifInBroadcastPkts. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCOutOctets -- read-only * The total number of octets transmitted out of the * interface, including framing characters. This object is a * 64-bit version of ifOutOctets. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCOutUcastPkts -- read-only * The total number of packets that higher-level protocols * requested be transmitted, and which were not addressed to a * multicast or broadcast address at this sub-layer, including * those that were discarded or not sent. This object is a * 64-bit version of ifOutUcastPkts. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCOutMulticastPkts -- read-only * The total number of packets that higher-level protocols * requested be transmitted, and which were addressed to a * multicast address at this sub-layer, including those that * were discarded or not sent. For a MAC layer protocol, this * includes both Group and Functional addresses. This object * is a 64-bit version of ifOutMulticastPkts. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifHCOutBroadcastPkts -- read-only * The total number of packets that higher-level protocols * requested be transmitted, and which were addressed to a * broadcast address at this sub-layer, including those that * were discarded or not sent. This object is a 64-bit version * of ifOutBroadcastPkts. * * Discontinuities in the value of this counter can occur at * re-initialization of the management system, and at other * times as indicated by the value of * ifCounterDiscontinuityTime. * * ifLinkUpDownTrapEnable -- read-write * Indicates whether linkUp/linkDown traps should be generated * for this interface. * * By default, this object should have the value enabled(1) for * interfaces which do not operate on 'top' of any other * interface (as defined in the ifStackTable), and disabled(2) * otherwise. * * ifHighSpeed -- read-only * An estimate of the interface's current bandwidth in units * of 1,000,000 bits per second. If this object reports a * value of `n' then the speed of the interface is somewhere in * the range of `n-500,000' to `n+499,999'. For interfaces * which do not vary in bandwidth or for those where no * accurate estimation can be made, this object should contain * the nominal bandwidth. For a sub-layer which has no concept * of bandwidth, this object should be zero. * * ifPromiscuousMode -- read-write * This object has a value of false(2) if this interface only * accepts packets/frames that are addressed to this station. * This object has a value of true(1) when the station accepts * all packets/frames transmitted on the media. The value * true(1) is only legal on certain types of media. If legal, * setting this object to a value of true(1) may require the * interface to be reset before becoming effective. * * The value of ifPromiscuousMode does not affect the reception * of broadcast and multicast packets/frames by the interface. * * ifConnectorPresent -- read-only * This object has the value 'true(1)' if the interface * sublayer has a physical connector and the value 'false(2)' * otherwise. * * ifAlias -- read-write * This object is an 'alias' name for the interface as * specified by a network manager, and provides a non-volatile * 'handle' for the interface. * * On the first instantiation of an interface, the value of * ifAlias associated with that interface is the zero-length * string. As and when a value is written into an instance of * ifAlias through a network management set operation, then the * agent must retain the supplied value in the ifAlias instance * associated with the same interface for as long as that * interface remains instantiated, including across all re- * initializations/reboots of the network management system, * including those which result in a change of the interface's * ifIndex value. * * An example of the value which a network manager might store * in this object for a WAN interface is the (Telco's) circuit * number/identifier of the interface. * * Some agents may support write-access only for interfaces * having particular values of ifType. An agent which supports * write access to this object is required to keep the value in * non-volatile storage, but it may limit the length of new * values depending on how much storage is already occupied by * the current values for other interfaces. * * ifCounterDiscontinuityTime -- read-only * The value of sysUpTime on the most recent occasion at which * any one or more of this interface's counters suffered a * discontinuity. The relevant counters are the specific * instances associated with this interface of any Counter32 or * Counter64 object contained in the ifTable or ifXTable. If * no such discontinuities have occurred since the last re- * initialization of the local management subsystem, then this * object contains a zero value. */ /* An internal routine to retrieve the values of the variables, used * by the method routines ifEntry_get and ifEntry_next. */ static int ifEntry_get_value ( OIDC_T lastmatch, SNMP_PKT_T *pktp, VB_T *vbp, Ipnet_netif *netif ) { if (STRCMP (VB_TO_COOKIE (vbp), "_ifTable") == 0) { switch(lastmatch) { case LEAF_ifIndex: getproc_got_int32(pktp, vbp, netif->ipcom.ifindex); break; case LEAF_ifDescr: getproc_got_octet_string(pktp, vbp, (ALENGTH_T)ipcom_strlen(netif->ipcom.name), (OCTET_T *) netif->ipcom.name, VT_STRING); break; case LEAF_ifType: /* Values: * other(1) = VAL_ifType_other * regular1822(2) = VAL_ifType_regular1822 * hdh1822(3) = VAL_ifType_hdh1822 * ddnX25(4) = VAL_ifType_ddnX25 * rfc877x25(5) = VAL_ifType_rfc877x25 * ethernetCsmacd(6) = VAL_ifType_ethernetCsmacd * iso88023Csmacd(7) = VAL_ifType_iso88023Csmacd * iso88024TokenBus(8) = VAL_ifType_iso88024TokenBus * iso88025TokenRing(9) = VAL_ifType_iso88025TokenRing * iso88026Man(10) = VAL_ifType_iso88026Man * starLan(11) = VAL_ifType_starLan * proteon10Mbit(12) = VAL_ifType_proteon10Mbit * proteon80Mbit(13) = VAL_ifType_proteon80Mbit * hyperchannel(14) = VAL_ifType_hyperchannel * fddi(15) = VAL_ifType_fddi * lapb(16) = VAL_ifType_lapb * sdlc(17) = VAL_ifType_sdlc * ds1(18) = VAL_ifType_ds1 * e1(19) = VAL_ifType_e1 * basicISDN(20) = VAL_ifType_basicISDN * primaryISDN(21) = VAL_ifType_primaryISDN * propPointToPointSerial(22) = VAL_ifType_propPointToPointSerial * ppp(23) = VAL_ifType_ppp * softwareLoopback(24) = VAL_ifType_softwareLoopback * eon(25) = VAL_ifType_eon * ethernet3Mbit(26) = VAL_ifType_ethernet3Mbit * nsip(27) = VAL_ifType_nsip * slip(28) = VAL_ifType_slip * ultra(29) = VAL_ifType_ultra * ds3(30) = VAL_ifType_ds3 * sip(31) = VAL_ifType_sip * frameRelay(32) = VAL_ifType_frameRelay * rs232(33) = VAL_ifType_rs232 * para(34) = VAL_ifType_para * arcnet(35) = VAL_ifType_arcnet * arcnetPlus(36) = VAL_ifType_arcnetPlus * atm(37) = VAL_ifType_atm * miox25(38) = VAL_ifType_miox25 * sonet(39) = VAL_ifType_sonet * x25ple(40) = VAL_ifType_x25ple * iso88022llc(41) = VAL_ifType_iso88022llc * localTalk(42) = VAL_ifType_localTalk * smdsDxi(43) = VAL_ifType_smdsDxi * frameRelayService(44) = VAL_ifType_frameRelayService * v35(45) = VAL_ifType_v35 * hssi(46) = VAL_ifType_hssi * hippi(47) = VAL_ifType_hippi * modem(48) = VAL_ifType_modem * aal5(49) = VAL_ifType_aal5 * sonetPath(50) = VAL_ifType_sonetPath * sonetVT(51) = VAL_ifType_sonetVT * smdsIcip(52) = VAL_ifType_smdsIcip * propVirtual(53) = VAL_ifType_propVirtual * propMultiplexor(54) = VAL_ifType_propMultiplexor */ getproc_got_int32(pktp, vbp, netif->ipcom.type); break; case LEAF_ifMtu: getproc_got_int32(pktp, vbp, netif->ipcom.mtu); break; case LEAF_ifSpeed: if (netif->ipcom.type == IP_IFT_PPP) getproc_got_uint32(pktp, vbp, IPCOM_DRV_PPP_BAUDRATE, VT_GAUGE); else getproc_got_uint32(pktp, vbp, 100000000, VT_GAUGE); break; case LEAF_ifPhysAddress: getproc_got_octet_string(pktp, vbp, netif->ipcom.link_addr_size, netif->ipcom.link_addr, VT_STRING); break; case LEAF_ifAdminStatus: /* Values: * up(1) = VAL_ifAdminStatus_up * down(2) = VAL_ifAdminStatus_down * testing(3) = VAL_ifAdminStatus_testing */ if (IP_BIT_ISSET (netif->ipcom.flags, IP_IFF_UP)) getproc_got_int32(pktp, vbp, VAL_ifAdminStatus_up); else getproc_got_int32(pktp, vbp, VAL_ifAdminStatus_down); break; case LEAF_ifOperStatus: /* Values: * up(1) = VAL_ifOperStatus_up * down(2) = VAL_ifOperStatus_down * testing(3) = VAL_ifOperStatus_testing * unknown(4) = VAL_ifOperStatus_unknown * dormant(5) = VAL_ifOperStatus_dormant * notPresent(6) = VAL_ifOperStatus_notPresent * lowerLayerDown(7) = VAL_ifOperStatus_lowerLayerDown */ if (IP_BIT_ARESET (netif->ipcom.flags, IP_IFF_UP | IP_IFF_RUNNING)) getproc_got_int32(pktp, vbp, VAL_ifOperStatus_up); else getproc_got_int32(pktp, vbp, VAL_ifOperStatus_down); break; case LEAF_ifLastChange: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifLastChange, VT_TIMETICKS); break; case LEAF_ifInOctets: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInOctets, VT_COUNTER); break; case LEAF_ifInUcastPkts: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInUcastPkts, VT_COUNTER); break; case LEAF_ifInDiscards: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInDiscards, VT_COUNTER); break; case LEAF_ifInErrors: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInErrors, VT_COUNTER); break; case LEAF_ifInUnknownProtos: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInUnknownProtos, VT_COUNTER); break; case LEAF_ifOutOctets: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifOutOctets, VT_COUNTER); break; case LEAF_ifOutUcastPkts: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifOutUcastPkts, VT_COUNTER); break; case LEAF_ifOutDiscards: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifOutDiscards, VT_COUNTER); break; case LEAF_ifOutErrors: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifOutErrors, VT_COUNTER); break; default: return GEN_ERR; } } else if (STRCMP (VB_TO_COOKIE (vbp), "_ifXTable") == 0) { switch (lastmatch) { case LEAF_ifName: getproc_got_octet_string(pktp, vbp, (ALENGTH_T)ipcom_strlen(netif->ipcom.name), (OCTET_T *)netif->ipcom.name, VT_STRING); break; case LEAF_ifInMulticastPkts: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInMulticastPkts, VT_COUNTER); break; case LEAF_ifInBroadcastPkts: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifInBroadcastPkts, VT_COUNTER); break; case LEAF_ifOutMulticastPkts: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifOutMulticastPkts, VT_COUNTER); break; case LEAF_ifOutBroadcastPkts: getproc_got_uint32(pktp, vbp, netif->ipcom.mib2.ifOutBroadcastPkts, VT_COUNTER); break; case LEAF_ifLinkUpDownTrapEnable: /* Values: * enabled(1) = VAL_ifLinkUpDownTrapEnable_enabled * disabled(2) = VAL_ifLinkUpDownTrapEnable_disabled */ if (netif->ipcom.mib2.ifLinkUpDownTrapEnable == 0) netif->ipcom.mib2.ifLinkUpDownTrapEnable = VAL_ifLinkUpDownTrapEnable_enabled; getproc_got_int32(pktp, vbp, netif->ipcom.mib2.ifLinkUpDownTrapEnable); break; case LEAF_ifHighSpeed: if (netif->ipcom.type == IP_IFT_PPP) getproc_got_uint32(pktp, vbp, 0, VT_GAUGE); else getproc_got_uint32(pktp, vbp, 100, VT_GAUGE); break; case LEAF_ifPromiscuousMode: /* Values: * true(1) = VAL_ifPromiscuousMode_true * false(2) = VAL_ifPromiscuousMode_false */ if (IP_BIT_ISSET (netif->ipcom.flags, IP_IFF_PROMISC)) getproc_got_int32(pktp, vbp, VAL_ifPromiscuousMode_true); else getproc_got_int32(pktp, vbp, VAL_ifPromiscuousMode_false); break; case LEAF_ifConnectorPresent: /* Values: * true(1) = VAL_ifConnectorPresent_true * false(2) = VAL_ifConnectorPresent_false */ getproc_got_int32(pktp, vbp, VAL_ifConnectorPresent_false); break; case LEAF_ifAlias: getproc_got_octet_string(pktp, vbp, 0, IP_NULL, VT_STRING); break; case LEAF_ifCounterDiscontinuityTime: getproc_got_uint32(pktp, vbp, 0, VT_TIMETICKS); break; default: return GEN_ERR; } } else return GEN_ERR; return NO_ERROR; } #define ifEntry_INSTANCE_LEN 1 void ifEntry_get ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipnet_netif *best_netif; bits32_t *ifindexes; int ifTable_num_entries; int i; int error; void * suspend_handle; IPNET_CODE_LOCK(suspend_handle); /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance(pktp, vbp, tcount, tlist); if (tcount != ifEntry_INSTANCE_LEN) { for ( ; vbp ; vbp = vbp->vb_link ) getproc_nosuchins (pktp, vbp); IPNET_CODE_UNLOCK(suspend_handle); return; } ifindexes = (bits32_t *)ipnet_if_get_index_array (IPCOM_VR_ANY, 0, (unsigned *)&ifTable_num_entries); if (ifindexes == IP_NULL) { for ( ; vbp ; vbp = vbp->vb_link ) getproc_nosuchins (pktp, vbp); IPNET_CODE_UNLOCK(suspend_handle); return; } best_netif = 0; for ( i=0; i < ifTable_num_entries ; i++ ) if (ifindexes[i] == tlist[0]) { best_netif = ipnet_if_indextonetif(IPCOM_VR_ANY, ifindexes[i]); break; } if (best_netif == IP_NULL) for ( ; vbp ; vbp = vbp->vb_link ) getproc_nosuchins (pktp, vbp); else { for ( ; vbp; vbp = vbp->vb_link) { if ((error = ifEntry_get_value(vbp->vb_ml.ml_last_match, pktp, vbp, best_netif)) != NO_ERROR) getproc_error(pktp, vbp, error); } } SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); } void ifEntry_next ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipnet_netif *best_netif = 0; OIDC_T best_inst; bits32_t *ifindexes; int ifTable_num_entries; bits32_t baseInstance; int i; int error; void * suspend_handle; IPNET_CODE_LOCK(suspend_handle); /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance(pktp, vbp, tcount, tlist); ifindexes = (bits32_t *)ipnet_if_get_index_array (IPCOM_VR_ANY, 0, (unsigned *)&ifTable_num_entries); if (ifindexes == IP_NULL) { for ( ; vbp ; vbp = vbp->vb_link) nextproc_no_next (pktp, vbp); IPNET_CODE_UNLOCK(suspend_handle); return; } best_inst = 0; if (tcount == 0) baseInstance = 0; else baseInstance = tlist[0]; for (i = 0; i < ifTable_num_entries; i++) { if ((ifindexes[i] > baseInstance) && ((best_inst == 0) || (ifindexes[i] < best_inst))) { best_inst = ifindexes[i]; } } if (best_inst != 0) { best_netif = ipnet_if_indextonetif (IPCOM_VR_ANY, best_inst); if (best_netif == IP_NULL) { nextproc_error(pktp, vbp, GEN_ERR); SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); return; } for ( ; vbp ; vbp = vbp->vb_link ) { if ((error = ifEntry_get_value(vbp->vb_ml.ml_last_match, pktp, vbp, best_netif)) == NO_ERROR) nextproc_next_instance(pktp, vbp, ifEntry_INSTANCE_LEN, &best_inst); else nextproc_error(pktp, vbp, error); } } else /* there's no more in this table */ for ( ; vbp ; vbp = vbp->vb_link ) nextproc_no_next(pktp, vbp); SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); } static int check_nvt ( OCTET_T *cp, size_t len ) { while (len--) { if ((*cp & 0200) != 0) return -1; if (*cp++ == '\r') { if (len-- == 0) return -1; if ((*cp == '\n') || (*cp == 0)) cp++; else return -1; } } return 0; } void ifEntry_test ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipnet_netif *best_netif = IP_NULL; bits32_t *ifindexes; int ifTable_num_entries; int i; VB_T *group_vbp; void * suspend_handle; IPNET_CODE_LOCK(suspend_handle); /* find all the varbinds that share the same getproc and instance and * group them together. */ group_by_getproc_and_instance(pktp, vbp, tcount, tlist); if (tcount != ifEntry_INSTANCE_LEN) { for ( ; vbp ; vbp = vbp->vb_link ) testproc_error (pktp, vbp, NO_SUCH_NAME); IPNET_CODE_UNLOCK(suspend_handle); return; } ifindexes = (bits32_t *)ipnet_if_get_index_array (IPCOM_VR_ANY, 0, (unsigned *) &ifTable_num_entries); if (ifindexes == IP_NULL) { for ( ; vbp ; vbp = vbp->vb_link ) testproc_error (pktp, vbp, NO_SUCH_NAME); IPNET_CODE_UNLOCK(suspend_handle); return; } for ( i=0 ; i < ifTable_num_entries ; i++ ) if (ifindexes[i] == tlist[0]) { best_netif = ipnet_if_indextonetif (IPCOM_VR_ANY, ifindexes[i]); break; } if (best_netif == IP_NULL) { for ( ; vbp ; vbp = vbp->vb_link ) testproc_error (pktp, vbp, NO_SUCH_NAME); SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); return; } /* stash the looked up information here for the setproc */ vbp->vb_priv = best_netif; /* now check each varbind */ for (group_vbp = vbp; group_vbp; group_vbp = group_vbp->vb_link) { if (STRCMP (VB_TO_COOKIE (group_vbp), "_ifTable") == 0) { switch (group_vbp->vb_ml.ml_last_match) { case LEAF_ifAdminStatus: switch (VB_GET_INT32(group_vbp)) { case VAL_ifAdminStatus_up: case VAL_ifAdminStatus_down: break; default: testproc_error(pktp, group_vbp, WRONG_VALUE); continue; } testproc_good (pktp, group_vbp); break; default: testproc_error(pktp, group_vbp, GEN_ERR); SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); return; } } else if (STRCMP (VB_TO_COOKIE (group_vbp), "_ifXTable") == 0) { switch (group_vbp->vb_ml.ml_last_match) { case LEAF_ifPromiscuousMode: testproc_error (pktp, group_vbp, WRONG_VALUE); break; case LEAF_ifAlias: { int errorType = 0; if (EBufferUsed (&group_vbp->value_u.v_string) > 64) errorType = WRONG_LENGTH; else if (check_nvt (EBufferStart (&vbp->value_u.v_string), EBufferUsed (&vbp->value_u.v_string))) errorType = WRONG_VALUE; testproc_error (pktp, group_vbp, errorType); break; } case LEAF_ifLinkUpDownTrapEnable: switch (VB_GET_INT32 (group_vbp)) { case VAL_ifLinkUpDownTrapEnable_enabled: case VAL_ifLinkUpDownTrapEnable_disabled: break; default: testproc_error (pktp, group_vbp, WRONG_VALUE); continue; } testproc_good (pktp, group_vbp); break; default: testproc_error (pktp, group_vbp, GEN_ERR); SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); return; } } else { testproc_error (pktp, group_vbp, GEN_ERR); SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); return; } } SNMP_memory_free(ifindexes); IPNET_CODE_UNLOCK(suspend_handle); } void ifEntry_set ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipnet_netif *best_netif = (Ipnet_netif *) vbp->vb_priv; struct Ip_ifreq ifreq; Ip_fd fd; void * suspend_handle; for ( ; vbp; vbp = vbp->vb_link) { if (STRCMP (VB_TO_COOKIE (vbp), "_ifTable") == 0) { switch (vbp->vb_ml.ml_last_match) { case LEAF_ifAdminStatus: if (((VB_GET_INT32 (vbp) == VAL_ifAdminStatus_up) && (IP_BIT_ISSET (best_netif->ipcom.flags, IP_IFF_UP))) || ((VB_GET_INT32 (vbp) == VAL_ifAdminStatus_down) && (!IP_BIT_ISSET (best_netif->ipcom.flags, IP_IFF_UP)))) setproc_good (pktp, vbp); else { fd = ipcom_socket (IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP); if (fd != IP_INVALID_SOCKET) { /* Change interface status */ ipcom_memset(&ifreq, 0, sizeof(struct Ip_ifreq)); ipcom_strcpy(ifreq.ifr_name, best_netif->ipcom.name); if (ipcom_socketioctl(fd, IP_SIOCGIFFLAGS, &ifreq) < 0) { setproc_error (pktp, vbp, COMMIT_FAILED); (void)ipcom_socketclose(fd); return; } if (VB_GET_INT32(vbp) == 1) IP_BIT_SET(ifreq.ip_ifr_flags, IP_IFF_UP); else IP_BIT_CLR(ifreq.ip_ifr_flags, (Ip_u16)IP_IFF_UP); if (ipcom_socketioctl(fd, IP_SIOCSIFFLAGS, &ifreq) < 0) { setproc_error (pktp, vbp, COMMIT_FAILED); (void)ipcom_socketclose(fd); return; } (void)ipcom_socketclose(fd); setproc_good(pktp, vbp); } else setproc_error (pktp, vbp, COMMIT_FAILED); } break; default: setproc_error(pktp, vbp, COMMIT_FAILED); return; } } else if (STRCMP (VB_TO_COOKIE (vbp), "_ifXTable") == 0) { switch (vbp->vb_ml.ml_last_match) { case LEAF_ifLinkUpDownTrapEnable: IPNET_CODE_LOCK(suspend_handle); best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = VB_GET_INT32 (vbp); IPNET_CODE_UNLOCK(suspend_handle); setproc_good (pktp, vbp); break; default: setproc_error (pktp, vbp, COMMIT_FAILED); return; } } else { setproc_error (pktp, vbp, COMMIT_FAILED); return; } } } /* * Method routines for the interfaces variables: * * ifNumber -- read-only * The number of network interfaces (regardless of * their current state) present on this system. * * ifTableLastChange -- read-only * The value of sysUpTime at the time of the last creation or deletion of an * entry in the ifTable. If the number of entries has been unchanged * since the last re-initialization of the local network management * subsystem, then this object contains a zero value." */ void interfaces_get ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { void * suspend_handle; IPNET_CODE_LOCK(suspend_handle); /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance(pktp, vbp, tcount, tlist); /* check that the instance is exactly .0 */ if (!((tcount == 1) && (*tlist == 0))) for ( ; vbp; vbp = vbp->vb_link) getproc_nosuchins(pktp, vbp); else for ( ; vbp; vbp = vbp->vb_link) switch (vbp->vb_ml.ml_last_match) { case LEAF_ifNumber: getproc_got_int32(pktp, vbp, IPNET_NETIF_NUM_ATTACHED); break; case LEAF_ifTableLastChange: getproc_got_uint32(pktp, vbp, 0, VT_TIMETICKS); break; default: getproc_error (pktp, vbp, GEN_ERR); } IPNET_CODE_UNLOCK(suspend_handle); }