Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
Main Page | Modules | Data Structures | File List | Data Fields | Related Pages | Examples

table_tdata.c

00001 #include <net-snmp/net-snmp-config.h>
00002 
00003 #if HAVE_STRING_H
00004 #include <string.h>
00005 #else
00006 #include <strings.h>
00007 #endif
00008 
00009 #include <net-snmp/net-snmp-includes.h>
00010 #include <net-snmp/agent/net-snmp-agent-includes.h>
00011 
00012 #include <net-snmp/agent/table.h>
00013 #include <net-snmp/agent/table_tdata.h>
00014 #include <net-snmp/agent/table_container.h>
00015 #include <net-snmp/agent/read_only.h>
00016 
00017 #if HAVE_DMALLOC_H
00018 #include <dmalloc.h>
00019 #endif
00020 
00036 /* ==================================
00037  *
00038  * TData API: Table maintenance
00039  *
00040  * ================================== */
00041 
00042 /*
00043  * generates the index portion of an table oid from a varlist.
00044  */
00045 void
00046 _netsnmp_tdata_generate_index_oid(netsnmp_tdata_row *row)
00047 {
00048     build_oid(&row->oid_index.oids, &row->oid_index.len, NULL, 0, row->indexes);
00049 }
00050 
00052 netsnmp_tdata *
00053 netsnmp_tdata_create_table(const char *name, long flags)
00054 {
00055     netsnmp_tdata *table = SNMP_MALLOC_TYPEDEF(netsnmp_tdata);
00056     if ( !table )
00057         return NULL;
00058 
00059     if (name)
00060         table->name = strdup(name);
00061     table->container = netsnmp_container_find( "table_container" );
00062     return table;
00063 }
00064 
00066 void
00067 netsnmp_tdata_delete_table(netsnmp_tdata *table)
00068 {
00069     if (!table)
00070        return;
00071 
00072     if (table->name)
00073        free(table->name);
00074     if (table->container)
00075        CONTAINER_FREE(table->container);
00076     
00077     SNMP_FREE(table);
00078     return;
00079 }
00080 
00082 netsnmp_tdata_row *
00083 netsnmp_tdata_create_row(void)
00084 {
00085     netsnmp_tdata_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_tdata_row);
00086     return row;
00087 }
00088 
00090 netsnmp_tdata_row *
00091 netsnmp_tdata_clone_row(netsnmp_tdata_row *row)
00092 {
00093     netsnmp_tdata_row *newrow = NULL;
00094     if (!row)
00095         return NULL;
00096 
00097     memdup((u_char **) & newrow, (u_char *) row,
00098            sizeof(netsnmp_tdata_row));
00099     if (!newrow)
00100         return NULL;
00101 
00102     if (row->indexes) {
00103         newrow->indexes = snmp_clone_varbind(newrow->indexes);
00104         if (!newrow->indexes)
00105             return NULL;
00106     }
00107 
00108     if (row->oid_index.oids) {
00109         memdup((u_char **) & newrow->oid_index.oids,
00110                (u_char *) row->oid_index.oids,
00111                row->oid_index.len * sizeof(oid));
00112         if (!newrow->oid_index.oids)
00113             return NULL;
00114     }
00115 
00116     return newrow;
00117 }
00118 
00121 int
00122 netsnmp_tdata_copy_row(netsnmp_tdata_row *dst_row, netsnmp_tdata_row *src_row)
00123 {
00124      if ( !src_row || !dst_row )
00125          return -1;
00126 
00127     memcpy((u_char *) dst_row, (u_char *) src_row,
00128            sizeof(netsnmp_tdata_row));
00129     if (src_row->indexes) {
00130         dst_row->indexes = snmp_clone_varbind(src_row->indexes);
00131         if (!dst_row->indexes)
00132             return -1;
00133     }
00134 
00135     if (src_row->oid_index.oids) {
00136         memdup((u_char **) &dst_row->oid_index.oids,
00137                (u_char  *)  src_row->oid_index.oids,
00138                src_row->oid_index.len * sizeof(oid));
00139         if (!dst_row->oid_index.oids)
00140             return -1;
00141     }
00142 
00143     return 0;
00144 }
00145 
00149 void           *
00150 netsnmp_tdata_delete_row(netsnmp_tdata_row *row)
00151 {
00152     void           *data;
00153 
00154     if (!row)
00155         return NULL;
00156 
00157     /*
00158      * free the memory we can 
00159      */
00160     if (row->indexes)
00161         snmp_free_varbind(row->indexes);
00162     SNMP_FREE(row->oid_index.oids);
00163     data = row->data;
00164     free(row);
00165 
00166     /*
00167      * return the void * pointer 
00168      */
00169     return data;
00170 }
00171 
00178 int
00179 netsnmp_tdata_add_row(netsnmp_tdata     *table,
00180                       netsnmp_tdata_row *row)
00181 {
00182     if (!row || !table)
00183         return SNMPERR_GENERR;
00184 
00185     if (row->indexes)
00186         _netsnmp_tdata_generate_index_oid(row);
00187 
00188     if (!row->oid_index.oids) {
00189         snmp_log(LOG_ERR,
00190                  "illegal data attempted to be added to table %s (no index)\n",
00191                  table->name);
00192         return SNMPERR_GENERR;
00193     }
00194 
00195     /*
00196      * The individual index values probably won't be needed,
00197      *    so this memory can be released.
00198      * Note that this is purely internal to the helper.
00199      * The calling application can set this flag as
00200      *    a hint to the helper that these values aren't
00201      *    required, but it's up to the helper as to
00202      *    whether it takes any notice or not!
00203      */
00204     if (table->flags & TDATA_FLAG_NO_STORE_INDEXES) {
00205         snmp_free_varbind(row->indexes);
00206         row->indexes = NULL;
00207     }
00208 
00209     /*
00210      * add this row to the stored table
00211      */
00212     CONTAINER_INSERT( table->container, row );
00213     DEBUGMSGTL(("tdata_add_row", "added row (%x)\n", row));
00214 
00215     return SNMPERR_SUCCESS;
00216 }
00217 
00219 void
00220 netsnmp_tdata_replace_row(netsnmp_tdata *table,
00221                                netsnmp_tdata_row *origrow,
00222                                netsnmp_tdata_row *newrow)
00223 {
00224     netsnmp_tdata_remove_row(table, origrow);
00225     netsnmp_tdata_add_row(table, newrow);
00226 }
00227 
00234 netsnmp_tdata_row *
00235 netsnmp_tdata_remove_row(netsnmp_tdata *table,
00236                               netsnmp_tdata_row *row)
00237 {
00238     if (!row || !table)
00239         return NULL;
00240 
00241     CONTAINER_REMOVE( table->container, row );
00242     return row;
00243 }
00244 
00252 void           *
00253 netsnmp_tdata_remove_and_delete_row(netsnmp_tdata     *table,
00254                                     netsnmp_tdata_row *row)
00255 {
00256     if (!row || !table)
00257         return NULL;
00258 
00259     /*
00260      * remove it from the list 
00261      */
00262     netsnmp_tdata_remove_row(table, row);
00263     return netsnmp_tdata_delete_row(row);
00264 }
00265 
00266 
00267 /* ==================================
00268  *
00269  * TData API: MIB maintenance
00270  *
00271  * ================================== */
00272 
00273 Netsnmp_Node_Handler _netsnmp_tdata_helper_handler;
00274 
00276 netsnmp_mib_handler *
00277 netsnmp_get_tdata_handler(netsnmp_tdata *table)
00278 {
00279     netsnmp_mib_handler *ret = NULL;
00280 
00281     if (!table) {
00282         snmp_log(LOG_INFO,
00283                  "netsnmp_get_tdata_handler(NULL) called\n");
00284         return NULL;
00285     }
00286 
00287     ret = netsnmp_create_handler(TABLE_TDATA_NAME,
00288                                _netsnmp_tdata_helper_handler);
00289     if (ret) {
00290         ret->flags |= MIB_HANDLER_AUTO_NEXT;
00291         ret->myvoid = (void *) table;
00292     }
00293     return ret;
00294 }
00295 
00296 /*
00297  * The helper handler that takes care of passing a specific row of
00298  * data down to the lower handler(s).  The table_container helper
00299  * has already taken care of identifying the appropriate row of the
00300  * table (and converting GETNEXT requests into an equivalent GET request)
00301  * So all we need to do here is make sure that the row is accessible
00302  * using tdata-style retrieval techniques as well.
00303  */
00304 int
00305 _netsnmp_tdata_helper_handler(netsnmp_mib_handler *handler,
00306                                   netsnmp_handler_registration *reginfo,
00307                                   netsnmp_agent_request_info *reqinfo,
00308                                   netsnmp_request_info *requests)
00309 {
00310     netsnmp_tdata *table = (netsnmp_tdata *) handler->myvoid;
00311     netsnmp_request_info       *request;
00312     netsnmp_table_request_info *table_info;
00313     netsnmp_tdata_row          *row;
00314 
00315     switch ( reqinfo->mode ) {
00316     case MODE_GET:
00317     case MODE_SET_RESERVE1:
00318 
00319         for (request = requests; request; request = request->next) {
00320             if (request->processed)
00321                 continue;
00322     
00323             table_info = netsnmp_extract_table_info(request);
00324             if (!table_info)
00325                 continue;           /* ack */
00326             row = netsnmp_container_table_row_extract( request );
00327 
00328             netsnmp_request_add_list_data(request,
00329                                       netsnmp_create_data_list(
00330                                           TABLE_TDATA_TABLE, table, NULL));
00331             netsnmp_request_add_list_data(request,
00332                                       netsnmp_create_data_list(
00333                                           TABLE_TDATA_ROW,   row,   NULL));
00334         }
00335     }
00336 
00337     /* next handler called automatically - 'AUTO_NEXT' */
00338     return SNMP_ERR_NOERROR;
00339 }
00340 
00341 
00343 int
00344 netsnmp_tdata_register(netsnmp_handler_registration    *reginfo,
00345                        netsnmp_tdata                   *table,
00346                        netsnmp_table_registration_info *table_info)
00347 {
00348     netsnmp_inject_handler(reginfo, netsnmp_get_tdata_handler(table));
00349     return netsnmp_container_table_register(reginfo, table_info,
00350                   table->container, TABLE_CONTAINER_KEY_NETSNMP_INDEX);
00351 }
00352 
00354 netsnmp_tdata *
00355 netsnmp_tdata_extract_table(netsnmp_request_info *request)
00356 {
00357     return (netsnmp_tdata *) netsnmp_request_get_list_data(request,
00358                                                            TABLE_TDATA_TABLE);
00359 }
00360 
00362 netsnmp_container *
00363 netsnmp_tdata_extract_container(netsnmp_request_info *request)
00364 {
00365     netsnmp_tdata *tdata = netsnmp_request_get_list_data(request,
00366                                                          TABLE_TDATA_TABLE);
00367     return ( tdata ? tdata->container : NULL );
00368 }
00369 
00371 netsnmp_tdata_row *
00372 netsnmp_tdata_extract_row(netsnmp_request_info *request)
00373 {
00374     return (netsnmp_tdata_row *) netsnmp_container_table_row_extract(request);
00375 }
00376 
00379 void           *
00380 netsnmp_tdata_extract_entry(netsnmp_request_info *request)
00381 {
00382     netsnmp_tdata_row *row =
00383         (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request);
00384     if (row)
00385         return row->data;
00386     else
00387         return NULL;
00388 }
00389 
00391 NETSNMP_INLINE void
00392 netsnmp_insert_tdata_row(netsnmp_request_info *request,
00393                          netsnmp_tdata_row *row)
00394 {
00395     netsnmp_container_table_row_insert(request, (netsnmp_index *)row);
00396 }
00397 
00398 
00399 /* ==================================
00400  *
00401  * Generic API: Row operations
00402  *
00403  * ================================== */
00404 
00406 void *
00407 netsnmp_tdata_row_entry( netsnmp_tdata_row *row )
00408 {
00409     if (row)
00410         return row->data;
00411     else
00412         return NULL;
00413 }
00414 
00416 netsnmp_tdata_row *
00417 netsnmp_tdata_row_first(netsnmp_tdata *table)
00418 {
00419     return (netsnmp_tdata_row *)CONTAINER_FIRST( table->container );
00420 }
00421 
00423 netsnmp_tdata_row *
00424 netsnmp_tdata_row_get(  netsnmp_tdata     *table,
00425                         netsnmp_tdata_row *row)
00426 {
00427     return CONTAINER_FIND( table->container, row );
00428 }
00429 
00431 netsnmp_tdata_row *
00432 netsnmp_tdata_row_next( netsnmp_tdata      *table,
00433                         netsnmp_tdata_row  *row)
00434 {
00435     return (netsnmp_tdata_row *)CONTAINER_NEXT( table->container, row  );
00436 }
00437 
00439 netsnmp_tdata_row *
00440 netsnmp_tdata_row_get_byidx(netsnmp_tdata         *table,
00441                             netsnmp_variable_list *indexes)
00442 {
00443     oid             searchfor[      MAX_OID_LEN];
00444     size_t          searchfor_len = MAX_OID_LEN;
00445 
00446     build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
00447                       indexes);
00448     return netsnmp_tdata_row_get_byoid(table, searchfor, searchfor_len);
00449 }
00450 
00452 netsnmp_tdata_row *
00453 netsnmp_tdata_row_get_byoid(netsnmp_tdata *table,
00454                             oid * searchfor, size_t searchfor_len)
00455 {
00456     netsnmp_index index;
00457     if (!table)
00458         return NULL;
00459 
00460     index.oids = searchfor;
00461     index.len  = searchfor_len;
00462     return CONTAINER_FIND( table->container, &index );
00463 }
00464 
00467 netsnmp_tdata_row *
00468 netsnmp_tdata_row_next_byidx(netsnmp_tdata         *table,
00469                              netsnmp_variable_list *indexes)
00470 {
00471     oid             searchfor[      MAX_OID_LEN];
00472     size_t          searchfor_len = MAX_OID_LEN;
00473 
00474     build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
00475                       indexes);
00476     return netsnmp_tdata_row_next_byoid(table, searchfor, searchfor_len);
00477 }
00478 
00481 netsnmp_tdata_row *
00482 netsnmp_tdata_row_next_byoid(netsnmp_tdata *table,
00483                              oid * searchfor, size_t searchfor_len)
00484 {
00485     netsnmp_index index;
00486     if (!table)
00487         return NULL;
00488 
00489     index.oids = searchfor;
00490     index.len  = searchfor_len;
00491     return CONTAINER_NEXT( table->container, &index );
00492 }
00493 
00494 int
00495 netsnmp_tdata_row_count(netsnmp_tdata *table)
00496 {
00497     if (!table)
00498         return 0;
00499     return CONTAINER_SIZE( table->container );
00500 }
00501 
00502 /* ==================================
00503  *
00504  * Generic API: Index operations on a 'tdata' table
00505  *
00506  * ================================== */
00507 
00508 
00510 int
00511 netsnmp_tdata_compare_idx(netsnmp_tdata_row     *row,
00512                           netsnmp_variable_list *indexes)
00513 {
00514     oid             searchfor[      MAX_OID_LEN];
00515     size_t          searchfor_len = MAX_OID_LEN;
00516 
00517     build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
00518                       indexes);
00519     return netsnmp_tdata_compare_oid(row, searchfor, searchfor_len);
00520 }
00521 
00523 int
00524 netsnmp_tdata_compare_oid(netsnmp_tdata_row     *row,
00525                           oid * compareto, size_t compareto_len)
00526 {
00527     netsnmp_index *index = (netsnmp_index *)row;
00528     return snmp_oid_compare( index->oids, index->len,
00529                              compareto,   compareto_len);
00530 }
00531 
00532 int
00533 netsnmp_tdata_compare_subtree_idx(netsnmp_tdata_row     *row,
00534                                   netsnmp_variable_list *indexes)
00535 {
00536     oid             searchfor[      MAX_OID_LEN];
00537     size_t          searchfor_len = MAX_OID_LEN;
00538 
00539     build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
00540                       indexes);
00541     return netsnmp_tdata_compare_subtree_oid(row, searchfor, searchfor_len);
00542 }
00543 
00544 int
00545 netsnmp_tdata_compare_subtree_oid(netsnmp_tdata_row     *row,
00546                                   oid * compareto, size_t compareto_len)
00547 {
00548     netsnmp_index *index = (netsnmp_index *)row;
00549     return snmp_oidtree_compare( index->oids, index->len,
00550                                  compareto,   compareto_len);
00551 }
00552 
00553 /*
00554  * @} 
00555  */

Generated on Fri Dec 30 13:47:51 2005 for net-snmp by  doxygen 1.3.9.1

Valid CSS!


Last modified: Thursday, 01-Mar-2007 16:20:09 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.