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