libnl  3.6.0
log.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
4  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
5  * Copyright (c) 2007 Secure Computing Corporation
6  */
7 
8 /**
9  * @ingroup nfnl
10  * @defgroup log Log
11  * @brief
12  * @{
13  */
14 
15 #include <sys/types.h>
16 #include <linux/netfilter/nfnetlink_log.h>
17 
18 #include <netlink-private/netlink.h>
19 #include <netlink/attr.h>
20 #include <netlink/netfilter/nfnl.h>
21 #include <netlink/netfilter/log.h>
22 
23 /**
24  * @name Log Commands
25  * @{
26  */
27 
28 static int build_log_cmd_request(uint8_t family, uint16_t queuenum,
29  uint8_t command, struct nl_msg **result)
30 {
31  struct nl_msg *msg;
32  struct nfulnl_msg_config_cmd cmd;
33 
34  msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
35  family, queuenum);
36  if (msg == NULL)
37  return -NLE_NOMEM;
38 
39  cmd.command = command;
40  if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
41  goto nla_put_failure;
42 
43  *result = msg;
44  return 0;
45 
46 nla_put_failure:
47  nlmsg_free(msg);
48  return -NLE_MSGSIZE;
49 }
50 
51 static int send_log_request(struct nl_sock *sk, struct nl_msg *msg)
52 {
53  int err;
54 
55  err = nl_send_auto_complete(sk, msg);
56  nlmsg_free(msg);
57  if (err < 0)
58  return err;
59 
60  return wait_for_ack(sk);
61 }
62 
63 int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result)
64 {
65  return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result);
66 }
67 
68 int nfnl_log_pf_bind(struct nl_sock *nlh, uint8_t pf)
69 {
70  struct nl_msg *msg;
71  int err;
72 
73  if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0)
74  return err;
75 
76  return send_log_request(nlh, msg);
77 }
78 
79 int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result)
80 {
81  return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result);
82 }
83 
84 int nfnl_log_pf_unbind(struct nl_sock *nlh, uint8_t pf)
85 {
86  struct nl_msg *msg;
87  int err;
88 
89  if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0)
90  return err;
91 
92  return send_log_request(nlh, msg);
93 }
94 
95 static int nfnl_log_build_request(const struct nfnl_log *log,
96  struct nl_msg **result)
97 {
98  struct nl_msg *msg;
99 
100  if (!nfnl_log_test_group(log))
101  return -NLE_MISSING_ATTR;
102 
103  msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
104  0, nfnl_log_get_group(log));
105  if (msg == NULL)
106  return -NLE_NOMEM;
107 
108  /* This sucks. The nfnetlink_log interface always expects both
109  * parameters to be present. Needs to be done properly.
110  */
111  if (nfnl_log_test_copy_mode(log)) {
112  struct nfulnl_msg_config_mode mode;
113 
114  switch (nfnl_log_get_copy_mode(log)) {
115  case NFNL_LOG_COPY_NONE:
116  mode.copy_mode = NFULNL_COPY_NONE;
117  break;
118  case NFNL_LOG_COPY_META:
119  mode.copy_mode = NFULNL_COPY_META;
120  break;
121  case NFNL_LOG_COPY_PACKET:
122  mode.copy_mode = NFULNL_COPY_PACKET;
123  break;
124  }
125  mode.copy_range = htonl(nfnl_log_get_copy_range(log));
126  mode._pad = 0;
127 
128  if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0)
129  goto nla_put_failure;
130  }
131 
132  if (nfnl_log_test_flush_timeout(log) &&
133  nla_put_u32(msg, NFULA_CFG_TIMEOUT,
134  htonl(nfnl_log_get_flush_timeout(log))) < 0)
135  goto nla_put_failure;
136 
137  if (nfnl_log_test_alloc_size(log) &&
138  nla_put_u32(msg, NFULA_CFG_NLBUFSIZ,
139  htonl(nfnl_log_get_alloc_size(log))) < 0)
140  goto nla_put_failure;
141 
142  if (nfnl_log_test_queue_threshold(log) &&
143  nla_put_u32(msg, NFULA_CFG_QTHRESH,
144  htonl(nfnl_log_get_queue_threshold(log))) < 0)
145  goto nla_put_failure;
146 
147  if (nfnl_log_get_flags(log) &&
148  nla_put_u16(msg, NFULA_CFG_FLAGS,
149  htons(nfnl_log_get_flags(log))) < 0)
150  goto nla_put_failure;
151 
152  *result = msg;
153  return 0;
154 
155 nla_put_failure:
156  nlmsg_free(msg);
157  return -NLE_MSGSIZE;
158 }
159 
160 int nfnl_log_build_create_request(const struct nfnl_log *log,
161  struct nl_msg **result)
162 {
163  struct nfulnl_msg_config_cmd cmd;
164  int err;
165 
166  if ((err = nfnl_log_build_request(log, result)) < 0)
167  return err;
168 
169  cmd.command = NFULNL_CFG_CMD_BIND;
170 
171  if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
172  goto nla_put_failure;
173 
174  return 0;
175 
176 nla_put_failure:
177  nlmsg_free(*result);
178  return -NLE_MSGSIZE;
179 }
180 
181 int nfnl_log_create(struct nl_sock *nlh, const struct nfnl_log *log)
182 {
183  struct nl_msg *msg;
184  int err;
185 
186  if ((err = nfnl_log_build_create_request(log, &msg)) < 0)
187  return err;
188 
189  return send_log_request(nlh, msg);
190 }
191 
192 int nfnl_log_build_change_request(const struct nfnl_log *log,
193  struct nl_msg **result)
194 {
195  return nfnl_log_build_request(log, result);
196 }
197 
198 int nfnl_log_change(struct nl_sock *nlh, const struct nfnl_log *log)
199 {
200  struct nl_msg *msg;
201  int err;
202 
203  if ((err = nfnl_log_build_change_request(log, &msg)) < 0)
204  return err;
205 
206  return send_log_request(nlh, msg);
207 }
208 
209 int nfnl_log_build_delete_request(const struct nfnl_log *log,
210  struct nl_msg **result)
211 {
212  if (!nfnl_log_test_group(log))
213  return -NLE_MISSING_ATTR;
214 
215  return build_log_cmd_request(0, nfnl_log_get_group(log),
216  NFULNL_CFG_CMD_UNBIND, result);
217 }
218 
219 int nfnl_log_delete(struct nl_sock *nlh, const struct nfnl_log *log)
220 {
221  struct nl_msg *msg;
222  int err;
223 
224  if ((err = nfnl_log_build_delete_request(log, &msg)) < 0)
225  return err;
226 
227  return send_log_request(nlh, msg);
228 }
229 
230 /** @} */
231 
232 static struct nl_cache_ops nfnl_log_ops = {
233  .co_name = "netfilter/log",
234  .co_obj_ops = &log_obj_ops,
235  .co_msgtypes = {
236  END_OF_MSGTYPES_LIST,
237  },
238 };
239 
240 static void __init log_init(void)
241 {
242  nl_cache_mngt_register(&nfnl_log_ops);
243 }
244 
245 static void __exit log_exit(void)
246 {
247  nl_cache_mngt_unregister(&nfnl_log_ops);
248 }
249 
250 /** @} */
int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
Add 16 bit integer attribute to netlink message.
Definition: attr.c:638
int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
Add 32 bit integer attribute to netlink message.
Definition: attr.c:688
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
Definition: attr.c:493
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition: cache_mngt.c:281
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition: cache_mngt.c:246
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:558
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.
Definition: nfnl.c:197
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1241