/* * Copyright 2007 by egnite Software GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ */ #include #include #include #include #include #include "mib2if.h" #define MIB_IF_ENTRIES 4 #if defined(ETHERNUT1) || defined(XNUT_100) || defined(XNUT_105) || defined(CHARON2) #define PHY_NAME "RTL8019AS 10 Mbit Ethernet" #elif defined(ETHERNUT2) || defined(INTECH21) #define PHY_NAME "LAN91C111 100Mbit Ethernet" #elif defined(ETHERNUT3) #define PHY_NAME "DM9000E 100Mbit Ethernet" #elif defined(AT91SAM7X_EK) || defined(AT91SAM9260_EK) #define PHY_NAME "DM9161A 100Mbit Ethernet" #elif defined(ETHERNUT5) #define PHY_NAME "LAN8700I 100Mbit Ethernet" #else #define PHY_NAME "Ethernet" #endif static uint8_t *MibVarsIfGet(const SNMPVAR *, OID *, size_t *, int, size_t *, WMETHOD **); #define MAG_IF_NUMBER 0 #define MAG_IF_INDEX 1 #define MAG_IF_DESCR 2 #define MAG_IF_TYPE 3 #define MAG_IF_MTU 4 #define MAG_IF_SPEED 5 #define MAG_IF_PHYSADDRESS 6 #define MAG_IF_ADMINSTATUS 7 #define MAG_IF_OPERSTATUS 8 #define MAG_IF_LASTCHANGE 9 #define MAG_IF_INOCTETS 10 #define MAG_IF_INUCASTPKTS 11 #define MAG_IF_INNUCASTPKTS 12 #define MAG_IF_INDISCARDS 13 #define MAG_IF_INERRORS 14 #define MAG_IF_INUNKNOWNPROTOS 15 #define MAG_IF_OUTOCTETS 16 #define MAG_IF_OUTUCASTPKTS 17 #define MAG_IF_OUTNUCASTPKTS 18 #define MAG_IF_OUTDISCARDS 19 #define MAG_IF_OUTERRORS 20 #define MAG_IF_OUTQLEN 21 #define MAG_IF_SPECIFIC 22 static OID base_oid[] = { SNMP_OID_MIB2, 2 }; static size_t base_oidlen = sizeof(base_oid) / sizeof(OID); static SNMPVAR mib_variables[] = { {MAG_IF_NUMBER, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 1, {1}}, {MAG_IF_INDEX, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 1}}, {MAG_IF_DESCR, ASN_OCTET_STR, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 2}}, {MAG_IF_TYPE, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 3}}, {MAG_IF_MTU, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 4}}, {MAG_IF_SPEED, ASN_GAUGE, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 5}}, {MAG_IF_PHYSADDRESS, ASN_OCTET_STR, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 6}}, {MAG_IF_ADMINSTATUS, ASN_INTEGER, ACL_RWRITE, MibVarsIfGet, 3, {2, 1, 7}}, {MAG_IF_OPERSTATUS, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 8}}, {MAG_IF_LASTCHANGE, ASN_TIMETICKS, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 9}}, {MAG_IF_INOCTETS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 10}}, {MAG_IF_INUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 11}}, {MAG_IF_INNUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 12}}, {MAG_IF_INDISCARDS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 13}}, {MAG_IF_INERRORS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 14}}, {MAG_IF_INUNKNOWNPROTOS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 15}}, {MAG_IF_OUTOCTETS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 16}}, {MAG_IF_OUTUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 17}}, {MAG_IF_OUTNUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 18}}, {MAG_IF_OUTDISCARDS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 19}}, {MAG_IF_OUTERRORS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 20}}, {MAG_IF_OUTQLEN, ASN_GAUGE, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 21}}, {MAG_IF_SPECIFIC, ASN_OBJECT_ID, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 22}} }; static long if_number; static long if_type; static long if_mtu; static uint32_t if_speed; static long if_index; static char *if_descr; static OID if_specific[] = { 0, 0 }; static long if_admin_status[MIB_IF_ENTRIES]; /*! * \brief Register MIB II variables of the interfaces. * * \note Preliminary code with hard coded values. */ int MibRegisterIfVars(void) { int i; if_number = 1; for (i = 0; i < if_number; i++) { if_admin_status[i] = 1; } if_type = 6; if_mtu = 1500; if_speed = 100000000UL; if_index = 1; if ((if_descr = malloc(strlen(PHY_NAME) + 1)) != NULL) { strcpy(if_descr, PHY_NAME); } return SnmpMibRegister(base_oid, base_oidlen, mib_variables, sizeof(mib_variables) / sizeof(SNMPVAR)); } static int MibVarsIfSet(int action, uint8_t * var_val, uint8_t var_val_type, size_t var_val_len, OID * name, size_t name_len) { size_t bigsize = 1000; uint32_t value = 0; if (action != SNMP_ACT_COMMIT) { return 0; } switch (name[9]) { case 7: if (var_val_type != ASN_INTEGER) return SNMP_ERR_WRONGTYPE; if (var_val_len > sizeof(uint32_t)) return SNMP_ERR_WRONGLENGTH; AsnUnsignedParse(var_val, &bigsize, &var_val_type, &value); if (name[10] > 0 && name[10] < MIB_IF_ENTRIES) { if_admin_status[name[10] - 1] = value; } break; } return 0; } static uint8_t *MibVarsIfGet(const SNMPVAR * vp, OID * name, size_t * namelen, int exact, size_t * varlen, WMETHOD ** wmethod) { int rc; int ifc = 0; OID index = 0; static long zero = 0; OID *fullname; size_t fullnamelen = base_oidlen + vp->var_namelen + 1; fullname = malloc(fullnamelen * sizeof(OID)); memcpy(fullname, base_oid, base_oidlen * sizeof(OID)); memcpy(fullname + base_oidlen, vp->var_name, vp->var_namelen * sizeof(OID)); if (vp->var_magic == MAG_IF_NUMBER) { /* Determine the number of interfaces. */ *(fullname + fullnamelen - 1) = index; rc = SnmpOidCmp(name, *namelen, fullname, fullnamelen); if ((exact && rc) || (!exact && rc >= 0)) { free(fullname); return NULL; } } else { /* Determine the interface number. */ for (; ifc < if_number; ifc++) { *(fullname + fullnamelen - 1) = ifc + 1; rc = SnmpOidCmp(name, *namelen, fullname, fullnamelen); if ((exact && rc == 0) || (!exact && rc < 0)) { index = ifc + 1; break; } } if (index == 0) { free(fullname); return NULL; } } memcpy(name, fullname, fullnamelen * sizeof(OID)); free(fullname); *namelen = fullnamelen; *wmethod = NULL; *varlen = sizeof(long); switch (vp->var_magic) { case MAG_IF_NUMBER: return (uint8_t *) & if_number; case MAG_IF_INDEX: return (uint8_t *) & if_index; case MAG_IF_DESCR: *varlen = strlen(if_descr); return (uint8_t *) if_descr; case MAG_IF_TYPE: return (uint8_t *) & if_type; case MAG_IF_MTU: return (uint8_t *) & if_mtu; case MAG_IF_SPEED: return (uint8_t *) & if_speed; case MAG_IF_PHYSADDRESS: *varlen = 6; return confnet.cdn_mac; case MAG_IF_ADMINSTATUS: case MAG_IF_OPERSTATUS: *wmethod = MibVarsIfSet; return (uint8_t *) & if_admin_status[ifc]; case MAG_IF_LASTCHANGE: case MAG_IF_INOCTETS: case MAG_IF_INUCASTPKTS: case MAG_IF_INNUCASTPKTS: case MAG_IF_INDISCARDS: case MAG_IF_INERRORS: case MAG_IF_INUNKNOWNPROTOS: case MAG_IF_OUTOCTETS: case MAG_IF_OUTUCASTPKTS: case MAG_IF_OUTNUCASTPKTS: case MAG_IF_OUTDISCARDS: case MAG_IF_OUTERRORS: case MAG_IF_OUTQLEN: return (uint8_t *) & zero; case MAG_IF_SPECIFIC: *varlen = sizeof(if_specific); return (uint8_t *) if_specific; } return NULL; }