1 /*
2  * Note: this file originally auto-generated by mib2c using
3  *        : mib2c.create-dataset.conf,v 5.2 2002/07/17 14:41:53 dts12 Exp $
4  */
5 
6 #include <net-snmp/net-snmp-config.h>
7 #include <net-snmp/net-snmp-features.h>
8 #include <net-snmp/net-snmp-includes.h>
9 #include <net-snmp/agent/net-snmp-agent-includes.h>
10 #include "mteTriggerTable.h"
11 #include "mteEventTable.h"
12 #include "mteEventNotificationTable.h"
13 #include "mteObjectsTable.h"
14 
15 netsnmp_feature_require(table_dataset);
16 netsnmp_feature_require(table_set_multi_add_default_row);
17 
18 static netsnmp_table_data_set *table_set = NULL;
19 
20 /** Initialize the mteEventTable table by defining its contents and how it's structured */
21 void
initialize_table_mteEventTable(void)22 initialize_table_mteEventTable(void)
23 {
24     static oid      mteEventTable_oid[] =
25         { 1, 3, 6, 1, 2, 1, 88, 1, 4, 2 };
26     size_t          mteEventTable_oid_len = OID_LENGTH(mteEventTable_oid);
27 
28     /*
29      * create the table structure itself
30      */
31     table_set = netsnmp_create_table_data_set("mteEventTable");
32 
33     /*
34      * comment this out or delete if you don't support creation of new rows
35      */
36     table_set->allow_creation = 1;
37     /* mark the row status column */
38     table_set->rowstatus_column = COLUMN_MTEEVENTENTRYSTATUS;
39 
40     /***************************************************
41      * Adding indexes
42      */
43     DEBUGMSGTL(("initialize_table_mteEventTable",
44                 "adding indexes to table mteEventTable\n"));
45     netsnmp_table_set_add_indexes(table_set,
46                                   ASN_OCTET_STR,   /* index: mteOwner */
47                                   ASN_PRIV_IMPLIED_OCTET_STR, /* index: mteEventName */
48                                   0);
49 
50     DEBUGMSGTL(("initialize_table_mteEventTable",
51                 "adding column types to table mteEventTable\n"));
52     netsnmp_table_set_multi_add_default_row(table_set,
53                                             COLUMN_MTEEVENTNAME,
54                                             ASN_OCTET_STR, 0, NULL, 0,
55                                             COLUMN_MTEEVENTCOMMENT,
56                                             ASN_OCTET_STR, 1, NULL, 0,
57                                             COLUMN_MTEEVENTACTIONS,
58                                             ASN_OCTET_STR, 1, NULL, 0,
59                                             COLUMN_MTEEVENTENABLED,
60                                             ASN_INTEGER, 1, NULL, 0,
61                                             COLUMN_MTEEVENTENTRYSTATUS,
62                                             ASN_INTEGER, 1, NULL, 0, 0);
63 
64     /* keep index values around for comparisons later */
65     table_set->table->store_indexes = 1;
66     /*
67      * registering the table with the master agent
68      */
69     /*
70      * note: if you don't need a subhandler to deal with any aspects
71      * of the request, change mteEventTable_handler to "NULL"
72      */
73     netsnmp_register_table_data_set(netsnmp_create_handler_registration
74                                     ("mteEventTable",
75                                      mteEventTable_handler,
76                                      mteEventTable_oid,
77                                      mteEventTable_oid_len,
78                                      HANDLER_CAN_RWRITE), table_set, NULL);
79 }
80 
81 /** Initializes the mteEventTable module */
82 void
init_mteEventTable(void)83 init_mteEventTable(void)
84 {
85 
86     /*
87      * here we initialize all the tables we're planning on supporting
88      */
89     initialize_table_mteEventTable();
90 
91     snmpd_register_config_handler("notificationEvent", parse_notificationEvent,
92                                   NULL,
93                                   "notificationEvent NAME TRAP_OID [[-w] EXTRA_OID ...]");
94 
95     snmpd_register_config_handler("linkUpDownNotifications",
96                                   parse_linkUpDownNotifications,
97                                   NULL,
98                                   "linkUpDownNotifications (yes|no)");
99 }
100 
101 /** handles requests for the mteEventTable table, if anything else needs to be done */
102 int
mteEventTable_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)103 mteEventTable_handler(netsnmp_mib_handler *handler,
104                       netsnmp_handler_registration *reginfo,
105                       netsnmp_agent_request_info *reqinfo,
106                       netsnmp_request_info *requests)
107 {
108     /*
109      * perform anything here that you need to do.  The requests have
110      * already been processed by the master table_dataset handler, but
111      * this gives you chance to act on the request in some other way
112      * if need be.
113      */
114 
115     /* XXX: on rowstatus = destroy, remove the corresponding rows from the
116        other tables: snmpEventNotificationTable and the set table */
117     return SNMP_ERR_NOERROR;
118 }
119 
120 void
parse_linkUpDownNotifications(const char * token,char * line)121 parse_linkUpDownNotifications(const char *token, char *line) {
122     if (strncmp(line, "y", 1) == 0) {
123         parse_notificationEvent("notificationEvent", "linkUpTrap   	 linkUp     ifIndex ifAdminStatus ifOperStatus");
124         parse_notificationEvent("notificationEvent", "linkDownTrap 	 linkDown   ifIndex ifAdminStatus ifOperStatus");
125 
126         parse_simple_monitor("monitor", "-r 60 -e linkUpTrap \"Generate linkUp\" ifOperStatus != 2");
127         parse_simple_monitor("monitor", "-r 60 -e linkDownTrap \"Generate linkDown\" ifOperStatus == 2");
128     }
129 }
130 
131 void
parse_notificationEvent(const char * token,char * line)132 parse_notificationEvent(const char *token, char *line) {
133     char            name_buf[64];
134     char            oid_name_buf[SPRINT_MAX_LEN];
135     oid             oid_buf[MAX_OID_LEN];
136     size_t          oid_buf_len = MAX_OID_LEN;
137     int             wild = 1;
138     netsnmp_table_row *row;
139     long tlong;
140     char tc;
141 
142     /* get the owner */
143     const char *owner = "snmpd.conf";
144 
145     /* get the name */
146     char *cp = copy_nword(line, name_buf, SPRINT_MAX_LEN);
147 
148     if (!cp || name_buf[0] == '\0') {
149         config_perror("syntax error.");
150         return;
151     }
152 
153     for(row = table_set->table->first_row; row; row = row->next) {
154         if (strcmp(row->indexes->val.string, owner) == 0 &&
155             strcmp(row->indexes->next_variable->val.string,
156                    name_buf) == 0) {
157             config_perror("An eventd by that name has already been defined.");
158             return;
159         }
160     }
161 
162     /* now, get all the trap oid */
163     cp = copy_nword(cp, oid_name_buf, SPRINT_MAX_LEN);
164 
165     if (oid_name_buf[0] == '\0') {
166         config_perror("syntax error.");
167         return;
168     }
169     if (!snmp_parse_oid(oid_name_buf, oid_buf, &oid_buf_len)) {
170         snmp_log(LOG_ERR,"namebuf: %s\n",oid_name_buf);
171         config_perror("unable to parse trap oid");
172         return;
173     }
174 
175     /*
176      * add to the mteEventNotificationtable to point to the
177      * notification and the objects.
178      */
179     row = netsnmp_create_table_data_row();
180 
181     /* indexes */
182     netsnmp_table_row_add_index(row, ASN_OCTET_STR, owner, strlen(owner));
183     netsnmp_table_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
184                                 name_buf, strlen(name_buf));
185 
186 
187     /* columns */
188     netsnmp_set_row_column(row, COLUMN_MTEEVENTNOTIFICATION, ASN_OBJECT_ID,
189                            (char *) oid_buf, oid_buf_len * sizeof(oid));
190     netsnmp_set_row_column(row, COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER,
191                            ASN_OCTET_STR, owner, strlen(owner));
192     netsnmp_set_row_column(row, COLUMN_MTEEVENTNOTIFICATIONOBJECTS,
193                            ASN_OCTET_STR, name_buf, strlen(name_buf));
194 
195     netsnmp_table_data_add_row(mteEventNotif_table_set->table, row);
196 
197     /*
198      * add to the mteEventTable to make it a notification to trigger
199      * notification and the objects.
200      */
201     row = netsnmp_create_table_data_row();
202 
203     /* indexes */
204     netsnmp_table_row_add_index(row, ASN_OCTET_STR, owner, strlen(owner));
205     netsnmp_table_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
206                                 name_buf, strlen(name_buf));
207 
208 
209     /* columns */
210     tc = (u_char)0x80;
211     netsnmp_set_row_column(row, COLUMN_MTEEVENTACTIONS, ASN_OCTET_STR,
212                            &tc, 1);
213     tlong = MTETRIGGERENABLED_TRUE;
214     netsnmp_set_row_column(row, COLUMN_MTEEVENTENABLED,
215                            ASN_INTEGER, (char *) &tlong, sizeof(tlong));
216     tlong = RS_ACTIVE;
217     netsnmp_set_row_column(row, COLUMN_MTEEVENTENTRYSTATUS,
218                            ASN_INTEGER, (char *) &tlong, sizeof(tlong));
219 
220     netsnmp_table_data_add_row(table_set->table, row);
221 
222     /*
223      * now all the objects to put into the trap's object row
224      */
225     while(cp) {
226         cp = copy_nword(cp, oid_name_buf, SPRINT_MAX_LEN);
227         if (strcmp(oid_name_buf, "-w") == 0) {
228             wild = 0;
229             continue;
230         }
231         oid_buf_len = MAX_OID_LEN;
232         if (!snmp_parse_oid(oid_name_buf, oid_buf, &oid_buf_len)) {
233             config_perror("unable to parse an object oid");
234             return;
235         }
236         mte_add_object_to_table("snmpd.conf", name_buf,
237                                 oid_buf, oid_buf_len, wild);
238         wild = 1;
239     }
240 }
241 
242 /*
243  * send trap
244  */
245 void
run_mte_events(struct mteTriggerTable_data * item,oid * name_oid,size_t name_oid_len,const char * eventobjowner,const char * eventobjname)246 run_mte_events(struct mteTriggerTable_data *item,
247                oid * name_oid, size_t name_oid_len,
248                const char *eventobjowner, const char *eventobjname)
249 {
250     static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };     /* snmpTrapIOD.0 */
251 
252     netsnmp_variable_list *var_list = NULL;
253 
254     netsnmp_table_row *row, *notif_row;
255     netsnmp_table_data_set_storage *col1, *tc, *no, *noo;
256 
257     for(row = table_set->table->first_row; row; row = row->next) {
258         if (strcmp(row->indexes->val.string, eventobjowner) == 0 &&
259             strcmp(row->indexes->next_variable->val.string,
260                    eventobjname) == 0) {
261             /* run this event */
262             col1 = (netsnmp_table_data_set_storage *) row->data;
263 
264             tc = netsnmp_table_data_set_find_column(col1,
265                                                     COLUMN_MTEEVENTACTIONS);
266             if (!(tc->data.bitstring[0] & 0x80)) {
267                 /* not a notification.  next! (XXX: do sets) */
268                 continue;
269             }
270 
271             tc = netsnmp_table_data_set_find_column(col1,
272                                                     COLUMN_MTEEVENTENABLED);
273             if (*(tc->data.integer) != 1) {
274                 /* not enabled.  next! */
275                 continue;
276             }
277 
278             if (!mteEventNotif_table_set) {
279                 /* no notification info */
280                 continue;
281             }
282 
283             /* send the notification */
284             var_list = NULL;
285 
286             /* XXX: get notif information */
287             for(notif_row = mteEventNotif_table_set->table->first_row;
288                 notif_row; notif_row = notif_row->next) {
289                 if (strcmp(notif_row->indexes->val.string,
290                            eventobjowner) == 0 &&
291                     strcmp(notif_row->indexes->next_variable->val.string,
292                            eventobjname) == 0) {
293 
294                     /* run this event */
295                     col1 = (netsnmp_table_data_set_storage *) notif_row->data;
296 
297                     tc = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATION);
298                     no = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTS);
299                     noo = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER);
300                     if (!tc)
301                         continue; /* no notification to be had. XXX: return? */
302 
303                     /*
304                      * snmpTrap oid
305                      */
306                     snmp_varlist_add_variable(&var_list, objid_snmptrap,
307                                               sizeof(objid_snmptrap) /
308                                               sizeof(oid),
309                                               ASN_OBJECT_ID,
310                                               (u_char *) tc->data.objid,
311                                               tc->data_len);
312 
313                     /* XXX: add objects from the mteObjectsTable */
314                     DEBUGMSGTL(("mteEventTable:send_events", "no: %x, no->data: %s", no, no->data.string));
315                     DEBUGMSGTL(("mteEventTable:send_events", "noo: %x, noo->data: %s", noo, noo->data.string));
316                     DEBUGMSGTL(("mteEventTable:send_events", "name_oid: %x",name_oid));
317                     if (no && no->data.string &&
318                         noo && noo->data.string && name_oid) {
319                         char *tmpowner =
320                             netsnmp_strdup_and_null(noo->data.string,
321                                                     noo->data_len);
322                         char *tmpname =
323                             netsnmp_strdup_and_null(no->data.string,
324                                                     no->data_len);
325 
326                         DEBUGMSGTL(("mteEventTable:send_events", "Adding objects for owner=%s name=%s", tmpowner, tmpname));
327                         mte_add_objects(var_list, item,
328                                         tmpowner, tmpname,
329                                        name_oid + item->mteTriggerValueIDLen,
330                                         name_oid_len - item->mteTriggerValueIDLen);
331                         free(tmpowner);
332                         free(tmpname);
333                     }
334 
335                     DEBUGMSGTL(("mteEventTable:send_events", "sending an event "));
336                     DEBUGMSGOID(("mteEventTable:send_events", tc->data.objid, tc->data_len / sizeof(oid)));
337                     DEBUGMSG(("mteEventTable:send_events", "\n"));
338 
339                     send_v2trap(var_list);
340                     snmp_free_varbind(var_list);
341                 }
342             }
343         }
344     }
345 }
346