net-snmp 5.7
|
00001 /* 00002 * table_row.c 00003 * 00004 * Helper for registering single row slices of a shared table 00005 * 00006 * $Id$ 00007 */ 00008 #define TABLE_ROW_DATA "table_row" 00009 00010 #include <net-snmp/net-snmp-config.h> 00011 #include <net-snmp/net-snmp-features.h> 00012 00013 #if HAVE_STRING_H 00014 #include <string.h> 00015 #else 00016 #include <strings.h> 00017 #endif 00018 00019 #include <net-snmp/net-snmp-includes.h> 00020 #include <net-snmp/agent/net-snmp-agent-includes.h> 00021 00022 #include <net-snmp/agent/table.h> 00023 #include <net-snmp/agent/table_container.h> 00024 #include <net-snmp/library/container.h> 00025 #include <net-snmp/library/snmp_assert.h> 00026 00027 netsnmp_feature_child_of(table_row_all, mib_helpers) 00028 00029 netsnmp_feature_child_of(table_row_extract, table_row_all) 00030 00031 00032 /* 00033 * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN -1 00034 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1 0 00035 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2 1 00036 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION 2 00037 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT 3 00038 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE 4 00039 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO 5 00040 */ 00041 00050 static Netsnmp_Node_Handler _table_row_handler; 00051 static Netsnmp_Node_Handler _table_row_default_handler; 00052 00053 /********************************************************************** 00054 ********************************************************************** 00055 * * 00056 * * 00057 * PUBLIC Registration functions * 00058 * * 00059 * * 00060 ********************************************************************** 00061 **********************************************************************/ 00062 00063 /* ================================== 00064 * 00065 * Table Row API: Table maintenance 00066 * 00067 * This helper doesn't operate with the complete 00068 * table, so these routines are not relevant. 00069 * 00070 * ================================== */ 00071 00072 00073 /* ================================== 00074 * 00075 * Table Row API: MIB maintenance 00076 * 00077 * ================================== */ 00078 00080 netsnmp_mib_handler * 00081 netsnmp_table_row_handler_get(void *row) 00082 { 00083 netsnmp_mib_handler *handler; 00084 00085 handler = netsnmp_create_handler("table_row", 00086 _table_row_handler); 00087 if(NULL == handler) { 00088 snmp_log(LOG_ERR, 00089 "malloc failure in netsnmp_table_row_register\n"); 00090 return NULL; 00091 } 00092 00093 handler->myvoid = (void*)row; 00094 handler->flags |= MIB_HANDLER_INSTANCE; 00095 /* handler->flags |= MIB_HANDLER_AUTO_NEXT; ??? */ 00096 00097 return handler; 00098 } 00099 00100 int 00101 netsnmp_table_row_register(netsnmp_handler_registration *reginfo, 00102 netsnmp_table_registration_info *tabreg, 00103 void *row, netsnmp_variable_list *index) 00104 { 00105 netsnmp_handler_registration *reg2; 00106 netsnmp_mib_handler *handler; 00107 oid row_oid[MAX_OID_LEN]; 00108 size_t row_oid_len, len; 00109 char tmp[SNMP_MAXBUF_MEDIUM]; 00110 00111 if ((NULL == reginfo) || (NULL == reginfo->handler) || (NULL == tabreg)) { 00112 snmp_log(LOG_ERR, "bad param in netsnmp_table_row_register\n"); 00113 return SNMPERR_GENERR; 00114 } 00115 00116 /* 00117 * The first table_row invoked for a particular table should 00118 * register the full table as well, with a default handler to 00119 * process requests for non-existent (or incomplete) rows. 00120 * 00121 * Subsequent table_row registrations attempting to set up 00122 * this default handler would fail - preferably silently! 00123 */ 00124 snprintf(tmp, sizeof(tmp), "%s_table", reginfo->handlerName); 00125 reg2 = netsnmp_create_handler_registration( 00126 tmp, _table_row_default_handler, 00127 reginfo->rootoid, reginfo->rootoid_len, 00128 reginfo->modes); 00129 netsnmp_register_table(reg2, tabreg); /* Ignore return value */ 00130 00131 /* 00132 * Adjust the OID being registered, to take account 00133 * of the indexes and column range provided.... 00134 */ 00135 row_oid_len = reginfo->rootoid_len; 00136 memcpy( row_oid, (u_char *) reginfo->rootoid, row_oid_len * sizeof(oid)); 00137 row_oid[row_oid_len++] = 1; /* tableEntry */ 00138 row_oid[row_oid_len++] = tabreg->min_column; 00139 reginfo->range_ubound = tabreg->max_column; 00140 reginfo->range_subid = row_oid_len-1; 00141 build_oid_noalloc(&row_oid[row_oid_len], 00142 MAX_OID_LEN-row_oid_len, &len, NULL, 0, index); 00143 row_oid_len += len; 00144 free(reginfo->rootoid); 00145 reginfo->rootoid = snmp_duplicate_objid(row_oid, row_oid_len); 00146 reginfo->rootoid_len = row_oid_len; 00147 00148 00149 /* 00150 * ... insert a minimal handler ... 00151 */ 00152 handler = netsnmp_table_row_handler_get(row); 00153 netsnmp_inject_handler(reginfo, handler ); 00154 00155 /* 00156 * ... and register the row 00157 */ 00158 return netsnmp_register_handler(reginfo); 00159 } 00160 00161 00163 #ifndef NETSNMP_FEATURE_REMOVE_TABLE_ROW_EXTRACT 00164 void * 00165 netsnmp_table_row_extract(netsnmp_request_info *request) 00166 { 00167 return netsnmp_request_get_list_data(request, TABLE_ROW_DATA); 00168 } 00169 #endif /* NETSNMP_FEATURE_REMOVE_TABLE_ROW_EXTRACT */ 00170 00172 /********************************************************************** 00173 ********************************************************************** 00174 * * 00175 * * 00176 * netsnmp_table_row_helper_handler() * 00177 * * 00178 * * 00179 ********************************************************************** 00180 **********************************************************************/ 00181 00182 static int 00183 _table_row_handler(netsnmp_mib_handler *handler, 00184 netsnmp_handler_registration *reginfo, 00185 netsnmp_agent_request_info *reqinfo, 00186 netsnmp_request_info *requests) 00187 { 00188 int rc = SNMP_ERR_NOERROR; 00189 netsnmp_request_info *req; 00190 void *row; 00191 00193 netsnmp_assert((NULL != handler) && (NULL != handler->myvoid)); 00194 netsnmp_assert((NULL != reginfo) && (NULL != reqinfo)); 00195 00196 DEBUGMSGTL(("table_row", "Mode %s, Got request:\n", 00197 se_find_label_in_slist("agent_mode",reqinfo->mode))); 00198 00199 /* 00200 * First off, get our pointer from the handler. 00201 * This contains the row that was actually registered. 00202 * Make this available for each of the requests passed in. 00203 */ 00204 row = handler->myvoid; 00205 for (req = requests; req; req=req->next) 00206 netsnmp_request_add_list_data(req, 00207 netsnmp_create_data_list(TABLE_ROW_DATA, row, NULL)); 00208 00209 /* 00210 * Then call the next handler, to actually process the request 00211 */ 00212 rc = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); 00213 if (rc != SNMP_ERR_NOERROR) { 00214 DEBUGMSGTL(("table_row", "next handler returned %d\n", rc)); 00215 } 00216 00217 return rc; 00218 } 00219 00220 static int 00221 _table_row_default_handler(netsnmp_mib_handler *handler, 00222 netsnmp_handler_registration *reginfo, 00223 netsnmp_agent_request_info *reqinfo, 00224 netsnmp_request_info *requests) 00225 { 00226 netsnmp_request_info *req; 00227 netsnmp_table_request_info *table_info; 00228 netsnmp_table_registration_info *tabreg; 00229 00230 tabreg = netsnmp_find_table_registration_info(reginfo); 00231 for ( req=requests; req; req=req->next ) { 00232 table_info = netsnmp_extract_table_info( req ); 00233 if (( table_info->colnum >= tabreg->min_column ) || 00234 ( table_info->colnum <= tabreg->max_column )) { 00235 netsnmp_set_request_error( reqinfo, req, SNMP_NOSUCHINSTANCE ); 00236 } else { 00237 netsnmp_set_request_error( reqinfo, req, SNMP_NOSUCHOBJECT ); 00238 } 00239 } 00240 return SNMP_ERR_NOERROR; 00241 } 00245 /* ================================== 00246 * 00247 * Table Row API: Row operations 00248 * 00249 * This helper doesn't operate with the complete 00250 * table, so these routines are not relevant. 00251 * 00252 * ================================== */ 00253 00254 00255 /* ================================== 00256 * 00257 * Table Row API: Index operations 00258 * 00259 * This helper doesn't operate with the complete 00260 * table, so these routines are not relevant. 00261 * 00262 * ================================== */ 00263