diff options
Diffstat (limited to 'lib/netfilter/log_msg_obj.c')
-rw-r--r-- | lib/netfilter/log_msg_obj.c | 258 |
1 files changed, 236 insertions, 22 deletions
diff --git a/lib/netfilter/log_msg_obj.c b/lib/netfilter/log_msg_obj.c index 90b7bc93..6b26bc58 100644 --- a/lib/netfilter/log_msg_obj.c +++ b/lib/netfilter/log_msg_obj.c @@ -1,12 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-only */ /* - * lib/netfilter/log_msg_obj.c Netfilter Log Object - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> * Copyright (c) 2007 Secure Computing Corporation @@ -34,6 +27,13 @@ #define LOG_MSG_ATTR_GID (1UL << 13) #define LOG_MSG_ATTR_SEQ (1UL << 14) #define LOG_MSG_ATTR_SEQ_GLOBAL (1UL << 15) +#define LOG_MSG_ATTR_HWTYPE (1UL << 16) +#define LOG_MSG_ATTR_HWLEN (1UL << 17) +#define LOG_MSG_ATTR_HWHEADER (1UL << 18) +#define LOG_MSG_ATTR_VLAN_PROTO (1UL << 19) +#define LOG_MSG_ATTR_VLAN_TAG (1UL << 20) +#define LOG_MSG_ATTR_CT_INFO (1UL << 21) +#define LOG_MSG_ATTR_CT (1UL << 22) /** @endcond */ static void log_msg_free_data(struct nl_object *c) @@ -45,6 +45,9 @@ static void log_msg_free_data(struct nl_object *c) free(msg->log_msg_payload); free(msg->log_msg_prefix); + free(msg->log_msg_hwheader); + if (msg->log_msg_ct) + nfnl_ct_put(msg->log_msg_ct); } static int log_msg_clone(struct nl_object *_dst, struct nl_object *_src) @@ -53,22 +56,41 @@ static int log_msg_clone(struct nl_object *_dst, struct nl_object *_src) struct nfnl_log_msg *src = (struct nfnl_log_msg *) _src; int err; + dst->log_msg_payload = NULL; + dst->log_msg_payload_len = 0; + dst->log_msg_prefix = NULL; + dst->log_msg_hwheader = NULL; + dst->log_msg_hwheader_len = 0; + dst->log_msg_ct = NULL; + if (src->log_msg_payload) { err = nfnl_log_msg_set_payload(dst, src->log_msg_payload, - src->log_msg_payload_len); + src->log_msg_payload_len); if (err < 0) - goto errout; + return err; } if (src->log_msg_prefix) { err = nfnl_log_msg_set_prefix(dst, src->log_msg_prefix); if (err < 0) - goto errout; + return err; + } + + if (src->log_msg_hwheader) { + err = nfnl_log_msg_set_hwheader(dst, src->log_msg_hwheader, + src->log_msg_hwheader_len); + if (err < 0) + return err; + } + + if (src->log_msg_ct) { + dst->log_msg_ct = (struct nfnl_ct *) nl_object_clone((struct nl_object *) src->log_msg_ct); + if (!dst->log_msg_ct) { + return -NLE_NOMEM; + } } return 0; -errout: - return err; } static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) @@ -101,7 +123,7 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) msg->log_msg_physindev, buf, sizeof(buf))); else - nl_dump(p, "IN=%d ", msg->log_msg_physindev); + nl_dump(p, "PHYSIN=%d ", msg->log_msg_physindev); } if (msg->ce_mask & LOG_MSG_ATTR_OUTDEV) { @@ -167,8 +189,35 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) if (msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL) nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global); + if (msg->ce_mask & LOG_MSG_ATTR_HWTYPE) + nl_dump(p, "HWTYPE=%u ", msg->log_msg_hwtype); + + if (msg->ce_mask & LOG_MSG_ATTR_HWLEN) + nl_dump(p, "HWLEN=%u ", msg->log_msg_hwlen); + + if (msg->ce_mask & LOG_MSG_ATTR_HWHEADER) { + int i; + + nl_dump(p, "HWHEADER"); + for (i = 0; i < msg->log_msg_hwheader_len; i++) + nl_dump(p, "%c%02x", i?':':'=', ((uint8_t*) msg->log_msg_hwheader) [i]); + nl_dump(p, " "); + } + + if (msg->ce_mask & LOG_MSG_ATTR_VLAN_TAG) + nl_dump(p, "VLAN=%d CFI=%d PRIO=%d", + (int) nfnl_log_msg_get_vlan_id(msg), + (int) nfnl_log_msg_get_vlan_cfi(msg), + (int) nfnl_log_msg_get_vlan_prio(msg)); + + if (msg->ce_mask & LOG_MSG_ATTR_CT_INFO) + nl_dump(p, "CTINFO=%u ", msg->log_msg_ct_info); + nl_dump(p, "\n"); + if (msg->ce_mask & LOG_MSG_ATTR_CT) + ct_obj_ops.oo_dump[NL_DUMP_LINE]((struct nl_object *)msg->log_msg_ct, p); + if (link_cache) nl_cache_put(link_cache); } @@ -342,14 +391,22 @@ const uint8_t *nfnl_log_msg_get_hwaddr(const struct nfnl_log_msg *msg, int *len) int nfnl_log_msg_set_payload(struct nfnl_log_msg *msg, uint8_t *payload, int len) { - free(msg->log_msg_payload); - msg->log_msg_payload = malloc(len); - if (!msg->log_msg_payload) + uint8_t *p = NULL; + + if (len < 0) + return -NLE_INVAL; + + p = _nl_memdup(payload, len); + if (!p && len > 0) return -NLE_NOMEM; - memcpy(msg->log_msg_payload, payload, len); + free(msg->log_msg_payload); + msg->log_msg_payload = p; msg->log_msg_payload_len = len; - msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD; + if (len > 0) + msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD; + else + msg->ce_mask &= ~LOG_MSG_ATTR_PAYLOAD; return 0; } @@ -366,12 +423,21 @@ const void *nfnl_log_msg_get_payload(const struct nfnl_log_msg *msg, int *len) int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix) { + char *p = NULL; + + if (prefix) { + p = strdup(prefix); + if (!p) + return -NLE_NOMEM; + } + free(msg->log_msg_prefix); - msg->log_msg_prefix = strdup(prefix); - if (!msg->log_msg_prefix) - return -NLE_NOMEM; + msg->log_msg_prefix = p; - msg->ce_mask |= LOG_MSG_ATTR_PREFIX; + if (p) + msg->ce_mask |= LOG_MSG_ATTR_PREFIX; + else + msg->ce_mask &= ~LOG_MSG_ATTR_PREFIX; return 0; } @@ -445,6 +511,154 @@ uint32_t nfnl_log_msg_get_seq_global(const struct nfnl_log_msg *msg) return msg->log_msg_seq_global; } +void nfnl_log_msg_set_hwtype(struct nfnl_log_msg *msg, uint16_t hwtype) +{ + msg->log_msg_hwtype = hwtype; + msg->ce_mask |= LOG_MSG_ATTR_HWTYPE; +} + +int nfnl_log_msg_test_hwtype(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_HWTYPE); +} + +uint16_t nfnl_log_msg_get_hwtype(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_hwtype; +} + +void nfnl_log_msg_set_hwlen(struct nfnl_log_msg *msg, uint16_t hwlen) +{ + msg->log_msg_hwlen = hwlen; + msg->ce_mask |= LOG_MSG_ATTR_HWLEN; +} + +int nfnl_log_msg_test_hwlen(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_HWLEN); +} + +uint16_t nfnl_log_msg_get_hwlen(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_hwlen; +} + +int nfnl_log_msg_set_hwheader(struct nfnl_log_msg *msg, void *data, int len) +{ + void *p = NULL; + + if (len < 0) + return -NLE_INVAL; + + p = _nl_memdup(data, len); + if (!p && len > 0) + return -NLE_NOMEM; + + free(msg->log_msg_hwheader); + msg->log_msg_hwheader = p; + msg->log_msg_hwheader_len = len; + if (len > 0) + msg->ce_mask |= LOG_MSG_ATTR_HWHEADER; + else + msg->ce_mask &= ~LOG_MSG_ATTR_HWHEADER; + return 0; +} + +int nfnl_log_msg_test_hwheader(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_HWHEADER); +} + +const void *nfnl_log_msg_get_hwheader(const struct nfnl_log_msg *msg, int *len) +{ + if (!(msg->ce_mask & LOG_MSG_ATTR_HWHEADER)) { + *len = 0; + return NULL; + } + + *len = msg->log_msg_hwheader_len; + return msg->log_msg_hwheader; +} + +void nfnl_log_msg_set_vlan_proto(struct nfnl_log_msg *msg, uint16_t vlan_proto) +{ + msg->log_msg_vlan_proto = vlan_proto; + msg->ce_mask |= LOG_MSG_ATTR_VLAN_PROTO; +} + +int nfnl_log_msg_test_vlan_proto(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_VLAN_PROTO); +} + +uint16_t nfnl_log_msg_get_vlan_proto(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_vlan_proto; +} + +void nfnl_log_msg_set_vlan_tag(struct nfnl_log_msg *msg, uint16_t vlan_tag) +{ + msg->log_msg_vlan_tag = vlan_tag; + msg->ce_mask |= LOG_MSG_ATTR_VLAN_TAG; +} + +int nfnl_log_msg_test_vlan_tag(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_VLAN_TAG); +} + +uint16_t nfnl_log_msg_get_vlan_tag(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_vlan_tag; +} + +uint16_t nfnl_log_msg_get_vlan_id(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_vlan_tag & 0x0fff; +} + +uint16_t nfnl_log_msg_get_vlan_cfi(const struct nfnl_log_msg *msg) +{ + return !!(msg->log_msg_vlan_tag & 0x1000); +} + +uint16_t nfnl_log_msg_get_vlan_prio(const struct nfnl_log_msg *msg) +{ + return (msg->log_msg_vlan_tag & 0xe000 ) >> 13; +} + +void nfnl_log_msg_set_ct_info(struct nfnl_log_msg *msg, uint32_t ct_info) +{ + msg->log_msg_ct_info = ct_info; + msg->ce_mask |= LOG_MSG_ATTR_CT_INFO; +} + +int nfnl_log_msg_test_ct_info(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_CT_INFO); +} + +uint32_t nfnl_log_msg_get_ct_info(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_ct_info; +} + +void nfnl_log_msg_set_ct(struct nfnl_log_msg *msg, struct nfnl_ct *ct) +{ + msg->log_msg_ct = (struct nfnl_ct *) nl_object_clone((struct nl_object *)ct); + msg->ce_mask |= LOG_MSG_ATTR_CT; +} + +int nfnl_log_msg_test_ct(const struct nfnl_log_msg *msg) +{ + return !!(msg->ce_mask & LOG_MSG_ATTR_CT); +} + +struct nfnl_ct *nfnl_log_msg_get_ct(const struct nfnl_log_msg *msg) +{ + return msg->log_msg_ct; +} + /** @} */ struct nl_object_ops log_msg_obj_ops = { |