1 /*
2 * Note: this file originally auto-generated by mib2c using
3 * version : 1.67 $ of : mfd-interface.m2c,v $
4 *
5 * $Id$
6 */
7 /*
8 * *********************************************************************
9 * *********************************************************************
10 * *********************************************************************
11 * *** ***
12 * *** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ***
13 * *** ***
14 * *** ***
15 * *** THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE. ***
16 * *** ***
17 * *** ***
18 * *** THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND ***
19 * *** ***
20 * *** ***
21 * *** IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES. ***
22 * *** ***
23 * *** ***
24 * *********************************************************************
25 * *********************************************************************
26 * *********************************************************************
27 */
28
29 /*
30 * standard Net-SNMP includes
31 */
32 #include <net-snmp/net-snmp-config.h>
33 #include <net-snmp/net-snmp-features.h>
34 #include <net-snmp/net-snmp-includes.h>
35 #include <net-snmp/agent/net-snmp-agent-includes.h>
36
37 /*
38 * include our parent header
39 */
40 #include "ipAddressTable.h"
41
42
43 #include <net-snmp/agent/table_container.h>
44 #include <net-snmp/library/container.h>
45
46 #include "ipAddressTable_interface.h"
47
48 #include <ctype.h>
49
50 netsnmp_feature_child_of(ipAddressTable_external_access, libnetsnmpmibs);
51
52 netsnmp_feature_require(row_merge);
53 netsnmp_feature_require(baby_steps);
54 netsnmp_feature_require(table_container_row_insert);
55 netsnmp_feature_require(check_all_requests_error);
56
57
58 netsnmp_feature_child_of(ipAddressTable_container_size, ipAddressTable_external_access);
59 netsnmp_feature_child_of(ipAddressTable_registration_set, ipAddressTable_external_access);
60 netsnmp_feature_child_of(ipAddressTable_registration_get, ipAddressTable_external_access);
61 netsnmp_feature_child_of(ipAddressTable_container_get, ipAddressTable_external_access);
62
63 /**********************************************************************
64 **********************************************************************
65 ***
66 *** Table ipAddressTable
67 ***
68 **********************************************************************
69 **********************************************************************/
70 /*
71 * IP-MIB::ipAddressTable is subid 34 of ip.
72 * Its status is Current.
73 * OID: .1.3.6.1.2.1.4.34, length: 8
74 */
75 typedef struct ipAddressTable_interface_ctx_s {
76
77 netsnmp_container *container;
78 netsnmp_cache *cache;
79
80 ipAddressTable_registration *user_ctx;
81
82 netsnmp_table_registration_info tbl_info;
83
84 netsnmp_baby_steps_access_methods access_multiplexer;
85
86 u_int table_dirty;
87
88 } ipAddressTable_interface_ctx;
89
90 static ipAddressTable_interface_ctx ipAddressTable_if_ctx;
91
92 static void _ipAddressTable_container_init(ipAddressTable_interface_ctx
93 * if_ctx);
94 static void
95 _ipAddressTable_container_shutdown(ipAddressTable_interface_ctx * if_ctx);
96
97 #ifndef NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_CONTAINER_GET
98 netsnmp_container *
ipAddressTable_container_get(void)99 ipAddressTable_container_get(void)
100 {
101 return ipAddressTable_if_ctx.container;
102 }
103 #endif /* NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_CONTAINER_GET */
104
105 #ifndef NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_REGISTRATION_GET
106 ipAddressTable_registration *
ipAddressTable_registration_get(void)107 ipAddressTable_registration_get(void)
108 {
109 return ipAddressTable_if_ctx.user_ctx;
110 }
111 #endif /* NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_REGISTRATION_GET */
112
113 #ifndef NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_REGISTRATION_SET
114 ipAddressTable_registration *
ipAddressTable_registration_set(ipAddressTable_registration * newreg)115 ipAddressTable_registration_set(ipAddressTable_registration * newreg)
116 {
117 ipAddressTable_registration *old = ipAddressTable_if_ctx.user_ctx;
118 ipAddressTable_if_ctx.user_ctx = newreg;
119 return old;
120 }
121 #endif /* NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_REGISTRATION_SET */
122
123 #ifndef NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_CONTAINER_SIZE
124 int
ipAddressTable_container_size(void)125 ipAddressTable_container_size(void)
126 {
127 return CONTAINER_SIZE(ipAddressTable_if_ctx.container);
128 }
129 #endif /* NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_CONTAINER_SIZE */
130
131 u_int
ipAddressTable_dirty_get(void)132 ipAddressTable_dirty_get(void)
133 {
134 return ipAddressTable_if_ctx.table_dirty;
135 }
136
137 void
ipAddressTable_dirty_set(u_int status)138 ipAddressTable_dirty_set(u_int status)
139 {
140 DEBUGMSGTL(("ipAddressTable:ipAddressTable_dirty_set",
141 "called. was %d, now %d\n",
142 ipAddressTable_if_ctx.table_dirty, status));
143 ipAddressTable_if_ctx.table_dirty = status;
144 }
145
146 /*
147 * mfd multiplexer modes
148 */
149 static Netsnmp_Node_Handler _mfd_ipAddressTable_pre_request;
150 static Netsnmp_Node_Handler _mfd_ipAddressTable_post_request;
151 static Netsnmp_Node_Handler _mfd_ipAddressTable_object_lookup;
152 static Netsnmp_Node_Handler _mfd_ipAddressTable_get_values;
153 #if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
154 static Netsnmp_Node_Handler _mfd_ipAddressTable_check_objects;
155 static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_setup;
156 static Netsnmp_Node_Handler _mfd_ipAddressTable_set_values;
157 static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_cleanup;
158 static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_values;
159 static Netsnmp_Node_Handler _mfd_ipAddressTable_commit;
160 static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_commit;
161 static Netsnmp_Node_Handler _mfd_ipAddressTable_irreversible_commit;
162 static Netsnmp_Node_Handler _mfd_ipAddressTable_check_dependencies;
163
164 NETSNMP_STATIC_INLINE int
165 _ipAddressTable_undo_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
166 netsnmp_variable_list * var,
167 int column);
168 #endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */
169
170 NETSNMP_STATIC_INLINE int
171 _ipAddressTable_check_indexes(ipAddressTable_rowreq_ctx * rowreq_ctx);
172
173 /**
174 * @internal
175 * Initialize the table ipAddressTable
176 * (Define its contents and how it's structured)
177 */
178 void
_ipAddressTable_initialize_interface(ipAddressTable_registration * reg_ptr,u_long flags)179 _ipAddressTable_initialize_interface(ipAddressTable_registration * reg_ptr,
180 u_long flags)
181 {
182 netsnmp_baby_steps_access_methods *access_multiplexer =
183 &ipAddressTable_if_ctx.access_multiplexer;
184 netsnmp_table_registration_info *tbl_info =
185 &ipAddressTable_if_ctx.tbl_info;
186 netsnmp_handler_registration *reginfo;
187 netsnmp_mib_handler *handler;
188 int mfd_modes = 0;
189
190 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_initialize_interface", "called\n"));
191
192
193 /*************************************************
194 *
195 * save interface context for ipAddressTable
196 */
197 /*
198 * Setting up the table's definition
199 */
200 netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
201 /** index: ipAddressAddrType */
202 ASN_OCTET_STR,
203 /** index: ipAddressAddr */
204 0);
205
206 /*
207 * Define the minimum and maximum accessible columns. This
208 * optimizes retrieval.
209 */
210 tbl_info->min_column = IPADDRESSTABLE_MIN_COL;
211 tbl_info->max_column = IPADDRESSTABLE_MAX_COL;
212
213 /*
214 * save users context
215 */
216 ipAddressTable_if_ctx.user_ctx = reg_ptr;
217
218 /*
219 * call data access initialization code
220 */
221 ipAddressTable_init_data(reg_ptr);
222
223 /*
224 * set up the container
225 */
226 _ipAddressTable_container_init(&ipAddressTable_if_ctx);
227 if (NULL == ipAddressTable_if_ctx.container) {
228 snmp_log(LOG_ERR,
229 "could not initialize container for ipAddressTable\n");
230 return;
231 }
232
233 /*
234 * access_multiplexer: REQUIRED wrapper for get request handling
235 */
236 access_multiplexer->object_lookup = _mfd_ipAddressTable_object_lookup;
237 access_multiplexer->get_values = _mfd_ipAddressTable_get_values;
238
239 /*
240 * no wrappers yet
241 */
242 access_multiplexer->pre_request = _mfd_ipAddressTable_pre_request;
243 access_multiplexer->post_request = _mfd_ipAddressTable_post_request;
244
245
246 #if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
247 /*
248 * REQUIRED wrappers for set request handling
249 */
250 access_multiplexer->object_syntax_checks =
251 _mfd_ipAddressTable_check_objects;
252 access_multiplexer->undo_setup = _mfd_ipAddressTable_undo_setup;
253 access_multiplexer->undo_cleanup = _mfd_ipAddressTable_undo_cleanup;
254 access_multiplexer->set_values = _mfd_ipAddressTable_set_values;
255 access_multiplexer->undo_sets = _mfd_ipAddressTable_undo_values;
256
257 /*
258 * no wrappers yet
259 */
260 access_multiplexer->commit = _mfd_ipAddressTable_commit;
261 access_multiplexer->undo_commit = _mfd_ipAddressTable_undo_commit;
262 access_multiplexer->irreversible_commit =
263 _mfd_ipAddressTable_irreversible_commit;
264
265 /*
266 * REQUIRED for tables with dependencies
267 */
268 access_multiplexer->consistency_checks =
269 _mfd_ipAddressTable_check_dependencies;
270 #endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */
271
272 /*************************************************
273 *
274 * Create a registration, save our reg data, register table.
275 */
276 DEBUGMSGTL(("ipAddressTable:init_ipAddressTable",
277 "Registering ipAddressTable as a mibs-for-dummies table.\n"));
278 handler =
279 netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
280 reginfo =
281 netsnmp_handler_registration_create("ipAddressTable", handler,
282 ipAddressTable_oid,
283 ipAddressTable_oid_size,
284 HANDLER_CAN_BABY_STEP |
285 #ifndef NETSNMP_DISABLE_SET_SUPPORT
286 HANDLER_CAN_RWRITE
287 #else
288 HANDLER_CAN_RONLY
289 #endif /* NETSNMP_DISABLE_SET_SUPPORT */
290 );
291 if (NULL == reginfo) {
292 snmp_log(LOG_ERR, "error registering table ipAddressTable\n");
293 return;
294 }
295 reginfo->my_reg_void = &ipAddressTable_if_ctx;
296
297 /*************************************************
298 *
299 * set up baby steps handler, create it and inject it
300 */
301 if (access_multiplexer->object_lookup)
302 mfd_modes |= BABY_STEP_OBJECT_LOOKUP;
303 if (access_multiplexer->pre_request)
304 mfd_modes |= BABY_STEP_PRE_REQUEST;
305 if (access_multiplexer->post_request)
306 mfd_modes |= BABY_STEP_POST_REQUEST;
307
308 #if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
309 if (access_multiplexer->set_values)
310 mfd_modes |= BABY_STEP_SET_VALUES;
311 if (access_multiplexer->irreversible_commit)
312 mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT;
313 if (access_multiplexer->object_syntax_checks)
314 mfd_modes |= BABY_STEP_CHECK_OBJECT;
315
316 if (access_multiplexer->undo_setup)
317 mfd_modes |= BABY_STEP_UNDO_SETUP;
318 if (access_multiplexer->undo_cleanup)
319 mfd_modes |= BABY_STEP_UNDO_CLEANUP;
320 if (access_multiplexer->undo_sets)
321 mfd_modes |= BABY_STEP_UNDO_SETS;
322
323 if (access_multiplexer->row_creation)
324 mfd_modes |= BABY_STEP_ROW_CREATE;
325 if (access_multiplexer->consistency_checks)
326 mfd_modes |= BABY_STEP_CHECK_CONSISTENCY;
327 if (access_multiplexer->commit)
328 mfd_modes |= BABY_STEP_COMMIT;
329 if (access_multiplexer->undo_commit)
330 mfd_modes |= BABY_STEP_UNDO_COMMIT;
331 #endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */
332
333 handler = netsnmp_baby_steps_handler_get(mfd_modes);
334 netsnmp_inject_handler(reginfo, handler);
335
336 /*************************************************
337 *
338 * inject row_merge helper with prefix rootoid_len + 2 (entry.col)
339 */
340 handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2);
341 netsnmp_inject_handler(reginfo, handler);
342
343 /*************************************************
344 *
345 * inject container_table helper
346 */
347 handler =
348 netsnmp_container_table_handler_get(tbl_info,
349 ipAddressTable_if_ctx.
350 container,
351 TABLE_CONTAINER_KEY_NETSNMP_INDEX);
352 netsnmp_inject_handler(reginfo, handler);
353
354 /*************************************************
355 *
356 * inject cache helper
357 */
358 if (NULL != ipAddressTable_if_ctx.cache) {
359 handler = netsnmp_cache_handler_get(ipAddressTable_if_ctx.cache);
360 netsnmp_inject_handler(reginfo, handler);
361 }
362
363 /*
364 * register table
365 */
366 netsnmp_register_table(reginfo, tbl_info);
367
368 } /* _ipAddressTable_initialize_interface */
369
370 /**
371 * @internal
372 * Shutdown the table ipAddressTable
373 */
374 void
_ipAddressTable_shutdown_interface(ipAddressTable_registration * reg_ptr)375 _ipAddressTable_shutdown_interface(ipAddressTable_registration * reg_ptr)
376 {
377 /*
378 * shutdown the container
379 */
380 _ipAddressTable_container_shutdown(&ipAddressTable_if_ctx);
381 }
382
383 void
ipAddressTable_valid_columns_set(netsnmp_column_info * vc)384 ipAddressTable_valid_columns_set(netsnmp_column_info *vc)
385 {
386 ipAddressTable_if_ctx.tbl_info.valid_columns = vc;
387 } /* ipAddressTable_valid_columns_set */
388
389 /**
390 * @internal
391 * convert the index component stored in the context to an oid
392 */
393 int
ipAddressTable_index_to_oid(netsnmp_index * oid_idx,ipAddressTable_mib_index * mib_idx)394 ipAddressTable_index_to_oid(netsnmp_index * oid_idx,
395 ipAddressTable_mib_index * mib_idx)
396 {
397 int err = SNMP_ERR_NOERROR;
398
399 /*
400 * temp storage for parsing indexes
401 */
402 /*
403 * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
404 */
405 netsnmp_variable_list var_ipAddressAddrType;
406 /*
407 * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
408 */
409 netsnmp_variable_list var_ipAddressAddr;
410
411 /*
412 * set up varbinds
413 */
414 memset(&var_ipAddressAddrType, 0x00, sizeof(var_ipAddressAddrType));
415 var_ipAddressAddrType.type = ASN_INTEGER;
416 memset(&var_ipAddressAddr, 0x00, sizeof(var_ipAddressAddr));
417 var_ipAddressAddr.type = ASN_OCTET_STR;
418
419 /*
420 * chain temp index varbinds together
421 */
422 var_ipAddressAddrType.next_variable = &var_ipAddressAddr;
423 var_ipAddressAddr.next_variable = NULL;
424
425
426 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_index_to_oid",
427 "called\n"));
428
429 /*
430 * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
431 */
432 snmp_set_var_value(&var_ipAddressAddrType,
433 (u_char *) & mib_idx->ipAddressAddrType,
434 sizeof(mib_idx->ipAddressAddrType));
435
436 /*
437 * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
438 */
439 snmp_set_var_value(&var_ipAddressAddr,
440 (u_char *) & mib_idx->ipAddressAddr,
441 mib_idx->ipAddressAddr_len *
442 sizeof(mib_idx->ipAddressAddr[0]));
443
444
445 err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
446 NULL, 0, &var_ipAddressAddrType);
447 if (err)
448 snmp_log(LOG_ERR, "error %d converting index to oid\n", err);
449
450 /*
451 * parsing may have allocated memory. free it.
452 */
453 snmp_reset_var_buffers(&var_ipAddressAddrType);
454
455 return err;
456 } /* ipAddressTable_index_to_oid */
457
458 /**
459 * extract ipAddressTable indexes from a netsnmp_index
460 *
461 * @retval SNMP_ERR_NOERROR : no error
462 * @retval SNMP_ERR_GENERR : error
463 */
464 int
ipAddressTable_index_from_oid(netsnmp_index * oid_idx,ipAddressTable_mib_index * mib_idx)465 ipAddressTable_index_from_oid(netsnmp_index * oid_idx,
466 ipAddressTable_mib_index * mib_idx)
467 {
468 int err = SNMP_ERR_NOERROR;
469
470 /*
471 * temp storage for parsing indexes
472 */
473 /*
474 * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
475 */
476 netsnmp_variable_list var_ipAddressAddrType;
477 /*
478 * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
479 */
480 netsnmp_variable_list var_ipAddressAddr;
481
482 /*
483 * set up varbinds
484 */
485 memset(&var_ipAddressAddrType, 0x00, sizeof(var_ipAddressAddrType));
486 var_ipAddressAddrType.type = ASN_INTEGER;
487 memset(&var_ipAddressAddr, 0x00, sizeof(var_ipAddressAddr));
488 var_ipAddressAddr.type = ASN_OCTET_STR;
489
490 /*
491 * chain temp index varbinds together
492 */
493 var_ipAddressAddrType.next_variable = &var_ipAddressAddr;
494 var_ipAddressAddr.next_variable = NULL;
495
496
497 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_index_from_oid",
498 "called\n"));
499
500 /*
501 * parse the oid into the individual index components
502 */
503 err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
504 &var_ipAddressAddrType);
505 if (err == SNMP_ERR_NOERROR) {
506 /*
507 * copy out values
508 */
509 mib_idx->ipAddressAddrType =
510 *((u_long *) var_ipAddressAddrType.val.string);
511 /*
512 * NOTE: val_len is in bytes, ipAddressAddr_len might not be
513 */
514 if (var_ipAddressAddr.val_len > sizeof(mib_idx->ipAddressAddr))
515 err = SNMP_ERR_GENERR;
516 else {
517 memcpy(mib_idx->ipAddressAddr, var_ipAddressAddr.val.string,
518 var_ipAddressAddr.val_len);
519 mib_idx->ipAddressAddr_len =
520 var_ipAddressAddr.val_len /
521 sizeof(mib_idx->ipAddressAddr[0]);
522 }
523
524
525 }
526
527 /*
528 * parsing may have allocated memory. free it.
529 */
530 snmp_reset_var_buffers(&var_ipAddressAddrType);
531
532 return err;
533 } /* ipAddressTable_index_from_oid */
534
535
536 /*
537 *********************************************************************
538 * @internal
539 * allocate resources for a ipAddressTable_rowreq_ctx
540 */
541 ipAddressTable_rowreq_ctx *
ipAddressTable_allocate_rowreq_ctx(ipAddressTable_data * data,void * user_init_ctx)542 ipAddressTable_allocate_rowreq_ctx(ipAddressTable_data * data,
543 void *user_init_ctx)
544 {
545 ipAddressTable_rowreq_ctx *rowreq_ctx =
546 SNMP_MALLOC_TYPEDEF(ipAddressTable_rowreq_ctx);
547
548 DEBUGMSGTL(("internal:ipAddressTable:ipAddressTable_allocate_rowreq_ctx", "called\n"));
549
550 if (NULL == rowreq_ctx) {
551 snmp_log(LOG_ERR, "Couldn't allocate memory for a "
552 "ipAddressTable_rowreq_ctx.\n");
553 return NULL;
554 } else {
555 if (NULL != data) {
556 /*
557 * track if we got data from user
558 */
559 rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
560 rowreq_ctx->data = data;
561 } else if (NULL ==
562 (rowreq_ctx->data = ipAddressTable_allocate_data())) {
563 SNMP_FREE(rowreq_ctx);
564 return NULL;
565 }
566 }
567
568 /*
569 * undo context will be allocated when needed (in *_undo_setup)
570 */
571
572 rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;
573
574 rowreq_ctx->ipAddressTable_data_list = NULL;
575
576 /*
577 * if we allocated data, call init routine
578 */
579 if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) {
580 if (SNMPERR_SUCCESS !=
581 ipAddressTable_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) {
582 ipAddressTable_release_rowreq_ctx(rowreq_ctx);
583 rowreq_ctx = NULL;
584 }
585 }
586
587 return rowreq_ctx;
588 } /* ipAddressTable_allocate_rowreq_ctx */
589
590 /*
591 * @internal
592 * release resources for a ipAddressTable_rowreq_ctx
593 */
594 void
ipAddressTable_release_rowreq_ctx(ipAddressTable_rowreq_ctx * rowreq_ctx)595 ipAddressTable_release_rowreq_ctx(ipAddressTable_rowreq_ctx * rowreq_ctx)
596 {
597 DEBUGMSGTL(("internal:ipAddressTable:ipAddressTable_release_rowreq_ctx", "called\n"));
598
599 netsnmp_assert(NULL != rowreq_ctx);
600
601 ipAddressTable_rowreq_ctx_cleanup(rowreq_ctx);
602
603 /*
604 * for non-transient data, don't free data we got from the user
605 */
606 if ((rowreq_ctx->data) &&
607 !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER))
608 ipAddressTable_release_data(rowreq_ctx->data);
609
610 if (rowreq_ctx->undo)
611 ipAddressTable_release_data(rowreq_ctx->undo);
612
613 /*
614 * free index oid pointer
615 */
616 if (rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp)
617 free(rowreq_ctx->oid_idx.oids);
618
619 SNMP_FREE(rowreq_ctx);
620 } /* ipAddressTable_release_rowreq_ctx */
621
622 /**
623 * @internal
624 * wrapper
625 */
626 static int
_mfd_ipAddressTable_pre_request(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)627 _mfd_ipAddressTable_pre_request(netsnmp_mib_handler *handler,
628 netsnmp_handler_registration *reginfo,
629 netsnmp_agent_request_info *agtreq_info,
630 netsnmp_request_info *requests)
631 {
632 int rc;
633
634 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_pre_request",
635 "called\n"));
636
637 if (1 != netsnmp_row_merge_status_first(reginfo, agtreq_info)) {
638 DEBUGMSGTL(("internal:ipAddressTable",
639 "skipping additional pre_request\n"));
640 return SNMP_ERR_NOERROR;
641 }
642
643 rc = ipAddressTable_pre_request(ipAddressTable_if_ctx.user_ctx);
644 if (MFD_SUCCESS != rc) {
645 /*
646 * nothing we can do about it but log it
647 */
648 DEBUGMSGTL(("ipAddressTable", "error %d from "
649 "ipAddressTable_pre_request\n", rc));
650 netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
651 }
652
653 return SNMP_ERR_NOERROR;
654 } /* _mfd_ipAddressTable_pre_request */
655
656 /**
657 * @internal
658 * wrapper
659 */
660 static int
_mfd_ipAddressTable_post_request(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)661 _mfd_ipAddressTable_post_request(netsnmp_mib_handler *handler,
662 netsnmp_handler_registration *reginfo,
663 netsnmp_agent_request_info *agtreq_info,
664 netsnmp_request_info *requests)
665 {
666 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
667 netsnmp_container_table_row_extract(requests);
668 int rc, packet_rc;
669
670 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_post_request",
671 "called\n"));
672
673 /*
674 * release row context, if deleted
675 */
676 if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED))
677 ipAddressTable_release_rowreq_ctx(rowreq_ctx);
678
679 /*
680 * wait for last call before calling user
681 */
682 if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
683 DEBUGMSGTL(("internal:ipAddressTable",
684 "waiting for last post_request\n"));
685 return SNMP_ERR_NOERROR;
686 }
687
688 packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0);
689 if ((MFD_SUCCESS != packet_rc) && ipAddressTable_dirty_get()) {
690 /*
691 * we shouldn't get here. the undo steps should also clear
692 * the dirty flags.
693 */
694 snmp_log(LOG_WARNING,
695 "ipAddressTable dirty flag set in post_request "
696 "but status != SUCCESS.\n");
697 }
698
699 rc = ipAddressTable_post_request(ipAddressTable_if_ctx.user_ctx,
700 packet_rc);
701 if (MFD_SUCCESS != rc) {
702 /*
703 * nothing we can do about it but log it
704 */
705 DEBUGMSGTL(("ipAddressTable", "error %d from "
706 "ipAddressTable_post_request\n", rc));
707 }
708
709 return SNMP_ERR_NOERROR;
710 } /* _mfd_ipAddressTable_post_request */
711
712
713 /**
714 * @internal
715 * wrapper
716 */
717 static ipAddressTable_rowreq_ctx *
_mfd_ipAddressTable_rowreq_from_index(netsnmp_index * oid_idx,int * rc_ptr)718 _mfd_ipAddressTable_rowreq_from_index(netsnmp_index * oid_idx, int *rc_ptr)
719 {
720 ipAddressTable_rowreq_ctx *rowreq_ctx;
721 ipAddressTable_mib_index mib_idx;
722 int rc;
723
724 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_rowreq_from_index", "called\n"));
725
726 if (NULL == rc_ptr)
727 rc_ptr = &rc;
728 *rc_ptr = MFD_SUCCESS;
729
730 memset(&mib_idx, 0x0, sizeof(mib_idx));
731
732 /*
733 * try to parse oid
734 */
735 *rc_ptr = ipAddressTable_index_from_oid(oid_idx, &mib_idx);
736 if (MFD_SUCCESS != *rc_ptr) {
737 DEBUGMSGT(("ipAddressTable", "error parsing index\n"));
738 return NULL;
739 }
740
741 /*
742 * allocate new context
743 */
744 rowreq_ctx = ipAddressTable_allocate_rowreq_ctx(NULL, NULL);
745 if (NULL == rowreq_ctx) {
746 *rc_ptr = MFD_ERROR;
747 return NULL; /* msg already logged */
748 }
749
750 memcpy(&rowreq_ctx->tbl_idx, &mib_idx, sizeof(mib_idx));
751
752 /*
753 * check indexes
754 */
755 *rc_ptr = _ipAddressTable_check_indexes(rowreq_ctx);
756 if (MFD_SUCCESS != *rc_ptr) {
757 netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
758 (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
759 ipAddressTable_release_rowreq_ctx(rowreq_ctx);
760 return NULL;
761 }
762
763 /*
764 * copy indexes
765 */
766 rowreq_ctx->oid_idx.len = oid_idx->len;
767 memcpy(rowreq_ctx->oid_idx.oids, oid_idx->oids,
768 oid_idx->len * sizeof(oid));
769
770 return rowreq_ctx;
771 } /* _mfd_ipAddressTable_rowreq_from_index */
772
773
774 /**
775 * @internal
776 * wrapper
777 */
778 static int
_mfd_ipAddressTable_object_lookup(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)779 _mfd_ipAddressTable_object_lookup(netsnmp_mib_handler *handler,
780 netsnmp_handler_registration *reginfo,
781 netsnmp_agent_request_info *agtreq_info,
782 netsnmp_request_info *requests)
783 {
784 int rc = SNMP_ERR_NOERROR;
785 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
786 netsnmp_container_table_row_extract(requests);
787
788 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_object_lookup", "called\n"));
789
790 /*
791 * get our context from mfd
792 * ipAddressTable_interface_ctx *if_ctx =
793 * (ipAddressTable_interface_ctx *)reginfo->my_reg_void;
794 */
795
796 if (NULL == rowreq_ctx) {
797 #define NETSNMP_IPADDRESSTABLE_CREATE_SUPPORT 1
798 #ifndef NETSNMP_IPADDRESSTABLE_CREATE_SUPPORT
799 rc = SNMP_ERR_NOCREATION;
800 #else
801 netsnmp_table_request_info *tblreq_info;
802 netsnmp_index oid_idx;
803
804 tblreq_info = netsnmp_extract_table_info(requests);
805 if (NULL == tblreq_info) {
806 snmp_log(LOG_ERR, "request had no table info\n");
807 return MFD_ERROR;
808 }
809
810 /*
811 * try create rowreq
812 */
813 oid_idx.oids = tblreq_info->index_oid;
814 oid_idx.len = tblreq_info->index_oid_len;
815
816 rowreq_ctx = _mfd_ipAddressTable_rowreq_from_index(&oid_idx, &rc);
817 if (MFD_SUCCESS == rc) {
818 netsnmp_assert(NULL != rowreq_ctx);
819 rowreq_ctx->rowreq_flags |= MFD_ROW_CREATED;
820 /*
821 * add rowreq_ctx to request data lists
822 */
823 netsnmp_container_table_row_insert(requests, (netsnmp_index *)
824 rowreq_ctx);
825 }
826 #endif
827 }
828
829 if (MFD_SUCCESS != rc)
830 netsnmp_request_set_error_all(requests, rc);
831 else
832 ipAddressTable_row_prep(rowreq_ctx);
833
834 return SNMP_VALIDATE_ERR(rc);
835 } /* _mfd_ipAddressTable_object_lookup */
836
837 /***********************************************************************
838 *
839 * GET processing
840 *
841 ***********************************************************************/
842 /*
843 * @internal
844 * Retrieve the value for a particular column
845 */
846 NETSNMP_STATIC_INLINE int
_ipAddressTable_get_column(ipAddressTable_rowreq_ctx * rowreq_ctx,netsnmp_variable_list * var,int column)847 _ipAddressTable_get_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
848 netsnmp_variable_list * var, int column)
849 {
850 int rc = SNMPERR_SUCCESS;
851
852 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_get_column",
853 "called for %d\n", column));
854
855
856 netsnmp_assert(NULL != rowreq_ctx);
857
858 switch (column) {
859
860 /*
861 * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H
862 */
863 case COLUMN_IPADDRESSIFINDEX:
864 var->val_len = sizeof(long);
865 var->type = ASN_INTEGER;
866 rc = ipAddressIfIndex_get(rowreq_ctx, (long *) var->val.string);
867 break;
868
869 /*
870 * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
871 */
872 case COLUMN_IPADDRESSTYPE:
873 var->val_len = sizeof(u_long);
874 var->type = ASN_INTEGER;
875 rc = ipAddressType_get(rowreq_ctx, (u_long *) var->val.string);
876 break;
877
878 /*
879 * ipAddressPrefix(5)/RowPointer/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/D/h
880 */
881 case COLUMN_IPADDRESSPREFIX:
882 var->type = ASN_OBJECT_ID;
883 rc = ipAddressPrefix_get(rowreq_ctx, (oid **) & var->val.string,
884 &var->val_len);
885 break;
886
887 /*
888 * ipAddressOrigin(6)/IpAddressOriginTC/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h
889 */
890 case COLUMN_IPADDRESSORIGIN:
891 var->val_len = sizeof(u_long);
892 var->type = ASN_INTEGER;
893 rc = ipAddressOrigin_get(rowreq_ctx, (u_long *) var->val.string);
894 break;
895
896 /*
897 * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
898 */
899 case COLUMN_IPADDRESSSTATUS:
900 var->val_len = sizeof(u_long);
901 var->type = ASN_INTEGER;
902 rc = ipAddressStatus_get(rowreq_ctx, (u_long *) var->val.string);
903 break;
904
905 /*
906 * ipAddressCreated(8)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h
907 */
908 case COLUMN_IPADDRESSCREATED:
909 var->val_len = sizeof(u_long);
910 var->type = ASN_TIMETICKS;
911 rc = ipAddressCreated_get(rowreq_ctx, (u_long *) var->val.string);
912 break;
913
914 /*
915 * ipAddressLastChanged(9)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h
916 */
917 case COLUMN_IPADDRESSLASTCHANGED:
918 var->val_len = sizeof(u_long);
919 var->type = ASN_TIMETICKS;
920 rc = ipAddressLastChanged_get(rowreq_ctx,
921 (u_long *) var->val.string);
922 break;
923
924 /*
925 * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
926 */
927 case COLUMN_IPADDRESSROWSTATUS:
928 var->val_len = sizeof(u_long);
929 var->type = ASN_INTEGER;
930 rc = ipAddressRowStatus_get(rowreq_ctx,
931 (u_long *) var->val.string);
932 break;
933
934 /*
935 * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
936 */
937 case COLUMN_IPADDRESSSTORAGETYPE:
938 var->val_len = sizeof(u_long);
939 var->type = ASN_INTEGER;
940 rc = ipAddressStorageType_get(rowreq_ctx,
941 (u_long *) var->val.string);
942 break;
943
944 default:
945 snmp_log(LOG_ERR,
946 "unknown column %d in _ipAddressTable_get_column\n",
947 column);
948 break;
949 }
950
951 return rc;
952 } /* _ipAddressTable_get_column */
953
954 int
_mfd_ipAddressTable_get_values(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)955 _mfd_ipAddressTable_get_values(netsnmp_mib_handler *handler,
956 netsnmp_handler_registration *reginfo,
957 netsnmp_agent_request_info *agtreq_info,
958 netsnmp_request_info *requests)
959 {
960 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
961 netsnmp_container_table_row_extract(requests);
962 netsnmp_table_request_info *tri;
963 u_char *old_string;
964 void (*dataFreeHook) (void *);
965 int rc;
966
967 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_get_values",
968 "called\n"));
969
970 netsnmp_assert(NULL != rowreq_ctx);
971
972 for (; requests; requests = requests->next) {
973 /*
974 * save old pointer, so we can free it if replaced
975 */
976 old_string = requests->requestvb->val.string;
977 dataFreeHook = requests->requestvb->dataFreeHook;
978 if (NULL == requests->requestvb->val.string) {
979 requests->requestvb->val.string = requests->requestvb->buf;
980 requests->requestvb->val_len =
981 sizeof(requests->requestvb->buf);
982 } else if (requests->requestvb->buf ==
983 requests->requestvb->val.string) {
984 if (requests->requestvb->val_len !=
985 sizeof(requests->requestvb->buf))
986 requests->requestvb->val_len =
987 sizeof(requests->requestvb->buf);
988 }
989
990 /*
991 * get column data
992 */
993 tri = netsnmp_extract_table_info(requests);
994 if (NULL == tri)
995 continue;
996
997 rc = _ipAddressTable_get_column(rowreq_ctx, requests->requestvb,
998 tri->colnum);
999 if (rc) {
1000 if (MFD_SKIP == rc) {
1001 requests->requestvb->type = SNMP_NOSUCHINSTANCE;
1002 rc = SNMP_ERR_NOERROR;
1003 }
1004 } else if (NULL == requests->requestvb->val.string) {
1005 snmp_log(LOG_ERR, "NULL varbind data pointer!\n");
1006 rc = SNMP_ERR_GENERR;
1007 }
1008 if (rc)
1009 netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
1010
1011 /*
1012 * if the buffer wasn't used previously for the old data (i.e. it
1013 * was allcoated memory) and the get routine replaced the pointer,
1014 * we need to free the previous pointer.
1015 */
1016 if (old_string && (old_string != requests->requestvb->buf) &&
1017 (requests->requestvb->val.string != old_string)) {
1018 if (dataFreeHook)
1019 (*dataFreeHook) (old_string);
1020 else
1021 free(old_string);
1022 }
1023 } /* for results */
1024
1025 return SNMP_ERR_NOERROR;
1026 } /* _mfd_ipAddressTable_get_values */
1027
1028 NETSNMP_STATIC_INLINE int
_ipAddressTable_check_indexes(ipAddressTable_rowreq_ctx * rowreq_ctx)1029 _ipAddressTable_check_indexes(ipAddressTable_rowreq_ctx * rowreq_ctx)
1030 {
1031 int rc = SNMPERR_SUCCESS;
1032
1033 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_check_indexes",
1034 "called\n"));
1035
1036 netsnmp_assert(NULL != rowreq_ctx);
1037
1038
1039 /*
1040 * (INDEX) ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
1041 */
1042 /*
1043 * check that the value is one of defined enums
1044 */
1045 if ((SNMPERR_SUCCESS == rc)
1046 && (rowreq_ctx->tbl_idx.ipAddressAddrType !=
1047 INETADDRESSTYPE_UNKNOWN)
1048 && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV4)
1049 && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV6)
1050 && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV4Z)
1051 && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV6Z)
1052 && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_DNS)
1053 ) {
1054 rc = SNMP_ERR_WRONGVALUE;
1055 }
1056 if (MFD_SUCCESS != rc)
1057 return rc;
1058 rc = ipAddressAddrType_check_index(rowreq_ctx);
1059 if (MFD_SUCCESS != rc)
1060 return SNMP_ERR_NOCREATION;
1061
1062 /*
1063 * (INDEX) ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
1064 */
1065 /*
1066 * check defined range(s).
1067 */
1068 if ((SNMPERR_SUCCESS == rc)
1069 && ((rowreq_ctx->tbl_idx.ipAddressAddr_len < 0)
1070 || (rowreq_ctx->tbl_idx.ipAddressAddr_len > 255))
1071 ) {
1072 rc = SNMP_ERR_WRONGLENGTH;
1073 }
1074 if (MFD_SUCCESS != rc)
1075 return rc;
1076 rc = ipAddressAddr_check_index(rowreq_ctx);
1077 if (MFD_SUCCESS != rc)
1078 return SNMP_ERR_NOCREATION;
1079
1080 /*
1081 * if individual parts look ok, check them as a whole
1082 */
1083 return ipAddressTable_validate_index(ipAddressTable_if_ctx.user_ctx,
1084 rowreq_ctx);
1085 } /* _ipAddressTable_check_indexes */
1086
1087 #if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
1088 /***********************************************************************
1089 *
1090 * SET processing
1091 *
1092 ***********************************************************************/
1093
1094 /*----------------------------------------------------------------------
1095 *
1096 * SET: Syntax checks
1097 *
1098 *---------------------------------------------------------------------*/
1099 /*
1100 * @internal
1101 * Check the syntax for a particular column
1102 */
1103 NETSNMP_STATIC_INLINE int
_ipAddressTable_check_column(ipAddressTable_rowreq_ctx * rowreq_ctx,netsnmp_variable_list * var,int column)1104 _ipAddressTable_check_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
1105 netsnmp_variable_list * var, int column)
1106 {
1107 int rc = SNMPERR_SUCCESS;
1108
1109 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_check_column",
1110 "called for %d\n", column));
1111
1112 netsnmp_assert(NULL != rowreq_ctx);
1113
1114 switch (column) {
1115 /*
1116 * (INDEX) ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
1117 */
1118 case COLUMN_IPADDRESSADDRTYPE:
1119 rc = SNMP_ERR_NOTWRITABLE; /* can not change index of active row */
1120 break;
1121 /*
1122 * (INDEX) ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
1123 */
1124 case COLUMN_IPADDRESSADDR:
1125 rc = SNMP_ERR_NOTWRITABLE; /* can not change index of active row */
1126 break;
1127
1128 /*
1129 * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H
1130 */
1131 case COLUMN_IPADDRESSIFINDEX:
1132 rc = netsnmp_check_vb_type(var, ASN_INTEGER);
1133 /*
1134 * check defined range(s).
1135 */
1136 if ((SNMPERR_SUCCESS == rc)
1137 && ((*var->val.integer < 1)
1138 || (*var->val.integer > 2147483647))
1139 ) {
1140 rc = SNMP_ERR_WRONGVALUE;
1141 }
1142 if (SNMPERR_SUCCESS != rc) {
1143 DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressIfIndex", "varbind validation failed (eg bad type or size)\n"));
1144 } else {
1145 rc = ipAddressIfIndex_check_value(rowreq_ctx,
1146 *((long *) var->val.string));
1147 if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
1148 && (MFD_NOT_VALID_NOW != rc)) {
1149 snmp_log(LOG_ERR,
1150 "bad rc %d from ipAddressIfIndex_check_value\n",
1151 rc);
1152 rc = SNMP_ERR_GENERR;
1153 }
1154 }
1155 break;
1156
1157 /*
1158 * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1159 */
1160 case COLUMN_IPADDRESSTYPE:
1161 rc = netsnmp_check_vb_type(var, ASN_INTEGER);
1162 /*
1163 * check that the value is one of defined enums
1164 */
1165 if ((SNMPERR_SUCCESS == rc)
1166 && (*var->val.integer != IPADDRESSTYPE_UNICAST)
1167 && (*var->val.integer != IPADDRESSTYPE_ANYCAST)
1168 && (*var->val.integer != IPADDRESSTYPE_BROADCAST)
1169 ) {
1170 rc = SNMP_ERR_WRONGVALUE;
1171 }
1172 if (SNMPERR_SUCCESS != rc) {
1173 DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressType", "varbind validation failed (eg bad type or size)\n"));
1174 } else {
1175 rc = ipAddressType_check_value(rowreq_ctx,
1176 *((u_long *) var->val.string));
1177 if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
1178 && (MFD_NOT_VALID_NOW != rc)) {
1179 snmp_log(LOG_ERR,
1180 "bad rc %d from ipAddressType_check_value\n", rc);
1181 rc = SNMP_ERR_GENERR;
1182 }
1183 }
1184 break;
1185
1186 /*
1187 * ipAddressPrefix(5)/RowPointer/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/D/h
1188 */
1189 case COLUMN_IPADDRESSPREFIX:
1190 rc = SNMP_ERR_NOTWRITABLE;
1191 break;
1192
1193 /*
1194 * ipAddressOrigin(6)/IpAddressOriginTC/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h
1195 */
1196 case COLUMN_IPADDRESSORIGIN:
1197 rc = SNMP_ERR_NOTWRITABLE;
1198 break;
1199
1200 /*
1201 * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1202 */
1203 case COLUMN_IPADDRESSSTATUS:
1204 rc = netsnmp_check_vb_type(var, ASN_INTEGER);
1205 /*
1206 * check that the value is one of defined enums
1207 */
1208 if ((SNMPERR_SUCCESS == rc)
1209 && (*var->val.integer != IPADDRESSSTATUSTC_PREFERRED)
1210 && (*var->val.integer != IPADDRESSSTATUSTC_INVALID)
1211 && (*var->val.integer != IPADDRESSSTATUSTC_INACCESSIBLE)
1212 && (*var->val.integer != IPADDRESSSTATUSTC_UNKNOWN)
1213 && (*var->val.integer != IPADDRESSSTATUSTC_TENTATIVE)
1214 && (*var->val.integer != IPADDRESSSTATUSTC_DUPLICATE)
1215 ) {
1216 rc = SNMP_ERR_WRONGVALUE;
1217 }
1218 if (SNMPERR_SUCCESS != rc) {
1219 DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressStatus", "varbind validation failed (eg bad type or size)\n"));
1220 } else {
1221 rc = ipAddressStatus_check_value(rowreq_ctx,
1222 *((u_long *) var->val.
1223 string));
1224 if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
1225 && (MFD_NOT_VALID_NOW != rc)) {
1226 snmp_log(LOG_ERR,
1227 "bad rc %d from ipAddressStatus_check_value\n",
1228 rc);
1229 rc = SNMP_ERR_GENERR;
1230 }
1231 }
1232 break;
1233
1234 /*
1235 * ipAddressCreated(8)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h
1236 */
1237 case COLUMN_IPADDRESSCREATED:
1238 rc = SNMP_ERR_NOTWRITABLE;
1239 break;
1240
1241 /*
1242 * ipAddressLastChanged(9)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h
1243 */
1244 case COLUMN_IPADDRESSLASTCHANGED:
1245 rc = SNMP_ERR_NOTWRITABLE;
1246 break;
1247
1248 /*
1249 * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
1250 */
1251 case COLUMN_IPADDRESSROWSTATUS:
1252 rc = netsnmp_check_vb_rowstatus_value(var);
1253 if (SNMPERR_SUCCESS != rc) {
1254 DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressRowStatus", "varbind validation failed (eg bad type or size)\n"));
1255 } else {
1256 rc = ipAddressRowStatus_check_value(rowreq_ctx,
1257 *((u_long *) var->val.
1258 string));
1259 if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
1260 && (MFD_NOT_VALID_NOW != rc)) {
1261 snmp_log(LOG_ERR,
1262 "bad rc %d from ipAddressRowStatus_check_value\n",
1263 rc);
1264 rc = SNMP_ERR_GENERR;
1265 }
1266 }
1267 break;
1268
1269 /*
1270 * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1271 */
1272 case COLUMN_IPADDRESSSTORAGETYPE:
1273 rc = netsnmp_check_vb_type(var, ASN_INTEGER);
1274 /*
1275 * check that the value is one of defined enums
1276 */
1277 if ((SNMPERR_SUCCESS == rc)
1278 && (*var->val.integer != STORAGETYPE_OTHER)
1279 && (*var->val.integer != STORAGETYPE_VOLATILE)
1280 && (*var->val.integer != STORAGETYPE_NONVOLATILE)
1281 && (*var->val.integer != STORAGETYPE_PERMANENT)
1282 && (*var->val.integer != STORAGETYPE_READONLY)
1283 ) {
1284 rc = SNMP_ERR_WRONGVALUE;
1285 }
1286 if (SNMPERR_SUCCESS != rc) {
1287 DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressStorageType", "varbind validation failed (eg bad type or size)\n"));
1288 } else {
1289 rc = ipAddressStorageType_check_value(rowreq_ctx,
1290 *((u_long *) var->val.
1291 string));
1292 if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
1293 && (MFD_NOT_VALID_NOW != rc)) {
1294 snmp_log(LOG_ERR,
1295 "bad rc %d from ipAddressStorageType_check_value\n",
1296 rc);
1297 rc = SNMP_ERR_GENERR;
1298 }
1299 }
1300 break;
1301
1302 default: /** We shouldn't get here */
1303 rc = SNMP_ERR_GENERR;
1304 snmp_log(LOG_ERR,
1305 "unknown column %d in _ipAddressTable_check_column\n",
1306 column);
1307 }
1308
1309 return rc;
1310 } /* _ipAddressTable_check_column */
1311
1312 int
_mfd_ipAddressTable_check_objects(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1313 _mfd_ipAddressTable_check_objects(netsnmp_mib_handler *handler,
1314 netsnmp_handler_registration *reginfo,
1315 netsnmp_agent_request_info *agtreq_info,
1316 netsnmp_request_info *requests)
1317 {
1318 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1319 netsnmp_container_table_row_extract(requests);
1320 netsnmp_table_request_info *tri;
1321 int rc;
1322
1323 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_check_objects", "called\n"));
1324
1325 netsnmp_assert(NULL != rowreq_ctx);
1326
1327 for (; requests; requests = requests->next) {
1328
1329 /*
1330 * get column number from table request info, and check that column
1331 */
1332 tri = netsnmp_extract_table_info(requests);
1333 if (NULL == tri)
1334 continue;
1335
1336 rc = _ipAddressTable_check_column(rowreq_ctx, requests->requestvb,
1337 tri->colnum);
1338 if (rc) {
1339 netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
1340 break;
1341 }
1342
1343 } /* for results */
1344
1345 return SNMP_ERR_NOERROR;
1346 } /* _mfd_ipAddressTable_check_objects */
1347
1348
1349 /*----------------------------------------------------------------------
1350 *
1351 * SET: check dependencies
1352 *
1353 *---------------------------------------------------------------------*/
1354 /*
1355 * @internal
1356 * Check dependencies wrapper
1357 */
1358 static int
_mfd_ipAddressTable_check_dependencies(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1359 _mfd_ipAddressTable_check_dependencies(netsnmp_mib_handler *handler, netsnmp_handler_registration
1360 *reginfo, netsnmp_agent_request_info
1361 *agtreq_info,
1362 netsnmp_request_info *requests)
1363 {
1364 int rc;
1365 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1366 netsnmp_container_table_row_extract(requests);
1367 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_check_dependencies", "called\n"));
1368
1369 netsnmp_assert(NULL != rowreq_ctx);
1370
1371 rc = ipAddressTable_check_dependencies(rowreq_ctx);
1372 if (rc) {
1373 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1374 "ipAddressTable_check_dependencies\n", rc));
1375 netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
1376 }
1377
1378 return SNMP_ERR_NOERROR;
1379 } /* _mfd_ipAddressTable_check_dependencies */
1380
1381 /*----------------------------------------------------------------------
1382 *
1383 * SET: Undo setup
1384 *
1385 *---------------------------------------------------------------------*/
1386 /*
1387 * @internal
1388 * Set the value for a particular column
1389 */
1390 NETSNMP_STATIC_INLINE int
_ipAddressTable_undo_setup_column(ipAddressTable_rowreq_ctx * rowreq_ctx,int column)1391 _ipAddressTable_undo_setup_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
1392 int column)
1393 {
1394 int rc = SNMPERR_SUCCESS;
1395
1396 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_undo_setup_column", "called for %d\n", column));
1397
1398 netsnmp_assert(NULL != rowreq_ctx);
1399
1400 switch (column) {
1401
1402 /*
1403 * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H
1404 */
1405 case COLUMN_IPADDRESSIFINDEX:
1406 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSIFINDEX_FLAG;
1407 rc = ipAddressIfIndex_undo_setup(rowreq_ctx);
1408 break;
1409
1410 /*
1411 * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1412 */
1413 case COLUMN_IPADDRESSTYPE:
1414 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSTYPE_FLAG;
1415 rc = ipAddressType_undo_setup(rowreq_ctx);
1416 break;
1417
1418 /*
1419 * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1420 */
1421 case COLUMN_IPADDRESSSTATUS:
1422 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTATUS_FLAG;
1423 rc = ipAddressStatus_undo_setup(rowreq_ctx);
1424 break;
1425
1426 /*
1427 * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
1428 */
1429 case COLUMN_IPADDRESSROWSTATUS:
1430 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSROWSTATUS_FLAG;
1431 rc = ipAddressRowStatus_undo_setup(rowreq_ctx);
1432 break;
1433
1434 /*
1435 * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1436 */
1437 case COLUMN_IPADDRESSSTORAGETYPE:
1438 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTORAGETYPE_FLAG;
1439 rc = ipAddressStorageType_undo_setup(rowreq_ctx);
1440 break;
1441
1442 default:
1443 snmp_log(LOG_ERR,
1444 "unknown column %d in _ipAddressTable_undo_setup_column\n",
1445 column);
1446 break;
1447 }
1448
1449 return rc;
1450 } /* _ipAddressTable_undo_setup_column */
1451
1452
1453 /**
1454 * @internal
1455 * undo setup
1456 */
1457 int
_mfd_ipAddressTable_undo_setup(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1458 _mfd_ipAddressTable_undo_setup(netsnmp_mib_handler *handler,
1459 netsnmp_handler_registration *reginfo,
1460 netsnmp_agent_request_info *agtreq_info,
1461 netsnmp_request_info *requests)
1462 {
1463 int rc;
1464 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1465 netsnmp_container_table_row_extract(requests);
1466
1467 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_setup",
1468 "called\n"));
1469
1470 netsnmp_assert(NULL != rowreq_ctx);
1471
1472 /*
1473 * allocate undo context
1474 */
1475 rowreq_ctx->undo = ipAddressTable_allocate_data();
1476 if (NULL == rowreq_ctx->undo) {
1477 /** msg already logged */
1478 netsnmp_request_set_error_all(requests,
1479 SNMP_ERR_RESOURCEUNAVAILABLE);
1480 return SNMP_ERR_NOERROR;
1481 }
1482
1483 /*
1484 * row undo setup
1485 */
1486 rowreq_ctx->column_set_flags = 0;
1487 rc = ipAddressTable_undo_setup(rowreq_ctx);
1488 if (MFD_SUCCESS != rc) {
1489 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1490 "ipAddressTable_undo_setup\n", rc));
1491 netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
1492 } else {
1493 /*
1494 * column undo setup
1495 */
1496 netsnmp_table_request_info *tri;
1497 for (; requests; requests = requests->next) {
1498 /*
1499 * set column data
1500 */
1501 tri = netsnmp_extract_table_info(requests);
1502 if (NULL == tri)
1503 continue;
1504
1505 rc = _ipAddressTable_undo_setup_column(rowreq_ctx,
1506 tri->colnum);
1507 if (MFD_SUCCESS != rc) {
1508 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1509 "ipAddressTable_undo_setup_column\n", rc));
1510 netsnmp_set_request_error(agtreq_info, requests,
1511 SNMP_VALIDATE_ERR(rc));
1512 }
1513 } /* for results */
1514 }
1515
1516 return SNMP_ERR_NOERROR;
1517 } /* _mfd_ipAddressTable_undo_setup */
1518
1519 /**
1520 * @internal
1521 * undo setup
1522 */
1523 int
_mfd_ipAddressTable_undo_cleanup(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1524 _mfd_ipAddressTable_undo_cleanup(netsnmp_mib_handler *handler,
1525 netsnmp_handler_registration *reginfo,
1526 netsnmp_agent_request_info *agtreq_info,
1527 netsnmp_request_info *requests)
1528 {
1529 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1530 netsnmp_container_table_row_extract(requests);
1531 int rc;
1532
1533 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_cleanup",
1534 "called\n"));
1535
1536 /*
1537 * failed row create in early stages has no rowreq_ctx
1538 */
1539 if (NULL == rowreq_ctx)
1540 return MFD_SUCCESS;
1541
1542 /*
1543 * call user cleanup
1544 */
1545 rc = ipAddressTable_undo_cleanup(rowreq_ctx);
1546 if (MFD_SUCCESS != rc) {
1547 /*
1548 * nothing we can do about it but log it
1549 */
1550 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1551 "ipAddressTable_undo_cleanup\n", rc));
1552 }
1553
1554 /*
1555 * release undo context, if needed
1556 */
1557 if (rowreq_ctx->undo) {
1558 ipAddressTable_release_data(rowreq_ctx->undo);
1559 rowreq_ctx->undo = NULL;
1560 }
1561
1562
1563 return SNMP_ERR_NOERROR;
1564 } /* _mfd_ipAddressTable_undo_cleanup */
1565
1566 /*----------------------------------------------------------------------
1567 *
1568 * SET: Set values
1569 *
1570 *---------------------------------------------------------------------*/
1571 /*
1572 * @internal
1573 * Set the value for a particular column
1574 */
1575 NETSNMP_STATIC_INLINE int
_ipAddressTable_set_column(ipAddressTable_rowreq_ctx * rowreq_ctx,netsnmp_variable_list * var,int column)1576 _ipAddressTable_set_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
1577 netsnmp_variable_list * var, int column)
1578 {
1579 int rc = SNMPERR_SUCCESS;
1580
1581 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_set_column",
1582 "called for %d\n", column));
1583
1584 netsnmp_assert(NULL != rowreq_ctx);
1585
1586 switch (column) {
1587
1588 /*
1589 * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H
1590 */
1591 case COLUMN_IPADDRESSIFINDEX:
1592 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSIFINDEX_FLAG;
1593 rc = ipAddressIfIndex_set(rowreq_ctx, *((long *) var->val.string));
1594 break;
1595
1596 /*
1597 * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1598 */
1599 case COLUMN_IPADDRESSTYPE:
1600 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSTYPE_FLAG;
1601 rc = ipAddressType_set(rowreq_ctx, *((u_long *) var->val.string));
1602 break;
1603
1604 /*
1605 * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1606 */
1607 case COLUMN_IPADDRESSSTATUS:
1608 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTATUS_FLAG;
1609 rc = ipAddressStatus_set(rowreq_ctx,
1610 *((u_long *) var->val.string));
1611 break;
1612
1613 /*
1614 * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
1615 */
1616 case COLUMN_IPADDRESSROWSTATUS:
1617 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSROWSTATUS_FLAG;
1618 rc = ipAddressRowStatus_set(rowreq_ctx,
1619 *((u_long *) var->val.string));
1620 break;
1621
1622 /*
1623 * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1624 */
1625 case COLUMN_IPADDRESSSTORAGETYPE:
1626 rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTORAGETYPE_FLAG;
1627 rc = ipAddressStorageType_set(rowreq_ctx,
1628 *((u_long *) var->val.string));
1629 break;
1630
1631 default:
1632 snmp_log(LOG_ERR,
1633 "unknown column %d in _ipAddressTable_set_column\n",
1634 column);
1635 rc = SNMP_ERR_GENERR;
1636 break;
1637 }
1638
1639 return rc;
1640 } /* _ipAddressTable_set_column */
1641
1642 int
_mfd_ipAddressTable_set_values(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1643 _mfd_ipAddressTable_set_values(netsnmp_mib_handler *handler,
1644 netsnmp_handler_registration *reginfo,
1645 netsnmp_agent_request_info *agtreq_info,
1646 netsnmp_request_info *requests)
1647 {
1648 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1649 netsnmp_container_table_row_extract(requests);
1650 netsnmp_table_request_info *tri;
1651 int rc = SNMP_ERR_NOERROR;
1652
1653 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_set_values",
1654 "called\n"));
1655
1656 netsnmp_assert(NULL != rowreq_ctx);
1657
1658 rowreq_ctx->column_set_flags = 0;
1659 for (; requests; requests = requests->next) {
1660 /*
1661 * set column data
1662 */
1663 tri = netsnmp_extract_table_info(requests);
1664 if (NULL == tri)
1665 continue;
1666
1667 rc = _ipAddressTable_set_column(rowreq_ctx,
1668 requests->requestvb, tri->colnum);
1669 if (MFD_SUCCESS != rc) {
1670 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1671 "ipAddressTable_set_column\n", rc));
1672 netsnmp_set_request_error(agtreq_info, requests,
1673 SNMP_VALIDATE_ERR(rc));
1674 }
1675 } /* for results */
1676
1677 return SNMP_ERR_NOERROR;
1678 } /* _mfd_ipAddressTable_set_values */
1679
1680 /*----------------------------------------------------------------------
1681 *
1682 * SET: commit
1683 *
1684 *---------------------------------------------------------------------*/
1685 /**
1686 * @internal
1687 * commit the values
1688 */
1689 int
_mfd_ipAddressTable_commit(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1690 _mfd_ipAddressTable_commit(netsnmp_mib_handler *handler,
1691 netsnmp_handler_registration *reginfo,
1692 netsnmp_agent_request_info *agtreq_info,
1693 netsnmp_request_info *requests)
1694 {
1695 int rc;
1696 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1697 netsnmp_container_table_row_extract(requests);
1698
1699 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_commit",
1700 "called\n"));
1701
1702 netsnmp_assert(NULL != rowreq_ctx);
1703
1704 rc = ipAddressTable_commit(rowreq_ctx);
1705 if (MFD_SUCCESS != rc) {
1706 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1707 "ipAddressTable_commit\n", rc));
1708 netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
1709 }
1710
1711 if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
1712 /*
1713 * if we successfully commited this row, set the dirty flag. Use the
1714 * current value + 1 (i.e. dirty = # rows changed).
1715 * this is checked in post_request...
1716 */
1717 ipAddressTable_dirty_set(ipAddressTable_dirty_get() + 1); /* set table dirty flag */
1718 }
1719
1720 return SNMP_ERR_NOERROR;
1721 }
1722
1723 int
_mfd_ipAddressTable_undo_commit(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1724 _mfd_ipAddressTable_undo_commit(netsnmp_mib_handler *handler,
1725 netsnmp_handler_registration *reginfo,
1726 netsnmp_agent_request_info *agtreq_info,
1727 netsnmp_request_info *requests)
1728 {
1729 int rc;
1730 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1731 netsnmp_container_table_row_extract(requests);
1732
1733 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_commit",
1734 "called\n"));
1735
1736 netsnmp_assert(NULL != rowreq_ctx);
1737
1738 if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
1739 u_int d = ipAddressTable_dirty_get();
1740
1741 netsnmp_assert(d != 0);
1742 if (d)
1743 ipAddressTable_dirty_set(d - 1);
1744 }
1745
1746 rc = ipAddressTable_undo_commit(rowreq_ctx);
1747 if (MFD_SUCCESS != rc) {
1748 /*
1749 * nothing we can do about it but log it
1750 */
1751 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1752 "ipAddressTable_undo_commit\n", rc));
1753 }
1754
1755 if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
1756 snmp_log(LOG_WARNING,
1757 "ipAddressTable row dirty flag still set after undo_commit\n");
1758 rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
1759 }
1760
1761 return SNMP_ERR_NOERROR;
1762 } /* _mfd_ipAddressTable_commit */
1763
1764 /*----------------------------------------------------------------------
1765 *
1766 * SET: Undo
1767 *
1768 *---------------------------------------------------------------------*/
1769 /**
1770 * @internal
1771 * undo the value for a particular column
1772 */
1773 NETSNMP_STATIC_INLINE int
_ipAddressTable_undo_column(ipAddressTable_rowreq_ctx * rowreq_ctx,netsnmp_variable_list * var,int column)1774 _ipAddressTable_undo_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
1775 netsnmp_variable_list * var, int column)
1776 {
1777 int rc = SNMPERR_SUCCESS;
1778
1779 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_undo_column",
1780 "called for %d\n", column));
1781
1782 netsnmp_assert(NULL != rowreq_ctx);
1783
1784 switch (column) {
1785
1786 /*
1787 * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H
1788 */
1789 case COLUMN_IPADDRESSIFINDEX:
1790 rc = ipAddressIfIndex_undo(rowreq_ctx);
1791 break;
1792
1793 /*
1794 * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1795 */
1796 case COLUMN_IPADDRESSTYPE:
1797 rc = ipAddressType_undo(rowreq_ctx);
1798 break;
1799
1800 /*
1801 * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1802 */
1803 case COLUMN_IPADDRESSSTATUS:
1804 rc = ipAddressStatus_undo(rowreq_ctx);
1805 break;
1806
1807 /*
1808 * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
1809 */
1810 case COLUMN_IPADDRESSROWSTATUS:
1811 rc = ipAddressRowStatus_undo(rowreq_ctx);
1812 break;
1813
1814 /*
1815 * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h
1816 */
1817 case COLUMN_IPADDRESSSTORAGETYPE:
1818 rc = ipAddressStorageType_undo(rowreq_ctx);
1819 break;
1820
1821 default:
1822 snmp_log(LOG_ERR,
1823 "unknown column %d in _ipAddressTable_undo_column\n",
1824 column);
1825 break;
1826 }
1827
1828 return rc;
1829 } /* _ipAddressTable_undo_column */
1830
1831 int
_mfd_ipAddressTable_undo_values(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1832 _mfd_ipAddressTable_undo_values(netsnmp_mib_handler *handler,
1833 netsnmp_handler_registration *reginfo,
1834 netsnmp_agent_request_info *agtreq_info,
1835 netsnmp_request_info *requests)
1836 {
1837 int rc;
1838 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1839 netsnmp_container_table_row_extract(requests);
1840 netsnmp_table_request_info *tri;
1841
1842 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_values",
1843 "called\n"));
1844
1845 netsnmp_assert(NULL != rowreq_ctx);
1846
1847 rc = ipAddressTable_undo(rowreq_ctx);
1848 if (MFD_SUCCESS != rc) {
1849 /*
1850 * nothing we can do about it but log it
1851 */
1852 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1853 "ipAddressTable_undo\n", rc));
1854 }
1855
1856 for (; requests; requests = requests->next) {
1857 /*
1858 * set column data
1859 */
1860 tri = netsnmp_extract_table_info(requests);
1861 if (NULL == tri)
1862 continue;
1863
1864 rc = _ipAddressTable_undo_column(rowreq_ctx, requests->requestvb,
1865 tri->colnum);
1866 if (MFD_SUCCESS != rc) {
1867 /*
1868 * nothing we can do about it but log it
1869 */
1870 DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
1871 "ipAddressTable_undo_column\n", rc));
1872 }
1873 } /* for results */
1874
1875 return SNMP_ERR_NOERROR;
1876 } /* _mfd_ipAddressTable_undo_values */
1877
1878 /*----------------------------------------------------------------------
1879 *
1880 * SET: irreversible commit
1881 *
1882 *---------------------------------------------------------------------*/
1883 /**
1884 * @internal
1885 * commit irreversible actions
1886 */
1887 int
_mfd_ipAddressTable_irreversible_commit(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * agtreq_info,netsnmp_request_info * requests)1888 _mfd_ipAddressTable_irreversible_commit(netsnmp_mib_handler *handler, netsnmp_handler_registration
1889 *reginfo, netsnmp_agent_request_info
1890 *agtreq_info,
1891 netsnmp_request_info *requests)
1892 {
1893 ipAddressTable_rowreq_ctx *rowreq_ctx = (ipAddressTable_rowreq_ctx*)
1894 netsnmp_container_table_row_extract(requests);
1895
1896 DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_irreversible:commit", "called\n"));
1897
1898 netsnmp_assert(NULL != rowreq_ctx);
1899
1900 /*
1901 * check for and handle row creation/deletion
1902 * and update column exist flags...
1903 */
1904 if (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED) {
1905 if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED))
1906 CONTAINER_REMOVE(ipAddressTable_if_ctx.container, rowreq_ctx);
1907 } else {
1908 if (rowreq_ctx->column_set_flags) {
1909 rowreq_ctx->column_set_flags = 0;
1910 }
1911 if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
1912 rowreq_ctx->rowreq_flags &= ~MFD_ROW_CREATED;
1913 CONTAINER_INSERT(ipAddressTable_if_ctx.container, rowreq_ctx);
1914 }
1915 }
1916
1917 return SNMP_ERR_NOERROR;
1918 } /* _mfd_ipAddressTable_irreversible_commit */
1919 #endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */
1920
1921 /***********************************************************************
1922 *
1923 * DATA ACCESS
1924 *
1925 ***********************************************************************/
1926 static void _container_free(netsnmp_container *container);
1927
1928 /**
1929 * @internal
1930 */
1931 static int
_cache_load(netsnmp_cache * cache,void * vmagic)1932 _cache_load(netsnmp_cache * cache, void *vmagic)
1933 {
1934 DEBUGMSGTL(("internal:ipAddressTable:_cache_load", "called\n"));
1935
1936 if ((NULL == cache) || (NULL == cache->magic)) {
1937 snmp_log(LOG_ERR, "invalid cache for ipAddressTable_cache_load\n");
1938 return -1;
1939 }
1940
1941 /** should only be called for an invalid or expired cache */
1942 netsnmp_assert((0 == cache->valid) || (1 == cache->expired));
1943
1944 /*
1945 * call user code
1946 */
1947 return ipAddressTable_container_load((netsnmp_container *) cache->
1948 magic);
1949 } /* _cache_load */
1950
1951 /**
1952 * @internal
1953 */
1954 static void
_cache_free(netsnmp_cache * cache,void * magic)1955 _cache_free(netsnmp_cache * cache, void *magic)
1956 {
1957 netsnmp_container *container;
1958
1959 DEBUGMSGTL(("internal:ipAddressTable:_cache_free", "called\n"));
1960
1961 if ((NULL == cache) || (NULL == cache->magic)) {
1962 snmp_log(LOG_ERR, "invalid cache in ipAddressTable_cache_free\n");
1963 return;
1964 }
1965
1966 container = (netsnmp_container *) cache->magic;
1967
1968 _container_free(container);
1969 } /* _cache_free */
1970
1971 /**
1972 * @internal
1973 */
1974 static void
_container_item_free(ipAddressTable_rowreq_ctx * rowreq_ctx,void * context)1975 _container_item_free(ipAddressTable_rowreq_ctx * rowreq_ctx, void *context)
1976 {
1977 DEBUGMSGTL(("internal:ipAddressTable:_container_item_free",
1978 "called\n"));
1979
1980 if (NULL == rowreq_ctx)
1981 return;
1982
1983 ipAddressTable_release_rowreq_ctx(rowreq_ctx);
1984 } /* _container_item_free */
1985
1986 /**
1987 * @internal
1988 */
1989 static void
_container_free(netsnmp_container * container)1990 _container_free(netsnmp_container *container)
1991 {
1992 DEBUGMSGTL(("internal:ipAddressTable:_container_free", "called\n"));
1993
1994 if (NULL == container) {
1995 snmp_log(LOG_ERR,
1996 "invalid container in ipAddressTable_container_free\n");
1997 return;
1998 }
1999
2000 /*
2001 * call user code
2002 */
2003 ipAddressTable_container_free(container);
2004
2005 /*
2006 * free all items. inefficient, but easy.
2007 */
2008 CONTAINER_CLEAR(container,
2009 (netsnmp_container_obj_func *) _container_item_free,
2010 NULL);
2011 } /* _container_free */
2012
2013 /**
2014 * @internal
2015 * initialize the container with functions or wrappers
2016 */
2017 void
_ipAddressTable_container_init(ipAddressTable_interface_ctx * if_ctx)2018 _ipAddressTable_container_init(ipAddressTable_interface_ctx * if_ctx)
2019 {
2020 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_container_init",
2021 "called\n"));
2022
2023 /*
2024 * cache init
2025 */
2026 if_ctx->cache = netsnmp_cache_create(30, /* timeout in seconds */
2027 _cache_load, _cache_free,
2028 ipAddressTable_oid,
2029 ipAddressTable_oid_size);
2030
2031 if (NULL == if_ctx->cache) {
2032 snmp_log(LOG_ERR, "error creating cache for ipAddressTable\n");
2033 return;
2034 }
2035
2036 if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;
2037
2038 ipAddressTable_container_init(&if_ctx->container, if_ctx->cache);
2039 if (NULL == if_ctx->container)
2040 if_ctx->container =
2041 netsnmp_container_find("ipAddressTable:table_container");
2042 if (NULL == if_ctx->container) {
2043 snmp_log(LOG_ERR, "error creating container in "
2044 "ipAddressTable_container_init\n");
2045 return;
2046 }
2047
2048 if (NULL != if_ctx->cache)
2049 if_ctx->cache->magic = (void *) if_ctx->container;
2050 } /* _ipAddressTable_container_init */
2051
2052 /**
2053 * @internal
2054 * shutdown the container with functions or wrappers
2055 */
2056 void
_ipAddressTable_container_shutdown(ipAddressTable_interface_ctx * if_ctx)2057 _ipAddressTable_container_shutdown(ipAddressTable_interface_ctx * if_ctx)
2058 {
2059 DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_container_shutdown", "called\n"));
2060
2061 ipAddressTable_container_shutdown(if_ctx->container);
2062
2063 _container_free(if_ctx->container);
2064
2065 } /* _ipAddressTable_container_shutdown */
2066
2067
2068 #ifndef NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_EXTERNAL_ACCESS
2069 ipAddressTable_rowreq_ctx *
ipAddressTable_row_find_by_mib_index(ipAddressTable_mib_index * mib_idx)2070 ipAddressTable_row_find_by_mib_index(ipAddressTable_mib_index * mib_idx)
2071 {
2072 ipAddressTable_rowreq_ctx *rowreq_ctx;
2073 oid oid_tmp[MAX_OID_LEN];
2074 netsnmp_index oid_idx;
2075 int rc;
2076
2077 /*
2078 * set up storage for OID
2079 */
2080 oid_idx.oids = oid_tmp;
2081 oid_idx.len = sizeof(oid_tmp) / sizeof(oid);
2082
2083 /*
2084 * convert
2085 */
2086 rc = ipAddressTable_index_to_oid(&oid_idx, mib_idx);
2087 if (MFD_SUCCESS != rc)
2088 return NULL;
2089
2090 rowreq_ctx = (ipAddressTable_rowreq_ctx*)CONTAINER_FIND(ipAddressTable_if_ctx.container, &oid_idx);
2091
2092 return rowreq_ctx;
2093 }
2094 #endif /* NETSNMP_FEATURE_REMOVE_IPADDRESSTABLE_EXTERNAL_ACCESS */
2095