Nut/OS  4.10.3
API Reference
snmp_mib.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 1998-2007 by egnite Software GmbH
00003  * Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00022  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * For additional information see http://www.ethernut.de/
00032  */
00033 
00034 #include <sys/types.h>
00035 
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <memdebug.h>
00039 
00040 #include <pro/snmp.h>
00041 #include <pro/snmp_api.h>
00042 #include <pro/snmp_mib.h>
00043 
00048 
00049 /*
00050  * The subtree structure contains a subtree prefix which applies to
00051  * all variables in the associated variable list.
00052  *
00053  * No subtree may be a subtree of another subtree in this list.
00054  * i.e.:   1.2
00055  *         1.2.0
00056  */
00057 typedef struct _SUBTREE {
00059     struct _SUBTREE *sub_next;
00061     int sub_numvars;
00063     SNMPVAR *sub_vars;
00065     size_t sub_namelen;
00067     OID sub_name[MAX_OID_LEN];
00068 } SUBTREE;
00069 
00070 static SUBTREE *mibtree;
00071 
00075 int SnmpMibRegister(OID basename[], size_t baselen, SNMPVAR * vars, int num)
00076 {
00077     SUBTREE **tpp;
00078     SUBTREE *branch;
00079 
00080     /* Create a new branch. */
00081     if ((branch = malloc(sizeof(SUBTREE))) == NULL) {
00082         return -1;
00083     }
00084     branch->sub_numvars = num;
00085     branch->sub_vars = vars;
00086     branch->sub_namelen = baselen;
00087     memcpy(branch->sub_name, basename, baselen * sizeof(OID));
00088 
00089     /* Locate the new branch's insertion point. */
00090     for (tpp = &mibtree; *tpp; tpp = &(*tpp)->sub_next) {
00091         if (SnmpOidCmp((*tpp)->sub_name, (*tpp)->sub_namelen, branch->sub_name, branch->sub_namelen) > 0) {
00092             break;
00093         }
00094     }
00095     /* Insert the branch. */
00096     branch->sub_next = *tpp;
00097     *tpp = branch;
00098 
00099     return 0;
00100 }
00101 
00114 uint8_t *SnmpMibFind(OID * name, size_t * namelen, uint8_t * type, size_t * len, uint16_t * acl, int exact, WMETHOD ** wmethod,
00115                     int *no_obj)
00116 {
00117     SUBTREE *tp;
00118     SNMPVAR *vp = 0;
00119     int i;
00120     uint8_t *access = NULL;
00121     int rc;
00122     OID *suffix;
00123     size_t sufflen;
00124     OID *ori_oid = NULL;
00125     size_t ori_len = 0;
00126     int found = 0;
00127 
00128     /* 
00129      * If not looking for an exact match, keep a copy of the original name. 
00130      */
00131     if (!exact) {
00132         if ((ori_oid = malloc(*namelen * sizeof(OID))) == NULL) {
00133             return NULL;
00134         }
00135         memcpy(ori_oid, name, *namelen * sizeof(OID));
00136         ori_len = *namelen;
00137     }
00138     *wmethod = NULL;
00139 
00140     /*
00141      * Walk along the linked list of subtrees.
00142      */
00143     for (tp = mibtree; tp; tp = tp->sub_next) {
00144         /* 
00145          * Check if name is part of this subtree. Or, if we don't need an exact match,
00146          * if the name is in front of the subtree.
00147          */
00148         rc = SnmpOidTreeCmp(name, *namelen, tp->sub_name, tp->sub_namelen);
00149         if (rc == 0 || (rc < 0 && !exact)) {
00150             sufflen = *namelen - tp->sub_namelen;
00151             suffix = name + tp->sub_namelen;
00152 
00153             for (i = 0, vp = tp->sub_vars; i < tp->sub_numvars; i++, vp++) {
00154                 if (vp->var_namelen && (exact || rc >= 0)) {
00155                     rc = SnmpOidTreeCmp(suffix, sufflen, vp->var_name, vp->var_namelen);
00156                 }
00157 
00158                 if ((exact && rc == 0) || (!exact && rc <= 0) || vp->var_namelen == 0) {
00159                     access = (*(vp->var_get)) (vp, name, namelen, exact, len, wmethod);
00160                     if (wmethod) {
00161                         *acl = vp->var_acl;
00162                     }
00163                     if (exact) {
00164                         found = 1;
00165                     }
00166                     if (access) {
00167                         break;
00168                     }
00169                 }
00170                 if (exact && rc <= 0) {
00171                     *type = vp->var_type;
00172                     *acl = vp->var_acl;
00173                     *no_obj = !found;
00174                     return NULL;
00175                 }
00176             }
00177             if (access) {
00178                 break;
00179             }
00180         }
00181     }
00182     if (tp == NULL) {
00183         if (!access && !exact) {
00184             memcpy(name, ori_oid, ori_len * sizeof(OID));
00185             *namelen = ori_len;
00186             free(ori_oid);
00187         }
00188         *no_obj = !found;
00189         return NULL;
00190     }
00191     if (ori_oid) {
00192         free(ori_oid);
00193     }
00194 
00195     /*
00196      * vp now points to the approprate struct.
00197      */
00198     *type = vp->var_type;
00199     *acl = vp->var_acl;
00200 
00201     return access;
00202 }
00203