1 /*
2 *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
3 *
4 *All right reserved
5 *
6 *File Name: expObjectTable.c
7 *File Description: expObjectTable MIB operation.
8 *
9 *Current Version:1.0
10 *Author:JianShun Tong
11 *Date:2004.8.20
12 */
13
14
15 /*
16 * This file was generated by mib2c and is intended for use as
17 * a mib module for the ucd-snmp snmpd agent.
18 */
19
20
21 /*
22 * This should always be included first before anything else
23 */
24 #include <net-snmp/net-snmp-config.h>
25 #include <net-snmp/net-snmp-features.h>
26 #if HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #if HAVE_STRING_H
30 #include <string.h>
31 #else
32 #include <strings.h>
33 #endif
34 #ifdef HAVE_LIMITS_H
35 #include <limits.h>
36 #endif
37
38 #ifndef NETSNMP_NO_WRITE_SUPPORT
39 netsnmp_feature_require(header_complex_find_entry);
40 #endif /* NETSNMP_NO_WRITE_SUPPORT */
41
42 /*
43 * minimal include directives
44 */
45 #include <net-snmp/net-snmp-includes.h>
46 #include <net-snmp/agent/net-snmp-agent-includes.h>
47
48 #include "header_complex.h"
49 #include "expExpressionTable.h"
50 #include "expObjectTable.h"
51
52
53 /*
54 * expObjectTable_variables_oid:
55 * this is the top level oid that we want to register under. This
56 * is essentially a prefix, with the suffix appearing in the
57 * variable below.
58 */
59 oid TimeInstance[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
60
61 oid expObjectTable_variables_oid[] =
62 { 1, 3, 6, 1, 2, 1, 90, 1, 2, 3 };
63
64 /*
65 * variable2 expObjectTable_variables:
66 */
67
68 struct variable2 expObjectTable_variables[] = {
69 /*
70 * magic number , variable type , ro/rw , callback fn , L, oidsuffix
71 */
72 #define EXPOBJECTID 2
73 {EXPOBJECTID, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
74 var_expObjectTable, 2, {1, 2}},
75 #define EXPOBJECTIDWILDCARD 3
76 {EXPOBJECTIDWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
77 var_expObjectTable, 2, {1, 3}},
78 #define EXPOBJECTSAMPLETYPE 4
79 {EXPOBJECTSAMPLETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
80 var_expObjectTable, 2, {1, 4}},
81 #define EXPOBJECTDELTADISCONTINUITYID 5
82 {EXPOBJECTDELTADISCONTINUITYID, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
83 var_expObjectTable, 2, {1, 5}},
84 #define EXPOBJECTDISCONTINUITYIDWILDCARD 6
85 {EXPOBJECTDISCONTINUITYIDWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
86 var_expObjectTable, 2, {1, 6}},
87 #define EXPOBJECTDISCONTINUITYIDTYPE 7
88 {EXPOBJECTDISCONTINUITYIDTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
89 var_expObjectTable, 2, {1, 7}},
90 #define EXPOBJECTCONDITIONAL 8
91 {EXPOBJECTCONDITIONAL, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
92 var_expObjectTable, 2, {1, 8}},
93 #define EXPOBJECTCONDITIONALWILDCARD 9
94 {EXPOBJECTCONDITIONALWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
95 var_expObjectTable, 2, {1, 9}},
96 #define EXPOBJECTENTRYSTATUS 10
97 {EXPOBJECTENTRYSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
98 var_expObjectTable, 2, {1, 10}}
99 };
100
101
102 struct header_complex_index *expObjectTableStorage = NULL;
103
104 /*
105 * init_expObjectTable():
106 * Initialization routine. This is called when the agent starts up.
107 * At a minimum, registration of your variables should take place here.
108 */
109 void
init_expObjectTable(void)110 init_expObjectTable(void)
111 {
112 DEBUGMSGTL(("expObjectTable", "initializing... "));
113
114
115 /*
116 * register ourselves with the agent to handle our mib tree
117 */
118 REGISTER_MIB("expObjectTable",
119 expObjectTable_variables, variable2,
120 expObjectTable_variables_oid);
121
122 /*
123 * register our config handler(s) to deal with registrations
124 */
125 snmpd_register_config_handler("expObjectTable", parse_expObjectTable,
126 NULL, NULL);
127
128 snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
129 store_expObjectTable, NULL);
130
131 DEBUGMSGTL(("expObjectTable", "done.\n"));
132 }
133
134
135 struct expObjectTable_data *
create_expObjectTable_data(void)136 create_expObjectTable_data(void)
137 {
138 struct expObjectTable_data *StorageNew;
139
140 StorageNew = SNMP_MALLOC_STRUCT(expObjectTable_data);
141
142 /*
143 * fill in default row values here into StorageNew
144 */
145 /*
146 * fill in values for all tables (even if not
147 * appropriate), since its easier to do here than anywhere
148 * else
149 */
150
151 StorageNew->expObjectIDWildcard = EXPOBJCETIDWILDCARD_FALSE;
152 StorageNew->expObjectSampleType = EXPOBJCETSAMPLETYPE_ABSOLUTEVALUE;
153 StorageNew->expObjectDeltaDiscontinuityID =
154 netsnmp_memdup(TimeInstance, sizeof(TimeInstance));
155 StorageNew->expObjectDeltaDiscontinuityIDLen =
156 sizeof(TimeInstance) / sizeof(oid);
157
158
159
160
161 StorageNew->expObjectDiscontinuityIDWildcard =
162 EXPOBJCETDISCONTINUITYIDWILDCARD_FALSE;
163 StorageNew->expObjectDiscontinuityIDType =
164 EXPOBJECTDISCONTINUITYIDTYPE_TIMETICKS;
165
166 StorageNew->expObjectConditional = calloc(1, sizeof(oid) * 2); /* 0.0 */
167 StorageNew->expObjectConditionalLen = 2;
168
169 StorageNew->expObjectID = calloc(1, sizeof(oid) * 2); /* 0.0 */
170 StorageNew->expObjectIDLen = 2;
171
172 StorageNew->expObjectConditionalWildcard =
173 EXPOBJECTCONDITIONALWILDCARD_FALSE;
174 StorageNew->storageType = ST_NONVOLATILE;
175
176 return StorageNew;
177 }
178
179 int
expObjectTable_add(struct expObjectTable_data * thedata)180 expObjectTable_add(struct expObjectTable_data *thedata)
181 {
182 netsnmp_variable_list *vars = NULL;
183
184
185 DEBUGMSGTL(("expObjectTable", "adding data... "));
186 /*
187 * add the index variables to the varbind list, which is
188 * used by header_complex to index the data
189 */
190
191
192 snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen); /* expExpressionOwner */
193 snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen); /* expExpressionName */
194 snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, (char *) &thedata->expObjectIndex, sizeof(thedata->expObjectIndex)); /* expExpressionName */
195
196
197
198
199 header_complex_add_data(&expObjectTableStorage, vars, thedata);
200 DEBUGMSGTL(("expObjectTable", "registered an entry\n"));
201
202
203 DEBUGMSGTL(("expObjectTable", "done.\n"));
204 return SNMPERR_SUCCESS;
205 }
206
207
208
209 /*
210 * parse_mteTriggerTable():
211 * parses .conf file entries needed to configure the mib.
212 */
213 void
parse_expObjectTable(const char * token,char * line)214 parse_expObjectTable(const char *token, char *line)
215 {
216 size_t tmpint;
217 struct expObjectTable_data *StorageTmp =
218 SNMP_MALLOC_STRUCT(expObjectTable_data);
219
220 DEBUGMSGTL(("expObjectTable", "parsing config... "));
221
222 if (StorageTmp == NULL) {
223 config_perror("malloc failure");
224 return;
225 }
226
227 line =
228 read_config_read_data(ASN_OCTET_STR, line,
229 &StorageTmp->expExpressionOwner,
230 &StorageTmp->expExpressionOwnerLen);
231 if (StorageTmp->expExpressionOwner == NULL) {
232 config_perror("invalid specification for expExpressionOwner");
233 return;
234 }
235
236 line =
237 read_config_read_data(ASN_OCTET_STR, line,
238 &StorageTmp->expExpressionName,
239 &StorageTmp->expExpressionNameLen);
240 if (StorageTmp->expExpressionName == NULL) {
241 config_perror("invalid specification for expExpressionName");
242 return;
243 }
244
245 line =
246 read_config_read_data(ASN_UNSIGNED, line,
247 &StorageTmp->expObjectIndex, &tmpint);
248
249 line =
250 read_config_read_data(ASN_OBJECT_ID, line,
251 &StorageTmp->expObjectID,
252 &StorageTmp->expObjectIDLen);
253 if (StorageTmp->expObjectID == NULL) {
254 config_perror("invalid specification for expObjectID");
255 return;
256 }
257
258 line =
259 read_config_read_data(ASN_INTEGER, line,
260 &StorageTmp->expObjectIDWildcard, &tmpint);
261
262 line =
263 read_config_read_data(ASN_INTEGER, line,
264 &StorageTmp->expObjectSampleType, &tmpint);
265
266 line =
267 read_config_read_data(ASN_OBJECT_ID, line,
268 &StorageTmp->expObjectDeltaDiscontinuityID,
269 &StorageTmp->
270 expObjectDeltaDiscontinuityIDLen);
271 if (StorageTmp->expObjectDeltaDiscontinuityID == NULL) {
272 config_perror
273 ("invalid specification for expObjectDeltaDiscontinuityID");
274 return;
275 }
276
277 line =
278 read_config_read_data(ASN_INTEGER, line,
279 &StorageTmp->
280 expObjectDiscontinuityIDWildcard, &tmpint);
281
282 line =
283 read_config_read_data(ASN_INTEGER, line,
284 &StorageTmp->expObjectDiscontinuityIDType,
285 &tmpint);
286
287 line =
288 read_config_read_data(ASN_OBJECT_ID, line,
289 &StorageTmp->expObjectConditional,
290 &StorageTmp->expObjectConditionalLen);
291 if (StorageTmp->expObjectConditional == NULL) {
292 config_perror("invalid specification for expObjectConditional");
293 return;
294 }
295
296 line =
297 read_config_read_data(ASN_INTEGER, line,
298 &StorageTmp->expObjectConditionalWildcard,
299 &tmpint);
300
301 line =
302 read_config_read_data(ASN_INTEGER, line,
303 &StorageTmp->expObjectEntryStatus, &tmpint);
304
305 StorageTmp->storageType = ST_NONVOLATILE;
306 expObjectTable_add(StorageTmp);
307
308 DEBUGMSGTL(("expObjectTable", "done.\n"));
309
310 }
311
312
313
314 /*
315 * store_expExpressionTable():
316 * stores .conf file entries needed to configure the mib.
317 */
318 int
store_expObjectTable(int majorID,int minorID,void * serverarg,void * clientarg)319 store_expObjectTable(int majorID, int minorID, void *serverarg,
320 void *clientarg)
321 {
322 char line[SNMP_MAXBUF];
323 char *cptr;
324 size_t tmpint;
325 struct expObjectTable_data *StorageTmp;
326 struct header_complex_index *hcindex;
327
328 DEBUGMSGTL(("expObjectTable", "storing data... "));
329
330 for (hcindex = expObjectTableStorage; hcindex != NULL;
331 hcindex = hcindex->next) {
332 StorageTmp = (struct expObjectTable_data *) hcindex->data;
333
334
335
336 if (StorageTmp->storageType == ST_NONVOLATILE) {
337
338 memset(line, 0, sizeof(line));
339 strcat(line, "expObjectTable ");
340 cptr = line + strlen(line);
341 /*
342 * expObjectTable
343 */
344
345 cptr =
346 read_config_store_data(ASN_OCTET_STR, cptr,
347 &StorageTmp->expExpressionOwner,
348 &StorageTmp->expExpressionOwnerLen);
349 cptr =
350 read_config_store_data(ASN_OCTET_STR, cptr,
351 &StorageTmp->expExpressionName,
352 &StorageTmp->expExpressionNameLen);
353 cptr =
354 read_config_store_data(ASN_UNSIGNED, cptr,
355 &StorageTmp->expObjectIndex,
356 &tmpint);
357 cptr =
358 read_config_store_data(ASN_OBJECT_ID, cptr,
359 &StorageTmp->expObjectID,
360 &StorageTmp->expObjectIDLen);
361 cptr =
362 read_config_store_data(ASN_INTEGER, cptr,
363 &StorageTmp->expObjectIDWildcard,
364 &tmpint);
365 cptr =
366 read_config_store_data(ASN_INTEGER, cptr,
367 &StorageTmp->expObjectSampleType,
368 &tmpint);
369 cptr =
370 read_config_store_data(ASN_OBJECT_ID, cptr,
371 &StorageTmp->
372 expObjectDeltaDiscontinuityID,
373 &StorageTmp->
374 expObjectDeltaDiscontinuityIDLen);
375 cptr =
376 read_config_store_data(ASN_INTEGER, cptr,
377 &StorageTmp->
378 expObjectDiscontinuityIDWildcard,
379 &tmpint);
380 cptr =
381 read_config_store_data(ASN_INTEGER, cptr,
382 &StorageTmp->
383 expObjectDiscontinuityIDType,
384 &tmpint);
385 cptr =
386 read_config_store_data(ASN_OBJECT_ID, cptr,
387 &StorageTmp->expObjectConditional,
388 &StorageTmp->
389 expObjectConditionalLen);
390 cptr =
391 read_config_store_data(ASN_INTEGER, cptr,
392 &StorageTmp->
393 expObjectConditionalWildcard,
394 &tmpint);
395 cptr =
396 read_config_store_data(ASN_INTEGER, cptr,
397 &StorageTmp->expObjectEntryStatus,
398 &tmpint);
399 snmpd_store_config(line);
400 }
401 }
402 DEBUGMSGTL(("expObjectTable", "storage done\n"));
403 return 0;
404 }
405
406
407 /*
408 * var_expObjectTable():
409 * Handle this table separately from the scalar value case.
410 * The workings of this are basically the same as for var_expObjectTable above.
411 */
412 unsigned char *
var_expObjectTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)413 var_expObjectTable(struct variable *vp,
414 oid * name,
415 size_t *length,
416 int exact, size_t *var_len, WriteMethod ** write_method)
417 {
418 struct expObjectTable_data *StorageTmp = NULL;
419
420
421 DEBUGMSGTL(("expObjectTable", "var_expObjectTable: Entering... \n"));
422 /*
423 * this assumes you have registered all your data properly
424 */
425 if ((StorageTmp =
426 header_complex(expObjectTableStorage, vp, name, length, exact,
427 var_len, write_method)) == NULL) {
428 if (vp->magic == EXPOBJECTENTRYSTATUS)
429 *write_method = write_expObjectEntryStatus;
430 return NULL;
431 }
432 /*
433 * this is where we do the value assignments for the mib results.
434 */
435 switch (vp->magic) {
436
437 case EXPOBJECTID:
438 *write_method = write_expObjectID;
439 *var_len = StorageTmp->expObjectIDLen * sizeof(oid);
440 return (u_char *) StorageTmp->expObjectID;
441
442 case EXPOBJECTIDWILDCARD:
443 *write_method = write_expObjectIDWildcard;
444 *var_len = sizeof(StorageTmp->expObjectIDWildcard);
445 return (u_char *) & StorageTmp->expObjectIDWildcard;
446
447 case EXPOBJECTSAMPLETYPE:
448 *write_method = write_expObjectSampleType;
449 *var_len = sizeof(StorageTmp->expObjectSampleType);
450 return (u_char *) & StorageTmp->expObjectSampleType;
451
452 case EXPOBJECTDELTADISCONTINUITYID:
453 *write_method = write_expObjectDeltaDiscontinuityID;
454 *var_len =
455 StorageTmp->expObjectDeltaDiscontinuityIDLen * sizeof(oid);
456 return (u_char *) StorageTmp->expObjectDeltaDiscontinuityID;
457
458 case EXPOBJECTDISCONTINUITYIDWILDCARD:
459 *write_method = write_expObjectDiscontinuityIDWildcard;
460 *var_len = sizeof(StorageTmp->expObjectDiscontinuityIDWildcard);
461 return (u_char *) & StorageTmp->expObjectDiscontinuityIDWildcard;
462
463 case EXPOBJECTDISCONTINUITYIDTYPE:
464 *write_method = write_expObjectDiscontinuityIDWildcard;
465 *var_len = sizeof(StorageTmp->expObjectDiscontinuityIDType);
466 return (u_char *) & StorageTmp->expObjectDiscontinuityIDType;
467
468 case EXPOBJECTCONDITIONAL:
469 *write_method = write_expObjectConditional;
470 *var_len = StorageTmp->expObjectConditionalLen * sizeof(oid);
471 return (u_char *) StorageTmp->expObjectConditional;
472
473 case EXPOBJECTCONDITIONALWILDCARD:
474 *write_method = write_expObjectConditionalWildcard;
475 *var_len = sizeof(StorageTmp->expObjectConditionalWildcard);
476 return (u_char *) & StorageTmp->expObjectConditionalWildcard;
477
478 case EXPOBJECTENTRYSTATUS:
479 *write_method = write_expObjectEntryStatus;
480 *var_len = sizeof(StorageTmp->expObjectEntryStatus);
481 return (u_char *) & StorageTmp->expObjectEntryStatus;
482
483
484 default:
485 ERROR_MSG("");
486 }
487 return NULL;
488 }
489
490 int
write_expObjectID(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)491 write_expObjectID(int action,
492 u_char * var_val,
493 u_char var_val_type,
494 size_t var_val_len,
495 u_char * statP, oid * name, size_t name_len)
496 {
497 static oid *tmpvar;
498 struct expObjectTable_data *StorageTmp = NULL;
499 static size_t tmplen;
500 size_t newlen =
501 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
502 3 - 1);
503
504
505 DEBUGMSGTL(("expObjectTable",
506 "write_expObjectID entering action=%d... \n", action));
507 if ((StorageTmp =
508 header_complex(expObjectTableStorage, NULL,
509 &name[sizeof(expObjectTable_variables_oid) /
510 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
511 NULL)) == NULL)
512 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
513
514
515 switch (action) {
516 case RESERVE1:
517 if (var_val_type != ASN_OBJECT_ID) {
518 snmp_log(LOG_ERR, "write to expObjectID not ASN_OBJECT_ID\n");
519 return SNMP_ERR_WRONGTYPE;
520 }
521 if (StorageTmp->storageType != ST_NONVOLATILE)
522 return SNMP_ERR_NOTWRITABLE;
523 break;
524
525
526 case RESERVE2:
527 /*
528 * memory reseveration, final preparation...
529 */
530 break;
531
532
533 case FREE:
534 /*
535 * Release any resources that have been allocated
536 */
537 break;
538
539
540 case ACTION:
541 /*
542 * The variable has been stored in objid for
543 * you to use, and you have just been asked to do something with
544 * it. Note that anything done here must be reversable in the UNDO case
545 */
546 tmpvar = StorageTmp->expObjectID;
547 tmplen = StorageTmp->expObjectIDLen;
548 StorageTmp->expObjectID = netsnmp_memdup(var_val, var_val_len);
549 StorageTmp->expObjectIDLen = var_val_len / sizeof(oid);
550 break;
551
552
553 case UNDO:
554 /*
555 * Back out any changes made in the ACTION case
556 */
557 SNMP_FREE(StorageTmp->expObjectID);
558 StorageTmp->expObjectID = tmpvar;
559 StorageTmp->expObjectIDLen = tmplen;
560 break;
561
562
563 case COMMIT:
564 /*
565 * Things are working well, so it's now safe to make the change
566 * permanently. Make sure that anything done here can't fail!
567 */
568
569 /*
570 * XXX: if the valueID has actually changed, shouldn't we dump any
571 * previous values, as these are from a different object?
572 */
573 SNMP_FREE(tmpvar);
574 snmp_store_needed(NULL);
575 break;
576 }
577 return SNMP_ERR_NOERROR;
578 }
579
580 int
write_expObjectIDWildcard(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)581 write_expObjectIDWildcard(int action,
582 u_char * var_val,
583 u_char var_val_type,
584 size_t var_val_len,
585 u_char * statP, oid * name, size_t name_len)
586 {
587 static int tmpvar;
588 struct expObjectTable_data *StorageTmp = NULL;
589 size_t newlen =
590 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
591 3 - 1);
592
593
594 DEBUGMSGTL(("expObjectTable",
595 "write_expObjectIDWildcard entering action=%d... \n",
596 action));
597 if ((StorageTmp =
598 header_complex(expObjectTableStorage, NULL,
599 &name[sizeof(expObjectTable_variables_oid) /
600 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
601 NULL)) == NULL)
602 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
603
604
605 switch (action) {
606 case RESERVE1:
607 if (var_val_type != ASN_INTEGER) {
608 snmp_log(LOG_ERR,
609 "write to expObjectIDWildcard not ASN_INTEGER\n");
610 return SNMP_ERR_WRONGTYPE;
611 }
612 if (StorageTmp->storageType != ST_NONVOLATILE)
613 return SNMP_ERR_NOTWRITABLE;
614 break;
615
616
617 case RESERVE2:
618 /*
619 * memory reseveration, final preparation...
620 */
621 break;
622
623
624 case FREE:
625 /*
626 * Release any resources that have been allocated
627 */
628 break;
629
630
631 case ACTION:
632 /*
633 * The variable has been stored in long_ret for
634 * you to use, and you have just been asked to do something with
635 * it. Note that anything done here must be reversable in the UNDO case
636 */
637 tmpvar = StorageTmp->expObjectIDWildcard;
638 StorageTmp->expObjectIDWildcard = *((long *) var_val);
639 break;
640
641
642 case UNDO:
643 /*
644 * Back out any changes made in the ACTION case
645 */
646 StorageTmp->expObjectIDWildcard = tmpvar;
647 break;
648
649
650 case COMMIT:
651 /*
652 * Things are working well, so it's now safe to make the change
653 * permanently. Make sure that anything done here can't fail!
654 */
655 snmp_store_needed(NULL);
656 break;
657 }
658 return SNMP_ERR_NOERROR;
659 }
660
661
662 int
write_expObjectSampleType(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)663 write_expObjectSampleType(int action,
664 u_char * var_val,
665 u_char var_val_type,
666 size_t var_val_len,
667 u_char * statP, oid * name, size_t name_len)
668 {
669 static int tmpvar;
670 struct expObjectTable_data *StorageTmp = NULL;
671 size_t newlen =
672 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
673 3 - 1);
674
675
676 DEBUGMSGTL(("expObjectTable",
677 "write_expObjectSampleType entering action=%d... \n",
678 action));
679 if ((StorageTmp =
680 header_complex(expObjectTableStorage, NULL,
681 &name[sizeof(expObjectTable_variables_oid) /
682 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
683 NULL)) == NULL)
684 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
685
686
687 switch (action) {
688 case RESERVE1:
689 if (var_val_type != ASN_INTEGER) {
690 snmp_log(LOG_ERR,
691 "write to expObjectSampleTypenot ASN_INTEGER\n");
692 return SNMP_ERR_WRONGTYPE;
693 }
694 if (StorageTmp->storageType != ST_NONVOLATILE)
695 return SNMP_ERR_NOTWRITABLE;
696 break;
697
698
699 case RESERVE2:
700 /*
701 * memory reseveration, final preparation...
702 */
703 break;
704
705
706 case FREE:
707 /*
708 * Release any resources that have been allocated
709 */
710 break;
711
712
713 case ACTION:
714 /*
715 * The variable has been stored in long_ret for
716 * you to use, and you have just been asked to do something with
717 * it. Note that anything done here must be reversable in the UNDO case
718 */
719 tmpvar = StorageTmp->expObjectSampleType;
720 StorageTmp->expObjectSampleType = *((long *) var_val);
721 break;
722
723
724 case UNDO:
725 /*
726 * Back out any changes made in the ACTION case
727 */
728 StorageTmp->expObjectSampleType = tmpvar;
729 break;
730
731
732 case COMMIT:
733 /*
734 * Things are working well, so it's now safe to make the change
735 * permanently. Make sure that anything done here can't fail!
736 */
737 snmp_store_needed(NULL);
738 break;
739 }
740 return SNMP_ERR_NOERROR;
741 }
742
743
744
745 int
write_expObjectDeltaDiscontinuityID(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)746 write_expObjectDeltaDiscontinuityID(int action,
747 u_char * var_val,
748 u_char var_val_type,
749 size_t var_val_len,
750 u_char * statP, oid * name,
751 size_t name_len)
752 {
753 static oid *tmpvar;
754 struct expObjectTable_data *StorageTmp = NULL;
755 static size_t tmplen;
756 size_t newlen =
757 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
758 3 - 1);
759
760
761 DEBUGMSGTL(("expObjectTable",
762 "write_expObjectDeltaDiscontinuityID entering action=%d... \n",
763 action));
764 if ((StorageTmp =
765 header_complex(expObjectTableStorage, NULL,
766 &name[sizeof(expObjectTable_variables_oid) /
767 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
768 NULL)) == NULL)
769 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
770
771
772 switch (action) {
773 case RESERVE1:
774 if (var_val_type != ASN_OBJECT_ID) {
775 snmp_log(LOG_ERR,
776 "write to expObjectDeltaDiscontinuityID not ASN_OBJECT_ID\n");
777 return SNMP_ERR_WRONGTYPE;
778 }
779 if (StorageTmp->storageType != ST_NONVOLATILE)
780 return SNMP_ERR_NOTWRITABLE;
781 break;
782
783
784 case RESERVE2:
785 /*
786 * memory reseveration, final preparation...
787 */
788 break;
789
790
791 case FREE:
792 /*
793 * Release any resources that have been allocated
794 */
795 break;
796
797
798 case ACTION:
799 /*
800 * The variable has been stored in objid for
801 * you to use, and you have just been asked to do something with
802 * it. Note that anything done here must be reversable in the UNDO case
803 */
804 tmpvar = StorageTmp->expObjectDeltaDiscontinuityID;
805 tmplen = StorageTmp->expObjectDeltaDiscontinuityIDLen;
806 StorageTmp->expObjectDeltaDiscontinuityID =
807 netsnmp_memdup(var_val, var_val_len);
808 StorageTmp->expObjectDeltaDiscontinuityIDLen =
809 var_val_len / sizeof(oid);
810 break;
811
812
813 case UNDO:
814 /*
815 * Back out any changes made in the ACTION case
816 */
817 SNMP_FREE(StorageTmp->expObjectDeltaDiscontinuityID);
818 StorageTmp->expObjectDeltaDiscontinuityID = tmpvar;
819 StorageTmp->expObjectDeltaDiscontinuityIDLen = tmplen;
820 break;
821
822
823 case COMMIT:
824 /*
825 * Things are working well, so it's now safe to make the change
826 * permanently. Make sure that anything done here can't fail!
827 */
828
829 /*
830 * XXX: if the valueID has actually changed, shouldn't we dump any
831 * previous values, as these are from a different object?
832 */
833 SNMP_FREE(tmpvar);
834 snmp_store_needed(NULL);
835 break;
836 }
837 return SNMP_ERR_NOERROR;
838 }
839
840
841
842 int
write_expObjectDiscontinuityIDWildcard(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)843 write_expObjectDiscontinuityIDWildcard(int action,
844 u_char * var_val,
845 u_char var_val_type,
846 size_t var_val_len,
847 u_char * statP,
848 oid * name, size_t name_len)
849 {
850 static int tmpvar;
851 struct expObjectTable_data *StorageTmp = NULL;
852 size_t newlen =
853 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
854 3 - 1);
855
856
857 DEBUGMSGTL(("expObjectTable",
858 "write_expObjectDiscontinuityIDWildcard entering action=%d... \n",
859 action));
860 if ((StorageTmp =
861 header_complex(expObjectTableStorage, NULL,
862 &name[sizeof(expObjectTable_variables_oid) /
863 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
864 NULL)) == NULL)
865 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
866
867
868 switch (action) {
869 case RESERVE1:
870 if (var_val_type != ASN_INTEGER) {
871 snmp_log(LOG_ERR,
872 "write to expObjectDiscontinuityIDWildcard not ASN_INTEGER\n");
873 return SNMP_ERR_WRONGTYPE;
874 }
875 if (StorageTmp->storageType != ST_NONVOLATILE)
876 return SNMP_ERR_NOTWRITABLE;
877 break;
878
879
880 case RESERVE2:
881 /*
882 * memory reseveration, final preparation...
883 */
884 break;
885
886
887 case FREE:
888 /*
889 * Release any resources that have been allocated
890 */
891 break;
892
893
894 case ACTION:
895 /*
896 * The variable has been stored in long_ret for
897 * you to use, and you have just been asked to do something with
898 * it. Note that anything done here must be reversable in the UNDO case
899 */
900 tmpvar = StorageTmp->expObjectDiscontinuityIDWildcard;
901 StorageTmp->expObjectDiscontinuityIDWildcard = *((long *) var_val);
902 break;
903
904
905 case UNDO:
906 /*
907 * Back out any changes made in the ACTION case
908 */
909 StorageTmp->expObjectDiscontinuityIDWildcard = tmpvar;
910 break;
911
912
913 case COMMIT:
914 /*
915 * Things are working well, so it's now safe to make the change
916 * permanently. Make sure that anything done here can't fail!
917 */
918 snmp_store_needed(NULL);
919 break;
920 }
921 return SNMP_ERR_NOERROR;
922 }
923
924
925
926 int
write_expObjectDiscontinuityIDType(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)927 write_expObjectDiscontinuityIDType(int action,
928 u_char * var_val,
929 u_char var_val_type,
930 size_t var_val_len,
931 u_char * statP,
932 oid * name, size_t name_len)
933 {
934 static int tmpvar;
935 struct expObjectTable_data *StorageTmp = NULL;
936 size_t newlen =
937 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
938 3 - 1);
939
940
941 DEBUGMSGTL(("expObjectTable",
942 "write_expObjectDiscontinuityIDWildcard entering action=%d... \n",
943 action));
944 if ((StorageTmp =
945 header_complex(expObjectTableStorage, NULL,
946 &name[sizeof(expObjectTable_variables_oid) /
947 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
948 NULL)) == NULL)
949 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
950
951
952 switch (action) {
953 case RESERVE1:
954 if (var_val_type != ASN_INTEGER) {
955 snmp_log(LOG_ERR,
956 "write to expObjectDiscontinuityIDType not ASN_INTEGER\n");
957 return SNMP_ERR_WRONGTYPE;
958 }
959 if (StorageTmp->storageType != ST_NONVOLATILE)
960 return SNMP_ERR_NOTWRITABLE;
961 break;
962
963
964 case RESERVE2:
965 /*
966 * memory reseveration, final preparation...
967 */
968 break;
969
970
971 case FREE:
972 /*
973 * Release any resources that have been allocated
974 */
975 break;
976
977
978 case ACTION:
979 /*
980 * The variable has been stored in long_ret for
981 * you to use, and you have just been asked to do something with
982 * it. Note that anything done here must be reversable in the UNDO case
983 */
984 tmpvar = StorageTmp->expObjectDiscontinuityIDType;
985 StorageTmp->expObjectDiscontinuityIDType = *((long *) var_val);
986 break;
987
988
989 case UNDO:
990 /*
991 * Back out any changes made in the ACTION case
992 */
993 StorageTmp->expObjectDiscontinuityIDType = tmpvar;
994 break;
995
996
997 case COMMIT:
998 /*
999 * Things are working well, so it's now safe to make the change
1000 * permanently. Make sure that anything done here can't fail!
1001 */
1002 snmp_store_needed(NULL);
1003 break;
1004 }
1005 return SNMP_ERR_NOERROR;
1006 }
1007
1008
1009
1010 int
write_expObjectConditional(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)1011 write_expObjectConditional(int action,
1012 u_char * var_val,
1013 u_char var_val_type,
1014 size_t var_val_len,
1015 u_char * statP, oid * name, size_t name_len)
1016 {
1017 static oid *tmpvar;
1018 struct expObjectTable_data *StorageTmp = NULL;
1019 static size_t tmplen;
1020 size_t newlen =
1021 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1022 3 - 1);
1023
1024
1025 DEBUGMSGTL(("expObjectTable",
1026 "write_expObjectConditional entering action=%d... \n",
1027 action));
1028 if ((StorageTmp =
1029 header_complex(expObjectTableStorage, NULL,
1030 &name[sizeof(expObjectTable_variables_oid) /
1031 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
1032 NULL)) == NULL)
1033 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
1034
1035
1036 switch (action) {
1037 case RESERVE1:
1038 if (var_val_type != ASN_OBJECT_ID) {
1039 snmp_log(LOG_ERR,
1040 "write to expObjectConditional not ASN_OBJECT_ID\n");
1041 return SNMP_ERR_WRONGTYPE;
1042 }
1043 if (StorageTmp->storageType != ST_NONVOLATILE)
1044 return SNMP_ERR_NOTWRITABLE;
1045 break;
1046
1047
1048 case RESERVE2:
1049 /*
1050 * memory reseveration, final preparation...
1051 */
1052 break;
1053
1054
1055 case FREE:
1056 /*
1057 * Release any resources that have been allocated
1058 */
1059 break;
1060
1061
1062 case ACTION:
1063 /*
1064 * The variable has been stored in objid for
1065 * you to use, and you have just been asked to do something with
1066 * it. Note that anything done here must be reversable in the UNDO case
1067 */
1068 tmpvar = StorageTmp->expObjectConditional;
1069 tmplen = StorageTmp->expObjectConditionalLen;
1070 StorageTmp->expObjectConditional = netsnmp_memdup(var_val, var_val_len);
1071 StorageTmp->expObjectConditionalLen = var_val_len / sizeof(oid);
1072 break;
1073
1074
1075 case UNDO:
1076 /*
1077 * Back out any changes made in the ACTION case
1078 */
1079 SNMP_FREE(StorageTmp->expObjectConditional);
1080 StorageTmp->expObjectConditional = tmpvar;
1081 StorageTmp->expObjectConditionalLen = tmplen;
1082 break;
1083
1084
1085 case COMMIT:
1086 /*
1087 * Things are working well, so it's now safe to make the change
1088 * permanently. Make sure that anything done here can't fail!
1089 */
1090
1091 /*
1092 * XXX: if the valueID has actually changed, shouldn't we dump any
1093 * previous values, as these are from a different object?
1094 */
1095 SNMP_FREE(tmpvar);
1096 snmp_store_needed(NULL);
1097 break;
1098 }
1099 return SNMP_ERR_NOERROR;
1100 }
1101
1102
1103
1104
1105 int
write_expObjectConditionalWildcard(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)1106 write_expObjectConditionalWildcard(int action,
1107 u_char * var_val,
1108 u_char var_val_type,
1109 size_t var_val_len,
1110 u_char * statP,
1111 oid * name, size_t name_len)
1112 {
1113 static int tmpvar;
1114 struct expObjectTable_data *StorageTmp = NULL;
1115 size_t newlen =
1116 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1117 3 - 1);
1118
1119
1120 DEBUGMSGTL(("expObjectTable",
1121 "write_expObjectConditionalWildcard entering action=%d... \n",
1122 action));
1123 if ((StorageTmp =
1124 header_complex(expObjectTableStorage, NULL,
1125 &name[sizeof(expObjectTable_variables_oid) /
1126 sizeof(oid) + 3 - 1], &newlen, 1, NULL,
1127 NULL)) == NULL)
1128 return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
1129
1130
1131 switch (action) {
1132 case RESERVE1:
1133 if (var_val_type != ASN_INTEGER) {
1134 snmp_log(LOG_ERR,
1135 "write to expObjectConditionalWildcard not ASN_INTEGER\n");
1136 return SNMP_ERR_WRONGTYPE;
1137 }
1138 if (StorageTmp->storageType != ST_NONVOLATILE)
1139 return SNMP_ERR_NOTWRITABLE;
1140 break;
1141
1142
1143 case RESERVE2:
1144 /*
1145 * memory reseveration, final preparation...
1146 */
1147 break;
1148
1149
1150 case FREE:
1151 /*
1152 * Release any resources that have been allocated
1153 */
1154 break;
1155
1156
1157 case ACTION:
1158 /*
1159 * The variable has been stored in long_ret for
1160 * you to use, and you have just been asked to do something with
1161 * it. Note that anything done here must be reversable in the UNDO case
1162 */
1163 tmpvar = StorageTmp->expObjectConditionalWildcard;
1164 StorageTmp->expObjectConditionalWildcard = *((long *) var_val);
1165 break;
1166
1167
1168 case UNDO:
1169 /*
1170 * Back out any changes made in the ACTION case
1171 */
1172 StorageTmp->expObjectConditionalWildcard = tmpvar;
1173 break;
1174
1175
1176 case COMMIT:
1177 /*
1178 * Things are working well, so it's now safe to make the change
1179 * permanently. Make sure that anything done here can't fail!
1180 */
1181 snmp_store_needed(NULL);
1182 break;
1183 }
1184 return SNMP_ERR_NOERROR;
1185 }
1186
1187
1188
1189
1190 int
write_expObjectEntryStatus(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)1191 write_expObjectEntryStatus(int action,
1192 u_char * var_val,
1193 u_char var_val_type,
1194 size_t var_val_len,
1195 u_char * statP, oid * name, size_t name_len)
1196 {
1197 struct expObjectTable_data *StorageTmp = NULL;
1198 static struct expObjectTable_data *StorageNew, *StorageDel;
1199 size_t newlen =
1200 name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1201 3 - 1);
1202 static int old_value;
1203 int set_value;
1204 static netsnmp_variable_list *vars, *vp;
1205 struct header_complex_index *hciptr;
1206
1207 StorageTmp =
1208 header_complex(expObjectTableStorage, NULL,
1209 &name[sizeof(expObjectTable_variables_oid) /
1210 sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
1211
1212
1213
1214
1215 if (var_val_type != ASN_INTEGER || var_val == NULL) {
1216 snmp_log(LOG_ERR,
1217 "write to expObjectEntryStatus not ASN_INTEGER\n");
1218 return SNMP_ERR_WRONGTYPE;
1219 }
1220 set_value = *((long *) var_val);
1221
1222
1223 /*
1224 * check legal range, and notReady is reserved for us, not a user
1225 */
1226 if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
1227 return SNMP_ERR_INCONSISTENTVALUE;
1228
1229
1230 switch (action) {
1231 case RESERVE1:
1232 /*
1233 * stage one: test validity
1234 */
1235 if (StorageTmp == NULL) {
1236 /*
1237 * create the row now?
1238 */
1239
1240
1241 /*
1242 * ditch illegal values now
1243 */
1244 if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE)
1245 return SNMP_ERR_INCONSISTENTVALUE;
1246
1247
1248 /*
1249 * destroying a non-existent row is actually legal
1250 */
1251 if (set_value == RS_DESTROY) {
1252 return SNMP_ERR_NOERROR;
1253 }
1254
1255
1256 /*
1257 * illegal creation values
1258 */
1259 if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
1260 return SNMP_ERR_INCONSISTENTVALUE;
1261 }
1262 } else {
1263 /*
1264 * row exists. Check for a valid state change
1265 */
1266 if (set_value == RS_CREATEANDGO
1267 || set_value == RS_CREATEANDWAIT) {
1268 /*
1269 * can't create a row that exists
1270 */
1271 return SNMP_ERR_INCONSISTENTVALUE;
1272 }
1273
1274 if (StorageTmp->expObjectEntryStatus == RS_ACTIVE &&
1275 set_value != RS_DESTROY) {
1276 /*
1277 * "Once made active an entry may not be modified except to
1278 * delete it." XXX: doesn't this in fact apply to ALL
1279 * columns of the table and not just this one?
1280 */
1281 return SNMP_ERR_INCONSISTENTVALUE;
1282 }
1283 if (StorageTmp->storageType != ST_NONVOLATILE)
1284 return SNMP_ERR_NOTWRITABLE;
1285 }
1286 break;
1287
1288
1289
1290
1291 case RESERVE2:
1292 /*
1293 * memory reseveration, final preparation...
1294 */
1295 if (StorageTmp == NULL) {
1296 /*
1297 * creation
1298 */
1299 vars = NULL;
1300
1301
1302 snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* expExpressionOwner */
1303 snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* expExpressionName */
1304 snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0); /* expObjectIndex */
1305
1306
1307
1308 if (header_complex_parse_oid
1309 (&
1310 (name
1311 [sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1312 2]), newlen, vars) != SNMPERR_SUCCESS) {
1313 /*
1314 * XXX: free, zero vars
1315 */
1316 return SNMP_ERR_INCONSISTENTNAME;
1317 }
1318 vp = vars;
1319
1320
1321 StorageNew = create_expObjectTable_data();
1322
1323 StorageNew->expExpressionOwner = malloc(vp->val_len + 1);
1324 memcpy(StorageNew->expExpressionOwner, vp->val.string,
1325 vp->val_len);
1326 StorageNew->expExpressionOwner[vp->val_len] = '\0';
1327 StorageNew->expExpressionOwnerLen = vp->val_len;
1328
1329 vp = vp->next_variable;
1330 StorageNew->expExpressionName = malloc(vp->val_len + 1);
1331 memcpy(StorageNew->expExpressionName, vp->val.string,
1332 vp->val_len);
1333
1334 StorageNew->expExpressionName[vp->val_len] = '\0';
1335 StorageNew->expExpressionNameLen = vp->val_len;
1336
1337 vp = vp->next_variable;
1338 StorageNew->expObjectIndex = *vp->val.integer;
1339
1340 StorageNew->expObjectEntryStatus = set_value;
1341
1342 }
1343
1344
1345 break;
1346
1347
1348
1349
1350 case FREE:
1351 /*
1352 * XXX: free, zero vars
1353 */
1354 /*
1355 * Release any resources that have been allocated
1356 */
1357 break;
1358
1359
1360
1361
1362 case ACTION:
1363 /*
1364 * The variable has been stored in set_value for you to
1365 * use, and you have just been asked to do something with
1366 * it. Note that anything done here must be reversable in
1367 * the UNDO case
1368 */
1369
1370
1371 if (StorageTmp == NULL && set_value != RS_DESTROY) {
1372 /*
1373 * row creation, so add it
1374 */
1375 if (StorageNew != NULL)
1376 expObjectTable_add(StorageNew);
1377 /*
1378 * XXX: ack, and if it is NULL?
1379 */
1380 } else if (StorageTmp != NULL && set_value != RS_DESTROY) {
1381 /*
1382 * set the flag?
1383 */
1384 old_value = StorageTmp->expObjectEntryStatus;
1385 StorageTmp->expObjectEntryStatus = *((long *) var_val);
1386 } else {
1387 /*
1388 * destroy... extract it for now
1389 */
1390 hciptr =
1391 header_complex_find_entry(expObjectTableStorage,
1392 StorageTmp);
1393 StorageDel =
1394 header_complex_extract_entry(&expObjectTableStorage,
1395 hciptr);
1396 }
1397 break;
1398
1399
1400
1401
1402 case UNDO:
1403 /*
1404 * Back out any changes made in the ACTION case
1405 */
1406 if (StorageTmp == NULL) {
1407 /*
1408 * row creation, so remove it again
1409 */
1410 hciptr =
1411 header_complex_find_entry(expObjectTableStorage,
1412 StorageTmp);
1413 StorageDel =
1414 header_complex_extract_entry(&expObjectTableStorage,
1415 hciptr);
1416 /*
1417 * XXX: free it
1418 */
1419 } else if (StorageDel != NULL) {
1420 /*
1421 * row deletion, so add it again
1422 */
1423 expObjectTable_add(StorageDel);
1424 } else {
1425 StorageTmp->expObjectEntryStatus = old_value;
1426 }
1427 break;
1428
1429
1430
1431
1432 case COMMIT:
1433 /*
1434 * Things are working well, so it's now safe to make the change
1435 * permanently. Make sure that anything done here can't fail!
1436 */
1437 if (StorageDel != NULL) {
1438 StorageDel = 0;
1439 /*
1440 * XXX: free it, its dead
1441 */
1442 } else {
1443 if (StorageTmp
1444 && StorageTmp->expObjectEntryStatus == RS_CREATEANDGO) {
1445 StorageTmp->expObjectEntryStatus = RS_ACTIVE;
1446 } else if (StorageTmp &&
1447 StorageTmp->expObjectEntryStatus ==
1448 RS_CREATEANDWAIT) {
1449 StorageTmp->expObjectEntryStatus = RS_NOTINSERVICE;
1450 }
1451 }
1452 snmp_store_needed(NULL);
1453 break;
1454 }
1455 return SNMP_ERR_NOERROR;
1456 }
1457