1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
14 #include "headers/debug_op.h"
16 #include "error_messages/error_messages.h"
18 /* We have two internal lists. One with the program_name
19 * and one without. This is going to improve greatly the
20 * performance of our decoder matching.
22 static OSDecoderNode *osdecodernode_forpname;
23 static OSDecoderNode *osdecodernode_nopname;
25 static OSDecoderNode *_OS_AddOSDecoder(OSDecoderNode *s_node, OSDecoderInfo *pi);
27 /* Create the Event List */
28 void OS_CreateOSDecoderList()
30 osdecodernode_forpname = NULL;
31 osdecodernode_nopname = NULL;
36 /* Get first osdecoder */
37 OSDecoderNode *OS_GetFirstOSDecoder(const char *p_name)
39 /* If program name is set, we return the forpname list */
41 return (osdecodernode_forpname);
44 return (osdecodernode_nopname);
47 /* Add an osdecoder to the list */
48 static OSDecoderNode *_OS_AddOSDecoder(OSDecoderNode *s_node, OSDecoderInfo *pi)
50 OSDecoderNode *tmp_node = s_node;
51 OSDecoderNode *new_node;
55 new_node = (OSDecoderNode *)calloc(1, sizeof(OSDecoderNode));
56 if (new_node == NULL) {
57 merror(MEM_ERROR, ARGV0, errno, strerror(errno));
61 /* Going to the last node */
63 /* Check for common names */
64 if ((strcmp(tmp_node->osdecoder->name, pi->name) == 0) &&
65 (pi->parent != NULL)) {
66 if ((tmp_node->osdecoder->prematch ||
67 tmp_node->osdecoder->regex ||
68 tmp_node->osdecoder->prematch_pcre2 ||
69 tmp_node->osdecoder->pcre2) && pi->regex_offset) {
73 /* Multi-regexes patterns cannot have prematch */
74 if (pi->prematch || pi->prematch_pcre2) {
75 merror(PDUP_INV, ARGV0, pi->name);
79 /* Multi-regex patterns cannot have fts set */
81 merror(PDUPFTS_INV, ARGV0, pi->name);
85 if (tmp_node->osdecoder->regex && pi->regex) {
86 tmp_node->osdecoder->get_next = 1;
87 } else if (tmp_node->osdecoder->pcre2 && pi->pcre2) {
88 tmp_node->osdecoder->get_next = 1;
90 merror(DUP_INV, ARGV0, pi->name);
95 } while (tmp_node->next && (tmp_node = tmp_node->next));
97 /* Must have a prematch set */
98 if (!rm_f && (pi->regex_offset & AFTER_PREVREGEX)) {
99 merror(INV_OFFSET, ARGV0, pi->name);
103 tmp_node->next = new_node;
105 new_node->next = NULL;
106 new_node->osdecoder = pi;
107 new_node->child = NULL;
111 /* Must not have a previous regex set */
112 if (pi->regex_offset & AFTER_PREVREGEX) {
113 merror(INV_OFFSET, ARGV0, pi->name);
117 tmp_node = (OSDecoderNode *)calloc(1, sizeof(OSDecoderNode));
119 if (tmp_node == NULL) {
120 ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
123 tmp_node->child = NULL;
124 tmp_node->next = NULL;
125 tmp_node->osdecoder = pi;
139 int OS_AddOSDecoder(OSDecoderInfo *pi)
142 OSDecoderNode *osdecodernode;
144 /* We can actually have two lists. One with program
145 * name and the other without.
147 if (pi->program_name || pi->program_name_pcre2) {
148 osdecodernode = osdecodernode_forpname;
150 osdecodernode = osdecodernode_nopname;
153 /* Search for parent on both lists */
155 OSDecoderNode *tmp_node = osdecodernode_forpname;
157 /* List with p_name */
159 if (strcmp(tmp_node->osdecoder->name, pi->parent) == 0) {
160 tmp_node->child = _OS_AddOSDecoder(tmp_node->child, pi);
161 if (!tmp_node->child) {
162 merror(DEC_PLUGIN_ERR, ARGV0);
167 tmp_node = tmp_node->next;
170 /* List without p name */
171 tmp_node = osdecodernode_nopname;
173 if (strcmp(tmp_node->osdecoder->name, pi->parent) == 0) {
174 tmp_node->child = _OS_AddOSDecoder(tmp_node->child, pi);
175 if (!tmp_node->child) {
176 merror(DEC_PLUGIN_ERR, ARGV0);
181 tmp_node = tmp_node->next;
184 /* OSDecoder was added correctly */
189 merror(PPLUGIN_INV, ARGV0, pi->parent);
192 osdecodernode = _OS_AddOSDecoder(osdecodernode, pi);
193 if (!osdecodernode) {
194 merror(DEC_PLUGIN_ERR, ARGV0);
198 /* Update global decoder pointers */
199 if (pi->program_name || pi->program_name_pcre2) {
200 osdecodernode_forpname = osdecodernode;
202 osdecodernode_nopname = osdecodernode;