17#include <linux/netfilter/nfnetlink_log.h> 
   19#include <netlink-private/netlink.h> 
   20#include <netlink/attr.h> 
   21#include <netlink/netfilter/nfnl.h> 
   22#include <netlink/netfilter/log_msg.h> 
   23#include <netlink-private/utils.h> 
   25static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
 
   26        [NFULA_PACKET_HDR]              = {
 
   27                .
minlen = 
sizeof(
struct nfulnl_msg_packet_hdr)
 
   29        [NFULA_MARK]                    = { .type = 
NLA_U32 },
 
   31                .minlen = 
sizeof(
struct nfulnl_msg_packet_timestamp)
 
   33        [NFULA_IFINDEX_INDEV]           = { .type = 
NLA_U32 },
 
   34        [NFULA_IFINDEX_OUTDEV]          = { .type = 
NLA_U32 },
 
   35        [NFULA_IFINDEX_PHYSINDEV]       = { .type = 
NLA_U32 },
 
   36        [NFULA_IFINDEX_PHYSOUTDEV]      = { .type = 
NLA_U32 },
 
   38                .minlen = 
sizeof(
struct nfulnl_msg_packet_hw)
 
   42        [NFULA_UID]                     = { .type = 
NLA_U32 },
 
   43        [NFULA_GID]                     = { .type = 
NLA_U32 },
 
   44        [NFULA_SEQ]                     = { .type = 
NLA_U32 },
 
   45        [NFULA_SEQ_GLOBAL]              = { .type = 
NLA_U32 },
 
   46        [NFULA_HWTYPE]                  = { .type = 
NLA_U16 },
 
   47        [NFULA_HWLEN]                   = { .type = 
NLA_U16 },
 
   50        [NFULA_CT_INFO]                 = { .type = 
NLA_U32 },
 
   53static struct nla_policy log_msg_vlan_policy[NFULA_VLAN_MAX+1] = {
 
   55        [NFULA_VLAN_TCI]                = { .type = 
NLA_U16 },
 
   59nfnlmsg_log_msg_parse_vlan(
struct nlattr *attr_full, 
struct nfnl_log_msg *msg)
 
   61        struct nlattr *tb[NFULA_VLAN_MAX+1];
 
   70        attr = tb[NFULA_VLAN_PROTO];
 
   72                nfnl_log_msg_set_vlan_proto(msg, 
nla_get_u16(attr));
 
   74        attr = tb[NFULA_VLAN_TCI];
 
   76                nfnl_log_msg_set_vlan_tag(msg, ntohs(
nla_get_u16(attr)));
 
   81int nfnlmsg_log_msg_parse(
struct nlmsghdr *nlh, 
struct nfnl_log_msg **result)
 
   83        struct nfnl_log_msg *msg;
 
   84        struct nlattr *tb[NFULA_MAX+1];
 
   88        msg = nfnl_log_msg_alloc();
 
   92        msg->ce_msgtype = nlh->nlmsg_type;
 
   94        err = 
nlmsg_parse(nlh, 
sizeof(
struct nfgenmsg), tb, NFULA_MAX,
 
  101        attr = tb[NFULA_PACKET_HDR];
 
  103                struct nfulnl_msg_packet_hdr *hdr = 
nla_data(attr);
 
  105                if (hdr->hw_protocol)
 
  106                        nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol);
 
  107                nfnl_log_msg_set_hook(msg, hdr->hook);
 
  110        attr = tb[NFULA_MARK];
 
  112                nfnl_log_msg_set_mark(msg, ntohl(
nla_get_u32(attr)));
 
  114        attr = tb[NFULA_TIMESTAMP];
 
  116                struct nfulnl_msg_packet_timestamp *timestamp = 
nla_data(attr);
 
  119                tv.tv_sec = ntohll(timestamp->sec);
 
  120                tv.tv_usec = ntohll(timestamp->usec);
 
  121                nfnl_log_msg_set_timestamp(msg, &tv);
 
  124        attr = tb[NFULA_IFINDEX_INDEV];
 
  126                nfnl_log_msg_set_indev(msg, ntohl(
nla_get_u32(attr)));
 
  128        attr = tb[NFULA_IFINDEX_OUTDEV];
 
  130                nfnl_log_msg_set_outdev(msg, ntohl(
nla_get_u32(attr)));
 
  132        attr = tb[NFULA_IFINDEX_PHYSINDEV];
 
  134                nfnl_log_msg_set_physindev(msg, ntohl(
nla_get_u32(attr)));
 
  136        attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
 
  138                nfnl_log_msg_set_physoutdev(msg, ntohl(
nla_get_u32(attr)));
 
  140        attr = tb[NFULA_HWADDR];
 
  142                struct nfulnl_msg_packet_hw *hw = 
nla_data(attr);
 
  144                nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen));
 
  147        attr = tb[NFULA_PAYLOAD];
 
  154        attr = tb[NFULA_PREFIX];
 
  156                err = nfnl_log_msg_set_prefix(msg, 
nla_data(attr));
 
  161        attr = tb[NFULA_UID];
 
  163                nfnl_log_msg_set_uid(msg, ntohl(
nla_get_u32(attr)));
 
  165        attr = tb[NFULA_GID];
 
  167                nfnl_log_msg_set_gid(msg, ntohl(
nla_get_u32(attr)));
 
  169        attr = tb[NFULA_SEQ];
 
  171                nfnl_log_msg_set_seq(msg, ntohl(
nla_get_u32(attr)));
 
  173        attr = tb[NFULA_SEQ_GLOBAL];
 
  175                nfnl_log_msg_set_seq_global(msg, ntohl(
nla_get_u32(attr)));
 
  177        attr = tb[NFULA_HWTYPE];
 
  179                nfnl_log_msg_set_hwtype(msg, ntohs(
nla_get_u16(attr)));
 
  181        attr = tb[NFULA_HWLEN];
 
  183                nfnl_log_msg_set_hwlen(msg, ntohs(
nla_get_u16(attr)));
 
  185        attr = tb[NFULA_HWHEADER];
 
  189        attr = tb[NFULA_VLAN];
 
  191                err = nfnlmsg_log_msg_parse_vlan(attr, msg);
 
  198                struct nfnl_ct *ct = NULL;
 
  199                err = nfnlmsg_ct_parse_nested(attr, &ct);
 
  202                nfnl_log_msg_set_ct(msg, ct);
 
  206        attr = tb[NFULA_CT_INFO];
 
  208                nfnl_log_msg_set_ct_info(msg, ntohl(
nla_get_u32(attr)));
 
  214        nfnl_log_msg_put(msg);
 
  218static int log_msg_parser(
struct nl_cache_ops *ops, 
struct sockaddr_nl *who,
 
  219                          struct nlmsghdr *nlh, 
struct nl_parser_param *pp)
 
  221        struct nfnl_log_msg *msg;
 
  224        if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
 
  227        err = pp->pp_cb((
struct nl_object *) msg, pp);
 
  228        nfnl_log_msg_put(msg);
 
  234#define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type)) 
  235static struct nl_cache_ops nfnl_log_msg_ops = {
 
  236        .co_name                = 
"netfilter/log_msg",
 
  237        .co_hdrsize             = NFNL_HDRLEN,
 
  239                { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, 
"new" },
 
  240                END_OF_MSGTYPES_LIST,
 
  242        .co_protocol            = NETLINK_NETFILTER,
 
  243        .co_msg_parser          = log_msg_parser,
 
  244        .co_obj_ops             = &log_msg_obj_ops,
 
  247static void __init log_msg_init(
void)
 
  252static void __exit log_msg_exit(
void)
 
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
 
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
 
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
 
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
 
int nla_len(const struct nlattr *nla)
Return length of the payload .
 
@ NLA_STRING
NUL terminated character string.
 
@ NLA_NESTED
Nested attributes.
 
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
 
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
 
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
 
uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
Get netfilter family from message.
 
Attribute validation policy.
 
uint16_t minlen
Minimal length of payload required.
 
uint16_t type
Type of attribute or NLA_UNSPEC.