1 /*
2 * DisMan Event MIB:
3 * Implementation of the mteTriggerBooleanTable MIB interface
4 * See 'mteTrigger.c' for active behaviour of this table.
5 *
6 * (based on mib2c.table_data.conf output)
7 */
8
9 #include <net-snmp/net-snmp-config.h>
10 #include <net-snmp/net-snmp-features.h>
11 #include <net-snmp/net-snmp-includes.h>
12 #include <net-snmp/agent/net-snmp-agent-includes.h>
13 #include "disman/event/mteTrigger.h"
14 #include "disman/event/mteTriggerBooleanTable.h"
15
16 netsnmp_feature_require(table_tdata);
17 #ifndef NETSNMP_NO_WRITE_SUPPORT
18 netsnmp_feature_require(check_vb_type_and_max_size);
19 netsnmp_feature_require(check_vb_truthvalue);
20 #endif /* NETSNMP_NO_WRITE_SUPPORT */
21
22 static netsnmp_table_registration_info *table_info;
23
24 /** Initializes the mteTriggerBooleanTable module */
25 void
init_mteTriggerBooleanTable(void)26 init_mteTriggerBooleanTable(void)
27 {
28 static oid mteTBoolTable_oid[] = { 1, 3, 6, 1, 2, 1, 88, 1, 2, 5 };
29 size_t mteTBoolTable_oid_len = OID_LENGTH(mteTBoolTable_oid);
30 netsnmp_handler_registration *reg;
31
32 /*
33 * Ensure the (combined) table container is available...
34 */
35 init_trigger_table_data();
36
37 /*
38 * ... then set up the MIB interface to the mteTriggerBooleanTable slice
39 */
40 #ifndef NETSNMP_NO_WRITE_SUPPORT
41 reg = netsnmp_create_handler_registration("mteTriggerBooleanTable",
42 mteTriggerBooleanTable_handler,
43 mteTBoolTable_oid,
44 mteTBoolTable_oid_len,
45 HANDLER_CAN_RWRITE);
46 #else /* !NETSNMP_NO_WRITE_SUPPORT */
47 reg = netsnmp_create_handler_registration("mteTriggerBooleanTable",
48 mteTriggerBooleanTable_handler,
49 mteTBoolTable_oid,
50 mteTBoolTable_oid_len,
51 HANDLER_CAN_RWRITE);
52 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
53
54 table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
55 netsnmp_table_helper_add_indexes(table_info,
56 ASN_OCTET_STR, /* index: mteOwner */
57 /* index: mteTriggerName */
58 ASN_PRIV_IMPLIED_OCTET_STR,
59 0);
60
61 table_info->min_column = COLUMN_MTETRIGGERBOOLEANCOMPARISON;
62 table_info->max_column = COLUMN_MTETRIGGERBOOLEANEVENT;
63
64 /* Register this using the (common) trigger_table_data container */
65 netsnmp_tdata_register(reg, trigger_table_data, table_info);
66 DEBUGMSGTL(("disman:event:init", "Trigger Bool Table\n"));
67 }
68
69 void
shutdown_mteTriggerBooleanTable(void)70 shutdown_mteTriggerBooleanTable(void)
71 {
72 if (table_info) {
73 netsnmp_table_registration_info_free(table_info);
74 table_info = NULL;
75 }
76 }
77
78 /** handles requests for the mteTriggerBooleanTable table */
79 int
mteTriggerBooleanTable_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)80 mteTriggerBooleanTable_handler(netsnmp_mib_handler *handler,
81 netsnmp_handler_registration *reginfo,
82 netsnmp_agent_request_info *reqinfo,
83 netsnmp_request_info *requests)
84 {
85
86 netsnmp_request_info *request;
87 netsnmp_table_request_info *tinfo;
88 struct mteTrigger *entry;
89 int ret;
90
91 DEBUGMSGTL(("disman:event:mib", "Boolean Table handler (%d)\n",
92 reqinfo->mode));
93
94 switch (reqinfo->mode) {
95 /*
96 * Read-support (also covers GetNext requests)
97 */
98 case MODE_GET:
99 for (request = requests; request; request = request->next) {
100 if (request->processed)
101 continue;
102
103 entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
104 tinfo = netsnmp_extract_table_info(request);
105
106 /*
107 * The mteTriggerBooleanTable should only contains entries for
108 * rows where the mteTriggerTest 'boolean(1)' bit is set.
109 * So skip entries where this isn't the case.
110 */
111 if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN )) {
112 netsnmp_request_set_error(request, SNMP_NOSUCHINSTANCE);
113 continue;
114 }
115
116 switch (tinfo->colnum) {
117 case COLUMN_MTETRIGGERBOOLEANCOMPARISON:
118 snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
119 entry->mteTBoolComparison);
120 break;
121 case COLUMN_MTETRIGGERBOOLEANVALUE:
122 snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
123 entry->mteTBoolValue);
124 break;
125 case COLUMN_MTETRIGGERBOOLEANSTARTUP:
126 ret = (entry->flags & MTE_TRIGGER_FLAG_BSTART ) ?
127 TV_TRUE : TV_FALSE;
128 snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret);
129 break;
130 case COLUMN_MTETRIGGERBOOLEANOBJECTSOWNER:
131 snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
132 (u_char *) entry->mteTBoolObjOwner,
133 strlen(entry->mteTBoolObjOwner));
134 break;
135 case COLUMN_MTETRIGGERBOOLEANOBJECTS:
136 snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
137 (u_char *) entry->mteTBoolObjects,
138 strlen(entry->mteTBoolObjects));
139 break;
140 case COLUMN_MTETRIGGERBOOLEANEVENTOWNER:
141 snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
142 (u_char *) entry->mteTBoolEvOwner,
143 strlen(entry->mteTBoolEvOwner));
144 break;
145 case COLUMN_MTETRIGGERBOOLEANEVENT:
146 snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
147 (u_char *) entry->mteTBoolEvent,
148 strlen(entry->mteTBoolEvent));
149 break;
150 }
151 }
152 break;
153
154 #ifndef NETSNMP_NO_WRITE_SUPPORT
155 /*
156 * Write-support
157 */
158 case MODE_SET_RESERVE1:
159 for (request = requests; request; request = request->next) {
160 if (request->processed)
161 continue;
162
163 entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
164 tinfo = netsnmp_extract_table_info(request);
165
166 /*
167 * Since the mteTriggerBooleanTable only contains entries for
168 * rows where the mteTriggerTest 'boolean(1)' bit is set,
169 * strictly speaking we should reject assignments where
170 * this isn't the case.
171 * But SET requests that include an assignment of the
172 * 'boolean(1)' bit at the same time are valid, so would
173 * need to be accepted. Unfortunately, this assignment
174 * is only applied in the COMMIT pass, so it's difficult
175 * to detect whether this holds or not.
176 *
177 * Let's fudge things for now, by processing assignments
178 * even if the 'boolean(1)' bit isn't set.
179 */
180 switch (tinfo->colnum) {
181 case COLUMN_MTETRIGGERBOOLEANCOMPARISON:
182 ret = netsnmp_check_vb_int_range(request->requestvb,
183 MTE_BOOL_UNEQUAL, MTE_BOOL_GREATEREQUAL);
184 if (ret != SNMP_ERR_NOERROR) {
185 netsnmp_set_request_error(reqinfo, request, ret);
186 return SNMP_ERR_NOERROR;
187 }
188 break;
189 case COLUMN_MTETRIGGERBOOLEANVALUE:
190 ret = netsnmp_check_vb_int(request->requestvb);
191 if (ret != SNMP_ERR_NOERROR) {
192 netsnmp_set_request_error(reqinfo, request, ret);
193 return SNMP_ERR_NOERROR;
194 }
195 break;
196 case COLUMN_MTETRIGGERBOOLEANSTARTUP:
197 ret = netsnmp_check_vb_truthvalue(request->requestvb);
198 if (ret != SNMP_ERR_NOERROR) {
199 netsnmp_set_request_error(reqinfo, request, ret);
200 return SNMP_ERR_NOERROR;
201 }
202 break;
203 case COLUMN_MTETRIGGERBOOLEANOBJECTSOWNER:
204 case COLUMN_MTETRIGGERBOOLEANOBJECTS:
205 case COLUMN_MTETRIGGERBOOLEANEVENTOWNER:
206 case COLUMN_MTETRIGGERBOOLEANEVENT:
207 ret = netsnmp_check_vb_type_and_max_size(
208 request->requestvb, ASN_OCTET_STR, MTE_STR1_LEN);
209 if (ret != SNMP_ERR_NOERROR) {
210 netsnmp_set_request_error(reqinfo, request, ret);
211 return SNMP_ERR_NOERROR;
212 }
213 break;
214 default:
215 netsnmp_set_request_error(reqinfo, request,
216 SNMP_ERR_NOTWRITABLE);
217 return SNMP_ERR_NOERROR;
218 }
219
220 /*
221 * The Event MIB is somewhat ambiguous as to whether the
222 * various trigger table entries can be modified once the
223 * main mteTriggerTable entry has been marked 'active'.
224 * But it's clear from discussion on the DisMan mailing
225 * list is that the intention is not.
226 *
227 * So check for whether this row is already active,
228 * and reject *all* SET requests if it is.
229 */
230 entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
231 if (entry &&
232 entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) {
233 netsnmp_set_request_error(reqinfo, request,
234 SNMP_ERR_INCONSISTENTVALUE);
235 return SNMP_ERR_NOERROR;
236 }
237 }
238 break;
239
240 case MODE_SET_RESERVE2:
241 case MODE_SET_FREE:
242 case MODE_SET_UNDO:
243 break;
244
245 case MODE_SET_ACTION:
246 for (request = requests; request; request = request->next) {
247 if (request->processed)
248 continue;
249
250 entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
251 if (!entry) {
252 /*
253 * New rows must be created via the RowStatus column
254 * (in the main mteTriggerTable)
255 */
256 netsnmp_set_request_error(reqinfo, request,
257 SNMP_ERR_NOCREATION);
258 /* or inconsistentName? */
259 return SNMP_ERR_NOERROR;
260 }
261 }
262 break;
263
264 case MODE_SET_COMMIT:
265 /*
266 * All these assignments are "unfailable", so it's
267 * (reasonably) safe to apply them in the Commit phase
268 */
269 for (request = requests; request; request = request->next) {
270 if (request->processed)
271 continue;
272
273 entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
274 tinfo = netsnmp_extract_table_info(request);
275
276 switch (tinfo->colnum) {
277 case COLUMN_MTETRIGGERBOOLEANCOMPARISON:
278 entry->mteTBoolComparison = *request->requestvb->val.integer;
279 break;
280 case COLUMN_MTETRIGGERBOOLEANVALUE:
281 entry->mteTBoolValue = *request->requestvb->val.integer;
282 break;
283 case COLUMN_MTETRIGGERBOOLEANSTARTUP:
284 if (*request->requestvb->val.integer == TV_TRUE)
285 entry->flags |= MTE_TRIGGER_FLAG_BSTART;
286 else
287 entry->flags &= ~MTE_TRIGGER_FLAG_BSTART;
288 break;
289 case COLUMN_MTETRIGGERBOOLEANOBJECTSOWNER:
290 memset(entry->mteTBoolObjOwner, 0, sizeof(entry->mteTBoolObjOwner));
291 memcpy(entry->mteTBoolObjOwner, request->requestvb->val.string,
292 request->requestvb->val_len);
293 break;
294 case COLUMN_MTETRIGGERBOOLEANOBJECTS:
295 memset(entry->mteTBoolObjects, 0, sizeof(entry->mteTBoolObjects));
296 memcpy(entry->mteTBoolObjects, request->requestvb->val.string,
297 request->requestvb->val_len);
298 break;
299 case COLUMN_MTETRIGGERBOOLEANEVENTOWNER:
300 memset(entry->mteTBoolEvOwner, 0, sizeof(entry->mteTBoolEvOwner));
301 memcpy(entry->mteTBoolEvOwner, request->requestvb->val.string,
302 request->requestvb->val_len);
303 break;
304 case COLUMN_MTETRIGGERBOOLEANEVENT:
305 memset(entry->mteTBoolEvent, 0, sizeof(entry->mteTBoolEvent));
306 memcpy(entry->mteTBoolEvent, request->requestvb->val.string,
307 request->requestvb->val_len);
308 break;
309 }
310 }
311 break;
312 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
313 }
314 return SNMP_ERR_NOERROR;
315 }
316