8#include <netlink-private/netlink.h> 
    9#include <netlink/netfilter/nfnl.h> 
   10#include <netlink/netfilter/netfilter.h> 
   11#include <netlink/netfilter/log_msg.h> 
   14#define LOG_MSG_ATTR_FAMILY             (1UL << 0) 
   15#define LOG_MSG_ATTR_HWPROTO            (1UL << 1) 
   16#define LOG_MSG_ATTR_HOOK               (1UL << 2) 
   17#define LOG_MSG_ATTR_MARK               (1UL << 3) 
   18#define LOG_MSG_ATTR_TIMESTAMP          (1UL << 4) 
   19#define LOG_MSG_ATTR_INDEV              (1UL << 5) 
   20#define LOG_MSG_ATTR_OUTDEV             (1UL << 6) 
   21#define LOG_MSG_ATTR_PHYSINDEV          (1UL << 7) 
   22#define LOG_MSG_ATTR_PHYSOUTDEV         (1UL << 8) 
   23#define LOG_MSG_ATTR_HWADDR             (1UL << 9) 
   24#define LOG_MSG_ATTR_PAYLOAD            (1UL << 10) 
   25#define LOG_MSG_ATTR_PREFIX             (1UL << 11) 
   26#define LOG_MSG_ATTR_UID                (1UL << 12) 
   27#define LOG_MSG_ATTR_GID                (1UL << 13) 
   28#define LOG_MSG_ATTR_SEQ                (1UL << 14) 
   29#define LOG_MSG_ATTR_SEQ_GLOBAL         (1UL << 15) 
   30#define LOG_MSG_ATTR_HWTYPE             (1UL << 16) 
   31#define LOG_MSG_ATTR_HWLEN              (1UL << 17) 
   32#define LOG_MSG_ATTR_HWHEADER           (1UL << 18) 
   33#define LOG_MSG_ATTR_VLAN_PROTO         (1UL << 19) 
   34#define LOG_MSG_ATTR_VLAN_TAG           (1UL << 20) 
   35#define LOG_MSG_ATTR_CT_INFO            (1UL << 21) 
   36#define LOG_MSG_ATTR_CT                 (1UL << 22) 
   39static void log_msg_free_data(
struct nl_object *c)
 
   41        struct nfnl_log_msg *msg = (
struct nfnl_log_msg *) c;
 
   46        free(msg->log_msg_payload);
 
   47        free(msg->log_msg_prefix);
 
   48        free(msg->log_msg_hwheader);
 
   50                nfnl_ct_put(msg->log_msg_ct);
 
   53static int log_msg_clone(
struct nl_object *_dst, 
struct nl_object *_src)
 
   55        struct nfnl_log_msg *dst = (
struct nfnl_log_msg *) _dst;
 
   56        struct nfnl_log_msg *src = (
struct nfnl_log_msg *) _src;
 
   59        dst->log_msg_payload = NULL;
 
   60        dst->log_msg_payload_len = 0;
 
   61        dst->log_msg_prefix = NULL;
 
   62        dst->log_msg_hwheader = NULL;
 
   63        dst->log_msg_hwheader_len = 0;
 
   64        dst->log_msg_ct = NULL;
 
   66        if (src->log_msg_payload) {
 
   67                err = nfnl_log_msg_set_payload(dst, src->log_msg_payload,
 
   68                                               src->log_msg_payload_len);
 
   73        if (src->log_msg_prefix) {
 
   74                err = nfnl_log_msg_set_prefix(dst, src->log_msg_prefix);
 
   79        if (src->log_msg_hwheader) {
 
   80                err = nfnl_log_msg_set_hwheader(dst, src->log_msg_hwheader,
 
   81                                                src->log_msg_hwheader_len);
 
   86        if (src->log_msg_ct) {
 
   87                dst->log_msg_ct = (
struct nfnl_ct *) 
nl_object_clone((
struct nl_object *) src->log_msg_ct);
 
   88                if (!dst->log_msg_ct) {
 
   96static void log_msg_dump(
struct nl_object *a, 
struct nl_dump_params *p)
 
   98        struct nfnl_log_msg *msg = (
struct nfnl_log_msg *) a;
 
   99        struct nl_cache *link_cache;
 
  106        if (msg->ce_mask & LOG_MSG_ATTR_PREFIX)
 
  107                nl_dump(p, 
"%s", msg->log_msg_prefix);
 
  109        if (msg->ce_mask & LOG_MSG_ATTR_INDEV) {
 
  116                        nl_dump(p, 
"IN=%d ", msg->log_msg_indev);
 
  119        if (msg->ce_mask & LOG_MSG_ATTR_PHYSINDEV) {
 
  123                                                 msg->log_msg_physindev,
 
  126                        nl_dump(p, 
"PHYSIN=%d ", msg->log_msg_physindev);
 
  129        if (msg->ce_mask & LOG_MSG_ATTR_OUTDEV) {
 
  136                        nl_dump(p, 
"OUT=%d ", msg->log_msg_outdev);
 
  139        if (msg->ce_mask & LOG_MSG_ATTR_PHYSOUTDEV) {
 
  143                                                 msg->log_msg_physoutdev,
 
  146                        nl_dump(p, 
"PHYSOUT=%d ", msg->log_msg_physoutdev);
 
  149        if (msg->ce_mask & LOG_MSG_ATTR_HWADDR) {
 
  153                for (i = 0; i < msg->log_msg_hwaddr_len; i++)
 
  154                        nl_dump(p, 
"%c%02x", i?
':':
'=', msg->log_msg_hwaddr[i]);
 
  160        if (msg->ce_mask & LOG_MSG_ATTR_FAMILY)
 
  162                        nl_af2str(msg->log_msg_family, buf, 
sizeof(buf)));
 
  164        if (msg->ce_mask & LOG_MSG_ATTR_HWPROTO)
 
  166                        nl_ether_proto2str(ntohs(msg->log_msg_hwproto),
 
  169        if (msg->ce_mask & LOG_MSG_ATTR_HOOK)
 
  171                        nfnl_inet_hook2str(msg->log_msg_hook,
 
  174        if (msg->ce_mask & LOG_MSG_ATTR_MARK)
 
  175                nl_dump(p, 
"MARK=%u ", msg->log_msg_mark);
 
  177        if (msg->ce_mask & LOG_MSG_ATTR_PAYLOAD)
 
  178                nl_dump(p, 
"PAYLOADLEN=%d ", msg->log_msg_payload_len);
 
  180        if (msg->ce_mask & LOG_MSG_ATTR_UID)
 
  181                nl_dump(p, 
"UID=%u ", msg->log_msg_uid);
 
  183        if (msg->ce_mask & LOG_MSG_ATTR_GID)
 
  184                nl_dump(p, 
"GID=%u ", msg->log_msg_gid);
 
  186        if (msg->ce_mask & LOG_MSG_ATTR_SEQ)
 
  187                nl_dump(p, 
"SEQ=%d ", msg->log_msg_seq);
 
  189        if (msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL)
 
  190                nl_dump(p, 
"SEQGLOBAL=%d ", msg->log_msg_seq_global);
 
  192        if (msg->ce_mask & LOG_MSG_ATTR_HWTYPE)
 
  193                nl_dump(p, 
"HWTYPE=%u ", msg->log_msg_hwtype);
 
  195        if (msg->ce_mask & LOG_MSG_ATTR_HWLEN)
 
  196                nl_dump(p, 
"HWLEN=%u ", msg->log_msg_hwlen);
 
  198        if (msg->ce_mask & LOG_MSG_ATTR_HWHEADER) {
 
  202                for (i = 0; i < msg->log_msg_hwheader_len; i++)
 
  203                        nl_dump(p, 
"%c%02x", i?
':':
'=', ((uint8_t*) msg->log_msg_hwheader) [i]);
 
  207        if (msg->ce_mask & LOG_MSG_ATTR_VLAN_TAG)
 
  208                nl_dump(p, 
"VLAN=%d CFI=%d PRIO=%d",
 
  209                        (
int) nfnl_log_msg_get_vlan_id(msg),
 
  210                        (
int) nfnl_log_msg_get_vlan_cfi(msg),
 
  211                        (
int) nfnl_log_msg_get_vlan_prio(msg));
 
  213        if (msg->ce_mask & LOG_MSG_ATTR_CT_INFO)
 
  214                nl_dump(p, 
"CTINFO=%u ", msg->log_msg_ct_info);
 
  218        if (msg->ce_mask & LOG_MSG_ATTR_CT)
 
  219                ct_obj_ops.oo_dump[
NL_DUMP_LINE]((
struct nl_object *)msg->log_msg_ct, p);
 
  222                nl_cache_put(link_cache);
 
  230struct nfnl_log_msg *nfnl_log_msg_alloc(
void)
 
  235void nfnl_log_msg_get(
struct nfnl_log_msg *msg)
 
  240void nfnl_log_msg_put(
struct nfnl_log_msg *msg)
 
  252void nfnl_log_msg_set_family(
struct nfnl_log_msg *msg, uint8_t family)
 
  254        msg->log_msg_family = family;
 
  255        msg->ce_mask |= LOG_MSG_ATTR_FAMILY;
 
  258uint8_t nfnl_log_msg_get_family(
const struct nfnl_log_msg *msg)
 
  260        if (msg->ce_mask & LOG_MSG_ATTR_FAMILY)
 
  261                return msg->log_msg_family;
 
  266void nfnl_log_msg_set_hwproto(
struct nfnl_log_msg *msg, uint16_t hwproto)
 
  268        msg->log_msg_hwproto = hwproto;
 
  269        msg->ce_mask |= LOG_MSG_ATTR_HWPROTO;
 
  272int nfnl_log_msg_test_hwproto(
const struct nfnl_log_msg *msg)
 
  274        return !!(msg->ce_mask & LOG_MSG_ATTR_HWPROTO);
 
  277uint16_t nfnl_log_msg_get_hwproto(
const struct nfnl_log_msg *msg)
 
  279        return msg->log_msg_hwproto;
 
  282void nfnl_log_msg_set_hook(
struct nfnl_log_msg *msg, uint8_t hook)
 
  284        msg->log_msg_hook = hook;
 
  285        msg->ce_mask |= LOG_MSG_ATTR_HOOK;
 
  288int nfnl_log_msg_test_hook(
const struct nfnl_log_msg *msg)
 
  290        return !!(msg->ce_mask & LOG_MSG_ATTR_HOOK);
 
  293uint8_t nfnl_log_msg_get_hook(
const struct nfnl_log_msg *msg)
 
  295        return msg->log_msg_hook;
 
  298void nfnl_log_msg_set_mark(
struct nfnl_log_msg *msg, uint32_t mark)
 
  300        msg->log_msg_mark = mark;
 
  301        msg->ce_mask |= LOG_MSG_ATTR_MARK;
 
  304int nfnl_log_msg_test_mark(
const struct nfnl_log_msg *msg)
 
  306        return !!(msg->ce_mask & LOG_MSG_ATTR_MARK);
 
  309uint32_t nfnl_log_msg_get_mark(
const struct nfnl_log_msg *msg)
 
  311        return msg->log_msg_mark;
 
  314void nfnl_log_msg_set_timestamp(
struct nfnl_log_msg *msg, 
struct timeval *tv)
 
  316        msg->log_msg_timestamp.tv_sec = tv->tv_sec;
 
  317        msg->log_msg_timestamp.tv_usec = tv->tv_usec;
 
  318        msg->ce_mask |= LOG_MSG_ATTR_TIMESTAMP;
 
  321const struct timeval *nfnl_log_msg_get_timestamp(
const struct nfnl_log_msg *msg)
 
  323        if (!(msg->ce_mask & LOG_MSG_ATTR_TIMESTAMP))
 
  325        return &msg->log_msg_timestamp;
 
  328void nfnl_log_msg_set_indev(
struct nfnl_log_msg *msg, uint32_t indev)
 
  330        msg->log_msg_indev = indev;
 
  331        msg->ce_mask |= LOG_MSG_ATTR_INDEV;
 
  334uint32_t nfnl_log_msg_get_indev(
const struct nfnl_log_msg *msg)
 
  336        return msg->log_msg_indev;
 
  339void nfnl_log_msg_set_outdev(
struct nfnl_log_msg *msg, uint32_t outdev)
 
  341        msg->log_msg_outdev = outdev;
 
  342        msg->ce_mask |= LOG_MSG_ATTR_OUTDEV;
 
  345uint32_t nfnl_log_msg_get_outdev(
const struct nfnl_log_msg *msg)
 
  347        return msg->log_msg_outdev;
 
  350void nfnl_log_msg_set_physindev(
struct nfnl_log_msg *msg, uint32_t physindev)
 
  352        msg->log_msg_physindev = physindev;
 
  353        msg->ce_mask |= LOG_MSG_ATTR_PHYSINDEV;
 
  356uint32_t nfnl_log_msg_get_physindev(
const struct nfnl_log_msg *msg)
 
  358        return msg->log_msg_physindev;
 
  361void nfnl_log_msg_set_physoutdev(
struct nfnl_log_msg *msg, uint32_t physoutdev)
 
  363        msg->log_msg_physoutdev = physoutdev;
 
  364        msg->ce_mask |= LOG_MSG_ATTR_PHYSOUTDEV;
 
  367uint32_t nfnl_log_msg_get_physoutdev(
const struct nfnl_log_msg *msg)
 
  369        return msg->log_msg_physoutdev;
 
  372void nfnl_log_msg_set_hwaddr(
struct nfnl_log_msg *msg, uint8_t *hwaddr, 
int len)
 
  374        if (len > 
sizeof(msg->log_msg_hwaddr))
 
  375                len = 
sizeof(msg->log_msg_hwaddr);
 
  376        msg->log_msg_hwaddr_len = len;
 
  377        memcpy(msg->log_msg_hwaddr, hwaddr, len);
 
  378        msg->ce_mask |= LOG_MSG_ATTR_HWADDR;
 
  381const uint8_t *nfnl_log_msg_get_hwaddr(
const struct nfnl_log_msg *msg, 
int *len)
 
  383        if (!(msg->ce_mask & LOG_MSG_ATTR_HWADDR)) {
 
  388        *len = msg->log_msg_hwaddr_len;
 
  389        return msg->log_msg_hwaddr;
 
  392int nfnl_log_msg_set_payload(
struct nfnl_log_msg *msg, uint8_t *payload, 
int len)
 
  399        p = _nl_memdup(payload, len);
 
  403        free(msg->log_msg_payload);
 
  404        msg->log_msg_payload = p;
 
  405        msg->log_msg_payload_len = len;
 
  407                msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD;
 
  409                msg->ce_mask &= ~LOG_MSG_ATTR_PAYLOAD;
 
  413const void *nfnl_log_msg_get_payload(
const struct nfnl_log_msg *msg, 
int *len)
 
  415        if (!(msg->ce_mask & LOG_MSG_ATTR_PAYLOAD)) {
 
  420        *len = msg->log_msg_payload_len;
 
  421        return msg->log_msg_payload;
 
  424int nfnl_log_msg_set_prefix(
struct nfnl_log_msg *msg, 
void *prefix)
 
  434        free(msg->log_msg_prefix);
 
  435        msg->log_msg_prefix = p;
 
  438                msg->ce_mask |= LOG_MSG_ATTR_PREFIX;
 
  440                msg->ce_mask &= ~LOG_MSG_ATTR_PREFIX;
 
  444const char *nfnl_log_msg_get_prefix(
const struct nfnl_log_msg *msg)
 
  446        return msg->log_msg_prefix;
 
  449void nfnl_log_msg_set_uid(
struct nfnl_log_msg *msg, uint32_t uid)
 
  451        msg->log_msg_uid = uid;
 
  452        msg->ce_mask |= LOG_MSG_ATTR_UID;
 
  455int nfnl_log_msg_test_uid(
const struct nfnl_log_msg *msg)
 
  457        return !!(msg->ce_mask & LOG_MSG_ATTR_UID);
 
  460uint32_t nfnl_log_msg_get_uid(
const struct nfnl_log_msg *msg)
 
  462        return msg->log_msg_uid;
 
  465void nfnl_log_msg_set_gid(
struct nfnl_log_msg *msg, uint32_t gid)
 
  467        msg->log_msg_gid = gid;
 
  468        msg->ce_mask |= LOG_MSG_ATTR_GID;
 
  471int nfnl_log_msg_test_gid(
const struct nfnl_log_msg *msg)
 
  473        return !!(msg->ce_mask & LOG_MSG_ATTR_GID);
 
  476uint32_t nfnl_log_msg_get_gid(
const struct nfnl_log_msg *msg)
 
  478        return msg->log_msg_gid;
 
  482void nfnl_log_msg_set_seq(
struct nfnl_log_msg *msg, uint32_t seq)
 
  484        msg->log_msg_seq = seq;
 
  485        msg->ce_mask |= LOG_MSG_ATTR_SEQ;
 
  488int nfnl_log_msg_test_seq(
const struct nfnl_log_msg *msg)
 
  490        return !!(msg->ce_mask & LOG_MSG_ATTR_SEQ);
 
  493uint32_t nfnl_log_msg_get_seq(
const struct nfnl_log_msg *msg)
 
  495        return msg->log_msg_seq;
 
  498void nfnl_log_msg_set_seq_global(
struct nfnl_log_msg *msg, uint32_t seq_global)
 
  500        msg->log_msg_seq_global = seq_global;
 
  501        msg->ce_mask |= LOG_MSG_ATTR_SEQ_GLOBAL;
 
  504int nfnl_log_msg_test_seq_global(
const struct nfnl_log_msg *msg)
 
  506        return !!(msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL);
 
  509uint32_t nfnl_log_msg_get_seq_global(
const struct nfnl_log_msg *msg)
 
  511        return msg->log_msg_seq_global;
 
  514void nfnl_log_msg_set_hwtype(
struct nfnl_log_msg *msg, uint16_t hwtype)
 
  516        msg->log_msg_hwtype = hwtype;
 
  517        msg->ce_mask |= LOG_MSG_ATTR_HWTYPE;
 
  520int nfnl_log_msg_test_hwtype(
const struct nfnl_log_msg *msg)
 
  522        return !!(msg->ce_mask & LOG_MSG_ATTR_HWTYPE);
 
  525uint16_t nfnl_log_msg_get_hwtype(
const struct nfnl_log_msg *msg)
 
  527        return msg->log_msg_hwtype;
 
  530void nfnl_log_msg_set_hwlen(
struct nfnl_log_msg *msg, uint16_t hwlen)
 
  532        msg->log_msg_hwlen = hwlen;
 
  533        msg->ce_mask |= LOG_MSG_ATTR_HWLEN;
 
  536int nfnl_log_msg_test_hwlen(
const struct nfnl_log_msg *msg)
 
  538        return !!(msg->ce_mask & LOG_MSG_ATTR_HWLEN);
 
  541uint16_t nfnl_log_msg_get_hwlen(
const struct nfnl_log_msg *msg)
 
  543        return msg->log_msg_hwlen;
 
  546int nfnl_log_msg_set_hwheader(
struct nfnl_log_msg *msg, 
void *data, 
int len)
 
  553        p = _nl_memdup(data, len);
 
  557        free(msg->log_msg_hwheader);
 
  558        msg->log_msg_hwheader = p;
 
  559        msg->log_msg_hwheader_len = len;
 
  561                msg->ce_mask |= LOG_MSG_ATTR_HWHEADER;
 
  563                msg->ce_mask &= ~LOG_MSG_ATTR_HWHEADER;
 
  567int nfnl_log_msg_test_hwheader(
const struct nfnl_log_msg *msg)
 
  569        return !!(msg->ce_mask & LOG_MSG_ATTR_HWHEADER);
 
  572const void *nfnl_log_msg_get_hwheader(
const struct nfnl_log_msg *msg, 
int *len)
 
  574        if (!(msg->ce_mask & LOG_MSG_ATTR_HWHEADER)) {
 
  579        *len = msg->log_msg_hwheader_len;
 
  580        return msg->log_msg_hwheader;
 
  583void nfnl_log_msg_set_vlan_proto(
struct nfnl_log_msg *msg, uint16_t vlan_proto)
 
  585        msg->log_msg_vlan_proto = vlan_proto;
 
  586        msg->ce_mask |= LOG_MSG_ATTR_VLAN_PROTO;
 
  589int nfnl_log_msg_test_vlan_proto(
const struct nfnl_log_msg *msg)
 
  591        return !!(msg->ce_mask & LOG_MSG_ATTR_VLAN_PROTO);
 
  594uint16_t nfnl_log_msg_get_vlan_proto(
const struct nfnl_log_msg *msg)
 
  596        return msg->log_msg_vlan_proto;
 
  599void nfnl_log_msg_set_vlan_tag(
struct nfnl_log_msg *msg, uint16_t vlan_tag)
 
  601        msg->log_msg_vlan_tag = vlan_tag;
 
  602        msg->ce_mask |= LOG_MSG_ATTR_VLAN_TAG;
 
  605int nfnl_log_msg_test_vlan_tag(
const struct nfnl_log_msg *msg)
 
  607        return !!(msg->ce_mask & LOG_MSG_ATTR_VLAN_TAG);
 
  610uint16_t nfnl_log_msg_get_vlan_tag(
const struct nfnl_log_msg *msg)
 
  612        return msg->log_msg_vlan_tag;
 
  615uint16_t nfnl_log_msg_get_vlan_id(
const struct nfnl_log_msg *msg)
 
  617        return msg->log_msg_vlan_tag & 0x0fff;
 
  620uint16_t nfnl_log_msg_get_vlan_cfi(
const struct nfnl_log_msg *msg)
 
  622        return !!(msg->log_msg_vlan_tag & 0x1000);
 
  625uint16_t nfnl_log_msg_get_vlan_prio(
const struct nfnl_log_msg *msg)
 
  627        return (msg->log_msg_vlan_tag & 0xe000 ) >> 13;
 
  630void nfnl_log_msg_set_ct_info(
struct nfnl_log_msg *msg, uint32_t ct_info)
 
  632        msg->log_msg_ct_info = ct_info;
 
  633        msg->ce_mask |= LOG_MSG_ATTR_CT_INFO;
 
  636int nfnl_log_msg_test_ct_info(
const struct nfnl_log_msg *msg)
 
  638        return !!(msg->ce_mask & LOG_MSG_ATTR_CT_INFO);
 
  641uint32_t nfnl_log_msg_get_ct_info(
const struct nfnl_log_msg *msg)
 
  643        return msg->log_msg_ct_info;
 
  646void nfnl_log_msg_set_ct(
struct nfnl_log_msg *msg, 
struct nfnl_ct *ct)
 
  648        msg->log_msg_ct = (
struct nfnl_ct *) 
nl_object_clone((
struct nl_object *)ct);
 
  649        msg->ce_mask |= LOG_MSG_ATTR_CT;
 
  652int nfnl_log_msg_test_ct(
const struct nfnl_log_msg *msg)
 
  654        return !!(msg->ce_mask & LOG_MSG_ATTR_CT);
 
  657struct nfnl_ct *nfnl_log_msg_get_ct(
const struct nfnl_log_msg *msg)
 
  659        return msg->log_msg_ct;
 
  664struct nl_object_ops log_msg_obj_ops = {
 
  665        .oo_name                = 
"netfilter/log_msg",
 
  666        .oo_size                = 
sizeof(
struct nfnl_log_msg),
 
  667        .oo_free_data           = log_msg_free_data,
 
  668        .oo_clone               = log_msg_clone,
 
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
 
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
 
struct nl_object * nl_object_clone(struct nl_object *obj)
Allocate a new object and copy all data from an existing object.
 
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
 
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
 
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
 
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
 
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
 
@ NL_DUMP_STATS
Dump all attributes including statistics.
 
@ NL_DUMP_LINE
Dump object briefly on one line.
 
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.