Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
agent_index.c File Reference
Main Page   Data Structures   File List   Data Fields   Globals  

agent_index.c File Reference

#include <config.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
#include <dmalloc.h>
#include "mibincl.h"
#include "snmp_client.h"
#include "default_store.h"
#include "ds_agent.h"
#include "callback.h"
#include "agent_callbacks.h"
#include "agent_index.h"
#include "snmp_alarm.h"
#include "snmp_secmod.h"
#include "snmpd.h"
#include "mibgroup/struct.h"
#include "helpers/table.h"
#include "helpers/table_iterator.h"
#include "mib_module_includes.h"

Go to the source code of this file.


Data Structures

struct  snmp_index

Functions

char * register_string_index (oid *name, size_t name_len, char *cp)
int register_int_index (oid *name, size_t name_len, int val)
variable_list * register_oid_index (oid *name, size_t name_len, oid *value, size_t value_len)
variable_list * register_index (struct variable_list *varbind, int flags, struct snmp_session *ss)
int release_index (struct variable_list *varbind)
int remove_index (struct variable_list *varbind, struct snmp_session *ss)
void unregister_index_by_session (struct snmp_session *ss)
int unregister_index (struct variable_list *varbind, int remember, struct snmp_session *ss)
void dump_idx_registry (void)

Variables

snmp_indexsnmp_index_head
snmp_session * main_session

Function Documentation

void dump_idx_registry void   
 

Definition at line 495 of file agent_index.c.

Referenced by dump_registry().

00496 {
00497     struct snmp_index *idxptr, *idxptr2;
00498     char start_oid[SPRINT_MAX_LEN];
00499     char end_oid[SPRINT_MAX_LEN];
00500 
00501     if ( snmp_index_head )
00502         printf("\nIndex Allocations:\n");
00503     for( idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid) {
00504         sprint_objid(start_oid, idxptr->varbind->name, idxptr->varbind->name_length);
00505         printf("%s indexes:\n", start_oid);
00506         for( idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx) {
00507             switch( idxptr2->varbind->type ) {
00508                 case ASN_INTEGER:
00509                     printf("    %c %ld %c\n",
00510                         ( idxptr2->session ? ' ' : '(' ),
00511                           *idxptr2->varbind->val.integer,
00512                         ( idxptr2->session ? ' ' : ')' ));
00513                     break;
00514                 case ASN_OCTET_STR:
00515                     printf("    %c %s %c\n",
00516                         ( idxptr2->session ? ' ' : '(' ),
00517                           idxptr2->varbind->val.string,
00518                         ( idxptr2->session ? ' ' : ')' ));
00519                     break;
00520                 case ASN_OBJECT_ID:
00521                     sprint_objid(end_oid, idxptr2->varbind->val.objid,
00522                                 idxptr2->varbind->val_len/sizeof(oid));
00523                     printf("    %c %s %c\n",
00524                         ( idxptr2->session ? ' ' : '(' ),
00525                           end_oid,
00526                         ( idxptr2->session ? ' ' : ')' ));
00527                     break;
00528                 default:
00529                     printf("unsupported type (%d)\n",
00530                                 idxptr2->varbind->type);
00531             }
00532         }
00533     }
00534 }

struct variable_list* register_index struct variable_list *    varbind,
int    flags,
struct snmp_session *    ss
 

Definition at line 140 of file agent_index.c.

00141 {
00142     struct snmp_index *new_index, *idxptr, *idxptr2;
00143     struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
00144     int res, res2, i;
00145 
00146 #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
00147     if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
00148         return( agentx_register_index( ss, varbind, flags ));
00149 #endif
00150                 /* Look for the requested OID entry */
00151     prev_oid_ptr = NULL;
00152     prev_idx_ptr = NULL;
00153     res  = 1;
00154     res2 = 1;
00155     for( idxptr = snmp_index_head ; idxptr != NULL;
00156                          prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
00157         if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
00158                                         idxptr->varbind->name,
00159                                         idxptr->varbind->name_length)) <= 0 )
00160                 break;
00161     }
00162 
00163                 /*  Found the OID - now look at the registered indices */
00164     if ( res == 0 && idxptr ) {
00165         if ( varbind->type != idxptr->varbind->type )
00166             return NULL;                /* wrong type */
00167 
00168                         /*
00169                          * If we've been asked for an arbitrary new value,
00170                          *      then find the end of the list.
00171                          * If we've been asked for any arbitrary value,
00172                          *      then look for an unused entry, and use that.
00173                          *      If there aren't any, continue as for new.
00174                          * Otherwise, locate the given value in the (sorted)
00175                          *      list of already allocated values
00176                          */
00177         if ( flags & ALLOCATE_ANY_INDEX ) {
00178             for(idxptr2 = idxptr ; idxptr2 != NULL;
00179                  prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
00180                 if ( flags == ALLOCATE_ANY_INDEX && idxptr2->session == NULL ) {
00181                     idxptr2->session = ss ;
00182                     return idxptr2->varbind;
00183                 }
00184             }
00185         }
00186         else {
00187             for(idxptr2 = idxptr ; idxptr2 != NULL;
00188                  prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
00189                 switch ( varbind->type ) {
00190                     case ASN_INTEGER:
00191                         res2 = (*varbind->val.integer - *idxptr2->varbind->val.integer);
00192                         break;
00193                     case ASN_OCTET_STR:
00194                         i = SNMP_MIN(varbind->val_len, idxptr2->varbind->val_len);
00195                         res2 = memcmp(varbind->val.string, idxptr2->varbind->val.string, i);
00196                         break;
00197                     case ASN_OBJECT_ID:
00198                         res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len/sizeof(oid),
00199                                         idxptr2->varbind->val.objid,
00200                                         idxptr2->varbind->val_len/sizeof(oid));
00201                         break;
00202                     default:
00203                         return NULL;            /* wrong type */
00204                 }
00205                 if ( res2 <= 0 )
00206                     break;
00207             }
00208             if ( res2 == 0 )
00209                 return NULL;                    /* duplicate value */
00210         }
00211     }
00212 
00213                 /*
00214                  * OK - we've now located where the new entry needs to
00215                  *      be fitted into the index registry tree          
00216                  * To recap:
00217                  *      'prev_oid_ptr' points to the head of the OID index
00218                  *          list prior to this one.  If this is null, then
00219                  *          it means that this is the first OID in the list.
00220                  *      'idxptr' points either to the head of this OID list,
00221                  *          or the next OID (if this is a new OID request)
00222                  *          These can be distinguished by the value of 'res'.
00223                  *
00224                  *      'prev_idx_ptr' points to the index entry that sorts
00225                  *          immediately prior to the requested value (if any).
00226                  *          If an arbitrary value is required, then this will
00227                  *          point to the last allocated index.
00228                  *          If this pointer is null, then either this is a new
00229                  *          OID request, or the requested value is the first
00230                  *          in the list.
00231                  *      'idxptr2' points to the next sorted index (if any)
00232                  *          but is not actually needed any more.
00233                  *
00234                  *  Clear?  Good!
00235                  *      I hope you've been paying attention.
00236                  *          There'll be a test later :-)
00237                  */
00238 
00239                 /*
00240                  *      We proceed by creating the new entry
00241                  *         (by copying the entry provided)
00242                  */
00243         new_index = (struct snmp_index *)calloc( 1, sizeof( struct snmp_index ));
00244         if (new_index == NULL)
00245             return NULL;
00246 
00247         if (0 == snmp_varlist_add_variable(&new_index->varbind,
00248                       varbind->name, 
00249                       varbind->name_length,
00250                       varbind->type,
00251                       varbind->val.string,
00252                       varbind->val_len)) {
00253 /*      if (snmp_clone_var( varbind, new_index->varbind ) != 0 ) */
00254             free( new_index );
00255             return NULL;
00256         }
00257         new_index->session = ss;
00258 
00259         if ( varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX )
00260             new_index->varbind->val.string[new_index->varbind->val_len] = 0;
00261 
00262                 /*
00263                  * If we've been given a value, then we can use that, but
00264                  *    otherwise, we need to create a new value for this entry.
00265                  * Note that ANY_INDEX and NEW_INDEX are both covered by this
00266                  *   test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?)
00267                  */
00268         if ( flags & ALLOCATE_ANY_INDEX ) {
00269             if ( prev_idx_ptr ) {
00270                 if ( snmp_clone_var( prev_idx_ptr->varbind, new_index->varbind ) != 0 ) {
00271                     free( new_index );
00272                     return NULL;
00273                 }
00274             }
00275             else
00276                 new_index->varbind->val.string = new_index->varbind->buf;
00277 
00278             switch ( varbind->type ) {
00279                 case ASN_INTEGER:
00280                     if ( prev_idx_ptr ) {
00281                         (*new_index->varbind->val.integer)++; 
00282                     }
00283                     else
00284                         *(new_index->varbind->val.integer) = 1;
00285                     new_index->varbind->val_len = sizeof(long);
00286                     break;
00287                 case ASN_OCTET_STR:
00288                     if ( prev_idx_ptr ) {
00289                         i =  new_index->varbind->val_len-1;
00290                         while ( new_index->varbind->buf[ i ] == 'z' ) {
00291                             new_index->varbind->buf[ i ] = 'a';
00292                             i--;
00293                             if ( i < 0 ) {
00294                                 i =  new_index->varbind->val_len;
00295                                 new_index->varbind->buf[ i ] = 'a';
00296                                 new_index->varbind->buf[ i+1 ] = 0;
00297                             }
00298                         }
00299                         new_index->varbind->buf[ i ]++;
00300                     }
00301                     else
00302                         strcpy((char *)new_index->varbind->buf, "aaaa");
00303                     new_index->varbind->val_len = strlen((char *)new_index->varbind->buf);
00304                     break;
00305                 case ASN_OBJECT_ID:
00306                     if ( prev_idx_ptr ) {
00307                         i =  prev_idx_ptr->varbind->val_len/sizeof(oid) -1;
00308                         while ( new_index->varbind->val.objid[ i ] == 255 ) {
00309                             new_index->varbind->val.objid[ i ] = 1;
00310                             i--;
00311                             if ( i == 0 && new_index->varbind->val.objid[0] == 2 ) {
00312                                 new_index->varbind->val.objid[ 0 ] = 1;
00313                                 i =  new_index->varbind->val_len/sizeof(oid);
00314                                 new_index->varbind->val.objid[ i ] = 0;
00315                                 new_index->varbind->val_len += sizeof(oid);
00316                             }
00317                         }
00318                         new_index->varbind->val.objid[ i ]++;
00319                     }
00320                     else {
00321                         /* If the requested OID name is small enough,
00322                          *   append another OID (1) and use this as the
00323                          *   default starting value for new indexes.
00324                          */
00325                         if ( (varbind->name_length+1) * sizeof(oid) <= 40 ) {
00326                             for ( i = 0 ; i < (int)varbind->name_length ; i++ )
00327                                 new_index->varbind->val.objid[i] = varbind->name[i];
00328                             new_index->varbind->val.objid[varbind->name_length] = 1;
00329                             new_index->varbind->val_len =
00330                                         (varbind->name_length+1) * sizeof(oid);
00331                         }
00332                         else {
00333                             /* Otherwise use '.1.1.1.1...' */
00334                             i = 40/sizeof(oid);
00335                             if ( i > 4 )
00336                                 i = 4;
00337                             new_index->varbind->val_len = i * (sizeof(oid));
00338                             for (i-- ; i>=0 ; i-- )
00339                                 new_index->varbind->val.objid[i] = 1;
00340                         }
00341                     }
00342                     break;
00343                 default:
00344                     snmp_free_var(new_index->varbind);
00345                     free( new_index );
00346                     return NULL;        /* Index type not supported */
00347             }
00348         }
00349 
00350                 /*
00351                  * Right - we've set up the new entry.
00352                  * All that remains is to link it into the tree.
00353                  * There are a number of possible cases here,
00354                  *   so watch carefully.
00355                  */
00356         if ( prev_idx_ptr ) {
00357             new_index->next_idx = prev_idx_ptr->next_idx;
00358             new_index->next_oid = prev_idx_ptr->next_oid;
00359             prev_idx_ptr->next_idx = new_index;
00360         }
00361         else {
00362             if ( res == 0 && idxptr ) {
00363                 new_index->next_idx = idxptr;
00364                 new_index->next_oid = idxptr->next_oid;
00365             }
00366             else {
00367                 new_index->next_idx = NULL;
00368                 new_index->next_oid = idxptr;
00369             }
00370 
00371             if ( prev_oid_ptr ) {
00372                 while ( prev_oid_ptr ) {
00373                     prev_oid_ptr->next_oid = new_index;
00374                     prev_oid_ptr = prev_oid_ptr->next_idx;
00375                 }
00376             }
00377             else
00378                 snmp_index_head = new_index;
00379         }
00380     return new_index->varbind;
00381 }

int register_int_index oid *    name,
size_t    name_len,
int    val
 

Definition at line 100 of file agent_index.c.

00101 {
00102     struct variable_list varbind, *res;
00103     
00104     memset( &varbind, 0, sizeof(struct variable_list));
00105     varbind.type = ASN_INTEGER;
00106     snmp_set_var_objid( &varbind, name, name_len );
00107     varbind.val.string = varbind.buf;
00108     if ( val != ANY_INTEGER_INDEX ) {
00109         varbind.val_len = sizeof(long);
00110         *varbind.val.integer = val;
00111         res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
00112     }
00113     else
00114         res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
00115 
00116     if ( res == NULL )
00117         return -1;
00118     else
00119         return *res->val.integer;
00120 }

struct variable_list* register_oid_index oid *    name,
size_t    name_len,
oid *    value,
size_t    value_len
 

Definition at line 123 of file agent_index.c.

00125 {
00126     struct variable_list varbind;
00127     
00128     memset( &varbind, 0, sizeof(struct variable_list));
00129     varbind.type = ASN_OBJECT_ID;
00130     snmp_set_var_objid( &varbind, name, name_len );
00131     if ( value != ANY_OID_INDEX ) {
00132         snmp_set_var_value( &varbind, (u_char*)value, value_len*sizeof(oid) );
00133         return( register_index( &varbind, ALLOCATE_THIS_INDEX, main_session ));
00134     }
00135     else
00136         return( register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ));
00137 }

char* register_string_index oid *    name,
size_t    name_len,
char *    cp
 

Definition at line 79 of file agent_index.c.

00080 {
00081     struct variable_list varbind, *res;
00082     
00083     memset( &varbind, 0, sizeof(struct variable_list));
00084     varbind.type = ASN_OCTET_STR;
00085     snmp_set_var_objid( &varbind, name, name_len );
00086     if ( cp != ANY_STRING_INDEX ) {
00087         snmp_set_var_value( &varbind, (u_char *)cp, strlen(cp) );
00088         res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
00089     }
00090     else
00091         res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
00092 
00093     if ( res == NULL )
00094         return NULL;
00095     else
00096         return (char *)res->val.string;
00097 }

int release_index struct variable_list *    varbind
 

Definition at line 388 of file agent_index.c.

00389 {
00390     return( unregister_index( varbind, TRUE, NULL ));
00391 }

int remove_index struct variable_list *    varbind,
struct snmp_session *    ss
 

Definition at line 398 of file agent_index.c.

00399 {
00400     return( unregister_index( varbind, FALSE, ss ));
00401 }

int unregister_index struct variable_list *    varbind,
int    remember,
struct snmp_session *    ss
 

Definition at line 415 of file agent_index.c.

00416 {
00417     struct snmp_index *idxptr, *idxptr2;
00418     struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
00419     int res, res2, i;
00420 
00421 #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
00422     if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
00423         return( agentx_unregister_index( ss, varbind ));
00424 #endif
00425                 /* Look for the requested OID entry */
00426     prev_oid_ptr = NULL;
00427     prev_idx_ptr = NULL;
00428     res  = 1;
00429     res2 = 1;
00430     for( idxptr = snmp_index_head ; idxptr != NULL;
00431                          prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
00432         if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
00433                                         idxptr->varbind->name,
00434                                         idxptr->varbind->name_length)) <= 0 )
00435                 break;
00436     }
00437 
00438     if ( res != 0 )
00439         return INDEX_ERR_NOT_ALLOCATED;
00440     if ( varbind->type != idxptr->varbind->type )
00441         return INDEX_ERR_WRONG_TYPE;
00442 
00443     for(idxptr2 = idxptr ; idxptr2 != NULL;
00444                 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
00445         i = SNMP_MIN(varbind->val_len, idxptr2->varbind->val_len);
00446         res2 = memcmp(varbind->val.string, idxptr2->varbind->val.string, i);
00447         if ( res2 <= 0 )
00448             break;
00449     }
00450     if ( res2 != 0 )
00451         return INDEX_ERR_NOT_ALLOCATED;
00452     if ( ss != idxptr2->session )
00453         return INDEX_ERR_WRONG_SESSION;
00454 
00455                 /*
00456                  *  If this is a "normal" index unregistration,
00457                  *      mark the index entry as unused, but leave
00458                  *      it in situ.  This allows differentiation
00459                  *      between ANY_INDEX and NEW_INDEX
00460                  */
00461     if ( remember ) {
00462         idxptr2->session = NULL;        /* Unused index */
00463         return SNMP_ERR_NOERROR;
00464     }
00465                 /*
00466                  *  If this is a failed attempt to register a
00467                  *      number of indexes, the successful ones
00468                  *      must be removed completely.
00469                  */
00470     if ( prev_idx_ptr ) {
00471         prev_idx_ptr->next_idx = idxptr2->next_idx;
00472     }
00473     else if ( prev_oid_ptr ) {
00474         if ( idxptr2->next_idx )        /* Use p_idx_ptr as a temp variable */
00475             prev_idx_ptr = idxptr2->next_idx;
00476         else
00477             prev_idx_ptr = idxptr2->next_oid;
00478         while ( prev_oid_ptr ) {
00479             prev_oid_ptr->next_oid = prev_idx_ptr;
00480             prev_oid_ptr = prev_oid_ptr->next_idx;
00481         }
00482     }
00483     else {
00484         if ( idxptr2->next_idx )
00485             snmp_index_head = idxptr2->next_idx;
00486         else
00487             snmp_index_head = idxptr2->next_oid;
00488     }
00489     snmp_free_var( idxptr2->varbind );
00490     free( idxptr2 );
00491     return SNMP_ERR_NOERROR;
00492 }

void unregister_index_by_session struct snmp_session *    ss
 

Definition at line 404 of file agent_index.c.

00405 {
00406     struct snmp_index *idxptr, *idxptr2;
00407     for(idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid)
00408         for(idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx)
00409             if ( idxptr2->session == ss )
00410                 idxptr2->session = NULL;
00411 }

Variable Documentation

struct snmp_session* main_session
 

Definition at line 76 of file agent_index.c.

struct snmp_index * snmp_index_head
 


Generated on Sat Nov 10 14:09:53 2001 for net-snmp by doxygen1.2.11 written by Dimitri van Heesch, © 1997-2001
[an error occurred while processing this directive] [an error occurred while processing this directive]

Valid CSS!


Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.