1 /* 2 * Copyright (c) 2015 by Farsight Security, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef NMSG_FLTMOD_PLUGIN_H 18 #define NMSG_FLTMOD_PLUGIN_H 19 20 /*! \file nmsg/fltmod_plugin.h 21 * \brief Implementing message filter modules. 22 * 23 * This file defines the interface that developers of message filter modules 24 * must implement. For the interface for loading and calling filter modules, 25 * see nmsg/fltmod.h. 26 * 27 * Filter modules are dynamically loaded shared objects that must export a 28 * symbol called <tt>nmsg_fltmod_plugin_export</tt>. This is a structure of 29 * type #nmsg_fltmod_plugin and is the sole entry point into the module. 30 * 31 * The first field of the nmsg_fltmod_plugin structure is the version of the 32 * API/ABI between libnmsg and the filter module. Module developers should 33 * assign this field the value #NMSG_FLTMOD_VERSION, or they can add 34 * <tt>NMSG_FLTMOD_REQUIRED_INIT,</tt> to the initializer, which is a 35 * convenience macro that initializes required fields. 36 * 37 * A filter module needs to provide at least one function, the core message 38 * filtering function <tt>filter_message</tt>. This function must be 39 * thread-safe, since it may be called simultaneously from multiple threads. 40 * 41 * Optionally, up to four more functions may be provided: a global module 42 * initializer and finalizer (<tt>module_init</tt> and <tt>module_fini</tt>), 43 * and a per-thread initializer and finalizer (<tt>thread_init</tt> and 44 * <tt>thread_fini</tt>). These functions can be used to acquire and release 45 * resources, generate debug messages, etc. The module and thread initializers 46 * may provide opaque data pointers. These pointers will be provided as 47 * parameters to the message filtering function. 48 * 49 * The <tt>module_init</tt> function will only be called once, immediately 50 * after the plugin module has been loaded. It will be called before all other 51 * module functions. Therefore, it does not need to be thread-safe. 52 * 53 * The <tt>module_fini</tt> function will only be called once, immediately 54 * before the plugin module will be unloaded from the process. It will be 55 * called after all other module functions. Therefore, it does not need to be 56 * thread-safe, either. 57 * 58 * The <tt>thread_init</tt> and <tt>thread_fini</tt> functions may be called by 59 * a processing thread after the thread has started and before the thread 60 * exits. They need to be thread-safe, since they be called by independently 61 * executing threads. A thread may not call a module's <tt>filter_message</tt> 62 * function before it has called <tt>thread_init</tt>, and it may not call 63 * <tt>filter_message</tt> after it has called <tt>thread_fini</tt>. 64 * 65 * For an example of a simple message filtering module, see the "sample" filter 66 * module in the fltmod/ directory of the nmsg distribution. The "sample" 67 * filter performs either systematic count-based or uniform probabilistic 68 * sampling of the message stream. 69 */ 70 71 #include <nmsg.h> 72 73 /** Version number of the nmsg fltmod ABI. */ 74 #define NMSG_FLTMOD_VERSION 1 75 76 /** 77 * Initialize the filter module. 78 * 79 * Data with module-defined meaning may be passed in via the 'param' and 80 * 'len_param' parameters. This can be used to, for example, configure 81 * module-specific filtering parameters. 82 * 83 * \param[in] param 84 * Module-defined data needed for the initialization of the module. 85 * 86 * \param[in] len_param 87 * Length of 'param'. 88 * 89 * \param[out] mod_data 90 * Module-defined, module-wide state, passed to other module functions 91 * that take a 'mod_data' parameter. 92 * 93 * \return #nmsg_res_success 94 * If the module was successfully initialized. 95 * \return 96 * Any other result to indicate a fatal error. 97 */ 98 typedef nmsg_res 99 (*nmsg_fltmod_module_init_fp)(const void *param, 100 const size_t len_param, 101 void **mod_data); 102 103 /** 104 * Destroy the filter module. Any module-wide resources acquired by the module 105 * must be released. 106 * 107 * \param[in] mod_data 108 * Module-defined, module-wide state. 109 */ 110 typedef void 111 (*nmsg_fltmod_module_fini_fp)(void *mod_data); 112 113 /** 114 * Initialize module-defined, thread-wide state. 115 * 116 * \param[in] mod_data 117 * Module-defined, module-wide state. 118 * 119 * \param[out] thr_data 120 * Module-defined, thread-wide state. 121 * 122 * \return #nmsg_res_success 123 * If the thread-wide state was successfully initialized. 124 * \return 125 * Any other result to indicate a fatal error. 126 */ 127 typedef nmsg_res 128 (*nmsg_fltmod_thread_init_fp)(void *mod_data, void **thr_data); 129 130 /** 131 * Destroy thread-wide state. Any thread-wide resources corresponding to the 132 * passed in 'thr_data' value that have been acquired by the module must be 133 * released. 134 * 135 * \param[in] mod_data 136 * Module-defined, module-wide state. 137 * 138 * \param[in] thr_data 139 * Module-defined, thread-wide state. 140 * 141 * \return #nmsg_res_success 142 * If the thread-wide state was successfully destroyed. 143 * \return 144 * Any other result to indicate a fatal error. 145 */ 146 typedef nmsg_res 147 (*nmsg_fltmod_thread_fini_fp)(void *mod_data, void *thr_data); 148 149 /** 150 * Filter a message object and return the filter verdict. 151 * 152 * The filter function may alter the message object, or it may replace the 153 * message object with an entirely new message. If the filter function replaces 154 * the message object, it is responsible for disposing of the old message, for 155 * instance by calling nmsg_message_destroy(). 156 * 157 * \param[in,out] msg 158 * Pointer to the message object to be filtered. The message object may 159 * optionally be altered, or it may be replaced with an entirely new 160 * message object. 161 * 162 * \param[in] mod_data 163 * Module-defined, module-wide state. 164 * 165 * \param[in] thr_data 166 * Module-defined, thread-wide state. 167 * 168 * \param[out] vres 169 * The filter verdict. \see #nmsg_filter_message_verdict for the possible 170 * verdict results and meanings. 171 * 172 * \return #nmsg_res_success 173 * The filtering completed and returned a verdict in 'vres'. 174 * \return 175 * Any other result to indicate a fatal error. 176 */ 177 typedef nmsg_res 178 (*nmsg_fltmod_filter_message_fp)(nmsg_message_t *msg, 179 void *mod_data, 180 void *thr_data, 181 nmsg_filter_message_verdict *vres); 182 183 /** Convenience macro. */ 184 #define NMSG_FLTMOD_REQUIRED_INIT \ 185 .fltmod_version = NMSG_FLTMOD_VERSION 186 187 /** 188 * Structure exported by filter modules. 189 */ 190 struct nmsg_fltmod_plugin { 191 /** 192 * Module interface version. 193 * Must be set to #NMSG_FLTMOD_VERSION or the module will be rejected 194 * at load time. 195 */ 196 long fltmod_version; 197 198 /** 199 * Module-wide initialization function. Optional, may be NULL. If this 200 * function exists, it will be called once at module startup by 201 * nmsg_fltmod_init(). 202 */ 203 nmsg_fltmod_module_init_fp module_init; 204 205 /** 206 * Module-wide finalization function. Optional, may be NULL. If this 207 * function exists, it will be called once at module shutdown by 208 * nmsg_fltmod_destroy(). This function should clean up any resources 209 * acquired by 'module_init'. 210 */ 211 nmsg_fltmod_module_fini_fp module_fini; 212 213 /** 214 * Per-thread initialization function. Optional, may be NULL. If this 215 * function exists, it will be called by each thread that wants to 216 * perform message filtering via nmsg_fltmod_thread_init(). 217 */ 218 nmsg_fltmod_thread_init_fp thread_init; 219 220 /** 221 * Per-thread finalization function. Optional, may be NULL. If this 222 * function exists, it will be called by each thread that has called 223 * 'thread_init' before the thread exits by nmsg_fltmod_thread_fini(). 224 * This function should clean up any resources acquired by 225 * 'thread_init'. 226 */ 227 nmsg_fltmod_thread_fini_fp thread_fini; 228 229 /** 230 * Message filter function. Required, must not be NULL. This function 231 * is called by nmsg_fltmod_filter_message(). 232 */ 233 nmsg_fltmod_filter_message_fp filter_message; 234 235 /** 236 * \private Reserved fields. 237 */ 238 void *_reserved15; 239 void *_reserved14; 240 void *_reserved13; 241 void *_reserved12; 242 void *_reserved11; 243 void *_reserved10; 244 void *_reserved9; 245 void *_reserved8; 246 void *_reserved7; 247 void *_reserved6; 248 void *_reserved5; 249 void *_reserved4; 250 void *_reserved3; 251 void *_reserved2; 252 void *_reserved1; 253 void *_reserved0; 254 }; 255 256 #endif /* NMSG_FLTMOD_PLUGIN_H */ 257