Nut/OS  4.10.3
API Reference
mib2if.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2007 by egnite Software GmbH
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00021  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  */
00032 
00033 #include <sys/confnet.h>
00034 
00035 #include <pro/snmp.h>
00036 #include <pro/snmp_api.h>
00037 
00038 #include <stdlib.h>
00039 #include <string.h>
00040 
00041 #include "mib2if.h"
00042 
00043 #define MIB_IF_ENTRIES   4
00044 
00045 #if defined(ETHERNUT1) || defined(XNUT_100) || defined(XNUT_105) || defined(CHARON2)
00046 #define PHY_NAME    "RTL8019AS 10 Mbit Ethernet"
00047 #elif defined(ETHERNUT2) || defined(INTECH21)
00048 #define PHY_NAME    "LAN91C111 100Mbit Ethernet"
00049 #elif defined(ETHERNUT3)
00050 #define PHY_NAME    "DM9000E 100Mbit Ethernet"
00051 #elif defined(AT91SAM7X_EK) || defined(AT91SAM9260_EK)
00052 #define PHY_NAME    "DM9161A 100Mbit Ethernet"
00053 #elif defined(ETHERNUT5)
00054 #define PHY_NAME    "LAN8700I 100Mbit Ethernet"
00055 #else
00056 #define PHY_NAME    "Ethernet"
00057 #endif
00058 
00059 static uint8_t *MibVarsIfGet(CONST SNMPVAR *, OID *, size_t *, int, size_t *, WMETHOD **);
00060 
00061 #define MAG_IF_NUMBER           0
00062 
00063 #define MAG_IF_INDEX            1
00064 #define MAG_IF_DESCR            2
00065 #define MAG_IF_TYPE             3
00066 #define MAG_IF_MTU              4
00067 #define MAG_IF_SPEED            5
00068 #define MAG_IF_PHYSADDRESS      6
00069 #define MAG_IF_ADMINSTATUS      7
00070 #define MAG_IF_OPERSTATUS       8
00071 #define MAG_IF_LASTCHANGE       9
00072 #define MAG_IF_INOCTETS         10
00073 #define MAG_IF_INUCASTPKTS      11
00074 #define MAG_IF_INNUCASTPKTS     12
00075 #define MAG_IF_INDISCARDS       13
00076 #define MAG_IF_INERRORS         14
00077 #define MAG_IF_INUNKNOWNPROTOS  15
00078 #define MAG_IF_OUTOCTETS        16
00079 #define MAG_IF_OUTUCASTPKTS     17
00080 #define MAG_IF_OUTNUCASTPKTS    18
00081 #define MAG_IF_OUTDISCARDS      19
00082 #define MAG_IF_OUTERRORS        20
00083 #define MAG_IF_OUTQLEN          21
00084 #define MAG_IF_SPECIFIC         22
00085 
00086 static OID base_oid[] = { SNMP_OID_MIB2, 2 };
00087 static size_t base_oidlen = sizeof(base_oid) / sizeof(OID);
00088 
00089 static SNMPVAR mib_variables[] = {
00090     {MAG_IF_NUMBER, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 1, {1}},
00091     {MAG_IF_INDEX, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 1}},
00092     {MAG_IF_DESCR, ASN_OCTET_STR, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 2}},
00093     {MAG_IF_TYPE, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 3}},
00094     {MAG_IF_MTU, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 4}},
00095     {MAG_IF_SPEED, ASN_GAUGE, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 5}},
00096     {MAG_IF_PHYSADDRESS, ASN_OCTET_STR, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 6}},
00097     {MAG_IF_ADMINSTATUS, ASN_INTEGER, ACL_RWRITE, MibVarsIfGet, 3, {2, 1, 7}},
00098     {MAG_IF_OPERSTATUS, ASN_INTEGER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 8}},
00099     {MAG_IF_LASTCHANGE, ASN_TIMETICKS, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 9}},
00100     {MAG_IF_INOCTETS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 10}},
00101     {MAG_IF_INUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 11}},
00102     {MAG_IF_INNUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 12}},
00103     {MAG_IF_INDISCARDS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 13}},
00104     {MAG_IF_INERRORS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 14}},
00105     {MAG_IF_INUNKNOWNPROTOS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 15}},
00106     {MAG_IF_OUTOCTETS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 16}},
00107     {MAG_IF_OUTUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 17}},
00108     {MAG_IF_OUTNUCASTPKTS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 18}},
00109     {MAG_IF_OUTDISCARDS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 19}},
00110     {MAG_IF_OUTERRORS, ASN_COUNTER, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 20}},
00111     {MAG_IF_OUTQLEN, ASN_GAUGE, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 21}},
00112     {MAG_IF_SPECIFIC, ASN_OBJECT_ID, ACL_RONLY, MibVarsIfGet, 3, {2, 1, 22}}
00113 };
00114 
00115 static long if_number;
00116 static long if_type;
00117 static long if_mtu;
00118 static uint32_t if_speed;
00119 static long if_index;
00120 static char *if_descr;
00121 static OID if_specific[] = { 0, 0 };
00122 
00123 static long if_admin_status[MIB_IF_ENTRIES];
00124 
00130 int MibRegisterIfVars(void)
00131 {
00132     int i;
00133 
00134     if_number = 1;
00135     for (i = 0; i < if_number; i++) {
00136         if_admin_status[i] = 1;
00137     }
00138     if_type = 6;
00139     if_mtu = 1500;
00140     if_speed = 100000000UL;
00141     if_index = 1;
00142     if ((if_descr = malloc(strlen(PHY_NAME) + 1)) != NULL) {
00143         strcpy(if_descr, PHY_NAME);
00144     }
00145     return SnmpMibRegister(base_oid, base_oidlen, mib_variables, sizeof(mib_variables) / sizeof(SNMPVAR));
00146 }
00147 
00148 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)
00149 {
00150     size_t bigsize = 1000;
00151     uint32_t value = 0;
00152 
00153     if (action != SNMP_ACT_COMMIT) {
00154         return 0;
00155     }
00156     switch (name[9]) {
00157     case 7:
00158         if (var_val_type != ASN_INTEGER)
00159             return SNMP_ERR_WRONGTYPE;
00160         if (var_val_len > sizeof(uint32_t))
00161             return SNMP_ERR_WRONGLENGTH;
00162         AsnUnsignedParse(var_val, &bigsize, &var_val_type, &value);
00163         if (name[10] > 0 && name[10] < MIB_IF_ENTRIES) {
00164             if_admin_status[name[10] - 1] = value;
00165         }
00166         break;
00167     }
00168     return 0;
00169 }
00170 
00171 static uint8_t *MibVarsIfGet(CONST SNMPVAR * vp, OID * name, size_t * namelen, int exact, size_t * varlen, WMETHOD ** wmethod)
00172 {
00173     int rc;
00174     int ifc = 0;
00175     OID index = 0;
00176     static long zero = 0;
00177     OID *fullname;
00178     size_t fullnamelen = base_oidlen + vp->var_namelen + 1;
00179 
00180     fullname = malloc(fullnamelen * sizeof(OID));
00181     memcpy(fullname, base_oid, base_oidlen * sizeof(OID));
00182     memcpy(fullname + base_oidlen, vp->var_name, vp->var_namelen * sizeof(OID));
00183 
00184     if (vp->var_magic == MAG_IF_NUMBER) {
00185         /* Determine the number of interfaces. */
00186         *(fullname + fullnamelen - 1) = index;
00187         rc = SnmpOidCmp(name, *namelen, fullname, fullnamelen);
00188         if ((exact && rc) || (!exact && rc >= 0)) {
00189             free(fullname);
00190             return NULL;
00191         }
00192     } else {
00193         /* Determine the interface number. */
00194         for (; ifc < if_number; ifc++) {
00195             *(fullname + fullnamelen - 1) = ifc + 1;
00196             rc = SnmpOidCmp(name, *namelen, fullname, fullnamelen);
00197             if ((exact && rc == 0) || (!exact && rc < 0)) {
00198                 index = ifc + 1;
00199                 break;
00200             }
00201         }
00202         if (index == 0) {
00203             free(fullname);
00204             return NULL;
00205         }
00206     }
00207 
00208     memcpy(name, fullname, fullnamelen * sizeof(OID));
00209     free(fullname);
00210     *namelen = fullnamelen;
00211     *wmethod = NULL;
00212     *varlen = sizeof(long);
00213 
00214     switch (vp->var_magic) {
00215     case MAG_IF_NUMBER:
00216         return (uint8_t *) & if_number;
00217     case MAG_IF_INDEX:
00218         return (uint8_t *) & if_index;
00219     case MAG_IF_DESCR:
00220         *varlen = strlen(if_descr);
00221         return (uint8_t *) if_descr;
00222     case MAG_IF_TYPE:
00223         return (uint8_t *) & if_type;
00224     case MAG_IF_MTU:
00225         return (uint8_t *) & if_mtu;
00226     case MAG_IF_SPEED:
00227         return (uint8_t *) & if_speed;
00228     case MAG_IF_PHYSADDRESS:
00229         *varlen = 6;
00230         return confnet.cdn_mac;
00231     case MAG_IF_ADMINSTATUS:
00232     case MAG_IF_OPERSTATUS:
00233         *wmethod = MibVarsIfSet;
00234         return (uint8_t *) & if_admin_status[ifc];
00235     case MAG_IF_LASTCHANGE:
00236     case MAG_IF_INOCTETS:
00237     case MAG_IF_INUCASTPKTS:
00238     case MAG_IF_INNUCASTPKTS:
00239     case MAG_IF_INDISCARDS:
00240     case MAG_IF_INERRORS:
00241     case MAG_IF_INUNKNOWNPROTOS:
00242     case MAG_IF_OUTOCTETS:
00243     case MAG_IF_OUTUCASTPKTS:
00244     case MAG_IF_OUTNUCASTPKTS:
00245     case MAG_IF_OUTDISCARDS:
00246     case MAG_IF_OUTERRORS:
00247     case MAG_IF_OUTQLEN:
00248         return (uint8_t *) & zero;
00249     case MAG_IF_SPECIFIC:
00250         *varlen = sizeof(if_specific);
00251         return (uint8_t *) if_specific;
00252     }
00253     return NULL;
00254 }