1 /* 2 * Copyright (c) 2008-2019 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_OUTPUT_H 18 #define NMSG_OUTPUT_H 19 20 /*! \file nmsg/output.h 21 * \brief Write nmsg containers to output streams. 22 * 23 * Nmsg payloads can be buffered and written to a file descriptor, or 24 * converted to presentation format and written to a file descriptor. 25 * 26 * <b>MP:</b> 27 * \li Clients must ensure synchronized access when writing to an 28 * nmsg_output_t object. 29 * 30 * <b>Reliability:</b> 31 * \li Clients must not touch the underlying file descriptor. 32 */ 33 34 /** 35 * An enum identifying the underlying implementation of an nmsg_output_t object. 36 * This is used for nmsg_io's close event notification. 37 */ 38 typedef enum { 39 nmsg_output_type_stream, 40 nmsg_output_type_pres, 41 nmsg_output_type_callback, 42 nmsg_output_type_json, 43 } nmsg_output_type; 44 45 /** 46 * Initialize a new byte-stream nmsg output. 47 * 48 * For efficiency reasons, files should probably be opened with a bufsz of 49 * #NMSG_WBUFSZ_MAX. 50 * 51 * \param[in] fd Writable file descriptor. 52 * 53 * \param[in] bufsz Value between #NMSG_WBUFSZ_MIN and #NMSG_WBUFSZ_MAX. 54 * 55 * \return Opaque pointer that is NULL on failure or non-NULL on success. 56 */ 57 nmsg_output_t 58 nmsg_output_open_file(int fd, size_t bufsz); 59 60 /** 61 * Initialize a new datagram socket nmsg output. 62 * 63 * For UDP sockets which are physically transported over an Ethernet, 64 * #NMSG_WBUFSZ_ETHER or #NMSG_WBUFSZ_JUMBO (for jumbo frame Ethernets) should 65 * be used for bufsz. 66 * 67 * \param[in] fd Writable datagram socket. 68 * 69 * \param[in] bufsz Value between #NMSG_WBUFSZ_MIN and #NMSG_WBUFSZ_MAX. 70 * 71 * \return Opaque pointer that is NULL on failure or non-NULL on success. 72 */ 73 nmsg_output_t 74 nmsg_output_open_sock(int fd, size_t bufsz); 75 76 /** 77 * Initialize a new ZMQ socket NMSG output. 78 * 79 * \param[in] s ZMQ output socket. 80 * 81 * \param[in] bufsz Value between #NMSG_WBUFSZ_MIN and #NMSG_WBUFSZ_MAX. 82 * 83 * \return Opaque pointer that is NULL on failure or non-NULL on success. 84 */ 85 nmsg_output_t 86 nmsg_output_open_zmq(void *s, size_t bufsz); 87 88 /** 89 * Create an ZMQ socket and initialize a new NMSG stream output from it. 90 * 91 * This function is a wrapper for nmsg_output_open_zmq(). Instead of taking an 92 * already initialized ZMQ socket object, it takes an endpoint argument like 93 * zmq_connect() and zmq_bind() do which is a string containing a 94 * "transport://address" specification and initializes a ZMQ socket object. 95 * However, this endpoint string will be munged in order to support additional 96 * functionality: 97 * 98 * The caller may select between a bound or connected ZMQ socket by appending 99 * ",accept" or ",connect" to the endpoint argument. (If not given, this 100 * function behaves as if ",connect" was passed.) That is, ",accept" uses 101 * zmq_bind() to obtain a ZMQ endpoint, and ",connect" uses zmq_connect(). 102 * 103 * The caller may additionally select between a PUB socket or a PUSH 104 * socket by appending ",pubsub" or ",pushpull". (If not given, this function 105 * behaves as if ",pubsub" was passed.) 106 * 107 * \see nmsg_input_open_zmq_endpoint() 108 * 109 * \param[in] zmq_ctx ZMQ context object. 110 * 111 * \param[in] ep ZMQ endpoint (with nmsg-specific extensions) 112 * 113 * \param[in] bufsz Value between #NMSG_WBUFSZ_MIN and #NMSG_WBUFSZ_MAX. 114 * 115 * \return Opaque pointer that is NULL on failure or non-NULL on success. 116 */ 117 nmsg_output_t 118 nmsg_output_open_zmq_endpoint(void *zmq_ctx, const char *ep, size_t bufsz); 119 120 /** 121 * Initialize a new presentation format (ASCII lines) nmsg output. 122 * 123 * \param[in] fd Writable file descriptor. 124 * 125 * \return Opaque pointer that is NULL on failure or non-NULL on success. 126 */ 127 nmsg_output_t 128 nmsg_output_open_pres(int fd); 129 130 /** 131 * Initialize a new JSON format nmsg output. 132 * 133 * JSON outputs write payloads as JSON dictionaries with keys: 134 * - time: the payload timestamp 135 * - vname: the vendor name, or "(unknown)" if not known 136 * - mname: the message type name, or "(unknown)" if not known 137 * - source: the payload source id as a hexadecimal string, if present 138 * - group: the payload group name or number, if present 139 * - operator: the payload operator name or number, if present 140 * - message: a dictionary containing a key-value pari for each message field 141 * 142 * Values of repeated fields are represented as lists. 143 * 144 * Message modules can provide optional formatting and parsing methods 145 * for fields. If a field has no formatter or parser, the following default 146 * formats are used: 147 * - Numeric types: JSON number 148 * - Boolean: JSON bool 149 * - IP address: string representation of the IP address. 150 * - Enumerated types: a string with the value name if known, integer otherwise. 151 * - Byte sequences: a string with the base64 encoding of the sequence. 152 * - Strings: JSON strings, with invalid UTF-8 sequences replaced with U+FFFD. 153 * 154 * \param[in] fd Writable file descriptor. 155 * 156 * \return Opaque pointer that is NULL on failure or non-NULL on success. 157 */ 158 nmsg_output_t 159 nmsg_output_open_json(int fd); 160 161 /** 162 * Initialize a new nmsg output closure. This allows a user-provided callback to 163 * function as an nmsg output, for instance to participate in an nmsg_io loop. 164 * The callback is responsible for disposing of each nmsg message. 165 * 166 * \param[in] cb Non-NULL function pointer that will be called once for each 167 * payload. 168 * 169 * \param[in] user Optionally NULL pointer which will be passed to the callback. 170 * 171 * \return Opaque pointer that is NULL on failure or non-NULL on success. 172 */ 173 nmsg_output_t 174 nmsg_output_open_callback(nmsg_cb_message cb, void *user); 175 176 /** 177 * Flush an nmsg_output_t object. 178 * 179 * This function writes out any messages in the output buffer. 180 * 181 * This function is only implemented for byte-stream and datagram socket 182 * nmsg outputs. 183 * 184 * \param[in] output nmsg_output_t object. 185 * 186 * \return #nmsg_res_success 187 * \return #nmsg_res_failure 188 */ 189 nmsg_res 190 nmsg_output_flush(nmsg_output_t output); 191 192 /** 193 * Write an nmsg message to an nmsg_output_t object. 194 * 195 * nmsg_output_write() does not deallocate the nmsg message object. Callers 196 * should call nmsg_message_destroy() when finished with a message object. 197 * 198 * \param[in] output nmsg_output_t object. 199 * 200 * \param[in] msg nmsg message to be serialized and written to 'output'. 201 * 202 * \return #nmsg_res_success 203 * \return #nmsg_res_failure 204 */ 205 nmsg_res 206 nmsg_output_write(nmsg_output_t output, nmsg_message_t msg); 207 208 /** 209 * Close an nmsg_output_t object. 210 * 211 * \param[in] output Pointer to an nmsg_output_t object. 212 * 213 * \return #nmsg_res_success 214 */ 215 nmsg_res 216 nmsg_output_close(nmsg_output_t *output); 217 218 /** 219 * Make an nmsg_output_t socket output buffered or unbuffered. 220 * 221 * By default, file and socket nmsg_output_t outputs are buffered. Extremely low 222 * volume output streams should probably be unbuffered to reduce latency. 223 * 224 * \param[in] output Socket nmsg_output_t object. 225 * 226 * \param[in] buffered True (buffered) or false (unbuffered). 227 */ 228 void 229 nmsg_output_set_buffered(nmsg_output_t output, bool buffered); 230 231 /** 232 * Filter an nmsg_output_t for a given vendor ID / message type. 233 * 234 * NMSG messages whose vid and msgtype fields do not match the filter will not 235 * be output and will instead be silently discarded. 236 * 237 * Calling this function with vid=0 and msgtype=0 will disable the filter. 238 * 239 * \param[in] output nmsg_output_t object. 240 * 241 * \param[in] vid Vendor ID. 242 * 243 * \param[in] msgtype Message type. 244 */ 245 void 246 nmsg_output_set_filter_msgtype(nmsg_output_t output, unsigned vid, unsigned msgtype); 247 248 /** 249 * Filter an nmsg_output_t for a given vendor ID / message type. 250 * 251 * \param[in] output nmsg_output_t object. 252 * 253 * \param[in] vname Vendor ID name. 254 * 255 * \param[in] mname Message type name. 256 */ 257 nmsg_res 258 nmsg_output_set_filter_msgtype_byname(nmsg_output_t output, 259 const char *vname, const char *mname); 260 261 /** 262 * Limit the payload output rate. 263 * 264 * The caller of nmsg_output_set_rate() is responsible for reclaiming 265 * unused nmsg_rate_t objects with nmsg_rate_destroy(). 266 * 267 * \param[in] output nmsg_output_t object. 268 * 269 * \param[in] rate nmsg_rate_t object or NULL to disable rate limiting. 270 */ 271 void 272 nmsg_output_set_rate(nmsg_output_t output, nmsg_rate_t rate); 273 274 /** 275 * Set the line continuation string for presentation format output. The default 276 * is "\n". 277 * 278 * \param[in] output nmsg_output_t object. 279 * 280 * \param[in] endline End-of-line character string. 281 */ 282 void 283 nmsg_output_set_endline(nmsg_output_t output, const char *endline); 284 285 /** 286 * Set the 'source' field on all output NMSG payloads. This has no effect on 287 * non-NMSG outputs. 288 * 289 * The source ID must be positive. 290 * 291 * \param[in] output NMSG stream nmsg_output_t object. 292 * 293 * \param[in] source Source ID. 294 */ 295 void 296 nmsg_output_set_source(nmsg_output_t output, unsigned source); 297 298 /** 299 * Set the 'operator' field on all output NMSG payloads. This has no effect on 300 * non-NMSG outputs. 301 * 302 * The operator ID must be positive. 303 * 304 * \param[in] output NMSG stream nmsg_output_t object. 305 * 306 * \param[in] operator_ Operator ID. 307 */ 308 void 309 nmsg_output_set_operator(nmsg_output_t output, unsigned operator_); 310 311 /** 312 * Set the 'group' field on all output NMSG payloads. This has no effect on 313 * non-NMSG outputs. 314 * 315 * The group ID must be positive. 316 * 317 * \param[in] output NMSG stream nmsg_output_t object. 318 * 319 * \param[in] group Group ID. 320 */ 321 void 322 nmsg_output_set_group(nmsg_output_t output, unsigned group); 323 324 /** 325 * Enable or disable zlib compression of output NMSG containers. 326 * 327 * \param[in] output nmsg_output_t object. 328 * 329 * \param[in] zlibout True (zlib enabled) or false (zlib disabled). 330 */ 331 void 332 nmsg_output_set_zlibout(nmsg_output_t output, bool zlibout); 333 334 #endif /* NMSG_OUTPUT_H */ 335