1 /* 2 * Copyright (c) 2008-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_MSGMOD_H 18 #define NMSG_MSGMOD_H 19 20 /*! \file nmsg/msgmod.h 21 * \brief Message modules. 22 * 23 * Message modules extend nmsg by allowing new message types to be implemented 24 * in dynamically loaded plugins. Msgmods identify the types of messages they 25 * can handle by registering a vendor ID number and a per-vendor message type 26 * number with the msgmod loader. Functions for creating and interpreting NMSG 27 * payloads must be provided. 28 * 29 * Msgmods are dynamically loaded shared objects that must provide either a 30 * symbol called <tt>nmsg_msgmod_ctx</tt> of type nmsg_msgmod or a symbol called 31 * <tt>nmsg_msgmod_ctx_array</tt> which will be interpreted as an array of 32 * pointers to objects of type struct nmsg_msgmod. If an array is used, the array 33 * must be terminated by a NULL pointer. 34 * 35 * The first field of the nmsg_msgmod structure is the version of the API between 36 * libnmsg and the extension module; module developers should use this header 37 * file for the struct nmsg_msgmod definition and assign this field the value 38 * #NMSG_MSGMOD_VERSION. 39 * 40 * Modules must be reentrant, as exported message handling functions may be 41 * called from multiple threads simultaneously. An opaque pointer may be 42 * returned by the module initialization function; this pointer will be provided 43 * to module functions that require state and will be provided to the module 44 * finalization function for deallocation. 45 * 46 * If a message schema is restricted in a certain way, a C stub consisting of 47 * data definitions only can be used to interface with libnmsg. This is called 48 * a "transparent module". Transparent modules are implemented using the 49 * Protobuf-C compiler. 50 * 51 * For an example of a transparent module, see the base/email message type in 52 * the nmsg distribution. The file <tt>nmsg/base/email.proto</tt> is compiled 53 * with the <a href="http://code.google.com/p/protobuf-c/">Protobuf-C 54 * compiler</a> into the files email.pb-c.c and email.pb-c.h. The file 55 * email.c provides the C stub to interface with the msgmod 56 * interface, which is compiled into a shared object and installed into the 57 * nmsg module directory. 58 * 59 * <b>MP:</b> 60 * \li nmsg_msgmod_init() returns an opaque pointer which is used to 61 * differentiate threads if a message module is not stateless. 62 */ 63 64 /** 65 * Enum mapping protocol buffer schema types to nmsg-specific types for 66 * "transparent" modules. 67 * 68 * Protocol buffers provide basic data types on which transparent message 69 * modules can build more meaningful types. 70 */ 71 typedef enum { 72 /** Protobuf enum. */ 73 nmsg_msgmod_ft_enum, 74 75 /** Protobuf byte array. */ 76 nmsg_msgmod_ft_bytes, 77 78 /** 79 * Protobuf byte array. 80 * String should not contain newlines. 81 */ 82 nmsg_msgmod_ft_string, 83 84 /** 85 * Protobuf byte array. 86 * String can contain newlines. 87 */ 88 nmsg_msgmod_ft_mlstring, 89 90 /** 91 * Protobuf byte array. 92 * Length must be 4 for IPv4 addresses or 16 for IPv6 addresses. 93 */ 94 nmsg_msgmod_ft_ip, 95 96 /** Protobuf uint32. */ 97 nmsg_msgmod_ft_uint16, 98 99 /** Protobuf uint32. */ 100 nmsg_msgmod_ft_uint32, 101 102 /** Protobuf uint64. */ 103 nmsg_msgmod_ft_uint64, 104 105 /** Protobuf int32. */ 106 nmsg_msgmod_ft_int16, 107 108 /** Protobuf int32. */ 109 nmsg_msgmod_ft_int32, 110 111 /** Protobuf int64. */ 112 nmsg_msgmod_ft_int64, 113 114 /** Protobuf double. */ 115 nmsg_msgmod_ft_double, 116 117 /** Protobuf bool. */ 118 nmsg_msgmod_ft_bool, 119 } nmsg_msgmod_field_type; 120 121 #define NMSG_MSGMOD_FIELD_REPEATED 0x01 /*%< field is repeated */ 122 #define NMSG_MSGMOD_FIELD_REQUIRED 0x02 /*%< field is required */ 123 #define NMSG_MSGMOD_FIELD_HIDDEN 0x04 /*%< hide field from the message API */ 124 #define NMSG_MSGMOD_FIELD_NOPRINT 0x08 /*%< don't print the field */ 125 126 /** 127 * Initialize a message module. 128 * 129 * \param[in] mod Initialized msgmod. 130 * 131 * \param[out] clos Opaque pointer specific to this instantiation of the module. 132 * This pointer must be supplied to nmsg_msgmod functions taking a 'clos' 133 * parameter. 134 * 135 * \return #nmsg_res_success 136 * \return #nmsg_res_failure 137 * \return #nmsg_res_memfail 138 * \return #nmsg_res_notimpl 139 */ 140 nmsg_res 141 nmsg_msgmod_init(nmsg_msgmod_t mod, void **clos); 142 143 /** 144 * Finalize a mesage module. 145 * 146 * \param[in] mod Initialized msgmod. 147 * 148 * \param[in] clos Opaque pointer returned by the module initialization 149 * function. 150 * 151 * \return #nmsg_res_success 152 * \return #nmsg_res_failure 153 * \return #nmsg_res_notimpl 154 */ 155 nmsg_res 156 nmsg_msgmod_fini(nmsg_msgmod_t mod, void **clos); 157 158 /** 159 * Convert a presentation format line to an NMSG payload. 160 * Since the presentation format stream is line-delimited, not every line 161 * will necessarily result in a serialized message. 162 * 163 * When #nmsg_res_pbuf_ready is returned, the nmsg_msgmod_pres_to_payload_finalize() 164 * function should be used to obtain the serialized payload. 165 * 166 * Msgmods are not required to implement a function to convert presentation form 167 * data to payloads, in which case #nmsg_res_notimpl will be returned. 168 * 169 * \param[in] mod Initialized msgmod. 170 * 171 * \param[in] clos Opaque pointer returned by the module initialization 172 * function. 173 * 174 * \param[in] pres Line of presentation form input of the type handled by 'mod'. 175 * 176 * \return #nmsg_res_success 177 * \return #nmsg_res_failure 178 * \return #nmsg_res_memfail 179 * \return #nmsg_res_notimpl 180 * \return #nmsg_res_parse_error 181 * \return #nmsg_res_pbuf_ready 182 */ 183 nmsg_res 184 nmsg_msgmod_pres_to_payload(nmsg_msgmod_t mod, void *clos, const char *pres); 185 186 /** 187 * After a call to nmsg_msgmod_pres_to_payload() returns #nmsg_res_pbuf_ready, this 188 * function will return the serialized payload. The caller is responsible for 189 * freeing the payload returned. 190 * 191 * \param[in] mod Initialized msgmod. 192 * 193 * \param[in] clos Opaque pointer returned by the module initialization 194 * function. 195 * 196 * \param[out] pbuf Serialized payload. 197 * 198 * \param[out] sz Length of the serialized payload. 199 * 200 * \return #nmsg_res_success 201 * \return #nmsg_res_failure 202 * \return #nmsg_res_memfail 203 * \return #nmsg_res_notimpl 204 */ 205 nmsg_res 206 nmsg_msgmod_pres_to_payload_finalize(nmsg_msgmod_t mod, void *clos, uint8_t **pbuf, 207 size_t *sz); 208 209 /** 210 * Convert an IP datagram to an NMSG payload. 211 * 212 * Msgmods are not required to implement a function to convert IP datagrams to 213 * payloads, in which case #nmsg_res_notimpl will be returned. 214 * 215 * \param[in] mod Initialized msgmod. 216 * 217 * \param[in] clos Opaque pointer returned by the module initialization 218 * function. 219 * 220 * \param[in] dg Filled nmsg_ipdg structure. 221 * 222 * \param[out] pbuf Serialized payload. 223 * 224 * \param[out] sz Length of the serialized payload. 225 * 226 * \return #nmsg_res_parse_error 227 * \return #nmsg_res_pbuf_ready 228 * \return #nmsg_res_notimpl 229 */ 230 nmsg_res 231 nmsg_msgmod_ipdg_to_payload(nmsg_msgmod_t mod, void *clos, 232 const struct nmsg_ipdg *dg, 233 uint8_t **pbuf, size_t *sz); 234 235 /** 236 * Read a raw packet and optionally convert it to an NMSG payload. 237 * 238 * Msgmods are not required to implement a function to convert raw packets to 239 * payloads, in which case #nmsg_res_notimpl will be returned. 240 * 241 * A message will only be consumable if the return value is #nmsg_res_success. 242 * 243 * \param[in] mod Initialized msgmod. 244 * 245 * \param[in] clos Opaque pointer returned by the module initialization 246 * function. 247 * 248 * \param[in] pcap Pcap input to read packets from. 249 * 250 * \param[out] m Location to store payload. 251 * 252 * \return #nmsg_res_success 253 * \return #nmsg_res_again 254 * \return #nmsg_res_notimpl 255 */ 256 nmsg_res 257 nmsg_msgmod_pkt_to_payload(struct nmsg_msgmod *mod, void *clos, 258 nmsg_pcap_t pcap, nmsg_message_t *m); 259 260 /** 261 * Determine which nmsg_msgmod is responsible for a given vid/msgtype tuple, 262 * if any. 263 * 264 * \param[in] vid Numeric vendor ID. 265 * 266 * \param[in] msgtype Numeric message type. 267 * 268 * \return The nmsg_msgmod responsible for handling the given vid/msgtype tuple, 269 * if such a module has been loaded into the set, or NULL otherwise. 270 */ 271 nmsg_msgmod_t 272 nmsg_msgmod_lookup(unsigned vid, unsigned msgtype); 273 274 /** 275 * Determine which nmsg_msgmod is responsible for a given vid/msgtype tuple, 276 * if any. This function looks up the vid and msgtype by name. 277 * 278 * \param[in] vname Vendor name. 279 * 280 * \param[in] mname Message type name. 281 * 282 * \return The nmsg_msgmod responsible for handling the given vid/msgtype tuple, 283 * if such a module has been loaded into the set, or NULL otherwise. 284 */ 285 nmsg_msgmod_t 286 nmsg_msgmod_lookup_byname(const char *vname, const char *mname); 287 288 /** 289 * Convert the human-readable name of a message type to a message type ID. 290 * 291 * \param[in] vid Numeric vendor ID. 292 * 293 * \param[in] mname Message type name. 294 * 295 * \return A numeric message type ID. By convention, 0 is used to indicate an 296 * unknown message type. 297 */ 298 unsigned 299 nmsg_msgmod_mname_to_msgtype(unsigned vid, const char *mname); 300 301 /** 302 * Convert a vendor ID / message type ID tuple to the human-readable form 303 * of the message type. 304 * 305 * \param[in] vid Numeric vendor ID. 306 * 307 * \param[in] msgtype Numeric message type. 308 * 309 * \return A human-readable message type name. NULL is returned if the vendor ID 310 * or message type is unknown. 311 */ 312 const char * 313 nmsg_msgmod_msgtype_to_mname(unsigned vid, unsigned msgtype); 314 315 /** 316 * Convert a numeric vendor ID to its human-readable name. 317 * 318 * \param[in] vid Numeric vendor ID. 319 * 320 * \return A human-readable vendor name. NULL is returned if the vendor ID is 321 * unknown. 322 */ 323 const char * 324 nmsg_msgmod_vid_to_vname(unsigned vid); 325 326 /** 327 * Convert a human-readable vendor name to its numeric ID. 328 * 329 * \param[in] vname Vendor name. 330 * 331 * \return A numeric vendor ID. By convention, 0 is used to indicate an unknown 332 * vendor ID. 333 */ 334 unsigned 335 nmsg_msgmod_vname_to_vid(const char *vname); 336 337 /** 338 * Return the maximum vendor ID. 339 */ 340 unsigned 341 nmsg_msgmod_get_max_vid(void); 342 343 /** 344 * Return the maximum message type registered to a vendor ID. 345 * 346 * \param[in] vid Numeric vendor ID. 347 */ 348 unsigned 349 nmsg_msgmod_get_max_msgtype(unsigned vid); 350 351 #endif /* NMSG_MSGMOD_H */ 352