+/*
+ * Hash table functions for the audit event number to event class mask mapping.
+ */
+
+#define EVCLASSMAP_HASH_TABLE_SIZE 251
+struct evclass_elem {
+ au_event_t event;
+ au_class_t class;
+ LIST_ENTRY(evclass_elem) entry;
+};
+struct evclass_list {
+ LIST_HEAD(, evclass_elem) head;
+};
+
+struct evclass_list evclass_hash[EVCLASSMAP_HASH_TABLE_SIZE];
+
+au_class_t au_event_class(au_event_t event)
+{
+
+ struct evclass_list *evcl;
+ struct evclass_elem *evc;
+
+ evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE];
+
+ /* If an entry at our hash location matches the event, just return */
+ LIST_FOREACH(evc, &evcl->head, entry) {
+ if (evc->event == event)
+ return (evc->class);
+ }
+ return (AU_NULL);
+}
+
+/*
+ * Insert a event to class mapping. If the event already exists in the
+ * mapping, then replace the mapping with the new one.
+ * XXX There is currently no constraints placed on the number of mappings.
+ * May want to either limit to a number, or in terms of memory usage.
+ */
+void au_evclassmap_insert(au_event_t event, au_class_t class)
+{
+ struct evclass_list *evcl;
+ struct evclass_elem *evc;
+
+ evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE];
+
+ LIST_FOREACH(evc, &evcl->head, entry) {
+ if (evc->event == event) {
+ evc->class = class;
+ return;
+ }
+ }
+ kmem_alloc(kernel_map, &evc, sizeof(*evc));
+ if (evc == NULL) {
+ return;
+ }
+ evc->event = event;
+ evc->class = class;
+ LIST_INSERT_HEAD(&evcl->head, evc, entry);
+
+}
+
+void au_evclassmap_init()
+{
+ int i;
+ for (i = 0; i < EVCLASSMAP_HASH_TABLE_SIZE; i++) {
+ LIST_INIT(&evclass_hash[i].head);
+ }
+
+ /* Set up the initial event to class mapping for system calls. */
+ for (i = 0; i < nsys_au_event; i++) {
+ if (sys_au_event[i] != AUE_NULL) {
+ au_evclassmap_insert(sys_au_event[i], AU_NULL);
+ }
+ }
+ /* Add the Mach system call events */
+ au_evclassmap_insert(AUE_TASKFORPID, AU_NULL);
+ au_evclassmap_insert(AUE_PIDFORTASK, AU_NULL);
+ au_evclassmap_insert(AUE_SWAPON, AU_NULL);
+ au_evclassmap_insert(AUE_SWAPOFF, AU_NULL);
+ au_evclassmap_insert(AUE_MAPFD, AU_NULL);
+ au_evclassmap_insert(AUE_INITPROCESS, AU_NULL);
+
+ /* Add the specific open events to the mapping. */
+ au_evclassmap_insert(AUE_OPEN_R, AU_FREAD);
+ au_evclassmap_insert(AUE_OPEN_RC, AU_FREAD|AU_FCREATE);
+ au_evclassmap_insert(AUE_OPEN_RTC, AU_FREAD|AU_FCREATE|AU_FDELETE);
+ au_evclassmap_insert(AUE_OPEN_RT, AU_FREAD|AU_FDELETE);
+ au_evclassmap_insert(AUE_OPEN_RW, AU_FREAD|AU_FWRITE);
+ au_evclassmap_insert(AUE_OPEN_RWC, AU_FREAD|AU_FWRITE|AU_FCREATE);
+ au_evclassmap_insert(AUE_OPEN_RWTC, AU_FREAD|AU_FWRITE|AU_FCREATE|AU_FDELETE);
+ au_evclassmap_insert(AUE_OPEN_RWT, AU_FREAD|AU_FWRITE|AU_FDELETE);
+ au_evclassmap_insert(AUE_OPEN_W, AU_FWRITE);
+ au_evclassmap_insert(AUE_OPEN_WC, AU_FWRITE|AU_FCREATE);
+ au_evclassmap_insert(AUE_OPEN_WTC, AU_FWRITE|AU_FCREATE|AU_FDELETE);
+ au_evclassmap_insert(AUE_OPEN_WT, AU_FWRITE|AU_FDELETE);
+}
+