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

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