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 
00039 #include <pro/snmp.h>
00040 #include <pro/snmp_api.h>
00041 #include <pro/snmp_mib.h>
00042 
00043 /*
00044  * The subtree structure contains a subtree prefix which applies to
00045  * all variables in the associated variable list.
00046  *
00047  * No subtree may be a subtree of another subtree in this list.
00048  * i.e.:   1.2
00049  *         1.2.0
00050  */
00051 typedef struct _SUBTREE {
00053     struct _SUBTREE *sub_next;
00055     int sub_numvars;
00057     SNMPVAR *sub_vars;
00059     size_t sub_namelen;
00061     OID sub_name[MAX_OID_LEN];
00062 } SUBTREE;
00063 
00064 static SUBTREE *mibtree;
00065 
00069 int SnmpMibRegister(OID basename[], size_t baselen, SNMPVAR * vars, int num)
00070 {
00071     SUBTREE **tpp;
00072     SUBTREE *branch;
00073 
00074     /* Create a new branch. */
00075     if ((branch = malloc(sizeof(SUBTREE))) == NULL) {
00076         return -1;
00077     }
00078     branch->sub_numvars = num;
00079     branch->sub_vars = vars;
00080     branch->sub_namelen = baselen;
00081     memcpy(branch->sub_name, basename, baselen * sizeof(OID));
00082 
00083     /* Locate the new branch's insertion point. */
00084     for (tpp = &mibtree; *tpp; tpp = &(*tpp)->sub_next) {
00085         if (SnmpOidCmp((*tpp)->sub_name, (*tpp)->sub_namelen, branch->sub_name, branch->sub_namelen) > 0) {
00086             break;
00087         }
00088     }
00089     /* Insert the branch. */
00090     branch->sub_next = *tpp;
00091     *tpp = branch;
00092 
00093     return 0;
00094 }
00095 
00108 uint8_t *SnmpMibFind(OID * name, size_t * namelen, uint8_t * type, size_t * len, uint16_t * acl, int exact, WMETHOD ** wmethod,
00109                     int *no_obj)
00110 {
00111     SUBTREE *tp;
00112     SNMPVAR *vp = 0;
00113     int i;
00114     uint8_t *access = NULL;
00115     int rc;
00116     OID *suffix;
00117     size_t sufflen;
00118     OID *ori_oid = NULL;
00119     size_t ori_len = 0;
00120     int found = 0;
00121 
00122     /* 
00123      * If not looking for an exact match, keep a copy of the original name. 
00124      */
00125     if (!exact) {
00126         if ((ori_oid = malloc(*namelen * sizeof(OID))) == NULL) {
00127             return NULL;
00128         }
00129         memcpy(ori_oid, name, *namelen * sizeof(OID));
00130         ori_len = *namelen;
00131     }
00132     *wmethod = NULL;
00133 
00134     /*
00135      * Walk along the linked list of subtrees.
00136      */
00137     for (tp = mibtree; tp; tp = tp->sub_next) {
00138         /* 
00139          * Check if name is part of this subtree. Or, if we don't need an exact match,
00140          * if the name is in front of the subtree.
00141          */
00142         rc = SnmpOidTreeCmp(name, *namelen, tp->sub_name, tp->sub_namelen);
00143         if (rc == 0 || (rc < 0 && !exact)) {
00144             sufflen = *namelen - tp->sub_namelen;
00145             suffix = name + tp->sub_namelen;
00146 
00147             for (i = 0, vp = tp->sub_vars; i < tp->sub_numvars; i++, vp++) {
00148                 if (vp->var_namelen && (exact || rc >= 0)) {
00149                     rc = SnmpOidTreeCmp(suffix, sufflen, vp->var_name, vp->var_namelen);
00150                 }
00151 
00152                 if ((exact && rc == 0) || (!exact && rc <= 0) || vp->var_namelen == 0) {
00153                     access = (*(vp->var_get)) (vp, name, namelen, exact, len, wmethod);
00154                     if (wmethod) {
00155                         *acl = vp->var_acl;
00156                     }
00157                     if (exact) {
00158                         found = 1;
00159                     }
00160                     if (access) {
00161                         break;
00162                     }
00163                 }
00164                 if (exact && rc <= 0) {
00165                     *type = vp->var_type;
00166                     *acl = vp->var_acl;
00167                     *no_obj = !found;
00168                     return NULL;
00169                 }
00170             }
00171             if (access) {
00172                 break;
00173             }
00174         }
00175     }
00176     if (tp == NULL) {
00177         if (!access && !exact) {
00178             memcpy(name, ori_oid, ori_len * sizeof(OID));
00179             *namelen = ori_len;
00180             free(ori_oid);
00181         }
00182         *no_obj = !found;
00183         return NULL;
00184     }
00185     if (ori_oid) {
00186         free(ori_oid);
00187     }
00188 
00189     /*
00190      * vp now points to the approprate struct.
00191      */
00192     *type = vp->var_type;
00193     *acl = vp->var_acl;
00194 
00195     return access;
00196 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/