Nut/OS  4.10.3
API Reference
mib2sys.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/version.h>
00034 #include <sys/confos.h>
00035 #include <sys/confnet.h>
00036 #include <sys/environ.h>
00037 
00038 #include <pro/snmp.h>
00039 #include <pro/snmp_api.h>
00040 
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <ctype.h>
00044 #include <time.h>
00045 
00046 #include "mib2sys.h"
00047 
00048 #if defined(STK501)
00049 #define BOARD_NAME  "STK 501"
00050 #elif defined(INTECH21)
00051 #define BOARD_NAME  "Intech 21"
00052 #elif defined(XNUT_100)
00053 #define BOARD_NAME  "XNUT 100"
00054 #elif defined(XNUT_105)
00055 #define BOARD_NAME  "XNUT 105"
00056 #elif defined(AT91SAM7X_EK)
00057 #define BOARD_NAME  "AT91SAM7X-EK"
00058 #elif defined(AT91SAM9260_EK)
00059 #define BOARD_NAME  "AT91SAM9260-EK"
00060 #elif defined(CHARON2)
00061 #define BOARD_NAME  "Charon 2"
00062 #elif defined(ARTHERNET1)
00063 #define BOARD_NAME  "Arthernet 1"
00064 #elif defined(MMNET02)
00065 #define BOARD_NAME  "MMNET02"
00066 #elif defined(ETHERNUT1)
00067 #define BOARD_NAME  "Ethernut 1"
00068 #elif defined(ETHERNUT2)
00069 #define BOARD_NAME  "Ethernut 2"
00070 #elif defined(ETHERNUT3)
00071 #define BOARD_NAME  "Ethernut 3"
00072 #elif defined(ETHERNUT5)
00073 #define BOARD_NAME  "Ethernut 5"
00074 #else
00075 #define BOARD_NAME  "Custom"
00076 #endif
00077 
00078 #define MAG_SYS_DESCR       1
00079 #define MAG_SYS_OID         2
00080 #define MAG_SYS_UPTIME      3
00081 #define MAG_SYS_CONTACT     4
00082 #define MAG_SYS_NAME        5
00083 #define MAG_SYS_LOCATION    6
00084 #define MAG_SYS_SERVICES    7
00085 
00086 static uint8_t *MibVarsSysGet(CONST SNMPVAR *, OID *, size_t *, int, size_t *, WMETHOD **);
00087 
00088 static OID base_oid[] = { SNMP_OID_MIB2, 1 };
00089 static size_t base_oidlen = sizeof(base_oid) / sizeof(OID);
00090 
00091 static SNMPVAR mib_variables[] = {
00092     {MAG_SYS_DESCR, ASN_OCTET_STR, ACL_RONLY, MibVarsSysGet, 1, {1}},
00093     {MAG_SYS_OID, ASN_OBJECT_ID, ACL_RONLY, MibVarsSysGet, 1, {2}},
00094     {MAG_SYS_UPTIME, ASN_TIMETICKS, ACL_RONLY, MibVarsSysGet, 1, {3}},
00095     {MAG_SYS_CONTACT, ASN_OCTET_STR, ACL_RWRITE, MibVarsSysGet, 1, {4}},
00096     {MAG_SYS_NAME, ASN_OCTET_STR, ACL_RWRITE, MibVarsSysGet, 1, {5}},
00097     {MAG_SYS_LOCATION, ASN_OCTET_STR, ACL_RWRITE, MibVarsSysGet, 1, {6}},
00098     {MAG_SYS_SERVICES, ASN_INTEGER, ACL_RONLY, MibVarsSysGet, 1, {7}}
00099 };
00100 
00101 static char sys_descr[MAX_SYSSTR_LEN];
00102 static char *sys_contact;
00103 static char *sys_name;
00104 static char *sys_location;
00105 static time_t sys_starttime;
00106 static long sys_uptime;
00107 static long sys_services = 72;
00108 static OID sys_oid[] = {
00109     SNMP_OID_ENTERPRISES,
00110     3444,                       /* egnite */
00111     2,                          /* egnite products=1 local=2 experimental=3 */
00112     6,                          /* egnite Nut/OS */
00113 };
00114 
00115 static char *UpdateStringEnv(char *name, char *var, char *value)
00116 {
00117     if (var) {
00118         free(var);
00119     }
00120     if ((var = malloc(strlen(value) + 1)) != NULL) {
00121         strcpy(var, value);
00122         if (name) {
00123             setenv(name, value, 1);
00124         }
00125     }
00126     return var;
00127 }
00128 
00134 int MibRegisterSysVars(void)
00135 {
00136     char *cp;
00137 
00138     strcpy(sys_descr, BOARD_NAME);
00139     strcat(sys_descr, " Nut/OS ");
00140     strcat(sys_descr, NutVersionString());
00141 
00142     if ((cp = getenv("SYSCONTACT")) != NULL) {
00143         sys_contact = UpdateStringEnv(NULL, sys_contact, cp);
00144     }
00145     if ((cp = getenv("SYSNAME")) != NULL) {
00146         sys_name = UpdateStringEnv(NULL, sys_name, cp);
00147     } else {
00148         sys_name = UpdateStringEnv(NULL, sys_name, confos.hostname);
00149     }
00150     if ((cp = getenv("SYSLOCATION")) != NULL) {
00151         sys_location = UpdateStringEnv(NULL, sys_location, cp);
00152     }
00153 
00154     sys_starttime = time(NULL);
00155 
00156     return SnmpMibRegister(base_oid, base_oidlen, mib_variables, sizeof(mib_variables) / sizeof(SNMPVAR));
00157 }
00158 
00159 static int MibVarsSysSet(int action, uint8_t * var_val, uint8_t var_val_type, size_t var_val_len, OID * name, size_t name_len)
00160 {
00161     size_t len = SNMP_MAX_LEN;
00162     uint8_t *value;
00163     uint8_t *cp;
00164     size_t size;
00165 
00166     if (action != SNMP_ACT_COMMIT) {
00167         return 0;
00168     }
00169 
00170     if (var_val_type != ASN_OCTET_STR) {
00171         return SNMP_ERR_WRONGTYPE;
00172     }
00173     if (var_val_len > MAX_SYSSTR_LEN) {
00174         return SNMP_ERR_WRONGLENGTH;
00175     }
00176     size = MAX_SYSSTR_LEN;
00177     if ((value = (uint8_t *)malloc(MAX_SYSSTR_LEN) + 1) == NULL) {
00178         return SNMP_ERR_RESOURCEUNAVAILABLE;
00179     }
00180     AsnOctetStringParse(var_val, &len, &var_val_type, value, &size);
00181     value[size] = 0;
00182     for (cp = value; *cp; cp++) {
00183         if (!isprint(*cp)) {
00184             free(value);
00185             return SNMP_ERR_WRONGVALUE;
00186         }
00187     }
00188     if (action == SNMP_ACT_COMMIT) {
00189         switch (name[7]) {
00190         case 4:
00191             sys_contact = UpdateStringEnv("SYSCONTACT", sys_contact, (char *) value);
00192             break;
00193         case 5:
00194             sys_name = UpdateStringEnv("SYSNAME", sys_name, (char *) value);
00195             break;
00196         case 6:
00197             sys_location = UpdateStringEnv("SYSLOCATION", sys_location, (char *) value);
00198             break;
00199         }
00200     }
00201     free(value);
00202 
00203     return 0;
00204 }
00205 
00218 static uint8_t *MibVarsSysGet(CONST SNMPVAR * vp, OID * name, size_t * namelen, int exact, size_t * varlen, WMETHOD ** wmethod)
00219 {
00220     static uint8_t empty[1];
00221     int rc;
00222     OID *fullname;
00223     size_t fullnamelen = base_oidlen + vp->var_namelen + 1;
00224 
00225     fullname = malloc(fullnamelen * sizeof(OID));
00226     memcpy(fullname, base_oid, base_oidlen * sizeof(OID));
00227     memcpy(fullname + base_oidlen, vp->var_name, vp->var_namelen * sizeof(OID));
00228     *(fullname + fullnamelen - 1) = 0;
00229 
00230     rc = SnmpOidCmp(name, *namelen, fullname, fullnamelen);
00231     if ((exact && rc) || (!exact && rc >= 0)) {
00232         free(fullname);
00233         return NULL;
00234     }
00235     memcpy(name, fullname, fullnamelen * sizeof(OID));
00236     free(fullname);
00237     *namelen = fullnamelen;
00238 
00239     *wmethod = NULL;
00240     *varlen = sizeof(long);
00241     switch (vp->var_magic) {
00242     case MAG_SYS_DESCR:
00243         *varlen = strlen(sys_descr);
00244         return (uint8_t *) sys_descr;
00245     case MAG_SYS_OID:
00246         *varlen = sizeof(sys_oid);
00247         return (uint8_t *) sys_oid;
00248     case MAG_SYS_UPTIME:
00249         sys_uptime = time(NULL) - sys_starttime;
00250         sys_uptime *= 100;
00251         return (uint8_t *) & sys_uptime;
00252     case MAG_SYS_CONTACT:
00253         *wmethod = MibVarsSysSet;
00254         if (sys_contact) {
00255             *varlen = strlen(sys_contact);
00256             return (uint8_t *) sys_contact;
00257         }
00258         *varlen = 0;
00259         return empty;
00260     case MAG_SYS_NAME:
00261         *wmethod = MibVarsSysSet;
00262         if (sys_name) {
00263             *varlen = strlen(sys_name);
00264             return (uint8_t *) sys_name;
00265         }
00266         *varlen = 0;
00267         return empty;
00268     case MAG_SYS_LOCATION:
00269         *wmethod = MibVarsSysSet;
00270         if (sys_location) {
00271             *varlen = strlen(sys_location);
00272             return (uint8_t *) sys_location;
00273         }
00274         *varlen = 0;
00275         return empty;
00276     case MAG_SYS_SERVICES:
00277         return (uint8_t *) & sys_services;
00278     }
00279     return NULL;
00280 }