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