1 /*
2 * Note: this file originally auto-generated by mib2c using
3 * version : 1.48 $ of : mfd-top.m2c,v $
4 *
5 * $Id$
6 */
7 /** \page MFD helper for ipAddressTable
8 *
9 * \section intro Introduction
10 * Introductory text.
11 *
12 */
13 /*
14 * standard Net-SNMP includes
15 */
16 #include <net-snmp/net-snmp-config.h>
17 #include <net-snmp/net-snmp-features.h>
18 #include <net-snmp/net-snmp-includes.h>
19 #include <net-snmp/agent/net-snmp-agent-includes.h>
20
21 #include <net-snmp/data_access/interface.h>
22
23 /*
24 * include our parent header
25 */
26 #include "ipAddressTable.h"
27
28 #include <net-snmp/agent/mib_modules.h>
29
30 #include "ipAddressTable_interface.h"
31
32 netsnmp_feature_require(check_storage_transition);
33 netsnmp_feature_require(ipaddress_entry_copy);
34 netsnmp_feature_require(ipaddress_prefix_copy);
35
36 const oid ipAddressTable_oid[] = { IPADDRESSTABLE_OID };
37 const int ipAddressTable_oid_size = OID_LENGTH(ipAddressTable_oid);
38
39 ipAddressTable_registration ipAddressTable_user_context;
40 static ipAddressTable_registration *ipAddressTable_user_context_p;
41
42 void initialize_table_ipAddressTable(void);
43 void shutdown_table_ipAddressTable(void);
44
45
46 /* Called after the snmpd configuration has been read. */
47 static int
_init_ipAddressTable(int majorID,int minorID,void * serverargs,void * clientarg)48 _init_ipAddressTable(int majorID, int minorID, void *serverargs,
49 void *clientarg)
50 {
51 DEBUGMSGTL(("verbose:ipAddressTable:init_ipAddressTable", "called\n"));
52
53 netsnmp_access_interface_init();
54
55 /*
56 * TODO:300:o: Perform ipAddressTable one-time module initialization.
57 */
58
59 /*
60 * here we initialize all the tables we're planning on supporting
61 */
62 if (should_init("ipAddressTable"))
63 initialize_table_ipAddressTable();
64
65 return 0;
66 }
67
68 /**
69 * Initializes the ipAddressTable module
70 */
71 void
init_ipAddressTable(void)72 init_ipAddressTable(void)
73 {
74 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
75 SNMP_CALLBACK_POST_READ_CONFIG,
76 _init_ipAddressTable, NULL);
77 }
78
79 /**
80 * Shut-down the ipAddressTable module (agent is exiting)
81 */
82 void
shutdown_ipAddressTable(void)83 shutdown_ipAddressTable(void)
84 {
85 if (should_init("ipAddressTable"))
86 shutdown_table_ipAddressTable();
87
88 }
89
90 /**
91 * Initialize the table ipAddressTable
92 * (Define its contents and how it's structured)
93 */
94 void
initialize_table_ipAddressTable(void)95 initialize_table_ipAddressTable(void)
96 {
97 u_long flags;
98
99 DEBUGMSGTL(("verbose:ipAddressTable:initialize_table_ipAddressTable",
100 "called\n"));
101
102 /*
103 * TODO:301:o: Perform ipAddressTable one-time table initialization.
104 */
105
106 /*
107 * TODO:302:o: |->Initialize ipAddressTable user context
108 * if you'd like to pass in a pointer to some data for this
109 * table, allocate or set it up here.
110 */
111 ipAddressTable_user_context_p = NULL;
112
113 /*
114 * No support for any flags yet, but in the future you would
115 * set any flags here.
116 */
117 flags = 0;
118
119 /*
120 * call interface initialization code
121 */
122 _ipAddressTable_initialize_interface(ipAddressTable_user_context_p, flags);
123 } /* initialize_table_ipAddressTable */
124
125 /**
126 * Shutdown the table ipAddressTable
127 */
128 void
shutdown_table_ipAddressTable(void)129 shutdown_table_ipAddressTable(void)
130 {
131 /*
132 * call interface shutdown code
133 */
134 _ipAddressTable_shutdown_interface(ipAddressTable_user_context_p);
135 netsnmp_free_all_list_data(ipAddressTable_user_context_p);
136 ipAddressTable_user_context_p = NULL;
137 }
138
139 /**
140 * extra context initialization (eg default values)
141 *
142 * @param rowreq_ctx : row request context
143 * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
144 *
145 * @retval MFD_SUCCESS : no errors
146 * @retval MFD_ERROR : error (context allocate will fail)
147 */
148 int
ipAddressTable_rowreq_ctx_init(ipAddressTable_rowreq_ctx * rowreq_ctx,void * user_init_ctx)149 ipAddressTable_rowreq_ctx_init(ipAddressTable_rowreq_ctx * rowreq_ctx,
150 void *user_init_ctx)
151 {
152 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_rowreq_ctx_init",
153 "called\n"));
154
155 netsnmp_assert(NULL != rowreq_ctx);
156
157 /*
158 * TODO:210:o: |-> Perform extra ipAddressTable rowreq initialization. (eg DEFVALS)
159 */
160
161 return MFD_SUCCESS;
162 } /* ipAddressTable_rowreq_ctx_init */
163
164 /**
165 * extra context cleanup
166 *
167 */
168 void
ipAddressTable_rowreq_ctx_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)169 ipAddressTable_rowreq_ctx_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)
170 {
171 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_rowreq_ctx_cleanup",
172 "called\n"));
173
174 netsnmp_assert(NULL != rowreq_ctx);
175
176 /*
177 * TODO:211:o: |-> Perform extra ipAddressTable rowreq cleanup.
178 */
179 if (NULL != rowreq_ctx->data) {
180 ipAddressTable_release_data(rowreq_ctx->data);
181 rowreq_ctx->data = NULL;
182 }
183 } /* ipAddressTable_rowreq_ctx_cleanup */
184
185 /**
186 * pre-request callback
187 *
188 * @param user_context
189 *
190 * @retval MFD_SUCCESS : success.
191 * @retval MFD_ERROR : other error
192 */
193 int
ipAddressTable_pre_request(ipAddressTable_registration * user_context)194 ipAddressTable_pre_request(ipAddressTable_registration * user_context)
195 {
196 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_pre_request",
197 "called\n"));
198
199 /*
200 * TODO:510:o: Perform ipAddressTable pre-request actions.
201 */
202
203 return MFD_SUCCESS;
204 } /* ipAddressTable_pre_request */
205
206 /**
207 * post-request callback
208 *
209 * Note:
210 * New rows have been inserted into the container, and
211 * deleted rows have been removed from the container and
212 * released.
213 *
214 * @param user_context
215 * @param rc : MFD_SUCCESS if all requests succeeded
216 *
217 * @retval MFD_SUCCESS : success.
218 * @retval MFD_ERROR : other error (ignored)
219 */
220 int
ipAddressTable_post_request(ipAddressTable_registration * user_context,int rc)221 ipAddressTable_post_request(ipAddressTable_registration * user_context,
222 int rc)
223 {
224 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_post_request",
225 "called\n"));
226
227 /*
228 * TODO:511:o: Perform ipAddressTable post-request actions.
229 */
230
231 /*
232 * check to set if any rows were changed.
233 */
234 if (ipAddressTable_dirty_get()) {
235 /*
236 * check if request was successful. If so, this would be
237 * a good place to save data to its persistent store.
238 */
239 if (MFD_SUCCESS == rc) {
240 /*
241 * save changed rows, if you haven't already
242 */
243 }
244
245 ipAddressTable_dirty_set(0); /* clear table dirty flag */
246 }
247
248 return MFD_SUCCESS;
249 } /* ipAddressTable_post_request */
250
251
252 /**********************************************************************
253 **********************************************************************
254 ***
255 *** Table ipAddressTable
256 ***
257 **********************************************************************
258 **********************************************************************/
259 /*
260 * IP-MIB::ipAddressTable is subid 34 of ip.
261 * Its status is Current.
262 * OID: .1.3.6.1.2.1.4.34, length: 8
263 */
264
265 /*
266 * ---------------------------------------------------------------------
267 * * TODO:200:r: Implement ipAddressTable data context functions.
268 */
269 /*
270 * ipAddressTable_allocate_data
271 *
272 * Purpose: create new ipAddressTable_data.
273 */
274 ipAddressTable_data *
ipAddressTable_allocate_data(void)275 ipAddressTable_allocate_data(void)
276 {
277 /*
278 * TODO:201:r: |-> allocate memory for the ipAddressTable data context.
279 */
280 ipAddressTable_data *rtn = netsnmp_access_ipaddress_entry_create();
281
282 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_allocate_data",
283 "called\n"));
284
285 if (NULL == rtn) {
286 snmp_log(LOG_ERR, "unable to malloc memory for new "
287 "ipAddressTable_data.\n");
288 }
289
290 return rtn;
291 } /* ipAddressTable_allocate_data */
292
293 /*
294 * ipAddressTable_release_data
295 *
296 * Purpose: release ipAddressTable data.
297 */
298 void
ipAddressTable_release_data(ipAddressTable_data * data)299 ipAddressTable_release_data(ipAddressTable_data * data)
300 {
301 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_release_data",
302 "called\n"));
303
304 /*
305 * TODO:202:r: |-> release memory for the ipAddressTable data context.
306 */
307 netsnmp_access_ipaddress_entry_free(data);
308 } /* ipAddressTable_release_data */
309
310
311 /*---------------------------------------------------------------------
312 * IP-MIB::ipAddressEntry.ipAddressAddrType
313 * ipAddressAddrType is subid 1 of ipAddressEntry.
314 * Its status is Current, and its access level is NoAccess.
315 * OID: .1.3.6.1.2.1.4.34.1.1
316 * Description:
317 The address type of ipAddressAddr.
318 *
319 * Attributes:
320 * accessible 0 isscalar 0 enums 1 hasdefval 0
321 * readable 0 iscolumn 1 ranges 0 hashint 0
322 * settable 0
323 *
324 * Enum range: 5/8. Values: unknown(0), ipv4(1), ipv6(2), ipv4z(3), ipv6z(4), dns(16)
325 *
326 * Its syntax is InetAddressType (based on perltype INTEGER)
327 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
328 *
329 *
330 *
331 * NOTE: NODE ipAddressAddrType IS NOT ACCESSIBLE
332 *
333 *
334 */
335 /**
336 * map a value from its original native format to the MIB format.
337 *
338 * @retval MFD_SUCCESS : success
339 * @retval MFD_ERROR : Any other error
340 *
341 * @note parameters follow the memset convention (dest, src).
342 *
343 * @note generation and use of this function can be turned off by re-running
344 * mib2c after adding the following line to the file
345 * default-node-ipAddressAddrType.m2d :
346 * @verbatim $m2c_node_skip_mapping = 1@endverbatim
347 *
348 * @remark
349 * If the values for your data type don't exactly match the
350 * possible values defined by the mib, you should map them here.
351 * Otherwise, just do a direct copy.
352 */
353 int
ipAddressAddrType_map(long * mib_ipAddressAddrType_val_ptr,long raw_ipAddressAddrType_val)354 ipAddressAddrType_map(long * mib_ipAddressAddrType_val_ptr,
355 long raw_ipAddressAddrType_val)
356 {
357 netsnmp_assert(NULL != mib_ipAddressAddrType_val_ptr);
358
359 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressAddrType_map",
360 "called\n"));
361
362 /*
363 * TODO:241:o: |-> Implement ipAddressAddrType enum mapping.
364 * uses INTERNAL_* macros defined in the header files
365 */
366 switch (raw_ipAddressAddrType_val) {
367 case INTERNAL_IPADDRESSTABLE_IPADDRESSADDRTYPE_IPV4:
368 *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_IPV4;
369 break;
370
371 case INTERNAL_IPADDRESSTABLE_IPADDRESSADDRTYPE_IPV6:
372 *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_IPV6;
373 break;
374
375 default:
376 snmp_log(LOG_ERR, "couldn't map value %ld for ipAddressAddrType\n",
377 raw_ipAddressAddrType_val);
378 *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_UNKNOWN;
379 }
380
381 return MFD_SUCCESS;
382 } /* ipAddressAddrType_map */
383
384
385 /**
386 * set mib index(es)
387 *
388 * @param tbl_idx mib index structure
389 * @param ipAddressAddrType_val
390 * @param ipAddressAddr_val_ptr
391 * @param ipAddressAddr_val_ptr_len
392 *
393 * @retval MFD_SUCCESS : success.
394 * @retval MFD_ERROR : other error.
395 *
396 * @remark
397 * This convenience function is useful for setting all the MIB index
398 * components with a single function call. It is assume that the C values
399 * have already been mapped from their native/rawformat to the MIB format.
400 */
401 int
ipAddressTable_indexes_set_tbl_idx(ipAddressTable_mib_index * tbl_idx,long ipAddressAddrType_val,u_char * ipAddressAddr_val_ptr,size_t ipAddressAddr_val_ptr_len)402 ipAddressTable_indexes_set_tbl_idx(ipAddressTable_mib_index * tbl_idx,
403 long ipAddressAddrType_val,
404 u_char *ipAddressAddr_val_ptr,
405 size_t ipAddressAddr_val_ptr_len)
406 {
407 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_indexes_set_tbl_idx", "called\n"));
408
409 /*
410 * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
411 */
412 /** WARNING: this code might not work for netsnmp_ipaddress_entry */
413 ipAddressAddrType_map(&tbl_idx->ipAddressAddrType,
414 ipAddressAddrType_val);
415
416 /*
417 * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
418 */
419 tbl_idx->ipAddressAddr_len = sizeof(tbl_idx->ipAddressAddr) / sizeof(tbl_idx->ipAddressAddr[0]); /* max length */
420 /** WARNING: this code might not work for netsnmp_ipaddress_entry */
421 /*
422 * make sure there is enough space for ipAddressAddr data
423 */
424 if (tbl_idx->ipAddressAddr_len < ipAddressAddr_val_ptr_len) {
425 snmp_log(LOG_ERR, "not enough space for value\n");
426 return MFD_ERROR;
427 }
428 tbl_idx->ipAddressAddr_len = ipAddressAddr_val_ptr_len;
429 memcpy(tbl_idx->ipAddressAddr, ipAddressAddr_val_ptr,
430 ipAddressAddr_val_ptr_len * sizeof(ipAddressAddr_val_ptr[0]));
431
432
433 return MFD_SUCCESS;
434 } /* ipAddressTable_indexes_set_tbl_idx */
435
436 /**
437 * @internal
438 * set row context indexes
439 *
440 * @param reqreq_ctx the row context that needs updated indexes
441 *
442 * @retval MFD_SUCCESS : success.
443 * @retval MFD_ERROR : other error.
444 *
445 * @remark
446 * This function sets the mib indexs, then updates the oid indexs
447 * from the mib index.
448 */
449 int
ipAddressTable_indexes_set(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressAddrType_val,u_char * ipAddressAddr_val_ptr,size_t ipAddressAddr_val_ptr_len)450 ipAddressTable_indexes_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
451 u_long ipAddressAddrType_val,
452 u_char *ipAddressAddr_val_ptr,
453 size_t ipAddressAddr_val_ptr_len)
454 {
455 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_indexes_set",
456 "called\n"));
457
458 if (MFD_SUCCESS !=
459 ipAddressTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
460 ipAddressAddrType_val,
461 ipAddressAddr_val_ptr,
462 ipAddressAddr_val_ptr_len))
463 return MFD_ERROR;
464
465 /*
466 * convert mib index to oid index
467 */
468 rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
469 if (0 != ipAddressTable_index_to_oid(&rowreq_ctx->oid_idx,
470 &rowreq_ctx->tbl_idx)) {
471 return MFD_ERROR;
472 }
473
474 return MFD_SUCCESS;
475 } /* ipAddressTable_indexes_set */
476
477
478 /*---------------------------------------------------------------------
479 * IP-MIB::ipAddressEntry.ipAddressIfIndex
480 * ipAddressIfIndex is subid 3 of ipAddressEntry.
481 * Its status is Current, and its access level is Create.
482 * OID: .1.3.6.1.2.1.4.34.1.3
483 * Description:
484 The index value which uniquely identifies the interface to
485 which this entry is applicable. The interface identified by
486 a particular value of this index is the same interface as
487 identified by the same value of the IF-MIB's ifIndex.
488 *
489 * Attributes:
490 * accessible 1 isscalar 0 enums 0 hasdefval 0
491 * readable 1 iscolumn 1 ranges 1 hashint 1
492 * settable 1
493 * hint: d
494 *
495 * Ranges: 1 - 2147483647;
496 *
497 * Its syntax is InterfaceIndex (based on perltype INTEGER32)
498 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
499 */
500 /**
501 * Extract the current value of the ipAddressIfIndex data.
502 *
503 * Set a value using the data context for the row.
504 *
505 * @param rowreq_ctx
506 * Pointer to the row request context.
507 * @param ipAddressIfIndex_val_ptr
508 * Pointer to storage for a long variable
509 *
510 * @retval MFD_SUCCESS : success
511 * @retval MFD_SKIP : skip this node (no value for now)
512 * @retval MFD_ERROR : Any other error
513 */
514 int
ipAddressIfIndex_get(ipAddressTable_rowreq_ctx * rowreq_ctx,long * ipAddressIfIndex_val_ptr)515 ipAddressIfIndex_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
516 long *ipAddressIfIndex_val_ptr)
517 {
518 /** we should have a non-NULL pointer */
519 netsnmp_assert(NULL != ipAddressIfIndex_val_ptr);
520
521
522 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_get",
523 "called\n"));
524
525 netsnmp_assert(NULL != rowreq_ctx);
526
527 /*
528 * TODO:231:o: |-> Extract the current value of the ipAddressIfIndex data.
529 * copy (* ipAddressIfIndex_val_ptr ) from rowreq_ctx->data
530 */
531 (*ipAddressIfIndex_val_ptr) = rowreq_ctx->data->if_index;
532
533 return MFD_SUCCESS;
534 } /* ipAddressIfIndex_get */
535
536 /*---------------------------------------------------------------------
537 * IP-MIB::ipAddressEntry.ipAddressType
538 * ipAddressType is subid 4 of ipAddressEntry.
539 * Its status is Current, and its access level is Create.
540 * OID: .1.3.6.1.2.1.4.34.1.4
541 * Description:
542 The type of address. broadcast(3) is not a valid value for
543 IPv6 addresses (RFC3513).
544 *
545 * Attributes:
546 * accessible 1 isscalar 0 enums 1 hasdefval 1
547 * readable 1 iscolumn 1 ranges 0 hashint 0
548 * settable 1
549 * defval: unicast
550 *
551 * Enum range: 2/8. Values: unicast(1), anycast(2), broadcast(3)
552 *
553 * Its syntax is INTEGER (based on perltype INTEGER)
554 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
555 */
556 /**
557 * Extract the current value of the ipAddressType data.
558 *
559 * Set a value using the data context for the row.
560 *
561 * @param rowreq_ctx
562 * Pointer to the row request context.
563 * @param ipAddressType_val_ptr
564 * Pointer to storage for a long variable
565 *
566 * @retval MFD_SUCCESS : success
567 * @retval MFD_SKIP : skip this node (no value for now)
568 * @retval MFD_ERROR : Any other error
569 */
570 int
ipAddressType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressType_val_ptr)571 ipAddressType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
572 u_long * ipAddressType_val_ptr)
573 {
574 /** we should have a non-NULL pointer */
575 netsnmp_assert(NULL != ipAddressType_val_ptr);
576
577
578 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_get", "called\n"));
579
580 netsnmp_assert(NULL != rowreq_ctx);
581
582 /*
583 * TODO:231:o: |-> Extract the current value of the ipAddressType data.
584 * copy (* ipAddressType_val_ptr ) from rowreq_ctx->data
585 */
586 (*ipAddressType_val_ptr) = rowreq_ctx->data->ia_type;
587
588 return MFD_SUCCESS;
589 } /* ipAddressType_get */
590
591 /*---------------------------------------------------------------------
592 * IP-MIB::ipAddressEntry.ipAddressPrefix
593 * ipAddressPrefix is subid 5 of ipAddressEntry.
594 * Its status is Current, and its access level is ReadOnly.
595 * OID: .1.3.6.1.2.1.4.34.1.5
596 * Description:
597 A pointer to the row in the prefix table to which this
598 address belongs. May be { 0 0 } if there is no such row.
599 *
600 * Attributes:
601 * accessible 1 isscalar 0 enums 0 hasdefval 1
602 * readable 1 iscolumn 1 ranges 0 hashint 0
603 * settable 0
604 * defval: zeroDotZero
605 *
606 *
607 * Its syntax is RowPointer (based on perltype OBJECTID)
608 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
609 * This data type requires a length.
610 */
611 /**
612 * Extract the current value of the ipAddressPrefix data.
613 *
614 * Set a value using the data context for the row.
615 *
616 * @param rowreq_ctx
617 * Pointer to the row request context.
618 * @param ipAddressPrefix_val_ptr_ptr
619 * Pointer to storage for a oid variable
620 * @param ipAddressPrefix_val_ptr_len_ptr
621 * Pointer to a size_t. On entry, it will contain the size (in bytes)
622 * pointed to by ipAddressPrefix.
623 * On exit, this value should contain the data size (in bytes).
624 *
625 * @retval MFD_SUCCESS : success
626 * @retval MFD_SKIP : skip this node (no value for now)
627 * @retval MFD_ERROR : Any other error
628 *
629 * @note If you need more than (*ipAddressPrefix_val_ptr_len_ptr) bytes of memory,
630 * allocate it using malloc() and update ipAddressPrefix_val_ptr_ptr.
631 * <b>DO NOT</b> free the previous pointer.
632 * The MFD helper will release the memory you allocate.
633 *
634 * @remark If you call this function yourself, you are responsible
635 * for checking if the pointer changed, and freeing any
636 * previously allocated memory. (Not necessary if you pass
637 * in a pointer to static memory, obviously.)
638 */
639 int
ipAddressPrefix_get(ipAddressTable_rowreq_ctx * rowreq_ctx,oid ** ipAddressPrefix_val_ptr_ptr,size_t * ipAddressPrefix_val_ptr_len_ptr)640 ipAddressPrefix_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
641 oid ** ipAddressPrefix_val_ptr_ptr,
642 size_t * ipAddressPrefix_val_ptr_len_ptr)
643 {
644 oid *dst, tmp_oid[MAX_OID_LEN] =
645 { 1, 3, 6, 1, 2, 1, 4, 32, 1, 5 };
646 u_char tmp_buf[NETSNMP_ACCESS_IPADDRESS_BUF_SIZE];
647 size_t len;
648
649 /** we should have a non-NULL pointer and enough storage */
650 netsnmp_assert((NULL != ipAddressPrefix_val_ptr_ptr)
651 && (NULL != *ipAddressPrefix_val_ptr_ptr));
652 netsnmp_assert(NULL != ipAddressPrefix_val_ptr_len_ptr);
653
654
655 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressPrefix_get", "called\n"));
656
657 netsnmp_assert(NULL != rowreq_ctx);
658
659 /*
660 * TODO:231:o: |-> Extract the current value of the ipAddressPrefix data.
661 * copy (* ipAddressPrefix_val_ptr_ptr ) data and (* ipAddressPrefix_val_ptr_len_ptr ) from rowreq_ctx->data
662 */
663 dst = &tmp_oid[10];
664 *(dst++) = rowreq_ctx->data->if_index;
665 *(dst++) = rowreq_ctx->tbl_idx.ipAddressAddrType;
666 *(dst++) = rowreq_ctx->data->ia_address_len;
667 netsnmp_ipaddress_prefix_copy(tmp_buf,
668 (u_char *) rowreq_ctx->tbl_idx.ipAddressAddr,
669 rowreq_ctx->data->ia_address_len,
670 rowreq_ctx->data->ia_prefix_len);
671 for (len = 0; len < rowreq_ctx->data->ia_address_len; ++len)
672 *(dst++) = tmp_buf[len];
673 *(dst++) = rowreq_ctx->data->ia_prefix_len;
674 len = dst - tmp_oid;
675
676 len *= sizeof((*ipAddressPrefix_val_ptr_ptr)[0]);
677 if ((*ipAddressPrefix_val_ptr_len_ptr) < len) {
678 (*ipAddressPrefix_val_ptr_ptr) = (oid*)malloc(len);
679 if (NULL == (*ipAddressPrefix_val_ptr_ptr)) {
680 snmp_log(LOG_ERR, "could not allocate memory\n");
681 return MFD_ERROR;
682 }
683 }
684 (*ipAddressPrefix_val_ptr_len_ptr) = len;
685 memcpy((*ipAddressPrefix_val_ptr_ptr), tmp_oid, len);
686
687 return MFD_SUCCESS;
688 } /* ipAddressPrefix_get */
689
690 /*---------------------------------------------------------------------
691 * IP-MIB::ipAddressEntry.ipAddressOrigin
692 * ipAddressOrigin is subid 6 of ipAddressEntry.
693 * Its status is Current, and its access level is ReadOnly.
694 * OID: .1.3.6.1.2.1.4.34.1.6
695 * Description:
696 The origin of the address.
697 *
698 * Attributes:
699 * accessible 1 isscalar 0 enums 1 hasdefval 0
700 * readable 1 iscolumn 1 ranges 0 hashint 0
701 * settable 0
702 *
703 * Enum range: 4/8. Values: other(1), manual(2), dhcp(4), linklayer(5), random(6)
704 *
705 * Its syntax is IpAddressOriginTC (based on perltype INTEGER)
706 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
707 */
708 /**
709 * Extract the current value of the ipAddressOrigin data.
710 *
711 * Set a value using the data context for the row.
712 *
713 * @param rowreq_ctx
714 * Pointer to the row request context.
715 * @param ipAddressOrigin_val_ptr
716 * Pointer to storage for a long variable
717 *
718 * @retval MFD_SUCCESS : success
719 * @retval MFD_SKIP : skip this node (no value for now)
720 * @retval MFD_ERROR : Any other error
721 */
722 int
ipAddressOrigin_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressOrigin_val_ptr)723 ipAddressOrigin_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
724 u_long * ipAddressOrigin_val_ptr)
725 {
726 /** we should have a non-NULL pointer */
727 netsnmp_assert(NULL != ipAddressOrigin_val_ptr);
728
729
730 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressOrigin_get", "called\n"));
731
732 netsnmp_assert(NULL != rowreq_ctx);
733
734 /*
735 * TODO:231:o: |-> Extract the current value of the ipAddressOrigin data.
736 * copy (* ipAddressOrigin_val_ptr ) from rowreq_ctx->data
737 */
738 (*ipAddressOrigin_val_ptr) = rowreq_ctx->data->ia_origin;
739
740 return MFD_SUCCESS;
741 } /* ipAddressOrigin_get */
742
743 /*---------------------------------------------------------------------
744 * IP-MIB::ipAddressEntry.ipAddressStatus
745 * ipAddressStatus is subid 7 of ipAddressEntry.
746 * Its status is Current, and its access level is Create.
747 * OID: .1.3.6.1.2.1.4.34.1.7
748 * Description:
749 The status of the address, describing if the address can be
750 used for communication.
751
752
753 In the absence of other information, an IPv4 address is
754 always preferred(1).
755 *
756 * Attributes:
757 * accessible 1 isscalar 0 enums 1 hasdefval 1
758 * readable 1 iscolumn 1 ranges 0 hashint 0
759 * settable 1
760 * defval: preferred
761 *
762 * Enum range: 5/8. Values: preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
763 *
764 * Its syntax is IpAddressStatusTC (based on perltype INTEGER)
765 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
766 */
767 /**
768 * Extract the current value of the ipAddressStatus data.
769 *
770 * Set a value using the data context for the row.
771 *
772 * @param rowreq_ctx
773 * Pointer to the row request context.
774 * @param ipAddressStatus_val_ptr
775 * Pointer to storage for a long variable
776 *
777 * @retval MFD_SUCCESS : success
778 * @retval MFD_SKIP : skip this node (no value for now)
779 * @retval MFD_ERROR : Any other error
780 */
781 int
ipAddressStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressStatus_val_ptr)782 ipAddressStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
783 u_long * ipAddressStatus_val_ptr)
784 {
785 /** we should have a non-NULL pointer */
786 netsnmp_assert(NULL != ipAddressStatus_val_ptr);
787
788
789 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_get", "called\n"));
790
791 netsnmp_assert(NULL != rowreq_ctx);
792
793 /*
794 * TODO:231:o: |-> Extract the current value of the ipAddressStatus data.
795 * copy (* ipAddressStatus_val_ptr ) from rowreq_ctx->data
796 */
797 (*ipAddressStatus_val_ptr) = rowreq_ctx->data->ia_status;
798
799 return MFD_SUCCESS;
800 } /* ipAddressStatus_get */
801
802 /*---------------------------------------------------------------------
803 * IP-MIB::ipAddressEntry.ipAddressCreated
804 * ipAddressCreated is subid 8 of ipAddressEntry.
805 * Its status is Current, and its access level is ReadOnly.
806 * OID: .1.3.6.1.2.1.4.34.1.8
807 * Description:
808 The value of sysUpTime at the time this entry was created.
809 If this entry was created prior to the last re-
810 initialization of the local network management subsystem,
811 then this object contains a zero value.
812 *
813 * Attributes:
814 * accessible 1 isscalar 0 enums 0 hasdefval 0
815 * readable 1 iscolumn 1 ranges 0 hashint 0
816 * settable 0
817 *
818 *
819 * Its syntax is TimeStamp (based on perltype TICKS)
820 * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
821 */
822 /**
823 * Extract the current value of the ipAddressCreated data.
824 *
825 * Set a value using the data context for the row.
826 *
827 * @param rowreq_ctx
828 * Pointer to the row request context.
829 * @param ipAddressCreated_val_ptr
830 * Pointer to storage for a u_long variable
831 *
832 * @retval MFD_SUCCESS : success
833 * @retval MFD_SKIP : skip this node (no value for now)
834 * @retval MFD_ERROR : Any other error
835 */
836 int
ipAddressCreated_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressCreated_val_ptr)837 ipAddressCreated_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
838 u_long * ipAddressCreated_val_ptr)
839 {
840 /** we should have a non-NULL pointer */
841 netsnmp_assert(NULL != ipAddressCreated_val_ptr);
842
843
844 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressCreated_get",
845 "called\n"));
846
847 netsnmp_assert(NULL != rowreq_ctx);
848
849 /*
850 * TODO:231:o: |-> Extract the current value of the ipAddressCreated data.
851 * copy (* ipAddressCreated_val_ptr ) from rowreq_ctx->data
852 */
853 (*ipAddressCreated_val_ptr) = rowreq_ctx->ipAddressCreated;
854
855 return MFD_SUCCESS;
856 } /* ipAddressCreated_get */
857
858 /*---------------------------------------------------------------------
859 * IP-MIB::ipAddressEntry.ipAddressLastChanged
860 * ipAddressLastChanged is subid 9 of ipAddressEntry.
861 * Its status is Current, and its access level is ReadOnly.
862 * OID: .1.3.6.1.2.1.4.34.1.9
863 * Description:
864 The value of sysUpTime at the time this entry was last
865 updated. If this entry was updated prior to the last re-
866 initialization of the local network management subsystem,
867 then this object contains a zero value.
868 *
869 * Attributes:
870 * accessible 1 isscalar 0 enums 0 hasdefval 0
871 * readable 1 iscolumn 1 ranges 0 hashint 0
872 * settable 0
873 *
874 *
875 * Its syntax is TimeStamp (based on perltype TICKS)
876 * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
877 */
878 /**
879 * Extract the current value of the ipAddressLastChanged data.
880 *
881 * Set a value using the data context for the row.
882 *
883 * @param rowreq_ctx
884 * Pointer to the row request context.
885 * @param ipAddressLastChanged_val_ptr
886 * Pointer to storage for a u_long variable
887 *
888 * @retval MFD_SUCCESS : success
889 * @retval MFD_SKIP : skip this node (no value for now)
890 * @retval MFD_ERROR : Any other error
891 */
892 int
ipAddressLastChanged_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressLastChanged_val_ptr)893 ipAddressLastChanged_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
894 u_long * ipAddressLastChanged_val_ptr)
895 {
896 /** we should have a non-NULL pointer */
897 netsnmp_assert(NULL != ipAddressLastChanged_val_ptr);
898
899
900 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressLastChanged_get",
901 "called\n"));
902
903 netsnmp_assert(NULL != rowreq_ctx);
904
905 /*
906 * TODO:231:o: |-> Extract the current value of the ipAddressLastChanged data.
907 * copy (* ipAddressLastChanged_val_ptr ) from rowreq_ctx->data
908 */
909 (*ipAddressLastChanged_val_ptr) = rowreq_ctx->ipAddressLastChanged;
910
911 return MFD_SUCCESS;
912 } /* ipAddressLastChanged_get */
913
914 /*---------------------------------------------------------------------
915 * IP-MIB::ipAddressEntry.ipAddressRowStatus
916 * ipAddressRowStatus is subid 10 of ipAddressEntry.
917 * Its status is Current, and its access level is Create.
918 * OID: .1.3.6.1.2.1.4.34.1.10
919 * Description:
920 The status of this conceptual row.
921
922
923 The RowStatus TC requires that this DESCRIPTION clause
924 states under which circumstances other objects in this row
925 can be modified. The value of this object has no effect on
926 whether other objects in this conceptual row can be
927 modified.
928
929
930 A conceptual row can not be made active until the
931 ipAddressIfIndex has been set to a valid index.
932 *
933 * Attributes:
934 * accessible 1 isscalar 0 enums 1 hasdefval 0
935 * readable 1 iscolumn 1 ranges 0 hashint 0
936 * settable 1
937 *
938 * Enum range: 3/8. Values: active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
939 *
940 * Its syntax is RowStatus (based on perltype INTEGER)
941 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
942 */
943 /**
944 * Extract the current value of the ipAddressRowStatus data.
945 *
946 * Set a value using the data context for the row.
947 *
948 * @param rowreq_ctx
949 * Pointer to the row request context.
950 * @param ipAddressRowStatus_val_ptr
951 * Pointer to storage for a long variable
952 *
953 * @retval MFD_SUCCESS : success
954 * @retval MFD_SKIP : skip this node (no value for now)
955 * @retval MFD_ERROR : Any other error
956 */
957 int
ipAddressRowStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressRowStatus_val_ptr)958 ipAddressRowStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
959 u_long * ipAddressRowStatus_val_ptr)
960 {
961 /** we should have a non-NULL pointer */
962 netsnmp_assert(NULL != ipAddressRowStatus_val_ptr);
963
964 /** WARNING: this code might not work for netsnmp_ipaddress_entry */
965 if(rowreq_ctx->data->if_index)
966 (*ipAddressRowStatus_val_ptr) = rowreq_ctx->ipAddressRowStatus;
967 else
968 (*ipAddressRowStatus_val_ptr) = ROWSTATUS_NOTREADY;
969
970 return MFD_SUCCESS;
971 } /* ipAddressRowStatus_get */
972
973 /*---------------------------------------------------------------------
974 * IP-MIB::ipAddressEntry.ipAddressStorageType
975 * ipAddressStorageType is subid 11 of ipAddressEntry.
976 * Its status is Current, and its access level is Create.
977 * OID: .1.3.6.1.2.1.4.34.1.11
978 * Description:
979 The storage type for this conceptual row. If this object
980 has a value of 'permanent' then no other objects are
981 required to be able to be modified.
982 *
983 * Attributes:
984 * accessible 1 isscalar 0 enums 1 hasdefval 1
985 * readable 1 iscolumn 1 ranges 0 hashint 0
986 * settable 1
987 * defval: volatile
988 *
989 * Enum range: 4/8. Values: other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
990 *
991 * Its syntax is StorageType (based on perltype INTEGER)
992 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
993 */
994 /**
995 * Extract the current value of the ipAddressStorageType data.
996 *
997 * Set a value using the data context for the row.
998 *
999 * @param rowreq_ctx
1000 * Pointer to the row request context.
1001 * @param ipAddressStorageType_val_ptr
1002 * Pointer to storage for a long variable
1003 *
1004 * @retval MFD_SUCCESS : success
1005 * @retval MFD_SKIP : skip this node (no value for now)
1006 * @retval MFD_ERROR : Any other error
1007 */
1008 int
ipAddressStorageType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long * ipAddressStorageType_val_ptr)1009 ipAddressStorageType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
1010 u_long * ipAddressStorageType_val_ptr)
1011 {
1012 /** we should have a non-NULL pointer */
1013 netsnmp_assert(NULL != ipAddressStorageType_val_ptr);
1014
1015
1016 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_get",
1017 "called\n"));
1018
1019 netsnmp_assert(NULL != rowreq_ctx);
1020
1021 /*
1022 * TODO:231:o: |-> Extract the current value of the ipAddressStorageType data.
1023 * copy (* ipAddressStorageType_val_ptr ) from rowreq_ctx->data
1024 */
1025 (*ipAddressStorageType_val_ptr) = rowreq_ctx->data->ia_storagetype;
1026
1027 return MFD_SUCCESS;
1028 } /* ipAddressStorageType_get */
1029
1030
1031
1032 /** @} */
1033 /**********************************************************************
1034 **********************************************************************
1035 ***
1036 *** Table ipAddressTable
1037 ***
1038 **********************************************************************
1039 **********************************************************************/
1040 /*
1041 * IP-MIB::ipAddressTable is subid 34 of ip.
1042 * Its status is Current.
1043 * OID: .1.3.6.1.2.1.4.34, length: 8
1044 */
1045 /*
1046 * NOTE: if you update this chart, please update the versions in
1047 * local/mib2c-conf.d/parent-set.m2i
1048 * agent/mibgroup/helpers/baby_steps.c
1049 * while you're at it.
1050 */
1051 /*
1052 ***********************************************************************
1053 * Baby Steps Flow Chart (2004.06.05) *
1054 * *
1055 * +--------------+ +================+ U = unconditional path *
1056 * |optional state| ||required state|| S = path for success *
1057 * +--------------+ +================+ E = path for error *
1058 ***********************************************************************
1059 *
1060 * +--------------+
1061 * | pre |
1062 * | request |
1063 * +--------------+
1064 * | U
1065 * +-------------+ +==============+
1066 * | row |f|<-------|| object ||
1067 * | create |1| E || lookup ||
1068 * +-------------+ +==============+
1069 * E | | S | S
1070 * | +------------------>|
1071 * | +==============+
1072 * | E || check ||
1073 * |<---------------|| values ||
1074 * | +==============+
1075 * | | S
1076 * | +==============+
1077 * | +<-------|| undo ||
1078 * | | E || setup ||
1079 * | | +==============+
1080 * | | | S
1081 * | | +==============+
1082 * | | || set ||-------------------------->+
1083 * | | || value || E |
1084 * | | +==============+ |
1085 * | | | S |
1086 * | | +--------------+ |
1087 * | | | check |-------------------------->|
1088 * | | | consistency | E |
1089 * | | +--------------+ |
1090 * | | | S |
1091 * | | +==============+ +==============+ |
1092 * | | || commit ||-------->|| undo || |
1093 * | | || || E || commit || |
1094 * | | +==============+ +==============+ |
1095 * | | | S U |<--------+
1096 * | | +--------------+ +==============+
1097 * | | | irreversible | || undo ||
1098 * | | | commit | || set ||
1099 * | | +--------------+ +==============+
1100 * | | | U U |
1101 * | +-------------->|<------------------------+
1102 * | +==============+
1103 * | || undo ||
1104 * | || cleanup ||
1105 * | +==============+
1106 * +---------------------->| U
1107 * |
1108 * (err && f1)------------------->+
1109 * | |
1110 * +--------------+ +--------------+
1111 * | post |<--------| row |
1112 * | request | U | release |
1113 * +--------------+ +--------------+
1114 *
1115 */
1116
1117 /**
1118 * Setup up context with information needed to undo a set request.
1119 *
1120 * This function will be called before the individual node undo setup
1121 * functions are called. If you need to do any undo setup that is not
1122 * related to a specific column, you can do it here.
1123 *
1124 * Note that the undo context has been allocated with
1125 * ipAddressTable_allocate_data(), but may need extra
1126 * initialization similar to what you may have done in
1127 * ipAddressTable_rowreq_ctx_init().
1128 * Note that an individual node's undo_setup function will only be called
1129 * if that node is being set to a new value.
1130 *
1131 * If there is any setup specific to a particular column (e.g. allocating
1132 * memory for a string), you should do that setup in the node's undo_setup
1133 * function, so it won't be done unless it is necessary.
1134 *
1135 * @param rowreq_ctx
1136 * Pointer to the table context (ipAddressTable_rowreq_ctx)
1137 *
1138 * @retval MFD_SUCCESS : success
1139 * @retval MFD_ERROR : error. set will fail.
1140 */
1141 int
ipAddressTable_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)1142 ipAddressTable_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
1143 {
1144 int rc = MFD_SUCCESS;
1145
1146 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo_setup",
1147 "called\n"));
1148
1149 /** we should have a non-NULL pointer */
1150 netsnmp_assert(NULL != rowreq_ctx);
1151
1152 /*
1153 * TODO:451:M: |-> Setup ipAddressTable undo.
1154 * set up ipAddressTable undo information, in preparation for a set.
1155 * Undo storage is in (* ipAddressStorageType_val_ptr )*
1156 */
1157 /*
1158 * check for storage types that don't allow modification.
1159 * probably should try and do this earlier (and we could, by
1160 * adding code to the interface file), but this ought to suffice.
1161 */
1162 if (STORAGETYPE_READONLY == rowreq_ctx->data->ia_storagetype) {
1163 DEBUGMSGTL(("ipAddressTable", "can't change readonly row\n"));
1164 return MFD_NOT_VALID_EVER;
1165 }
1166
1167 /*
1168 * save last changed
1169 */
1170 rowreq_ctx->ipAddressLastChanged_undo =
1171 rowreq_ctx->ipAddressLastChanged;
1172
1173
1174 /*
1175 * just copy everything
1176 */
1177 rc = netsnmp_access_ipaddress_entry_copy(rowreq_ctx->undo,
1178 rowreq_ctx->data);
1179
1180 return rc;
1181 } /* ipAddressTable_undo_setup */
1182
1183 /**
1184 * Undo a set request.
1185 *
1186 * This function will be called before the individual node undo
1187 * functions are called. If you need to do any undo that is not
1188 * related to a specific column, you can do it here.
1189 *
1190 * Note that an individual node's undo function will only be called
1191 * if that node is being set to a new value.
1192 *
1193 * If there is anything specific to a particular column (e.g. releasing
1194 * memory for a string), you should do that setup in the node's undo
1195 * function, so it won't be done unless it is necessary.
1196 *
1197 * @param rowreq_ctx
1198 * Pointer to the table context (ipAddressTable_rowreq_ctx)
1199 *
1200 * @retval MFD_SUCCESS : success
1201 * @retval MFD_ERROR : error. set will fail.
1202 */
1203 int
ipAddressTable_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)1204 ipAddressTable_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
1205 {
1206 int rc = MFD_SUCCESS;
1207
1208 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo", "called\n"));
1209
1210 /** we should have a non-NULL pointer */
1211 netsnmp_assert(NULL != rowreq_ctx);
1212
1213 /*
1214 * TODO:451:M: |-> ipAddressTable undo.
1215 * ipAddressTable undo information, in response to a failed set.
1216 * Undo storage is in (* ipAddressStorageType_val_ptr )*
1217 */
1218
1219 return rc;
1220 } /* ipAddressTable_undo_setup */
1221
1222 /**
1223 * Cleanup up context undo information.
1224 *
1225 * This function will be called after set/commit processing. If you
1226 * allocated any resources in undo_setup, this is the place to release
1227 * those resources.
1228 *
1229 * This function is called regardless of the success or failure of the set
1230 * request. If you need to perform different steps for cleanup depending
1231 * on success or failure, you can add a flag to the rowreq_ctx.
1232 *
1233 * @param rowreq_ctx
1234 * Pointer to the table context (ipAddressTable_rowreq_ctx)
1235 *
1236 * @retval MFD_SUCCESS : success
1237 * @retval MFD_ERROR : error
1238 */
1239 int
ipAddressTable_undo_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)1240 ipAddressTable_undo_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)
1241 {
1242 int rc = MFD_SUCCESS;
1243
1244 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo_cleanup",
1245 "called\n"));
1246
1247 /** we should have a non-NULL pointer */
1248 netsnmp_assert(NULL != rowreq_ctx);
1249
1250 /*
1251 * TODO:452:M: |-> Cleanup ipAddressTable undo.
1252 * Undo storage is in (* ipAddressStorageType_val_ptr )*
1253 */
1254 rowreq_ctx->ipAddressLastChanged =
1255 rowreq_ctx->ipAddressLastChanged_undo;
1256
1257 return rc;
1258 } /* ipAddressTable_undo_cleanup */
1259
1260 /**
1261 * commit new values.
1262 *
1263 * At this point, you should have done everything you can to ensure that
1264 * this commit will not fail.
1265 *
1266 * Should you need different behavior depending on which columns were
1267 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
1268 * set. The definitions for the COLUMN_*_FLAG bits can be found in
1269 * ipAddressTable.h.
1270 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
1271 *
1272 * @param rowreq_ctx
1273 * Pointer to the users context.
1274 *
1275 * @retval MFD_SUCCESS : success
1276 * @retval MFD_ERROR : error
1277 */
1278 int
ipAddressTable_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)1279 ipAddressTable_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)
1280 {
1281 int rc = MFD_SUCCESS;
1282
1283 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_commit",
1284 "called\n"));
1285
1286 /** we should have a non-NULL pointer */
1287 netsnmp_assert(NULL != rowreq_ctx);
1288
1289 /*
1290 * commit ipAddressTable data
1291 * 1) check the column's flag to see if it was set.
1292 * 2) clear the flag when you handle that column
1293 * 3) set the column's flag in column_set_flags if it needs undo
1294 * processing in case of a failure.
1295 */
1296 /*
1297 * did anything change?
1298 */
1299 if (0 == rowreq_ctx->column_set_flags) {
1300 DEBUGMSGTL(("ipAddressTable:ipAddressTable_commit",
1301 "no change\n"));
1302 return MFD_SUCCESS;
1303 }
1304
1305 /*
1306 * pass everything to data access
1307 * let data access know what columns are set
1308 */
1309 rowreq_ctx->data->flags = rowreq_ctx->column_set_flags;
1310
1311 if (rowreq_ctx->column_set_flags & COLUMN_IPADDRESSROWSTATUS_FLAG) {
1312 if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
1313 rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CREATE;
1314 rowreq_ctx->ipAddressCreated = netsnmp_get_agent_uptime();
1315 } else if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
1316 rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_DELETE;
1317 } else
1318 rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
1319 } else
1320 rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
1321
1322 /*
1323 * do it
1324 */
1325 rc = netsnmp_access_ipaddress_entry_set(rowreq_ctx->data);
1326 if (rc) {
1327 DEBUGMSGTL(("ipAddressTable",
1328 "bad rc %d from IP address data access\n", rc));
1329 rc = MFD_ERROR;
1330 } else {
1331 rowreq_ctx->ipAddressLastChanged = netsnmp_get_agent_uptime();
1332 }
1333
1334 /*
1335 * if we successfully commited this row, set the dirty flag.
1336 */
1337 if (MFD_SUCCESS == rc) {
1338 rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
1339 }
1340
1341 return rc;
1342 } /* ipAddressTable_commit */
1343
1344 /**
1345 * undo commit new values.
1346 *
1347 * Should you need different behavior depending on which columns were
1348 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
1349 * set. The definitions for the COLUMN_*_FLAG bits can be found in
1350 * ipAddressTable.h.
1351 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
1352 *
1353 * @param rowreq_ctx
1354 * Pointer to the users context.
1355 *
1356 * @retval MFD_SUCCESS : success
1357 * @retval MFD_ERROR : error
1358 */
1359 int
ipAddressTable_undo_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)1360 ipAddressTable_undo_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)
1361 {
1362 int rc = MFD_SUCCESS;
1363
1364 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo_commit",
1365 "called\n"));
1366
1367 /** we should have a non-NULL pointer */
1368 netsnmp_assert(NULL != rowreq_ctx);
1369
1370 /*
1371 * TODO:485:M: |-> Undo ipAddressTable commit.
1372 * check the column's flag in rowreq_ctx->column_set_flags to see
1373 * if it was set during commit, then undo it.
1374 *
1375 * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
1376 */
1377 if (rowreq_ctx->column_set_flags & COLUMN_IPADDRESSROWSTATUS_FLAG) {
1378 /*
1379 * if we created an addr, delete it. if we deleted it,
1380 * re-create it. If we changed it, change it back.
1381 */
1382 if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
1383 rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_DELETE;
1384 } else if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
1385 rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CREATE;
1386 } else
1387 rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
1388 } else
1389 rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
1390
1391 /*
1392 * do it
1393 */
1394 rc = netsnmp_access_ipaddress_entry_set(rowreq_ctx->undo);
1395 if (rc) {
1396 DEBUGMSGTL(("ipAddressTable",
1397 "bad rc %d from IP address data access\n", rc));
1398 rc = MFD_ERROR;
1399 }
1400
1401 /*
1402 * if we successfully un-commited this row, clear the dirty flag.
1403 */
1404 if (MFD_SUCCESS == rc) {
1405 rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
1406 }
1407
1408 return rc;
1409 } /* ipAddressTable_undo_commit */
1410
1411 /*
1412 * TODO:440:M: Implement ipAddressTable node value checks.
1413 * TODO:450:M: Implement ipAddressTable undo functions.
1414 * TODO:460:M: Implement ipAddressTable set functions.
1415 * TODO:480:M: Implement ipAddressTable commit functions.
1416 */
1417 /*---------------------------------------------------------------------
1418 * IP-MIB::ipAddressEntry.ipAddressIfIndex
1419 * ipAddressIfIndex is subid 3 of ipAddressEntry.
1420 * Its status is Current, and its access level is Create.
1421 * OID: .1.3.6.1.2.1.4.34.1.3
1422 * Description:
1423 The index value which uniquely identifies the interface to
1424 which this entry is applicable. The interface identified by
1425 a particular value of this index is the same interface as
1426 identified by the same value of the IF-MIB's ifIndex.
1427 *
1428 * Attributes:
1429 * accessible 1 isscalar 0 enums 0 hasdefval 0
1430 * readable 1 iscolumn 1 ranges 1 hashint 1
1431 * settable 1
1432 * hint: d
1433 *
1434 * Ranges: 1 - 2147483647;
1435 *
1436 * Its syntax is InterfaceIndex (based on perltype INTEGER32)
1437 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
1438 */
1439 /**
1440 * Check that the proposed new value is potentially valid.
1441 *
1442 * @param rowreq_ctx
1443 * Pointer to the row request context.
1444 * @param ipAddressIfIndex_val
1445 * A long containing the new value.
1446 *
1447 * @retval MFD_SUCCESS : incoming value is legal
1448 * @retval MFD_NOT_VALID_NOW : incoming value is not valid now
1449 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
1450 *
1451 * This is the place to check for requirements that are not
1452 * expressed in the mib syntax (for example, a requirement that
1453 * is detailed in the description for an object).
1454 *
1455 * You should check that the requested change between the undo value and the
1456 * new value is legal (ie, the transistion from one value to another
1457 * is legal).
1458 *
1459 *@note
1460 * This check is only to determine if the new value
1461 * is \b potentially valid. This is the first check of many, and
1462 * is one of the simplest ones.
1463 *
1464 *@note
1465 * this is not the place to do any checks for values
1466 * which depend on some other value in the mib. Those
1467 * types of checks should be done in the
1468 * ipAddressTable_check_dependencies() function.
1469 *
1470 * The following checks have already been done for you:
1471 * The syntax is ASN_INTEGER
1472 * The value is in (one of) the range set(s): 1 - 2147483647
1473 *
1474 * If there a no other checks you need to do, simply return MFD_SUCCESS.
1475 *
1476 */
1477 int
ipAddressIfIndex_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,long ipAddressIfIndex_val)1478 ipAddressIfIndex_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
1479 long ipAddressIfIndex_val)
1480 {
1481 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_check_value",
1482 "called\n"));
1483
1484 /** should never get a NULL pointer */
1485 netsnmp_assert(NULL != rowreq_ctx);
1486
1487 /*
1488 * TODO:441:o: |-> Check for valid ipAddressIfIndex value.
1489 */
1490 /*
1491 * if the new value is the same as the old, accept it.
1492 */
1493 if (ipAddressIfIndex_val == (long)rowreq_ctx->data->if_index)
1494 return MFD_SUCCESS;
1495
1496 /*
1497 * currently don't support moving addresses between interfaces, so
1498 * if this isn't a new row, return error.
1499 */
1500 if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)) {
1501 DEBUGMSGT(("ipAddressTable",
1502 "changing ifIndex value not supported\n"));
1503 return MFD_NOT_VALID_EVER;
1504 }
1505
1506 /*
1507 * find name for ifIndex
1508 */
1509 if (NULL == netsnmp_access_interface_name_find(ipAddressIfIndex_val)) {
1510 DEBUGMSGT(("ipAddressTable", "cant find name for index %ld\n",
1511 ipAddressIfIndex_val));
1512 return MFD_NOT_VALID_NOW;
1513 }
1514
1515 return MFD_SUCCESS; /* ipAddressIfIndex value not illegal */
1516 } /* ipAddressIfIndex_check_value */
1517
1518 /**
1519 * Save old value information
1520 *
1521 * @param rowreq_ctx
1522 * Pointer to the table context (ipAddressTable_rowreq_ctx)
1523 *
1524 * @retval MFD_SUCCESS : success
1525 * @retval MFD_ERROR : error. set will fail.
1526 *
1527 * This function will be called after the table level undo setup function
1528 * ipAddressTable_undo_setup has been called.
1529 *
1530 *@note
1531 * this function will only be called if a new value is set for this column.
1532 *
1533 * If there is any setup specific to a particular column (e.g. allocating
1534 * memory for a string), you should do that setup in this function, so it
1535 * won't be done unless it is necessary.
1536 */
1537 int
ipAddressIfIndex_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)1538 ipAddressIfIndex_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
1539 {
1540 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_undo_setup",
1541 "called\n"));
1542
1543 /** should never get a NULL pointer */
1544 netsnmp_assert(NULL != rowreq_ctx);
1545
1546 /*
1547 * TODO:455:o: |-> Setup ipAddressIfIndex undo.
1548 */
1549 /*
1550 * handled in ipAddressTable_undo_setup
1551 */
1552
1553 return MFD_SUCCESS;
1554 } /* ipAddressIfIndex_undo_setup */
1555
1556 /**
1557 * Set the new value.
1558 *
1559 * @param rowreq_ctx
1560 * Pointer to the users context. You should know how to
1561 * manipulate the value from this object.
1562 * @param ipAddressIfIndex_val
1563 * A long containing the new value.
1564 */
1565 int
ipAddressIfIndex_set(ipAddressTable_rowreq_ctx * rowreq_ctx,long ipAddressIfIndex_val)1566 ipAddressIfIndex_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
1567 long ipAddressIfIndex_val)
1568 {
1569
1570 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_set",
1571 "called\n"));
1572
1573 /** should never get a NULL pointer */
1574 netsnmp_assert(NULL != rowreq_ctx);
1575
1576 /*
1577 * TODO:461:M: |-> Set ipAddressIfIndex value.
1578 * set ipAddressIfIndex value in rowreq_ctx->data
1579 */
1580 if (rowreq_ctx->data->if_index != (oid)ipAddressIfIndex_val)
1581 rowreq_ctx->data->if_index = (oid)ipAddressIfIndex_val;
1582 else
1583 rowreq_ctx->column_set_flags &= ~COLUMN_IPADDRESSIFINDEX_FLAG;
1584
1585 return MFD_SUCCESS;
1586 } /* ipAddressIfIndex_set */
1587
1588 /**
1589 * undo the previous set.
1590 *
1591 * @param rowreq_ctx
1592 * Pointer to the users context.
1593 */
1594 int
ipAddressIfIndex_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)1595 ipAddressIfIndex_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
1596 {
1597
1598 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_undo",
1599 "called\n"));
1600
1601 netsnmp_assert(NULL != rowreq_ctx);
1602
1603 /*
1604 * TODO:456:o: |-> Clean up ipAddressIfIndex undo.
1605 */
1606 /*
1607 * copy ipAddressIfIndex data
1608 * set rowreq_ctx->data->ipAddressIfIndex from rowreq_ctx->undo->ipAddressIfIndex
1609 */
1610 rowreq_ctx->data->if_index = rowreq_ctx->undo->if_index;
1611
1612 return MFD_SUCCESS;
1613 } /* ipAddressIfIndex_undo */
1614
1615 /*---------------------------------------------------------------------
1616 * IP-MIB::ipAddressEntry.ipAddressType
1617 * ipAddressType is subid 4 of ipAddressEntry.
1618 * Its status is Current, and its access level is Create.
1619 * OID: .1.3.6.1.2.1.4.34.1.4
1620 * Description:
1621 The type of address. broadcast(3) is not a valid value for
1622 IPv6 addresses (RFC3513).
1623 *
1624 * Attributes:
1625 * accessible 1 isscalar 0 enums 1 hasdefval 1
1626 * readable 1 iscolumn 1 ranges 0 hashint 0
1627 * settable 1
1628 * defval: unicast
1629 *
1630 * Enum range: 2/8. Values: unicast(1), anycast(2), broadcast(3)
1631 *
1632 * Its syntax is INTEGER (based on perltype INTEGER)
1633 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
1634 */
1635 /**
1636 * Check that the proposed new value is potentially valid.
1637 *
1638 * @param rowreq_ctx
1639 * Pointer to the row request context.
1640 * @param ipAddressType_val
1641 * A long containing the new value.
1642 *
1643 * @retval MFD_SUCCESS : incoming value is legal
1644 * @retval MFD_NOT_VALID_NOW : incoming value is not valid now
1645 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
1646 *
1647 * This is the place to check for requirements that are not
1648 * expressed in the mib syntax (for example, a requirement that
1649 * is detailed in the description for an object).
1650 *
1651 * You should check that the requested change between the undo value and the
1652 * new value is legal (ie, the transistion from one value to another
1653 * is legal).
1654 *
1655 *@note
1656 * This check is only to determine if the new value
1657 * is \b potentially valid. This is the first check of many, and
1658 * is one of the simplest ones.
1659 *
1660 *@note
1661 * this is not the place to do any checks for values
1662 * which depend on some other value in the mib. Those
1663 * types of checks should be done in the
1664 * ipAddressTable_check_dependencies() function.
1665 *
1666 * The following checks have already been done for you:
1667 * The syntax is ASN_INTEGER
1668 * The value is one of unicast(1), anycast(2), broadcast(3)
1669 *
1670 * If there a no other checks you need to do, simply return MFD_SUCCESS.
1671 *
1672 */
1673 int
ipAddressType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressType_val)1674 ipAddressType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
1675 u_long ipAddressType_val)
1676 {
1677 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_check_value",
1678 "called\n"));
1679
1680 /** should never get a NULL pointer */
1681 netsnmp_assert(NULL != rowreq_ctx);
1682
1683 /*
1684 * TODO:441:o: |-> Check for valid ipAddressType value.
1685 *
1686 * no support for anything but unicast yet
1687 */
1688 if (ipAddressType_val != IPADDRESSTYPE_UNICAST)
1689 return MFD_NOT_VALID_EVER;
1690
1691 return MFD_SUCCESS; /* ipAddressType value not illegal */
1692 } /* ipAddressType_check_value */
1693
1694 /**
1695 * Save old value information
1696 *
1697 * @param rowreq_ctx
1698 * Pointer to the table context (ipAddressTable_rowreq_ctx)
1699 *
1700 * @retval MFD_SUCCESS : success
1701 * @retval MFD_ERROR : error. set will fail.
1702 *
1703 * This function will be called after the table level undo setup function
1704 * ipAddressTable_undo_setup has been called.
1705 *
1706 *@note
1707 * this function will only be called if a new value is set for this column.
1708 *
1709 * If there is any setup specific to a particular column (e.g. allocating
1710 * memory for a string), you should do that setup in this function, so it
1711 * won't be done unless it is necessary.
1712 */
1713 int
ipAddressType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)1714 ipAddressType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
1715 {
1716 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_undo_setup",
1717 "called\n"));
1718
1719 /** should never get a NULL pointer */
1720 netsnmp_assert(NULL != rowreq_ctx);
1721
1722 /*
1723 * TODO:455:o: |-> Setup ipAddressType undo.
1724 */
1725 /*
1726 * handled in ipAddressTable_undo_setup
1727 */
1728
1729 return MFD_SUCCESS;
1730 } /* ipAddressType_undo_setup */
1731
1732 /**
1733 * Set the new value.
1734 *
1735 * @param rowreq_ctx
1736 * Pointer to the users context. You should know how to
1737 * manipulate the value from this object.
1738 * @param ipAddressType_val
1739 * A long containing the new value.
1740 */
1741 int
ipAddressType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressType_val)1742 ipAddressType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
1743 u_long ipAddressType_val)
1744 {
1745
1746 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_set", "called\n"));
1747
1748 /** should never get a NULL pointer */
1749 netsnmp_assert(NULL != rowreq_ctx);
1750
1751 /*
1752 * TODO:461:M: |-> Set ipAddressType value.
1753 * set ipAddressType value in rowreq_ctx->data
1754 */
1755 rowreq_ctx->data->ia_type = ipAddressType_val;
1756
1757 return MFD_SUCCESS;
1758 } /* ipAddressType_set */
1759
1760 /**
1761 * undo the previous set.
1762 *
1763 * @param rowreq_ctx
1764 * Pointer to the users context.
1765 */
1766 int
ipAddressType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)1767 ipAddressType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
1768 {
1769
1770 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_undo", "called\n"));
1771
1772 netsnmp_assert(NULL != rowreq_ctx);
1773
1774 /*
1775 * TODO:456:o: |-> Clean up ipAddressType undo.
1776 */
1777 /*
1778 * copy ipAddressType data
1779 * set rowreq_ctx->data->ipAddressType from rowreq_ctx->undo->ipAddressType
1780 */
1781 rowreq_ctx->data->ia_type = rowreq_ctx->undo->ia_type;
1782
1783 return MFD_SUCCESS;
1784 } /* ipAddressType_undo */
1785
1786 /*---------------------------------------------------------------------
1787 * IP-MIB::ipAddressEntry.ipAddressStatus
1788 * ipAddressStatus is subid 7 of ipAddressEntry.
1789 * Its status is Current, and its access level is Create.
1790 * OID: .1.3.6.1.2.1.4.34.1.7
1791 * Description:
1792 The status of the address, describing if the address can be
1793 used for communication.
1794
1795
1796 In the absence of other information, an IPv4 address is
1797 always preferred(1).
1798 *
1799 * Attributes:
1800 * accessible 1 isscalar 0 enums 1 hasdefval 1
1801 * readable 1 iscolumn 1 ranges 0 hashint 0
1802 * settable 1
1803 * defval: preferred
1804 *
1805 * Enum range: 5/8. Values: preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
1806 *
1807 * Its syntax is IpAddressStatusTC (based on perltype INTEGER)
1808 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
1809 */
1810 /**
1811 * Check that the proposed new value is potentially valid.
1812 *
1813 * @param rowreq_ctx
1814 * Pointer to the row request context.
1815 * @param ipAddressStatus_val
1816 * A long containing the new value.
1817 *
1818 * @retval MFD_SUCCESS : incoming value is legal
1819 * @retval MFD_NOT_VALID_NOW : incoming value is not valid now
1820 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
1821 *
1822 * This is the place to check for requirements that are not
1823 * expressed in the mib syntax (for example, a requirement that
1824 * is detailed in the description for an object).
1825 *
1826 * You should check that the requested change between the undo value and the
1827 * new value is legal (ie, the transistion from one value to another
1828 * is legal).
1829 *
1830 *@note
1831 * This check is only to determine if the new value
1832 * is \b potentially valid. This is the first check of many, and
1833 * is one of the simplest ones.
1834 *
1835 *@note
1836 * this is not the place to do any checks for values
1837 * which depend on some other value in the mib. Those
1838 * types of checks should be done in the
1839 * ipAddressTable_check_dependencies() function.
1840 *
1841 * The following checks have already been done for you:
1842 * The syntax is ASN_INTEGER
1843 * The value is one of preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
1844 *
1845 * If there a no other checks you need to do, simply return MFD_SUCCESS.
1846 *
1847 */
1848 int
ipAddressStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressStatus_val)1849 ipAddressStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
1850 u_long ipAddressStatus_val)
1851 {
1852 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_check_value",
1853 "called\n"));
1854
1855 /** should never get a NULL pointer */
1856 netsnmp_assert(NULL != rowreq_ctx);
1857
1858 /*
1859 * TODO:441:o: |-> Check for valid ipAddressStatus value.
1860 *
1861 * nothing but preferred supported yet
1862 */
1863 if (IPADDRESSSTATUSTC_PREFERRED != ipAddressStatus_val)
1864 return MFD_NOT_VALID_EVER;
1865
1866 return MFD_SUCCESS; /* ipAddressStatus value not illegal */
1867 } /* ipAddressStatus_check_value */
1868
1869 /**
1870 * Save old value information
1871 *
1872 * @param rowreq_ctx
1873 * Pointer to the table context (ipAddressTable_rowreq_ctx)
1874 *
1875 * @retval MFD_SUCCESS : success
1876 * @retval MFD_ERROR : error. set will fail.
1877 *
1878 * This function will be called after the table level undo setup function
1879 * ipAddressTable_undo_setup has been called.
1880 *
1881 *@note
1882 * this function will only be called if a new value is set for this column.
1883 *
1884 * If there is any setup specific to a particular column (e.g. allocating
1885 * memory for a string), you should do that setup in this function, so it
1886 * won't be done unless it is necessary.
1887 */
1888 int
ipAddressStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)1889 ipAddressStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
1890 {
1891 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_undo_setup",
1892 "called\n"));
1893
1894 /** should never get a NULL pointer */
1895 netsnmp_assert(NULL != rowreq_ctx);
1896
1897 /*
1898 * TODO:455:o: |-> Setup ipAddressStatus undo.
1899 */
1900 /*
1901 * handled in ipAddressTable_undo_setup
1902 */
1903
1904 return MFD_SUCCESS;
1905 } /* ipAddressStatus_undo_setup */
1906
1907 /**
1908 * Set the new value.
1909 *
1910 * @param rowreq_ctx
1911 * Pointer to the users context. You should know how to
1912 * manipulate the value from this object.
1913 * @param ipAddressStatus_val
1914 * A long containing the new value.
1915 */
1916 int
ipAddressStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressStatus_val)1917 ipAddressStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
1918 u_long ipAddressStatus_val)
1919 {
1920
1921 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_set", "called\n"));
1922
1923 /** should never get a NULL pointer */
1924 netsnmp_assert(NULL != rowreq_ctx);
1925
1926 /*
1927 * TODO:461:M: |-> Set ipAddressStatus value.
1928 * set ipAddressStatus value in rowreq_ctx->data
1929 */
1930 rowreq_ctx->data->ia_status = ipAddressStatus_val;
1931
1932 return MFD_SUCCESS;
1933 } /* ipAddressStatus_set */
1934
1935 /**
1936 * undo the previous set.
1937 *
1938 * @param rowreq_ctx
1939 * Pointer to the users context.
1940 */
1941 int
ipAddressStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)1942 ipAddressStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
1943 {
1944
1945 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_undo",
1946 "called\n"));
1947
1948 netsnmp_assert(NULL != rowreq_ctx);
1949
1950 /*
1951 * TODO:456:o: |-> Clean up ipAddressStatus undo.
1952 */
1953 /*
1954 * copy ipAddressStatus data
1955 * set rowreq_ctx->data->ipAddressStatus from rowreq_ctx->undo->ipAddressStatus
1956 */
1957 rowreq_ctx->data->ia_status = rowreq_ctx->undo->ia_status;
1958
1959 return MFD_SUCCESS;
1960 } /* ipAddressStatus_undo */
1961
1962 /*---------------------------------------------------------------------
1963 * IP-MIB::ipAddressEntry.ipAddressRowStatus
1964 * ipAddressRowStatus is subid 10 of ipAddressEntry.
1965 * Its status is Current, and its access level is Create.
1966 * OID: .1.3.6.1.2.1.4.34.1.10
1967 * Description:
1968 The status of this conceptual row.
1969
1970
1971 The RowStatus TC requires that this DESCRIPTION clause
1972 states under which circumstances other objects in this row
1973 can be modified. The value of this object has no effect on
1974 whether other objects in this conceptual row can be
1975 modified.
1976
1977
1978 A conceptual row can not be made active until the
1979 ipAddressIfIndex has been set to a valid index.
1980 *
1981 * Attributes:
1982 * accessible 1 isscalar 0 enums 1 hasdefval 0
1983 * readable 1 iscolumn 1 ranges 0 hashint 0
1984 * settable 1
1985 *
1986 * Enum range: 3/8. Values: active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
1987 *
1988 * Its syntax is RowStatus (based on perltype INTEGER)
1989 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
1990 */
1991 /**
1992 * Check that the proposed new value is potentially valid.
1993 *
1994 * @param rowreq_ctx
1995 * Pointer to the row request context.
1996 * @param ipAddressRowStatus_val
1997 * A long containing the new value.
1998 *
1999 * @retval MFD_SUCCESS : incoming value is legal
2000 * @retval MFD_NOT_VALID_NOW : incoming value is not valid now
2001 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
2002 *
2003 * This is the place to check for requirements that are not
2004 * expressed in the mib syntax (for example, a requirement that
2005 * is detailed in the description for an object).
2006 *
2007 * You should check that the requested change between the undo value and the
2008 * new value is legal (ie, the transistion from one value to another
2009 * is legal).
2010 *
2011 *@note
2012 * This check is only to determine if the new value
2013 * is \b potentially valid. This is the first check of many, and
2014 * is one of the simplest ones.
2015 *
2016 *@note
2017 * this is not the place to do any checks for values
2018 * which depend on some other value in the mib. Those
2019 * types of checks should be done in the
2020 * ipAddressTable_check_dependencies() function.
2021 *
2022 * The following checks have already been done for you:
2023 * The syntax is ASN_INTEGER
2024 * The value is one of active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
2025 *
2026 * If there a no other checks you need to do, simply return MFD_SUCCESS.
2027 *
2028 */
2029 int
ipAddressRowStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressRowStatus_val)2030 ipAddressRowStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
2031 u_long ipAddressRowStatus_val)
2032 {
2033 int rc;
2034
2035 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_check_value",
2036 "called\n"));
2037
2038 /** should never get a NULL pointer */
2039 netsnmp_assert(NULL != rowreq_ctx);
2040
2041 /*
2042 * TODO:441:o: |-> Check for valid ipAddressRowStatus value.
2043 *
2044 * don't support createAndWait
2045 * check for valid RowStatus transition (old, new)
2046 */
2047 if (ROWSTATUS_CREATEANDWAIT == ipAddressRowStatus_val) {
2048 DEBUGMSGTL(("ipAddressTable", "createAndWait not supported\n"));
2049 return MFD_NOT_VALID_EVER;
2050 }
2051
2052 rc = check_rowstatus_transition(rowreq_ctx->ipAddressRowStatus,
2053 ipAddressRowStatus_val);
2054 if (MFD_SUCCESS != rc) {
2055 DEBUGMSGTL(("ipAddressTable",
2056 "row status transition from %d to %lu\n",
2057 rowreq_ctx->ipAddressRowStatus,
2058 ipAddressRowStatus_val));
2059 return rc;
2060 }
2061
2062 return MFD_SUCCESS; /* ipAddressRowStatus value not illegal */
2063 } /* ipAddressRowStatus_check_value */
2064
2065 /**
2066 * Save old value information
2067 *
2068 * @param rowreq_ctx
2069 * Pointer to the table context (ipAddressTable_rowreq_ctx)
2070 *
2071 * @retval MFD_SUCCESS : success
2072 * @retval MFD_ERROR : error. set will fail.
2073 *
2074 * This function will be called after the table level undo setup function
2075 * ipAddressTable_undo_setup has been called.
2076 *
2077 *@note
2078 * this function will only be called if a new value is set for this column.
2079 *
2080 * If there is any setup specific to a particular column (e.g. allocating
2081 * memory for a string), you should do that setup in this function, so it
2082 * won't be done unless it is necessary.
2083 */
2084 int
ipAddressRowStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)2085 ipAddressRowStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
2086 {
2087 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_undo_setup",
2088 "called\n"));
2089
2090 /** should never get a NULL pointer */
2091 netsnmp_assert(NULL != rowreq_ctx);
2092
2093 /*
2094 * TODO:455:o: |-> Setup ipAddressRowStatus undo.
2095 */
2096 /*
2097 * handled in ipAddressTable_undo_setup
2098 */
2099
2100 return MFD_SUCCESS;
2101 } /* ipAddressRowStatus_undo_setup */
2102
2103 /**
2104 * Set the new value.
2105 *
2106 * @param rowreq_ctx
2107 * Pointer to the users context. You should know how to
2108 * manipulate the value from this object.
2109 * @param ipAddressRowStatus_val
2110 * A long containing the new value.
2111 */
2112 int
ipAddressRowStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressRowStatus_val)2113 ipAddressRowStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
2114 u_long ipAddressRowStatus_val)
2115 {
2116
2117 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_set",
2118 "called\n"));
2119
2120 /** should never get a NULL pointer */
2121 netsnmp_assert(NULL != rowreq_ctx);
2122
2123 /*
2124 * TODO:461:M: |-> Set ipAddressRowStatus value.
2125 * set ipAddressRowStatus value in rowreq_ctx->data
2126 */
2127 rowreq_ctx->ipAddressRowStatus = ipAddressRowStatus_val;
2128
2129 return MFD_SUCCESS;
2130 } /* ipAddressRowStatus_set */
2131
2132 /**
2133 * undo the previous set.
2134 *
2135 * @param rowreq_ctx
2136 * Pointer to the users context.
2137 */
2138 int
ipAddressRowStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)2139 ipAddressRowStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
2140 {
2141
2142 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_undo",
2143 "called\n"));
2144
2145 netsnmp_assert(NULL != rowreq_ctx);
2146
2147 /*
2148 * TODO:456:o: |-> Clean up ipAddressRowStatus undo.
2149 */
2150 /*
2151 * copy ipAddressRowStatus data
2152 * set rowreq_ctx->data->ipAddressRowStatus from rowreq_ctx->undo->ipAddressRowStatus
2153 */
2154 rowreq_ctx->ipAddressRowStatus = rowreq_ctx->ipAddressRowStatus_undo;
2155
2156 return MFD_SUCCESS;
2157 } /* ipAddressRowStatus_undo */
2158
2159 /*---------------------------------------------------------------------
2160 * IP-MIB::ipAddressEntry.ipAddressStorageType
2161 * ipAddressStorageType is subid 11 of ipAddressEntry.
2162 * Its status is Current, and its access level is Create.
2163 * OID: .1.3.6.1.2.1.4.34.1.11
2164 * Description:
2165 The storage type for this conceptual row. If this object
2166 has a value of 'permanent' then no other objects are
2167 required to be able to be modified.
2168 *
2169 * Attributes:
2170 * accessible 1 isscalar 0 enums 1 hasdefval 1
2171 * readable 1 iscolumn 1 ranges 0 hashint 0
2172 * settable 1
2173 * defval: volatile
2174 *
2175 * Enum range: 4/8. Values: other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
2176 *
2177 * Its syntax is StorageType (based on perltype INTEGER)
2178 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
2179 */
2180 /**
2181 * Check that the proposed new value is potentially valid.
2182 *
2183 * @param rowreq_ctx
2184 * Pointer to the row request context.
2185 * @param ipAddressStorageType_val
2186 * A long containing the new value.
2187 *
2188 * @retval MFD_SUCCESS : incoming value is legal
2189 * @retval MFD_NOT_VALID_NOW : incoming value is not valid now
2190 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
2191 *
2192 * This is the place to check for requirements that are not
2193 * expressed in the mib syntax (for example, a requirement that
2194 * is detailed in the description for an object).
2195 *
2196 * You should check that the requested change between the undo value and the
2197 * new value is legal (ie, the transistion from one value to another
2198 * is legal).
2199 *
2200 *@note
2201 * This check is only to determine if the new value
2202 * is \b potentially valid. This is the first check of many, and
2203 * is one of the simplest ones.
2204 *
2205 *@note
2206 * this is not the place to do any checks for values
2207 * which depend on some other value in the mib. Those
2208 * types of checks should be done in the
2209 * ipAddressTable_check_dependencies() function.
2210 *
2211 * The following checks have already been done for you:
2212 * The syntax is ASN_INTEGER
2213 * The value is one of other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
2214 *
2215 * If there a no other checks you need to do, simply return MFD_SUCCESS.
2216 *
2217 */
2218 int
ipAddressStorageType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressStorageType_val)2219 ipAddressStorageType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
2220 u_long ipAddressStorageType_val)
2221 {
2222 int rc;
2223
2224 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_check_value",
2225 "called\n"));
2226
2227 /** should never get a NULL pointer */
2228 netsnmp_assert(NULL != rowreq_ctx);
2229
2230 /*
2231 * TODO:441:o: |-> Check for valid ipAddressStorageType value.
2232 */
2233 /*
2234 * since I don't know how the various operating systems
2235 * deal with ip addresses, and whether or not changes will
2236 * be saved on reboot, so don't allow rows to be set to anything
2237 * but volatile. I'd prefer other, but since the default for
2238 * new rows, per the mib, is volatile...
2239 *
2240 * If some industrious soul would like
2241 * non-volaltile support, the first would need to
2242 * add it in the data access code for their os
2243 * define a flag bit for volatile/permanent/readonly
2244 * set the bit in data access
2245 * copy the bit to a new var in the rowreq_ctx (see _add_new_entry)
2246 * with a default of volatile (for os' w/out nonvolatile support)
2247 * update this code to use new flag
2248 */
2249 if (STORAGETYPE_VOLATILE != ipAddressStorageType_val)
2250 return MFD_NOT_VALID_EVER;
2251
2252 /*
2253 * check for valid StorageType transition (old, new)
2254 */
2255 rc = check_storage_transition(rowreq_ctx->data->ia_storagetype,
2256 ipAddressStorageType_val);
2257 if (MFD_SUCCESS != rc)
2258 return rc;
2259
2260 return MFD_SUCCESS; /* ipAddressStorageType value not illegal */
2261 } /* ipAddressStorageType_check_value */
2262
2263 /**
2264 * Save old value information
2265 *
2266 * @param rowreq_ctx
2267 * Pointer to the table context (ipAddressTable_rowreq_ctx)
2268 *
2269 * @retval MFD_SUCCESS : success
2270 * @retval MFD_ERROR : error. set will fail.
2271 *
2272 * This function will be called after the table level undo setup function
2273 * ipAddressTable_undo_setup has been called.
2274 *
2275 *@note
2276 * this function will only be called if a new value is set for this column.
2277 *
2278 * If there is any setup specific to a particular column (e.g. allocating
2279 * memory for a string), you should do that setup in this function, so it
2280 * won't be done unless it is necessary.
2281 */
2282 int
ipAddressStorageType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)2283 ipAddressStorageType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
2284 {
2285 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_undo_setup",
2286 "called\n"));
2287
2288 /** should never get a NULL pointer */
2289 netsnmp_assert(NULL != rowreq_ctx);
2290
2291 /*
2292 * TODO:455:o: |-> Setup ipAddressStorageType undo.
2293 */
2294 /*
2295 * handled in ipAddressTable_undo_setup
2296 */
2297
2298 return MFD_SUCCESS;
2299 } /* ipAddressStorageType_undo_setup */
2300
2301 /**
2302 * Set the new value.
2303 *
2304 * @param rowreq_ctx
2305 * Pointer to the users context. You should know how to
2306 * manipulate the value from this object.
2307 * @param ipAddressStorageType_val
2308 * A long containing the new value.
2309 */
2310 int
ipAddressStorageType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,u_long ipAddressStorageType_val)2311 ipAddressStorageType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
2312 u_long ipAddressStorageType_val)
2313 {
2314
2315 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_set",
2316 "called\n"));
2317
2318 /** should never get a NULL pointer */
2319 netsnmp_assert(NULL != rowreq_ctx);
2320
2321 /*
2322 * TODO:461:M: |-> Set ipAddressStorageType value.
2323 * set ipAddressStorageType value in rowreq_ctx->data
2324 */
2325 rowreq_ctx->data->ia_storagetype = ipAddressStorageType_val;
2326
2327 return MFD_SUCCESS;
2328 } /* ipAddressStorageType_set */
2329
2330 /**
2331 * undo the previous set.
2332 *
2333 * @param rowreq_ctx
2334 * Pointer to the users context.
2335 */
2336 int
ipAddressStorageType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)2337 ipAddressStorageType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
2338 {
2339
2340 DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_undo",
2341 "called\n"));
2342
2343 netsnmp_assert(NULL != rowreq_ctx);
2344
2345 /*
2346 * TODO:456:o: |-> Clean up ipAddressStorageType undo.
2347 */
2348 /*
2349 * copy ipAddressStorageType data
2350 * set rowreq_ctx->data->ipAddressStorageType from rowreq_ctx->undo->ipAddressStorageType
2351 */
2352 rowreq_ctx->data->ia_storagetype = rowreq_ctx->undo->ia_storagetype;
2353
2354 return MFD_SUCCESS;
2355 } /* ipAddressStorageType_undo */
2356
2357 /**
2358 * check dependencies
2359 *
2360 * This is useful for for tables which have dependencies between columns
2361 * (or rows, or tables). For example, two columns allocating a percentage
2362 * of something add up 100%.
2363 *
2364 * Should you need different behavior depending on which columns were
2365 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
2366 * set. The definitions for the COLUMN_*_FLAG bits can be found in
2367 * ipAddressTable.h.
2368 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
2369 *
2370 * @retval MFD_SUCCESS all the changes to the row are legal
2371 * @retval MFD_ERROR one or more changes are not legal
2372 *
2373 * (see README-table-ipAddressTable if you don't have dependencies)
2374 */
2375 int
ipAddressTable_check_dependencies(ipAddressTable_rowreq_ctx * rowreq_ctx)2376 ipAddressTable_check_dependencies(ipAddressTable_rowreq_ctx * rowreq_ctx)
2377 {
2378 int rc = MFD_SUCCESS;
2379
2380 DEBUGMSGTL(("internal:ipAddressTable:ipAddressTable_check_dependencies", "called\n"));
2381
2382 netsnmp_assert(NULL != rowreq_ctx);
2383
2384 /*
2385 * TODO:470:o: Check ipAddressTable row dependencies.
2386 * check that all new value are legal and consistent with each other
2387 */
2388 /*
2389 * check RowStatus dependencies
2390 */
2391 if (rowreq_ctx->column_set_flags & COLUMN_IPADDRESSROWSTATUS_FLAG) {
2392 /*
2393 * row creation requirements
2394 */
2395 if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
2396 if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
2397 rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
2398 } else if (ROWSTATUS_CREATEANDGO ==
2399 rowreq_ctx->ipAddressRowStatus) {
2400 if ((rowreq_ctx->
2401 column_set_flags & IPADDRESSTABLE_REQUIRED_COLS)
2402 != IPADDRESSTABLE_REQUIRED_COLS) {
2403 DEBUGMSGTL(("ipAddressTable",
2404 "required columns missing (0x%0x != 0x%0x)\n",
2405 rowreq_ctx->column_set_flags,
2406 IPADDRESSTABLE_REQUIRED_COLS));
2407 return MFD_CANNOT_CREATE_NOW;
2408 }
2409 rowreq_ctx->ipAddressRowStatus = ROWSTATUS_ACTIVE;
2410 }
2411 } /* row creation */
2412 else {
2413 /*
2414 * row change requirements
2415 */
2416 /*
2417 * don't allow a destroy if any other value was changed, since
2418 * that might call data access routines with bad info.
2419 *
2420 * you may or may not require the row be notInService before it
2421 * can be destroyed.
2422 */
2423 if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
2424 if (rowreq_ctx->
2425 column_set_flags & ~COLUMN_IPADDRESSROWSTATUS_FLAG) {
2426 DEBUGMSGTL(("ipAddressTable",
2427 "destroy must be only varbind for row\n"));
2428 return MFD_NOT_VALID_NOW;
2429 }
2430 rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
2431
2432 } /* row destroy */
2433 } /* row change */
2434 } else {
2435 /*
2436 * must have row status to create a row
2437 */
2438 if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
2439 DEBUGMSGTL(("ipAddressTable",
2440 "must use RowStatus to create rows\n"));
2441 return MFD_CANNOT_CREATE_NOW;
2442 }
2443 } /* row status not set */
2444
2445 return rc;
2446 } /* ipAddressTable_check_dependencies */
2447
2448 /** @} */
2449 /** @{ */
2450