00001
00002
00003
00004
00005
00006 #include <net-snmp/net-snmp-config.h>
00007 #include <net-snmp/net-snmp-includes.h>
00008 #include <net-snmp/agent/net-snmp-agent-includes.h>
00009 #include "netSnmpHostsTable.h"
00010 #include "netSnmpHostsTable_checkfns.h"
00011 #include "netSnmpHostsTable_access.h"
00012
00013 static netsnmp_oid_stash_node *undoStorage = NULL;
00014 static netsnmp_oid_stash_node *commitStorage = NULL;
00015
00016 struct undoInfo {
00017 void *ptr;
00018 size_t len;
00019 };
00020
00021 struct commitInfo {
00022 void *data_context;
00023 int have_committed;
00024 int new_row;
00025 };
00026
00027 void
00028 netSnmpHostsTable_free_undoInfo(void *vptr)
00029 {
00030 struct undoInfo *ui = vptr;
00031 if (!ui)
00032 return;
00033 SNMP_FREE(ui->ptr);
00034 SNMP_FREE(ui);
00035 }
00036
00038 void
00039 initialize_table_netSnmpHostsTable(void)
00040 {
00041 static oid netSnmpHostsTable_oid[] =
00042 { 1, 3, 6, 1, 4, 1, 8072, 2, 2, 2 };
00043 netsnmp_table_registration_info *table_info;
00044 netsnmp_handler_registration *my_handler;
00045 netsnmp_iterator_info *iinfo;
00046
00048 table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
00049 iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
00050
00053 my_handler = netsnmp_create_handler_registration("netSnmpHostsTable",
00054 netSnmpHostsTable_handler,
00055 netSnmpHostsTable_oid,
00056 OID_LENGTH
00057 (netSnmpHostsTable_oid),
00058 HANDLER_CAN_RWRITE);
00059
00060 if (!my_handler || !table_info || !iinfo) {
00061 snmp_log(LOG_ERR,
00062 "malloc failed in initialize_table_netSnmpHostsTable");
00063 return;
00064 }
00065
00066
00067
00068
00069 netsnmp_table_helper_add_indexes(table_info, ASN_OCTET_STR,
00071 0);
00072
00075 table_info->min_column = 2;
00076 table_info->max_column = 5;
00077
00079 iinfo->get_first_data_point = netSnmpHostsTable_get_first_data_point;
00080 iinfo->get_next_data_point = netSnmpHostsTable_get_next_data_point;
00081
00083 iinfo->make_data_context = netSnmpHostsTable_context_convert_function;
00084 iinfo->free_data_context = netSnmpHostsTable_data_free;
00085 iinfo->free_loop_context_at_end = netSnmpHostsTable_loop_free;
00086
00088 iinfo->table_reginfo = table_info;
00089
00090
00091
00092
00093 DEBUGMSGTL(("initialize_table_netSnmpHostsTable",
00094 "Registering table netSnmpHostsTable as a table iterator\n"));
00095 netsnmp_register_table_iterator(my_handler, iinfo);
00096 }
00097
00099 void
00100 init_netSnmpHostsTable(void)
00101 {
00102
00104 initialize_table_netSnmpHostsTable();
00105 }
00106
00108 int
00109 netSnmpHostsTable_handler(netsnmp_mib_handler *handler,
00110 netsnmp_handler_registration *reginfo,
00111 netsnmp_agent_request_info *reqinfo,
00112 netsnmp_request_info *requests)
00113 {
00114
00115 netsnmp_request_info *request;
00116 netsnmp_table_request_info *table_info;
00117 netsnmp_variable_list *var;
00118 struct commitInfo *ci = NULL;
00119
00120 void *data_context = NULL;
00121
00122 oid *suffix;
00123 size_t suffix_len;
00124
00125 for (request = requests; request; request = request->next) {
00126
00127 var = request->requestvb;
00128 suffix = var->name + reginfo->rootoid_len + 1;
00129 suffix_len = var->name_length - (reginfo->rootoid_len + 1);
00130
00131 if (request->processed != 0)
00132 continue;
00133
00134 switch (reqinfo->mode) {
00135 case MODE_GET:
00136 case MODE_SET_RESERVE1:
00137 data_context = netsnmp_extract_iterator_context(request);
00138 if (data_context == NULL) {
00139 if (reqinfo->mode == MODE_GET) {
00140 netsnmp_set_request_error(reqinfo, request,
00141 SNMP_NOSUCHINSTANCE);
00142 continue;
00143 }
00144 }
00145 break;
00146
00147 default:
00148 ci = netsnmp_oid_stash_get_data(commitStorage,
00149 suffix + 1, suffix_len - 1);
00150 break;
00151
00152 }
00153
00155 table_info = netsnmp_extract_table_info(request);
00161 if (table_info == NULL) {
00162 continue;
00163 }
00164
00165 switch (reqinfo->mode) {
00166 case MODE_GET:
00167 switch (table_info->colnum) {
00168 case COLUMN_NETSNMPHOSTADDRESSTYPE:
00169 {
00170 long *retval;
00171 size_t retval_len = 0;
00172 retval =
00173 get_netSnmpHostAddressType(data_context,
00174 &retval_len);
00175 snmp_set_var_typed_value(var, ASN_INTEGER,
00176 (const u_char *) retval,
00177 retval_len);
00178 }
00179 break;
00180
00181 case COLUMN_NETSNMPHOSTADDRESS:
00182 {
00183 char *retval;
00184 size_t retval_len = 0;
00185 retval =
00186 get_netSnmpHostAddress(data_context, &retval_len);
00187 snmp_set_var_typed_value(var, ASN_OCTET_STR,
00188 (const u_char *) retval,
00189 retval_len);
00190 }
00191 break;
00192
00193 case COLUMN_NETSNMPHOSTSTORAGE:
00194 {
00195 long *retval;
00196 size_t retval_len = 0;
00197 retval =
00198 get_netSnmpHostStorage(data_context, &retval_len);
00199 snmp_set_var_typed_value(var, ASN_INTEGER,
00200 (const u_char *) retval,
00201 retval_len);
00202 }
00203 break;
00204
00205 case COLUMN_NETSNMPHOSTROWSTATUS:
00206 {
00207 long *retval;
00208 size_t retval_len = 0;
00209 retval =
00210 get_netSnmpHostRowStatus(data_context,
00211 &retval_len);
00212 snmp_set_var_typed_value(var, ASN_INTEGER,
00213 (const u_char *) retval,
00214 retval_len);
00215 }
00216 break;
00217
00218 default:
00220 snmp_log(LOG_ERR,
00221 "problem encountered in netSnmpHostsTable_handler: unknown column\n");
00222 }
00223 break;
00224
00225 case MODE_SET_RESERVE1:
00226 ci = netsnmp_oid_stash_get_data(commitStorage,
00227 suffix + 1, suffix_len - 1);
00228
00229 if (!ci) {
00231 ci = SNMP_MALLOC_STRUCT(commitInfo);
00232 if (!data_context) {
00233 ci->data_context =
00234 netSnmpHostsTable_create_data_context(table_info->
00235 indexes);
00236 ci->new_row = 1;
00237 } else {
00238 ci->data_context = data_context;
00239 }
00240 netsnmp_oid_stash_add_data(&commitStorage,
00241 suffix + 1, suffix_len - 1, ci);
00242 }
00243 break;
00244
00245 case MODE_SET_RESERVE2:
00246 switch (table_info->colnum) {
00247 case COLUMN_NETSNMPHOSTADDRESSTYPE:
00248 {
00249 long *retval;
00250 size_t retval_len = 0;
00251 struct undoInfo *ui = NULL;
00252 int ret;
00253
00255 retval =
00256 get_netSnmpHostAddressType(ci->data_context,
00257 &retval_len);
00258 if (retval) {
00259 ui = SNMP_MALLOC_STRUCT(undoInfo);
00260 ui->len = retval_len;
00261 memdup((u_char **) & ui->ptr,
00262 (u_char *) retval, ui->len);
00263 }
00264
00267 ret =
00268 check_netSnmpHostAddressType(request->requestvb->
00269 type,
00270 (long *) request->
00271 requestvb->val.string,
00272 request->requestvb->
00273 val_len, retval,
00274 retval_len);
00275 if (ret != 0) {
00276 netsnmp_set_request_error(reqinfo, request, ret);
00277 netSnmpHostsTable_free_undoInfo(ui);
00278 } else if (ui) {
00280 netsnmp_oid_stash_add_data(&undoStorage,
00281 suffix, suffix_len, ui);
00282 }
00283
00284 }
00285 break;
00286 case COLUMN_NETSNMPHOSTADDRESS:
00287 {
00288 char *retval;
00289 size_t retval_len = 0;
00290 struct undoInfo *ui = NULL;
00291 int ret;
00292
00294 retval =
00295 get_netSnmpHostAddress(ci->data_context,
00296 &retval_len);
00297 if (retval) {
00298 ui = SNMP_MALLOC_STRUCT(undoInfo);
00299 ui->len = retval_len;
00300 memdup((u_char **) & ui->ptr,
00301 (u_char *) retval, ui->len);
00302 }
00303
00306 ret =
00307 check_netSnmpHostAddress(request->requestvb->type,
00308 (char *) request->
00309 requestvb->val.string,
00310 request->requestvb->
00311 val_len, retval,
00312 retval_len);
00313 if (ret != 0) {
00314 netsnmp_set_request_error(reqinfo, request, ret);
00315 netSnmpHostsTable_free_undoInfo(ui);
00316 } else if (ui) {
00318 netsnmp_oid_stash_add_data(&undoStorage,
00319 suffix, suffix_len, ui);
00320 }
00321
00322 }
00323 break;
00324 case COLUMN_NETSNMPHOSTSTORAGE:
00325 {
00326 long *retval;
00327 size_t retval_len = 0;
00328 struct undoInfo *ui = NULL;
00329 int ret;
00330
00332 retval =
00333 get_netSnmpHostStorage(ci->data_context,
00334 &retval_len);
00335 if (retval) {
00336 ui = SNMP_MALLOC_STRUCT(undoInfo);
00337 ui->len = retval_len;
00338 memdup((u_char **) & ui->ptr,
00339 (u_char *) retval, ui->len);
00340 }
00341
00344 ret =
00345 check_netSnmpHostStorage(request->requestvb->type,
00346 (long *) request->
00347 requestvb->val.string,
00348 request->requestvb->
00349 val_len, retval,
00350 retval_len);
00351 if (ret != 0) {
00352 netsnmp_set_request_error(reqinfo, request, ret);
00353 netSnmpHostsTable_free_undoInfo(ui);
00354 } else if (ui) {
00356 netsnmp_oid_stash_add_data(&undoStorage,
00357 suffix, suffix_len, ui);
00358 }
00359
00360 }
00361 break;
00362 case COLUMN_NETSNMPHOSTROWSTATUS:
00363 {
00364 long *retval;
00365 size_t retval_len = 0;
00366 struct undoInfo *ui = NULL;
00367 int ret;
00368
00370 retval =
00371 get_netSnmpHostRowStatus(ci->data_context,
00372 &retval_len);
00373 if (retval) {
00374 ui = SNMP_MALLOC_STRUCT(undoInfo);
00375 ui->len = retval_len;
00376 memdup((u_char **) & ui->ptr,
00377 (u_char *) retval, ui->len);
00378 }
00379
00382 ret =
00383 check_netSnmpHostRowStatus(request->requestvb->
00384 type,
00385 (long *) request->
00386 requestvb->val.string,
00387 request->requestvb->
00388 val_len, retval,
00389 retval_len);
00390 if (ret != 0) {
00391 netsnmp_set_request_error(reqinfo, request, ret);
00392 netSnmpHostsTable_free_undoInfo(ui);
00393 } else if (ui) {
00395 netsnmp_oid_stash_add_data(&undoStorage,
00396 suffix, suffix_len, ui);
00397 }
00398
00399 }
00400 break;
00401 default:
00402 netsnmp_set_request_error(reqinfo, request,
00403 SNMP_ERR_NOTWRITABLE);
00404 break;
00405 }
00406 break;
00407
00408 case MODE_SET_ACTION:
00410 switch (table_info->colnum) {
00411 case COLUMN_NETSNMPHOSTADDRESSTYPE:
00412 {
00413 int ret;
00414 ret = set_netSnmpHostAddressType(ci->data_context,
00415 (long *) request->
00416 requestvb->val.string,
00417 request->requestvb->
00418 val_len);
00419 if (ret) {
00420 netsnmp_set_request_error(reqinfo, request, ret);
00421 }
00422 }
00423 break;
00424 case COLUMN_NETSNMPHOSTADDRESS:
00425 {
00426 int ret;
00427 ret = set_netSnmpHostAddress(ci->data_context,
00428 (char *) request->
00429 requestvb->val.string,
00430 request->requestvb->
00431 val_len);
00432 if (ret) {
00433 netsnmp_set_request_error(reqinfo, request, ret);
00434 }
00435 }
00436 break;
00437 case COLUMN_NETSNMPHOSTSTORAGE:
00438 {
00439 int ret;
00440 ret = set_netSnmpHostStorage(ci->data_context,
00441 (long *) request->
00442 requestvb->val.string,
00443 request->requestvb->
00444 val_len);
00445 if (ret) {
00446 netsnmp_set_request_error(reqinfo, request, ret);
00447 }
00448 }
00449 break;
00450 case COLUMN_NETSNMPHOSTROWSTATUS:
00451 {
00452 int ret;
00453 ret = set_netSnmpHostRowStatus(ci->data_context,
00454 (long *) request->
00455 requestvb->val.string,
00456 request->requestvb->
00457 val_len);
00458 if (ret) {
00459 netsnmp_set_request_error(reqinfo, request, ret);
00460 }
00461 if (*request->requestvb->val.integer == RS_DESTROY) {
00462 ci->new_row = -1;
00463 }
00464 }
00465 break;
00466 }
00467 break;
00468
00469 case MODE_SET_COMMIT:
00470 if (!ci->have_committed) {
00472 netSnmpHostsTable_commit_row(&ci->data_context,
00473 ci->new_row);
00474 ci->have_committed = 1;
00475 }
00476 break;
00477
00478 case MODE_SET_UNDO:
00480 switch (table_info->colnum) {
00481 case COLUMN_NETSNMPHOSTADDRESSTYPE:
00482 {
00483 int retval;
00484 struct undoInfo *ui;
00485 ui = netsnmp_oid_stash_get_data(undoStorage,
00486 suffix, suffix_len);
00487 retval =
00488 set_netSnmpHostAddressType(ci->data_context,
00489 ui->ptr, ui->len);
00490 if (retval) {
00491 netsnmp_set_request_error(reqinfo, request,
00492 SNMP_ERR_UNDOFAILED);
00493 }
00494 }
00495 break;
00496 case COLUMN_NETSNMPHOSTADDRESS:
00497 {
00498 int retval;
00499 struct undoInfo *ui;
00500 ui = netsnmp_oid_stash_get_data(undoStorage,
00501 suffix, suffix_len);
00502 retval =
00503 set_netSnmpHostAddress(ci->data_context, ui->ptr,
00504 ui->len);
00505 if (retval) {
00506 netsnmp_set_request_error(reqinfo, request,
00507 SNMP_ERR_UNDOFAILED);
00508 }
00509 }
00510 break;
00511 case COLUMN_NETSNMPHOSTSTORAGE:
00512 {
00513 int retval;
00514 struct undoInfo *ui;
00515 ui = netsnmp_oid_stash_get_data(undoStorage,
00516 suffix, suffix_len);
00517 retval =
00518 set_netSnmpHostStorage(ci->data_context, ui->ptr,
00519 ui->len);
00520 if (retval) {
00521 netsnmp_set_request_error(reqinfo, request,
00522 SNMP_ERR_UNDOFAILED);
00523 }
00524 }
00525 break;
00526 case COLUMN_NETSNMPHOSTROWSTATUS:
00527 {
00528 int retval;
00529 struct undoInfo *ui;
00530 ui = netsnmp_oid_stash_get_data(undoStorage,
00531 suffix, suffix_len);
00532 retval =
00533 set_netSnmpHostRowStatus(ci->data_context, ui->ptr,
00534 ui->len);
00535 if (retval) {
00536 netsnmp_set_request_error(reqinfo, request,
00537 SNMP_ERR_UNDOFAILED);
00538 }
00539 }
00540 break;
00541 }
00542 break;
00543
00544 case MODE_SET_FREE:
00545 break;
00546
00547 default:
00548 snmp_log(LOG_ERR,
00549 "problem encountered in netSnmpHostsTable_handler: unsupported mode\n");
00550 }
00551 }
00552
00554 switch (reqinfo->mode) {
00555 case MODE_SET_UNDO:
00556 case MODE_SET_FREE:
00557 case MODE_SET_COMMIT:
00559 netsnmp_oid_stash_free(&undoStorage,
00560 netSnmpHostsTable_free_undoInfo);
00561 netsnmp_oid_stash_free(&commitStorage, netsnmp_oid_stash_no_free);
00562 }
00563
00564
00565 return SNMP_ERR_NOERROR;
00566 }