21 #include <sys/types.h>
22 #include <linux/netfilter/nfnetlink_log.h>
24 #include <netlink-local.h>
25 #include <netlink/attr.h>
26 #include <netlink/netfilter/nfnl.h>
27 #include <netlink/netfilter/log.h>
31 #if __BYTE_ORDER == __BIG_ENDIAN
32 static uint64_t ntohll(uint64_t x)
36 #elif __BYTE_ORDER == __LITTLE_ENDIAN
37 static uint64_t ntohll(uint64_t x)
43 static struct nla_policy log_policy[NFULA_MAX+1] = {
44 [NFULA_PACKET_HDR] = {
45 .
minlen =
sizeof(
struct nfulnl_msg_packet_hdr)
47 [NFULA_MARK] = { .type =
NLA_U32 },
49 .minlen =
sizeof(
struct nfulnl_msg_packet_timestamp)
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 },
56 .minlen =
sizeof(
struct nfulnl_msg_packet_hw)
60 [NFULA_UID] = { .type =
NLA_U32 },
61 [NFULA_SEQ] = { .type =
NLA_U32 },
62 [NFULA_SEQ_GLOBAL] = { .type =
NLA_U32 },
65 struct nfnl_log *nfnlmsg_log_parse(
struct nlmsghdr *nlh)
68 struct nlattr *tb[NFULA_MAX+1];
72 log = nfnl_log_alloc();
78 err =
nlmsg_parse(nlh,
sizeof(
struct nfgenmsg), tb, NFULA_MAX,
85 attr = tb[NFULA_PACKET_HDR];
87 struct nfulnl_msg_packet_hdr *hdr =
nla_data(attr);
89 nfnl_log_set_hwproto(log, hdr->hw_protocol);
90 nfnl_log_set_hook(log, hdr->hook);
93 attr = tb[NFULA_MARK];
97 attr = tb[NFULA_TIMESTAMP];
99 struct nfulnl_msg_packet_timestamp *timestamp =
nla_data(attr);
102 tv.tv_sec = ntohll(timestamp->sec);
103 tv.tv_usec = ntohll(timestamp->usec);
104 nfnl_log_set_timestamp(log, &tv);
107 attr = tb[NFULA_IFINDEX_INDEV];
111 attr = tb[NFULA_IFINDEX_OUTDEV];
113 nfnl_log_set_outdev(log, ntohl(
nla_get_u32(attr)));
115 attr = tb[NFULA_IFINDEX_PHYSINDEV];
117 nfnl_log_set_physindev(log, ntohl(
nla_get_u32(attr)));
119 attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
121 nfnl_log_set_physoutdev(log, ntohl(
nla_get_u32(attr)));
123 attr = tb[NFULA_HWADDR];
125 struct nfulnl_msg_packet_hw *hw =
nla_data(attr);
127 nfnl_log_set_hwaddr(log, hw->hw_addr, ntohs(hw->hw_addrlen));
130 attr = tb[NFULA_PAYLOAD];
137 attr = tb[NFULA_PREFIX];
139 err = nfnl_log_set_prefix(log,
nla_data(attr));
144 attr = tb[NFULA_UID];
148 attr = tb[NFULA_SEQ];
152 attr = tb[NFULA_SEQ_GLOBAL];
154 nfnl_log_set_seq_global(log, ntohl(
nla_get_u32(attr)));
166 struct nfnl_log *log;
169 log = nfnlmsg_log_parse(nlh);
173 err = pp->pp_cb((
struct nl_object *) log, pp);
184 err = nl_get_errno();
193 static struct nl_msg *build_log_cmd_msg(uint8_t family, uint16_t queuenum,
197 struct nfulnl_msg_config_cmd cmd;
204 cmd.command = command;
205 if (
nla_put(msg, NFULA_CFG_CMD,
sizeof(cmd), &cmd) < 0)
206 goto nla_put_failure;
215 static int send_log_msg(
struct nl_handle *handle,
struct nl_msg *msg)
227 struct nl_msg *nfnl_log_build_bind(uint16_t queuenum)
229 return build_log_cmd_msg(0, queuenum, NFULNL_CFG_CMD_BIND);
232 int nfnl_log_bind(
struct nl_handle *nlh, uint16_t queuenum)
236 msg = nfnl_log_build_bind(queuenum);
238 return nl_get_errno();
240 return send_log_msg(nlh, msg);
243 struct nl_msg *nfnl_log_build_unbind(uint16_t queuenum)
245 return build_log_cmd_msg(0, queuenum, NFULNL_CFG_CMD_UNBIND);
248 int nfnl_log_unbind(
struct nl_handle *nlh, uint16_t queuenum)
252 msg = nfnl_log_build_bind(queuenum);
254 return nl_get_errno();
256 return send_log_msg(nlh, msg);
259 struct nl_msg *nfnl_log_build_pf_bind(uint8_t pf)
261 return build_log_cmd_msg(pf, 0, NFULNL_CFG_CMD_PF_BIND);
264 int nfnl_log_pf_bind(
struct nl_handle *nlh, uint8_t pf)
268 msg = nfnl_log_build_pf_bind(pf);
270 return nl_get_errno();
272 return send_log_msg(nlh, msg);
275 struct nl_msg *nfnl_log_build_pf_unbind(uint8_t pf)
277 return build_log_cmd_msg(pf, 0, NFULNL_CFG_CMD_PF_UNBIND);
280 int nfnl_log_pf_unbind(
struct nl_handle *nlh, uint8_t pf)
284 msg = nfnl_log_build_pf_unbind(pf);
286 return nl_get_errno();
288 return send_log_msg(nlh, msg);
291 struct nl_msg *nfnl_log_build_mode(uint16_t queuenum, uint8_t copy_mode,
295 struct nfulnl_msg_config_mode mode;
302 mode.copy_mode = copy_mode;
303 mode.copy_range = htonl(copy_range);
304 if (
nla_put(msg, NFULA_CFG_MODE,
sizeof(mode), &mode) < 0)
305 goto nla_put_failure;
314 int nfnl_log_set_mode(
struct nl_handle *nlh, uint16_t queuenum,
315 uint8_t copy_mode, uint32_t copy_range)
319 msg = nfnl_log_build_mode(queuenum, copy_mode, copy_range);
321 return nl_get_errno();
322 return send_log_msg(nlh, msg);
327 #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
329 .co_name =
"netfilter/log",
330 .co_hdrsize = NFNL_HDRLEN,
332 { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW,
"new" },
333 END_OF_MSGTYPES_LIST,
335 .co_protocol = NETLINK_NETFILTER,
336 .co_msg_parser = log_msg_parser,
337 .co_obj_ops = &log_obj_ops,
340 static void __init log_init(
void)
345 static void __exit log_exit(
void)
uint16_t nlmsg_type
Message type (content type)
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
attribute validation policy
int nl_wait_for_ack(struct nl_handle *handle)
Wait for ACK.
void nlmsg_free(struct nl_msg *n)
Free a netlink message.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy)
parse attributes of a netlink message
int nl_send_auto_complete(struct nl_handle *handle, struct nl_msg *msg)
Send netlink message and check & extend header values as needed.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
void * nla_data(const struct nlattr *nla)
head of payload
int nla_len(const struct nlattr *nla)
length of payload
uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
Get netfilter family from message.
uint16_t minlen
Minimal length of payload required to be available.
int nla_put(struct nl_msg *n, int attrtype, int attrlen, const void *data)
Add a netlink attribute to a netlink message.
uint32_t nla_get_u32(struct nlattr *nla)
Return payload of u32 attribute.
struct nl_msg * nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id)
Allocate a new netfilter netlink message.