| /* |
| * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org> |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| */ |
| |
| #include <stdlib.h> |
| #include <string.h> /* for memset */ |
| #include <errno.h> |
| #include <assert.h> |
| |
| #include "internal/internal.h" |
| |
| /** |
| * \defgroup exp Expect object handling |
| * @{ |
| */ |
| |
| /** |
| * nfexp_new - allocate a new expectation |
| * |
| * In case of success, this function returns a valid pointer to a memory blob, |
| * otherwise NULL is returned and errno is set appropiately. |
| */ |
| struct nf_expect *nfexp_new(void) |
| { |
| struct nf_expect *exp; |
| |
| exp = malloc(sizeof(struct nf_expect)); |
| if (!exp) |
| return NULL; |
| |
| memset(exp, 0, sizeof(struct nf_expect)); |
| |
| return exp; |
| } |
| |
| /** |
| * nfexp_destroy - release an expectation object |
| * \param exp pointer to the expectation object |
| */ |
| void nfexp_destroy(struct nf_expect *exp) |
| { |
| assert(exp != NULL); |
| free(exp); |
| exp = NULL; /* bugtrap */ |
| } |
| |
| /** |
| * nfexp_sizeof - return the size in bytes of a certain expect object |
| * \param exp pointer to the expect object |
| */ |
| size_t nfexp_sizeof(const struct nf_expect *exp) |
| { |
| assert(exp != NULL); |
| return sizeof(*exp); |
| } |
| |
| /** |
| * nfexp_maxsize - return the maximum size in bytes of a expect object |
| * |
| * Use this function if you want to allocate a expect object in the stack |
| * instead of the heap. For example: |
| * |
| * char buf[nfexp_maxsize()]; |
| * struct nf_expect *exp = (struct nf_expect *) buf; |
| * memset(exp, 0, nfexp_maxsize()); |
| * |
| * Note: As for now this function returns the same size that nfexp_sizeof(exp) |
| * does although _this could change in the future_. Therefore, do not assume |
| * that nfexp_sizeof(exp) == nfexp_maxsize(). |
| */ |
| size_t nfexp_maxsize(void) |
| { |
| return sizeof(struct nf_expect); |
| } |
| |
| /** |
| * nfexp_clone - clone a expectation object |
| * \param exp pointer to a valid expectation object |
| * |
| * On error, NULL is returned and errno is appropiately set. Otherwise, |
| * a valid pointer to the clone expect is returned. |
| */ |
| struct nf_expect *nfexp_clone(const struct nf_expect *exp) |
| { |
| struct nf_expect *clone; |
| |
| assert(exp != NULL); |
| |
| if ((clone = nfexp_new()) == NULL) |
| return NULL; |
| memcpy(clone, exp, sizeof(*exp)); |
| |
| return clone; |
| } |
| |
| /** |
| * nfexp_cmp - compare two expectation objects |
| * \param exp1 pointer to a valid expectation object |
| * \param exp2 pointer to a valid expectation object |
| * \param flags flags |
| * |
| * This function only compare attribute set in both objects, by default |
| * the comparison is not strict, ie. if a certain attribute is not set in one |
| * of the objects, then such attribute is not used in the comparison. |
| * If you want more strict comparisons, you can use the appropriate flags |
| * to modify this behaviour (see NFCT_CMP_STRICT and NFCT_CMP_MASK). |
| * |
| * The available flags are: |
| * - NFCT_CMP_STRICT: the compared objects must have the same attributes |
| * and the same values, otherwise it returns that the objects are |
| * different. |
| * - NFCT_CMP_MASK: the first object is used as mask, this means that |
| * if an attribute is present in exp1 but not in exp2, this function |
| * returns that the objects are different. |
| * |
| * Other existing flags that are used by nfct_cmp() are ignored. |
| * |
| * If both conntrack object are equal, this function returns 1, otherwise |
| * 0 is returned. |
| */ |
| int nfexp_cmp(const struct nf_expect *exp1, const struct nf_expect *exp2, |
| unsigned int flags) |
| { |
| assert(exp1 != NULL); |
| assert(exp2 != NULL); |
| |
| return __cmp_expect(exp1, exp2, flags); |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * \defgroup LibrarySetup Library setup |
| * @{ |
| */ |
| |
| /** |
| * nfexp_callback_register - register a callback |
| * \param h library handler |
| * \param cb callback used to process expect received |
| * \param data data used by the callback, if any. |
| * |
| * This function register a callback to handle the expect received, |
| * in case of error -1 is returned and errno is set appropiately, otherwise |
| * 0 is returned. |
| * |
| * Note that the data parameter is optional, if you do not want to pass any |
| * data to your callback, then use NULL. |
| */ |
| int nfexp_callback_register(struct nfct_handle *h, |
| enum nf_conntrack_msg_type type, |
| int (*cb)(enum nf_conntrack_msg_type type, |
| struct nf_expect *exp, |
| void *data), |
| void *data) |
| { |
| struct __data_container *container; |
| |
| assert(h != NULL); |
| |
| container = malloc(sizeof(struct __data_container)); |
| if (!container) |
| return -1; |
| memset(container, 0, sizeof(struct __data_container)); |
| |
| h->expect_cb = cb; |
| container->h = h; |
| container->type = type; |
| container->data = data; |
| |
| h->nfnl_cb_exp.call = __callback; |
| h->nfnl_cb_exp.data = container; |
| h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX; |
| |
| nfnl_callback_register(h->nfnlssh_exp, |
| IPCTNL_MSG_EXP_NEW, |
| &h->nfnl_cb_exp); |
| |
| nfnl_callback_register(h->nfnlssh_exp, |
| IPCTNL_MSG_EXP_DELETE, |
| &h->nfnl_cb_exp); |
| |
| return 0; |
| } |
| |
| /** |
| * nfexp_callback_unregister - unregister a callback |
| * \param h library handler |
| */ |
| void nfexp_callback_unregister(struct nfct_handle *h) |
| { |
| assert(h != NULL); |
| |
| nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW); |
| nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE); |
| |
| h->expect_cb = NULL; |
| free(h->nfnl_cb_exp.data); |
| |
| h->nfnl_cb_exp.call = NULL; |
| h->nfnl_cb_exp.data = NULL; |
| h->nfnl_cb_exp.attr_count = 0; |
| } |
| |
| /** |
| * nfexp_callback_register2 - register a callback |
| * \param h library handler |
| * \param cb callback used to process expect received |
| * \param data data used by the callback, if any. |
| * |
| * This function register a callback to handle the expect received, |
| * in case of error -1 is returned and errno is set appropiately, otherwise |
| * 0 is returned. |
| * |
| * Note that the data parameter is optional, if you do not want to pass any |
| * data to your callback, then use NULL. |
| * |
| * NOTICE: The difference with nfexp_callback_register() is that this function |
| * uses the new callback interface that includes the Netlink header. |
| * |
| * WARNING: Don't mix nfexp_callback_register() and nfexp_callback_register2() |
| * calls, use only once at a time. |
| */ |
| int nfexp_callback_register2(struct nfct_handle *h, |
| enum nf_conntrack_msg_type type, |
| int (*cb)(const struct nlmsghdr *nlh, |
| enum nf_conntrack_msg_type type, |
| struct nf_expect *exp, |
| void *data), |
| void *data) |
| { |
| struct __data_container *container; |
| |
| assert(h != NULL); |
| |
| container = malloc(sizeof(struct __data_container)); |
| if (!container) |
| return -1; |
| memset(container, 0, sizeof(struct __data_container)); |
| |
| h->expect_cb2 = cb; |
| container->h = h; |
| container->type = type; |
| container->data = data; |
| |
| h->nfnl_cb_exp.call = __callback; |
| h->nfnl_cb_exp.data = container; |
| h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX; |
| |
| nfnl_callback_register(h->nfnlssh_exp, |
| IPCTNL_MSG_EXP_NEW, |
| &h->nfnl_cb_exp); |
| |
| nfnl_callback_register(h->nfnlssh_exp, |
| IPCTNL_MSG_EXP_DELETE, |
| &h->nfnl_cb_exp); |
| |
| return 0; |
| } |
| |
| /** |
| * nfexp_callback_unregister2 - unregister a callback |
| * \param h library handler |
| */ |
| void nfexp_callback_unregister2(struct nfct_handle *h) |
| { |
| assert(h != NULL); |
| |
| nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW); |
| nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE); |
| |
| h->expect_cb2 = NULL; |
| free(h->nfnl_cb_exp.data); |
| |
| h->nfnl_cb_exp.call = NULL; |
| h->nfnl_cb_exp.data = NULL; |
| h->nfnl_cb_exp.attr_count = 0; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * \defgroup exp Expect object handling |
| * @{ |
| */ |
| |
| /** |
| * nfexp_set_attr - set the value of a certain expect attribute |
| * \param exp pointer to a valid expect |
| * \param type attribute type |
| * \param value pointer to the attribute value |
| * |
| * Note that certain attributes are unsettable: |
| * - ATTR_EXP_USE |
| * - ATTR_EXP_ID |
| * - ATTR_EXP_*_COUNTER_* |
| * The call of this function for such attributes do nothing. |
| */ |
| void nfexp_set_attr(struct nf_expect *exp, |
| const enum nf_expect_attr type, |
| const void *value) |
| { |
| assert(exp != NULL); |
| assert(value != NULL); |
| |
| if (type >= ATTR_EXP_MAX) |
| return; |
| |
| if (set_exp_attr_array[type]) { |
| set_exp_attr_array[type](exp, value); |
| set_bit(type, exp->set); |
| } |
| } |
| |
| /** |
| * nfexp_set_attr_u8 - set the value of a certain expect attribute |
| * \param exp pointer to a valid expect |
| * \param type attribute type |
| * \param value unsigned 8 bits attribute value |
| */ |
| void nfexp_set_attr_u8(struct nf_expect *exp, |
| const enum nf_expect_attr type, |
| uint8_t value) |
| { |
| nfexp_set_attr(exp, type, &value); |
| } |
| |
| /** |
| * nfexp_set_attr_u16 - set the value of a certain expect attribute |
| * \param exp pointer to a valid expect |
| * \param type attribute type |
| * \param value unsigned 16 bits attribute value |
| */ |
| void nfexp_set_attr_u16(struct nf_expect *exp, |
| const enum nf_expect_attr type, |
| uint16_t value) |
| { |
| nfexp_set_attr(exp, type, &value); |
| } |
| |
| /** |
| * nfexp_set_attr_u32 - set the value of a certain expect attribute |
| * \param exp pointer to a valid expect |
| * \param type attribute type |
| * \param value unsigned 32 bits attribute value |
| */ |
| void nfexp_set_attr_u32(struct nf_expect *exp, |
| const enum nf_expect_attr type, |
| uint32_t value) |
| { |
| nfexp_set_attr(exp, type, &value); |
| } |
| |
| /** |
| * nfexp_get_attr - get an expect attribute |
| * \param exp pointer to a valid expect |
| * \param type attribute type |
| * |
| * In case of success a valid pointer to the attribute requested is returned, |
| * on error NULL is returned and errno is set appropiately. |
| */ |
| const void *nfexp_get_attr(const struct nf_expect *exp, |
| const enum nf_expect_attr type) |
| { |
| assert(exp != NULL); |
| |
| if (type >= ATTR_EXP_MAX) { |
| errno = EINVAL; |
| return NULL; |
| } |
| |
| if (!test_bit(type, exp->set)) { |
| errno = ENODATA; |
| return NULL; |
| } |
| |
| return get_exp_attr_array[type](exp); |
| } |
| |
| /** |
| * nfexp_get_attr_u8 - get attribute of unsigned 8-bits long |
| * \param exp pointer to a valid expectation |
| * \param type attribute type |
| * |
| * Returns the value of the requested attribute, if the attribute is not |
| * set, 0 is returned. In order to check if the attribute is set or not, |
| * use nfexp_attr_is_set. |
| */ |
| uint8_t nfexp_get_attr_u8(const struct nf_expect *exp, |
| const enum nf_expect_attr type) |
| { |
| const uint8_t *ret = nfexp_get_attr(exp, type); |
| return ret == NULL ? 0 : *ret; |
| } |
| |
| /** |
| * nfexp_get_attr_u16 - get attribute of unsigned 16-bits long |
| * \param exp pointer to a valid expectation |
| * \param type attribute type |
| * |
| * Returns the value of the requested attribute, if the attribute is not |
| * set, 0 is returned. In order to check if the attribute is set or not, |
| * use nfexp_attr_is_set. |
| */ |
| uint16_t nfexp_get_attr_u16(const struct nf_expect *exp, |
| const enum nf_expect_attr type) |
| { |
| const uint16_t *ret = nfexp_get_attr(exp, type); |
| return ret == NULL ? 0 : *ret; |
| } |
| |
| /** |
| * nfexp_get_attr_u32 - get attribute of unsigned 32-bits long |
| * \param exp pointer to a valid expectation |
| * \param type attribute type |
| * |
| * Returns the value of the requested attribute, if the attribute is not |
| * set, 0 is returned. In order to check if the attribute is set or not, |
| * use nfexp_attr_is_set. |
| */ |
| uint32_t nfexp_get_attr_u32(const struct nf_expect *exp, |
| const enum nf_expect_attr type) |
| { |
| const uint32_t *ret = nfexp_get_attr(exp, type); |
| return ret == NULL ? 0 : *ret; |
| } |
| |
| /** |
| * nfexp_attr_is_set - check if a certain attribute is set |
| * \param exp pointer to a valid expectation object |
| * \param type attribute type |
| * |
| * On error, -1 is returned and errno is set appropiately, otherwise |
| * the value of the attribute is returned. |
| */ |
| int nfexp_attr_is_set(const struct nf_expect *exp, |
| const enum nf_expect_attr type) |
| { |
| assert(exp != NULL); |
| |
| if (type >= ATTR_EXP_MAX) { |
| errno = EINVAL; |
| return -1; |
| } |
| return test_bit(type, exp->set); |
| } |
| |
| /** |
| * nfexp_attr_unset - unset a certain attribute |
| * \param type attribute type |
| * \param exp pointer to a valid expectation object |
| * |
| * On error, -1 is returned and errno is set appropiately, otherwise |
| * 0 is returned. |
| */ |
| int nfexp_attr_unset(struct nf_expect *exp, |
| const enum nf_expect_attr type) |
| { |
| assert(exp != NULL); |
| |
| if (type >= ATTR_EXP_MAX) { |
| errno = EINVAL; |
| return -1; |
| } |
| unset_bit(type, exp->set); |
| |
| return 0; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * \defgroup nl Low level object to Netlink message |
| * @{ |
| */ |
| |
| /** |
| * nfexp_build_expect - build a netlink message from a conntrack object |
| * \param ssh nfnetlink subsystem handler |
| * \param req buffer used to build the netlink message |
| * \param size size of the buffer passed |
| * \param type netlink message type |
| * \param flags netlink flags |
| * \param exp pointer to a conntrack object |
| * |
| * This is a low level function for those that require to be close to |
| * netlink details via libnfnetlink. If you do want to obviate the netlink |
| * details then we suggest you to use nfexp_query. |
| * |
| * On error, -1 is returned and errno is appropiately set. |
| * On success, 0 is returned. |
| */ |
| int nfexp_build_expect(struct nfnl_subsys_handle *ssh, |
| void *req, |
| size_t size, |
| uint16_t type, |
| uint16_t flags, |
| const struct nf_expect *exp) |
| { |
| assert(ssh != NULL); |
| assert(req != NULL); |
| assert(exp != NULL); |
| |
| return __build_expect(ssh, req, size, type, flags, exp); |
| } |
| |
| static int |
| __build_query_exp(struct nfnl_subsys_handle *ssh, |
| const enum nf_conntrack_query qt, |
| const void *data, void *buffer, unsigned int size) |
| { |
| struct nfnlhdr *req = buffer; |
| const uint8_t *family = data; |
| |
| assert(ssh != NULL); |
| assert(data != NULL); |
| assert(req != NULL); |
| |
| memset(req, 0, size); |
| |
| switch(qt) { |
| case NFCT_Q_CREATE: |
| __build_expect(ssh, req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data); |
| break; |
| case NFCT_Q_CREATE_UPDATE: |
| __build_expect(ssh, req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data); |
| break; |
| case NFCT_Q_GET: |
| __build_expect(ssh, req, size, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_ACK, data); |
| break; |
| case NFCT_Q_DESTROY: |
| __build_expect(ssh, req, size, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK, data); |
| break; |
| case NFCT_Q_FLUSH: |
| nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK); |
| break; |
| case NFCT_Q_DUMP: |
| nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_DUMP); |
| break; |
| default: |
| errno = ENOTSUP; |
| return -1; |
| } |
| return 1; |
| } |
| |
| /** |
| * nfexp_build_query - build a query in netlink message format for ctnetlink |
| * \param ssh nfnetlink subsystem handler |
| * \param qt query type |
| * \param data data required to build the query |
| * \param req buffer to build the netlink message |
| * \param size size of the buffer passed |
| * |
| * This is a low level function, use it if you want to require to work |
| * with netlink details via libnfnetlink, otherwise we suggest you to |
| * use nfexp_query. |
| * |
| * The pointer to data can be a conntrack object or the protocol family |
| * depending on the request. |
| * |
| * For query types: |
| * NFEXP_Q_CREATE |
| * NFEXP_Q_DESTROY |
| * |
| * Pass a valid pointer to an expectation object. |
| * |
| * For query types: |
| * NFEXP_Q_FLUSH |
| * NFEXP_Q_DUMP |
| * |
| * Pass a valid pointer to the protocol family (uint8_t) |
| * |
| * On success, 0 is returned. On error, -1 is returned and errno is set |
| * appropiately. |
| */ |
| int nfexp_build_query(struct nfnl_subsys_handle *ssh, |
| const enum nf_conntrack_query qt, |
| const void *data, |
| void *buffer, |
| unsigned int size) |
| { |
| return __build_query_exp(ssh, qt, data, buffer, size); |
| } |
| |
| /** |
| * nfexp_parse_expect - translate a netlink message to a conntrack object |
| * \param type do the translation iif the message type is of a certain type |
| * \param nlh pointer to the netlink message |
| * \param exp pointer to the conntrack object |
| * |
| * This is a low level function, use it in case that you require to work |
| * with netlink details via libnfnetlink. Otherwise, we suggest you to |
| * use the high level API. |
| * |
| * The message types are: |
| * |
| * NFEXP_T_NEW: parse messages with new conntracks |
| * NFEXP_T_UPDATE: parse messages with conntrack updates |
| * NFEXP_T_DESTROY: parse messages with conntrack destroy |
| * NFEXP_T_ALL: all message types |
| * |
| * The message type is a flag, therefore the can be combined, ie. |
| * NFEXP_T_NEW | NFEXP_T_DESTROY to parse only new and destroy messages |
| * |
| * On error, NFEXP_T_ERROR is returned and errno is set appropiately. If |
| * the message received is not of the requested type then 0 is returned, |
| * otherwise this function returns the message type parsed. |
| */ |
| int nfexp_parse_expect(enum nf_conntrack_msg_type type, |
| const struct nlmsghdr *nlh, |
| struct nf_expect *exp) |
| { |
| unsigned int flags; |
| int len = nlh->nlmsg_len; |
| struct nfgenmsg *nfhdr = NLMSG_DATA(nlh); |
| struct nfattr *cda[CTA_EXPECT_MAX]; |
| |
| assert(nlh != NULL); |
| assert(exp != NULL); |
| |
| len -= NLMSG_LENGTH(sizeof(struct nfgenmsg)); |
| if (len < 0) { |
| errno = EINVAL; |
| return NFCT_T_ERROR; |
| } |
| |
| flags = __parse_expect_message_type(nlh); |
| if (!(flags & type)) |
| return 0; |
| |
| nfnl_parse_attr(cda, CTA_EXPECT_MAX, NFA_DATA(nfhdr), len); |
| |
| __parse_expect(nlh, cda, exp); |
| |
| return flags; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * \defgroup cmd Send commands to kernel-space and receive replies |
| * @{ |
| */ |
| |
| /** |
| * nfexp_query - send a query to ctnetlink |
| * \param h library handler |
| * \param qt query type |
| * \param data data required to send the query |
| * |
| * On error, -1 is returned and errno is explicitely set. On success, 0 |
| * is returned. |
| */ |
| int nfexp_query(struct nfct_handle *h, |
| const enum nf_conntrack_query qt, |
| const void *data) |
| { |
| const size_t size = 4096; /* enough for now */ |
| union { |
| char buffer[size]; |
| struct nfnlhdr req; |
| } u; |
| |
| assert(h != NULL); |
| assert(data != NULL); |
| |
| if (__build_query_exp(h->nfnlssh_exp, qt, data, &u.req, size) == -1) |
| return -1; |
| |
| return nfnl_query(h->nfnlh, &u.req.nlh); |
| } |
| |
| /** |
| * nfexp_send - send a query to ctnetlink |
| * \param h library handler |
| * \param qt query type |
| * \param data data required to send the query |
| * |
| * Like nfexp_query but we do not wait for the reply from ctnetlink. |
| * You can use nfexp_send() and nfexp_catch() to emulate nfexp_query(). |
| * This is particularly useful when the socket is non-blocking. |
| * |
| * On error, -1 is returned and errno is explicitely set. On success, 0 |
| * is returned. |
| */ |
| int nfexp_send(struct nfct_handle *h, |
| const enum nf_conntrack_query qt, |
| const void *data) |
| { |
| const size_t size = 4096; /* enough for now */ |
| union { |
| char buffer[size]; |
| struct nfnlhdr req; |
| } u; |
| |
| assert(h != NULL); |
| assert(data != NULL); |
| |
| if (__build_query_exp(h->nfnlssh_exp, qt, data, &u.req, size) == -1) |
| return -1; |
| |
| return nfnl_send(h->nfnlh, &u.req.nlh); |
| } |
| |
| /** |
| * nfexp_catch - catch events |
| * \param h library handler |
| * |
| * This function receives the event from the kernel and it invokes the |
| * callback that was registered to this handle. |
| * |
| * On error, -1 is returned and errno is set appropiately. On success, |
| * a value greater or equal to 0 is returned indicating the callback |
| * verdict: NFCT_CB_STOP, NFCT_CB_CONTINUE or NFCT_CB_STOLEN. |
| * |
| * Beware that this function is equivalent to nfct_catch(), so it handles both |
| * conntrack and expectation events. |
| */ |
| int nfexp_catch(struct nfct_handle *h) |
| { |
| assert(h != NULL); |
| |
| return nfnl_catch(h->nfnlh); |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * \defgroup exp Expect object handling |
| * @{ |
| */ |
| |
| /** |
| * nfexp_snprintf - print a conntrack object to a buffer |
| * \param buf buffer used to build the printable conntrack |
| * \param size size of the buffer |
| * \param exp pointer to a valid expectation object |
| * \param message_type print message type (NFEXP_T_UNKNOWN, NFEXP_T_NEW,...) |
| * \param output_type print type (NFEXP_O_DEFAULT, NFEXP_O_XML, ...) |
| * \param flags extra flags for the output type (NFEXP_OF_LAYER3) |
| * |
| * If you are listening to events, probably you want to display the message |
| * type as well. In that case, set the message type parameter to any of the |
| * known existing types, ie. NFEXP_T_NEW, NFEXP_T_UPDATE, NFEXP_T_DESTROY. |
| * If you pass NFEXP_T_UNKNOWN, the message type will not be output. |
| * |
| * Currently, the output available are: |
| * - NFEXP_O_DEFAULT: default /proc-like output |
| * - NFEXP_O_XML: XML output |
| * |
| * The output flags are: |
| * - NFEXP_O_LAYER: include layer 3 information in the output, this is |
| * *only* required by NFEXP_O_DEFAULT. |
| * |
| * On error, -1 is returned and errno is set appropiately. Otherwise, |
| * 0 is returned. |
| */ |
| int nfexp_snprintf(char *buf, |
| unsigned int size, |
| const struct nf_expect *exp, |
| unsigned int msg_type, |
| unsigned int out_type, |
| unsigned int flags) |
| { |
| assert(buf != NULL); |
| assert(size > 0); |
| assert(exp != NULL); |
| |
| return __snprintf_expect(buf, size, exp, msg_type, out_type, flags); |
| } |
| |
| /** |
| * @} |
| */ |