libnl 1.1.4
log_obj.c
1/*
2 * lib/netfilter/log_obj.c Netfilter Log Object
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-2006 Thomas Graf <tgraf@suug.ch>
10 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
11 * Copyright (c) 2007 Secure Computing Corporation
12 */
13
14#include <netlink-local.h>
15#include <netlink/netfilter/nfnl.h>
16#include <netlink/netfilter/log.h>
17
18/** @cond SKIP */
19#define LOG_ATTR_FAMILY (1UL << 0)
20#define LOG_ATTR_HWPROTO (1UL << 1)
21#define LOG_ATTR_HOOK (1UL << 2)
22#define LOG_ATTR_MARK (1UL << 3)
23#define LOG_ATTR_TIMESTAMP (1UL << 4)
24#define LOG_ATTR_INDEV (1UL << 5)
25#define LOG_ATTR_OUTDEV (1UL << 6)
26#define LOG_ATTR_PHYSINDEV (1UL << 7)
27#define LOG_ATTR_PHYSOUTDEV (1UL << 8)
28#define LOG_ATTR_HWADDR (1UL << 9)
29#define LOG_ATTR_PAYLOAD (1UL << 10)
30#define LOG_ATTR_PREFIX (1UL << 11)
31#define LOG_ATTR_UID (1UL << 12)
32#define LOG_ATTR_SEQ (1UL << 13)
33#define LOG_ATTR_SEQ_GLOBAL (1UL << 14)
34/** @endcond */
35
36static void log_free_data(struct nl_object *c)
37{
38 struct nfnl_log *log = (struct nfnl_log *) c;
39
40 if (log == NULL)
41 return;
42
43 free(log->log_payload);
44 free(log->log_prefix);
45}
46
47static int log_clone(struct nl_object *_dst, struct nl_object *_src)
48{
49 struct nfnl_log *dst = (struct nfnl_log *) _dst;
50 struct nfnl_log *src = (struct nfnl_log *) _src;
51 int err;
52
53 if (src->log_payload) {
54 err = nfnl_log_set_payload(dst, src->log_payload,
55 src->log_payload_len);
56 if (err < 0)
57 goto errout;
58 }
59
60 if (src->log_prefix) {
61 err = nfnl_log_set_prefix(dst, src->log_prefix);
62 if (err < 0)
63 goto errout;
64 }
65
66 return 0;
67errout:
68 return err;
69}
70
71static int log_dump(struct nl_object *a, struct nl_dump_params *p)
72{
73 struct nfnl_log *log = (struct nfnl_log *) a;
74 struct nl_cache *link_cache;
75 char buf[64];
76
77 link_cache = nl_cache_mngt_require("route/link");
78
79 if (log->ce_mask & LOG_ATTR_PREFIX)
80 dp_dump(p, "%s", log->log_prefix);
81
82 if (log->ce_mask & LOG_ATTR_INDEV) {
83 if (link_cache)
84 dp_dump(p, "IN=%s ",
85 rtnl_link_i2name(link_cache, log->log_indev,
86 buf, sizeof(buf)));
87 else
88 dp_dump(p, "IN=%d ", log->log_indev);
89 }
90
91 if (log->ce_mask & LOG_ATTR_PHYSINDEV) {
92 if (link_cache)
93 dp_dump(p, "PHYSIN=%s ",
94 rtnl_link_i2name(link_cache, log->log_physindev,
95 buf, sizeof(buf)));
96 else
97 dp_dump(p, "IN=%d ", log->log_physindev);
98 }
99
100 if (log->ce_mask & LOG_ATTR_OUTDEV) {
101 if (link_cache)
102 dp_dump(p, "OUT=%s ",
103 rtnl_link_i2name(link_cache, log->log_outdev,
104 buf, sizeof(buf)));
105 else
106 dp_dump(p, "OUT=%d ", log->log_outdev);
107 }
108
109 if (log->ce_mask & LOG_ATTR_PHYSOUTDEV) {
110 if (link_cache)
111 dp_dump(p, "PHYSOUT=%s ",
112 rtnl_link_i2name(link_cache,log->log_physoutdev,
113 buf, sizeof(buf)));
114 else
115 dp_dump(p, "PHYSOUT=%d ", log->log_physoutdev);
116 }
117
118 if (log->ce_mask & LOG_ATTR_HWADDR) {
119 int i;
120
121 dp_dump(p, "MAC");
122 for (i = 0; i < log->log_hwaddr_len; i++)
123 dp_dump(p, "%c%02x", i?':':'=', log->log_hwaddr[i]);
124 dp_dump(p, " ");
125 }
126
127 /* FIXME: parse the payload to get iptables LOG compatible format */
128
129 if (log->ce_mask & LOG_ATTR_FAMILY)
130 dp_dump(p, "FAMILY=%s ",
131 nl_af2str(log->log_family, buf, sizeof(buf)));
132
133 if (log->ce_mask & LOG_ATTR_HWPROTO)
134 dp_dump(p, "HWPROTO=%s ",
135 nl_ether_proto2str(ntohs(log->log_hwproto),
136 buf, sizeof(buf)));
137
138 if (log->ce_mask & LOG_ATTR_HOOK)
139 dp_dump(p, "HOOK=%d ", log->log_hook);
140
141 if (log->ce_mask & LOG_ATTR_MARK)
142 dp_dump(p, "MARK=%d ", log->log_mark);
143
144 if (log->ce_mask & LOG_ATTR_PAYLOAD)
145 dp_dump(p, "PAYLOADLEN=%d ", log->log_payload_len);
146
147 if (log->ce_mask & LOG_ATTR_SEQ)
148 dp_dump(p, "SEQ=%d ", log->log_seq);
149
150 if (log->ce_mask & LOG_ATTR_SEQ_GLOBAL)
151 dp_dump(p, "SEQGLOBAL=%d ", log->log_seq_global);
152
153 dp_dump(p, "\n");
154
155 return 1;
156}
157
158/**
159 * @name Allocation/Freeing
160 * @{
161 */
162
163struct nfnl_log *nfnl_log_alloc(void)
164{
165 return (struct nfnl_log *) nl_object_alloc(&log_obj_ops);
166}
167
168void nfnl_log_get(struct nfnl_log *log)
169{
170 nl_object_get((struct nl_object *) log);
171}
172
173void nfnl_log_put(struct nfnl_log *log)
174{
175 nl_object_put((struct nl_object *) log);
176}
177
178/** @} */
179
180/**
181 * @name Attributes
182 * @{
183 */
184
185void nfnl_log_set_family(struct nfnl_log *log, uint8_t family)
186{
187 log->log_family = family;
188 log->ce_mask |= LOG_ATTR_FAMILY;
189}
190
191uint8_t nfnl_log_get_family(const struct nfnl_log *log)
192{
193 if (log->ce_mask & LOG_ATTR_FAMILY)
194 return log->log_family;
195 else
196 return AF_UNSPEC;
197}
198
199void nfnl_log_set_hwproto(struct nfnl_log *log, uint16_t hwproto)
200{
201 log->log_hwproto = hwproto;
202 log->ce_mask |= LOG_ATTR_HWPROTO;
203}
204
205int nfnl_log_test_hwproto(const struct nfnl_log *log)
206{
207 return !!(log->ce_mask & LOG_ATTR_HWPROTO);
208}
209
210uint16_t nfnl_log_get_hwproto(const struct nfnl_log *log)
211{
212 return log->log_hwproto;
213}
214
215void nfnl_log_set_hook(struct nfnl_log *log, uint8_t hook)
216{
217 log->log_hook = hook;
218 log->ce_mask |= LOG_ATTR_HOOK;
219}
220
221int nfnl_log_test_hook(const struct nfnl_log *log)
222{
223 return !!(log->ce_mask & LOG_ATTR_HOOK);
224}
225
226uint8_t nfnl_log_get_hook(const struct nfnl_log *log)
227{
228 return log->log_hook;
229}
230
231void nfnl_log_set_mark(struct nfnl_log *log, uint32_t mark)
232{
233 log->log_mark = mark;
234 log->ce_mask |= LOG_ATTR_MARK;
235}
236
237int nfnl_log_test_mark(const struct nfnl_log *log)
238{
239 return !!(log->ce_mask & LOG_ATTR_MARK);
240}
241
242uint32_t nfnl_log_get_mark(const struct nfnl_log *log)
243{
244 return log->log_mark;
245}
246
247void nfnl_log_set_timestamp(struct nfnl_log *log, struct timeval *tv)
248{
249 log->log_timestamp.tv_sec = tv->tv_sec;
250 log->log_timestamp.tv_usec = tv->tv_usec;
251 log->ce_mask |= LOG_ATTR_TIMESTAMP;
252}
253
254const struct timeval *nfnl_log_get_timestamp(const struct nfnl_log *log)
255{
256 if (!(log->ce_mask & LOG_ATTR_TIMESTAMP))
257 return NULL;
258 return &log->log_timestamp;
259}
260
261void nfnl_log_set_indev(struct nfnl_log *log, uint32_t indev)
262{
263 log->log_indev = indev;
264 log->ce_mask |= LOG_ATTR_INDEV;
265}
266
267uint32_t nfnl_log_get_indev(const struct nfnl_log *log)
268{
269 return log->log_indev;
270}
271
272void nfnl_log_set_outdev(struct nfnl_log *log, uint32_t outdev)
273{
274 log->log_outdev = outdev;
275 log->ce_mask |= LOG_ATTR_OUTDEV;
276}
277
278uint32_t nfnl_log_get_outdev(const struct nfnl_log *log)
279{
280 return log->log_outdev;
281}
282
283void nfnl_log_set_physindev(struct nfnl_log *log, uint32_t physindev)
284{
285 log->log_physindev = physindev;
286 log->ce_mask |= LOG_ATTR_PHYSINDEV;
287}
288
289uint32_t nfnl_log_get_physindev(const struct nfnl_log *log)
290{
291 return log->log_physindev;
292}
293
294void nfnl_log_set_physoutdev(struct nfnl_log *log, uint32_t physoutdev)
295{
296 log->log_physoutdev = physoutdev;
297 log->ce_mask |= LOG_ATTR_PHYSOUTDEV;
298}
299
300uint32_t nfnl_log_get_physoutdev(const struct nfnl_log *log)
301{
302 return log->log_physoutdev;
303}
304
305void nfnl_log_set_hwaddr(struct nfnl_log *log, uint8_t *hwaddr, int len)
306{
307 if (len > sizeof(log->log_hwaddr))
308 len = sizeof(log->log_hwaddr);
309 log->log_hwaddr_len = len;
310 memcpy(log->log_hwaddr, hwaddr, len);
311 log->ce_mask |= LOG_ATTR_HWADDR;
312}
313
314const uint8_t *nfnl_log_get_hwaddr(const struct nfnl_log *log, int *len)
315{
316 if (!(log->ce_mask & LOG_ATTR_HWADDR)) {
317 *len = 0;
318 return NULL;
319 }
320
321 *len = log->log_hwaddr_len;
322 return log->log_hwaddr;
323}
324
325int nfnl_log_set_payload(struct nfnl_log *log, uint8_t *payload, int len)
326{
327 free(log->log_payload);
328 log->log_payload = malloc(len);
329 if (!log->log_payload)
330 return nl_errno(ENOMEM);
331
332 memcpy(log->log_payload, payload, len);
333 log->log_payload_len = len;
334 log->ce_mask |= LOG_ATTR_PAYLOAD;
335 return 0;
336}
337
338const void *nfnl_log_get_payload(const struct nfnl_log *log, int *len)
339{
340 if (!(log->ce_mask & LOG_ATTR_PAYLOAD)) {
341 *len = 0;
342 return NULL;
343 }
344
345 *len = log->log_payload_len;
346 return log->log_payload;
347}
348
349int nfnl_log_set_prefix(struct nfnl_log *log, void *prefix)
350{
351 free(log->log_prefix);
352 log->log_prefix = strdup(prefix);
353 if (!log->log_prefix)
354 return nl_errno(ENOMEM);
355
356 log->ce_mask |= LOG_ATTR_PREFIX;
357 return 0;
358}
359
360const char *nfnl_log_get_prefix(const struct nfnl_log *log)
361{
362 return log->log_prefix;
363}
364
365void nfnl_log_set_uid(struct nfnl_log *log, uint32_t uid)
366{
367 log->log_uid = uid;
368 log->ce_mask |= LOG_ATTR_UID;
369}
370
371int nfnl_log_test_uid(const struct nfnl_log *log)
372{
373 return !!(log->ce_mask & LOG_ATTR_UID);
374}
375
376uint32_t nfnl_log_get_uid(const struct nfnl_log *log)
377{
378 return log->log_uid;
379}
380
381void nfnl_log_set_seq(struct nfnl_log *log, uint32_t seq)
382{
383 log->log_seq = seq;
384 log->ce_mask |= LOG_ATTR_SEQ;
385}
386
387int nfnl_log_test_seq(const struct nfnl_log *log)
388{
389 return !!(log->ce_mask & LOG_ATTR_SEQ);
390}
391
392uint32_t nfnl_log_get_seq(const struct nfnl_log *log)
393{
394 return log->log_seq;
395}
396
397void nfnl_log_set_seq_global(struct nfnl_log *log, uint32_t seq_global)
398{
399 log->log_seq_global = seq_global;
400 log->ce_mask |= LOG_ATTR_SEQ_GLOBAL;
401}
402
403int nfnl_log_test_seq_global(const struct nfnl_log *log)
404{
405 return !!(log->ce_mask & LOG_ATTR_SEQ_GLOBAL);
406}
407
408uint32_t nfnl_log_get_seq_global(const struct nfnl_log *log)
409{
410 return log->log_seq_global;
411}
412
413/** @} */
414
415struct nl_object_ops log_obj_ops = {
416 .oo_name = "netfilter/log",
417 .oo_size = sizeof(struct nfnl_log),
418 .oo_free_data = log_free_data,
419 .oo_clone = log_clone,
420 .oo_dump[NL_DUMP_BRIEF] = log_dump,
421 .oo_dump[NL_DUMP_FULL] = log_dump,
422 .oo_dump[NL_DUMP_STATS] = log_dump,
423};
424
425/** @} */
struct nl_cache * nl_cache_mngt_require(const char *name)
Demand the use of a global cache.
Definition: cache_mngt.c:356
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:178
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:167
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition: object.c:42
@ NL_DUMP_FULL
Dump all attributes but no statistics.
Definition: types.h:23
@ NL_DUMP_BRIEF
Dump object in a brief one-liner.
Definition: types.h:22
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:24
Dumping parameters.
Definition: types.h:37
Object Operations.
Definition: object-api.h:255
char * oo_name
Unique name of object type.
Definition: object-api.h:261