1 /*
2 * DisMan Event MIB:
3 * Implementation of the mteObjectsTable MIB interface
4 * See 'mteObjects.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/mteObjects.h"
14 #include "disman/event/mteObjectsTable.h"
15
16 netsnmp_feature_require(table_tdata);
17 #ifndef NETSNMP_NO_WRITE_SUPPORT
18 netsnmp_feature_require(check_vb_oid);
19 netsnmp_feature_require(check_vb_truthvalue);
20 netsnmp_feature_require(table_tdata_insert_row);
21 #endif /* NETSNMP_NO_WRITE_SUPPORT */
22
23 static netsnmp_table_registration_info *table_info;
24
25 /** Initializes the mteObjectsTable module */
26 void
init_mteObjectsTable(void)27 init_mteObjectsTable(void)
28
29 {
30 static oid mteObjectsTable_oid[] = { 1, 3, 6, 1, 2, 1, 88, 1, 3, 1 };
31 size_t mteObjectsTable_oid_len = OID_LENGTH(mteObjectsTable_oid);
32 netsnmp_handler_registration *reg;
33
34 /*
35 * Ensure the object table container is available...
36 */
37 init_objects_table_data();
38
39 /*
40 * ... then set up the MIB interface to this table
41 */
42 #ifndef NETSNMP_NO_WRITE_SUPPORT
43 reg = netsnmp_create_handler_registration("mteObjectsTable",
44 mteObjectsTable_handler,
45 mteObjectsTable_oid,
46 mteObjectsTable_oid_len,
47 HANDLER_CAN_RWRITE);
48 #else /* !NETSNMP_NO_WRITE_SUPPORT */
49 reg = netsnmp_create_handler_registration("mteObjectsTable",
50 mteObjectsTable_handler,
51 mteObjectsTable_oid,
52 mteObjectsTable_oid_len,
53 HANDLER_CAN_RONLY);
54 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
55
56 table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
57 netsnmp_table_helper_add_indexes(table_info,
58 ASN_OCTET_STR, /* index: mteOwner */
59 ASN_OCTET_STR, /* index: mteObjectsName */
60 ASN_UNSIGNED, /* index: mteObjectsIndex */
61 0);
62
63 table_info->min_column = COLUMN_MTEOBJECTSID;
64 table_info->max_column = COLUMN_MTEOBJECTSENTRYSTATUS;
65
66
67 netsnmp_tdata_register(reg, objects_table_data, table_info);
68 }
69
70 void
shutdown_mteObjectsTable(void)71 shutdown_mteObjectsTable(void)
72 {
73 if (table_info) {
74 netsnmp_table_registration_info_free(table_info);
75 table_info = NULL;
76 }
77 }
78
79
80 /** handles requests for the mteObjectsTable table */
81 int
mteObjectsTable_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)82 mteObjectsTable_handler(netsnmp_mib_handler *handler,
83 netsnmp_handler_registration *reginfo,
84 netsnmp_agent_request_info *reqinfo,
85 netsnmp_request_info *requests)
86 {
87
88 netsnmp_request_info *request;
89 netsnmp_table_request_info *tinfo;
90 netsnmp_tdata_row *row;
91 struct mteObject *entry;
92 char mteOwner[MTE_STR1_LEN+1];
93 char mteOName[MTE_STR1_LEN+1];
94 long ret;
95
96 DEBUGMSGTL(("disman:event:mib", "ObjTable handler (%d)\n", reqinfo->mode));
97
98 switch (reqinfo->mode) {
99 /*
100 * Read-support (also covers GetNext requests)
101 */
102 case MODE_GET:
103 for (request = requests; request; request = request->next) {
104 if (request->processed)
105 continue;
106
107 entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
108 tinfo = netsnmp_extract_table_info(request);
109
110 if (!entry) {
111 netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
112 continue;
113 }
114 switch (tinfo->colnum) {
115 case COLUMN_MTEOBJECTSID:
116 snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID,
117 (u_char *) entry->mteObjectID,
118 entry->mteObjectID_len*sizeof(oid));
119 break;
120 case COLUMN_MTEOBJECTSIDWILDCARD:
121 ret = (entry->flags & MTE_OBJECT_FLAG_WILD ) ?
122 TV_TRUE : TV_FALSE;
123 snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret);
124 break;
125 case COLUMN_MTEOBJECTSENTRYSTATUS:
126 ret = (entry->flags & MTE_OBJECT_FLAG_ACTIVE ) ?
127 RS_ACTIVE : RS_NOTINSERVICE;
128 snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret);
129 break;
130 }
131 }
132 break;
133
134 #ifndef NETSNMP_NO_WRITE_SUPPORT
135 /*
136 * Write-support
137 */
138 case MODE_SET_RESERVE1:
139
140 for (request = requests; request; request = request->next) {
141 if (request->processed)
142 continue;
143
144 entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
145 tinfo = netsnmp_extract_table_info(request);
146
147 switch (tinfo->colnum) {
148 case COLUMN_MTEOBJECTSID:
149 ret = netsnmp_check_vb_oid( request->requestvb );
150 if (ret != SNMP_ERR_NOERROR) {
151 netsnmp_set_request_error(reqinfo, request, ret);
152 return SNMP_ERR_NOERROR;
153 }
154 /*
155 * Can't modify the OID of an active row
156 * (an unnecessary restriction, IMO)
157 */
158 if (entry &&
159 entry->flags & MTE_OBJECT_FLAG_ACTIVE ) {
160 netsnmp_set_request_error(reqinfo, request,
161 SNMP_ERR_INCONSISTENTVALUE);
162 return SNMP_ERR_NOERROR;
163 }
164 break;
165 case COLUMN_MTEOBJECTSIDWILDCARD:
166 ret = netsnmp_check_vb_truthvalue( request->requestvb );
167 if (ret != SNMP_ERR_NOERROR) {
168 netsnmp_set_request_error(reqinfo, request, ret);
169 return SNMP_ERR_NOERROR;
170 }
171 /*
172 * Can't modify the wildcarding of an active row
173 * (an unnecessary restriction, IMO)
174 */
175 if (entry &&
176 entry->flags & MTE_OBJECT_FLAG_ACTIVE ) {
177 netsnmp_set_request_error(reqinfo, request,
178 SNMP_ERR_INCONSISTENTVALUE);
179 return SNMP_ERR_NOERROR;
180 }
181 break;
182 case COLUMN_MTEOBJECTSENTRYSTATUS:
183 ret = netsnmp_check_vb_rowstatus(request->requestvb,
184 (entry ? RS_ACTIVE : RS_NONEXISTENT));
185 if (ret != SNMP_ERR_NOERROR) {
186 netsnmp_set_request_error(reqinfo, request, ret);
187 return SNMP_ERR_NOERROR;
188 }
189 /* An active row can only be deleted */
190 if (entry &&
191 entry->flags & MTE_OBJECT_FLAG_ACTIVE &&
192 *request->requestvb->val.integer == RS_NOTINSERVICE ) {
193 netsnmp_set_request_error(reqinfo, request,
194 SNMP_ERR_INCONSISTENTVALUE);
195 return SNMP_ERR_NOERROR;
196 }
197 break;
198 default:
199 netsnmp_set_request_error(reqinfo, request,
200 SNMP_ERR_NOTWRITABLE);
201 return SNMP_ERR_NOERROR;
202 }
203 }
204 break;
205
206 case MODE_SET_RESERVE2:
207 for (request = requests; request; request = request->next) {
208 if (request->processed)
209 continue;
210
211 tinfo = netsnmp_extract_table_info(request);
212
213 switch (tinfo->colnum) {
214 case COLUMN_MTEOBJECTSENTRYSTATUS:
215 switch (*request->requestvb->val.integer) {
216 case RS_CREATEANDGO:
217 case RS_CREATEANDWAIT:
218 /*
219 * Create an (empty) new row structure
220 */
221 memset(mteOwner, 0, sizeof(mteOwner));
222 memcpy(mteOwner, tinfo->indexes->val.string,
223 tinfo->indexes->val_len);
224 memset(mteOName, 0, sizeof(mteOName));
225 memcpy(mteOName,
226 tinfo->indexes->next_variable->val.string,
227 tinfo->indexes->next_variable->val_len);
228 ret = *tinfo->indexes->next_variable->next_variable->val.integer;
229
230 row = mteObjects_createEntry(mteOwner, mteOName, ret, 0);
231 if (!row) {
232 netsnmp_set_request_error(reqinfo, request,
233 SNMP_ERR_RESOURCEUNAVAILABLE);
234 return SNMP_ERR_NOERROR;
235 }
236 netsnmp_insert_tdata_row( request, row );
237 }
238 }
239 }
240 break;
241
242 case MODE_SET_FREE:
243 for (request = requests; request; request = request->next) {
244 if (request->processed)
245 continue;
246
247 tinfo = netsnmp_extract_table_info(request);
248
249 switch (tinfo->colnum) {
250 case COLUMN_MTEOBJECTSENTRYSTATUS:
251 switch (*request->requestvb->val.integer) {
252 case RS_CREATEANDGO:
253 case RS_CREATEANDWAIT:
254 /*
255 * Tidy up after a failed row creation request
256 */
257 entry = (struct mteObject *)
258 netsnmp_tdata_extract_entry(request);
259 if (entry &&
260 !(entry->flags & MTE_OBJECT_FLAG_VALID)) {
261 row = (netsnmp_tdata_row *)
262 netsnmp_tdata_extract_row(request);
263 mteObjects_removeEntry( row );
264 }
265 }
266 }
267 }
268 break;
269
270 case MODE_SET_ACTION:
271 for (request = requests; request; request = request->next) {
272 if (request->processed)
273 continue;
274
275 entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
276 if (!entry) {
277 /*
278 * New rows must be created via the RowStatus column
279 */
280 netsnmp_set_request_error(reqinfo, request,
281 SNMP_ERR_NOCREATION);
282 /* or inconsistentName? */
283 return SNMP_ERR_NOERROR;
284
285 }
286 }
287 break;
288
289 case MODE_SET_UNDO:
290 break;
291
292 case MODE_SET_COMMIT:
293 /*
294 * All these assignments are "unfailable", so it's
295 * (reasonably) safe to apply them in the Commit phase
296 */
297 for (request = requests; request; request = request->next) {
298 if (request->processed)
299 continue;
300
301 entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
302 tinfo = netsnmp_extract_table_info(request);
303
304 switch (tinfo->colnum) {
305 case COLUMN_MTEOBJECTSID:
306 memset(entry->mteObjectID, 0, sizeof(entry->mteObjectID));
307 memcpy(entry->mteObjectID, request->requestvb->val.objid,
308 request->requestvb->val_len);
309 entry->mteObjectID_len = request->requestvb->val_len/sizeof(oid);
310 break;
311
312 case COLUMN_MTEOBJECTSIDWILDCARD:
313 if (*request->requestvb->val.integer == TV_TRUE)
314 entry->flags |= MTE_OBJECT_FLAG_WILD;
315 else
316 entry->flags &= ~MTE_OBJECT_FLAG_WILD;
317 break;
318
319 case COLUMN_MTEOBJECTSENTRYSTATUS:
320 switch (*request->requestvb->val.integer) {
321 case RS_ACTIVE:
322 entry->flags |= MTE_OBJECT_FLAG_ACTIVE;
323 break;
324 case RS_CREATEANDGO:
325 entry->flags |= MTE_OBJECT_FLAG_VALID;
326 entry->flags |= MTE_OBJECT_FLAG_ACTIVE;
327 break;
328 case RS_CREATEANDWAIT:
329 entry->flags |= MTE_OBJECT_FLAG_VALID;
330 break;
331
332 case RS_DESTROY:
333 row = (netsnmp_tdata_row *)
334 netsnmp_tdata_extract_row(request);
335 mteObjects_removeEntry(row);
336 }
337 }
338 }
339
340 /** set up to save persistent store */
341 snmp_store_needed(NULL);
342
343 break;
344 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
345 }
346 return SNMP_ERR_NOERROR;
347 }
348