Home | History | Annotate | Download | only in netfilter
      1 /*
      2  * lib/netfilter/log_msg.c	Netfilter Log Message
      3  *
      4  *	This library is free software; you can redistribute it and/or
      5  *	modify it under the terms of the GNU Lesser General Public
      6  *	License as published by the Free Software Foundation version 2.1
      7  *	of the License.
      8  *
      9  * Copyright (c) 2003-2008 Thomas Graf <tgraf (at) suug.ch>
     10  * Copyright (c) 2007 Philip Craig <philipc (at) snapgear.com>
     11  * Copyright (c) 2007 Secure Computing Corporation
     12  * Copyright (c) 2008 Patrick McHardy <kaber (at) trash.net>
     13  */
     14 
     15 /**
     16  * @ingroup nfnl
     17  * @defgroup log Log
     18  * @brief
     19  * @{
     20  */
     21 
     22 #include <sys/types.h>
     23 #include <linux/netfilter/nfnetlink_log.h>
     24 
     25 #include <netlink-private/netlink.h>
     26 #include <netlink/attr.h>
     27 #include <netlink/netfilter/nfnl.h>
     28 #include <netlink/netfilter/log_msg.h>
     29 #include <byteswap.h>
     30 
     31 #if __BYTE_ORDER == __BIG_ENDIAN
     32 static uint64_t ntohll(uint64_t x)
     33 {
     34 	return x;
     35 }
     36 #elif __BYTE_ORDER == __LITTLE_ENDIAN
     37 static uint64_t ntohll(uint64_t x)
     38 {
     39 	return bswap_64(x);
     40 }
     41 #endif
     42 
     43 static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
     44 	[NFULA_PACKET_HDR]		= {
     45 		.minlen = sizeof(struct nfulnl_msg_packet_hdr)
     46 	},
     47 	[NFULA_MARK]			= { .type = NLA_U32 },
     48 	[NFULA_TIMESTAMP]		= {
     49 		.minlen = sizeof(struct nfulnl_msg_packet_timestamp)
     50 	},
     51 	[NFULA_IFINDEX_INDEV]		= { .type = NLA_U32 },
     52 	[NFULA_IFINDEX_OUTDEV]		= { .type = NLA_U32 },
     53 	[NFULA_IFINDEX_PHYSINDEV]	= { .type = NLA_U32 },
     54 	[NFULA_IFINDEX_PHYSOUTDEV]	= { .type = NLA_U32 },
     55 	[NFULA_HWADDR]			= {
     56 		.minlen = sizeof(struct nfulnl_msg_packet_hw)
     57 	},
     58 	//[NFULA_PAYLOAD]
     59 	[NFULA_PREFIX]			= { .type = NLA_STRING, },
     60 	[NFULA_UID]			= { .type = NLA_U32 },
     61 	[NFULA_GID]			= { .type = NLA_U32 },
     62 	[NFULA_SEQ]			= { .type = NLA_U32 },
     63 	[NFULA_SEQ_GLOBAL]		= { .type = NLA_U32 },
     64 };
     65 
     66 int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
     67 {
     68 	struct nfnl_log_msg *msg;
     69 	struct nlattr *tb[NFULA_MAX+1];
     70 	struct nlattr *attr;
     71 	int err;
     72 
     73 	msg = nfnl_log_msg_alloc();
     74 	if (!msg)
     75 		return -NLE_NOMEM;
     76 
     77 	msg->ce_msgtype = nlh->nlmsg_type;
     78 
     79 	err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
     80 			  log_msg_policy);
     81 	if (err < 0)
     82 		goto errout;
     83 
     84 	nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh));
     85 
     86 	attr = tb[NFULA_PACKET_HDR];
     87 	if (attr) {
     88 		struct nfulnl_msg_packet_hdr *hdr = nla_data(attr);
     89 
     90 		if (hdr->hw_protocol)
     91 			nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol);
     92 		nfnl_log_msg_set_hook(msg, hdr->hook);
     93 	}
     94 
     95 	attr = tb[NFULA_MARK];
     96 	if (attr)
     97 		nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr)));
     98 
     99 	attr = tb[NFULA_TIMESTAMP];
    100 	if (attr) {
    101 		struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
    102 		struct timeval tv;
    103 
    104 		tv.tv_sec = ntohll(timestamp->sec);
    105 		tv.tv_usec = ntohll(timestamp->usec);
    106 		nfnl_log_msg_set_timestamp(msg, &tv);
    107 	}
    108 
    109 	attr = tb[NFULA_IFINDEX_INDEV];
    110 	if (attr)
    111 		nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr)));
    112 
    113 	attr = tb[NFULA_IFINDEX_OUTDEV];
    114 	if (attr)
    115 		nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr)));
    116 
    117 	attr = tb[NFULA_IFINDEX_PHYSINDEV];
    118 	if (attr)
    119 		nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr)));
    120 
    121 	attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
    122 	if (attr)
    123 		nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr)));
    124 
    125 	attr = tb[NFULA_HWADDR];
    126 	if (attr) {
    127 		struct nfulnl_msg_packet_hw *hw = nla_data(attr);
    128 
    129 		nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen));
    130 	}
    131 
    132 	attr = tb[NFULA_PAYLOAD];
    133 	if (attr) {
    134 		err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr));
    135 		if (err < 0)
    136 			goto errout;
    137 	}
    138 
    139 	attr = tb[NFULA_PREFIX];
    140 	if (attr) {
    141 		err = nfnl_log_msg_set_prefix(msg, nla_data(attr));
    142 		if (err < 0)
    143 			goto errout;
    144 	}
    145 
    146 	attr = tb[NFULA_UID];
    147 	if (attr)
    148 		nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr)));
    149 
    150 	attr = tb[NFULA_GID];
    151 	if (attr)
    152 		nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr)));
    153 
    154 	attr = tb[NFULA_SEQ];
    155 	if (attr)
    156 		nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr)));
    157 
    158 	attr = tb[NFULA_SEQ_GLOBAL];
    159 	if (attr)
    160 		nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
    161 
    162 	*result = msg;
    163 	return 0;
    164 
    165 errout:
    166 	nfnl_log_msg_put(msg);
    167 	return err;
    168 }
    169 
    170 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
    171 			  struct nlmsghdr *nlh, struct nl_parser_param *pp)
    172 {
    173 	struct nfnl_log_msg *msg;
    174 	int err;
    175 
    176 	if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
    177 		return err;
    178 
    179 	err = pp->pp_cb((struct nl_object *) msg, pp);
    180 	nfnl_log_msg_put(msg);
    181 	return err;
    182 }
    183 
    184 /** @} */
    185 
    186 #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
    187 static struct nl_cache_ops nfnl_log_msg_ops = {
    188 	.co_name		= "netfilter/log_msg",
    189 	.co_hdrsize		= NFNL_HDRLEN,
    190 	.co_msgtypes		= {
    191 		{ NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" },
    192 		END_OF_MSGTYPES_LIST,
    193 	},
    194 	.co_protocol		= NETLINK_NETFILTER,
    195 	.co_msg_parser		= log_msg_parser,
    196 	.co_obj_ops		= &log_msg_obj_ops,
    197 };
    198 
    199 static void __init log_msg_init(void)
    200 {
    201 	nl_cache_mngt_register(&nfnl_log_msg_ops);
    202 }
    203 
    204 static void __exit log_msg_exit(void)
    205 {
    206 	nl_cache_mngt_unregister(&nfnl_log_msg_ops);
    207 }
    208 
    209 /** @} */
    210