Tizen 2.1 base
[platform/upstream/libnl2.git] / lib / netfilter / log_msg.c
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@suug.ch>
10  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
11  * Copyright (c) 2007 Secure Computing Corporation
12  * Copyright (c) 2008 Patrick McHardy <kaber@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-local.h>
26 #include <netlink/attr.h>
27 #include <netlink/netfilter/nfnl.h>
28 #include <netlink/netfilter/log_msg.h>
29
30 #if __BYTE_ORDER == __BIG_ENDIAN
31 static uint64_t ntohll(uint64_t x)
32 {
33         return x;
34 }
35 #elif __BYTE_ORDER == __LITTLE_ENDIAN
36 static uint64_t ntohll(uint64_t x)
37 {
38         return __bswap_64(x);
39 }
40 #endif
41
42 static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
43         [NFULA_PACKET_HDR]              = {
44                 .minlen = sizeof(struct nfulnl_msg_packet_hdr)
45         },
46         [NFULA_MARK]                    = { .type = NLA_U32 },
47         [NFULA_TIMESTAMP]               = {
48                 .minlen = sizeof(struct nfulnl_msg_packet_timestamp)
49         },
50         [NFULA_IFINDEX_INDEV]           = { .type = NLA_U32 },
51         [NFULA_IFINDEX_OUTDEV]          = { .type = NLA_U32 },
52         [NFULA_IFINDEX_PHYSINDEV]       = { .type = NLA_U32 },
53         [NFULA_IFINDEX_PHYSOUTDEV]      = { .type = NLA_U32 },
54         [NFULA_HWADDR]                  = {
55                 .minlen = sizeof(struct nfulnl_msg_packet_hw)
56         },
57         //[NFULA_PAYLOAD]
58         [NFULA_PREFIX]                  = { .type = NLA_STRING, },
59         [NFULA_UID]                     = { .type = NLA_U32 },
60         [NFULA_GID]                     = { .type = NLA_U32 },
61         [NFULA_SEQ]                     = { .type = NLA_U32 },
62         [NFULA_SEQ_GLOBAL]              = { .type = NLA_U32 },
63 };
64
65 int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
66 {
67         struct nfnl_log_msg *msg;
68         struct nlattr *tb[NFULA_MAX+1];
69         struct nlattr *attr;
70         int err;
71
72         msg = nfnl_log_msg_alloc();
73         if (!msg)
74                 return -NLE_NOMEM;
75
76         msg->ce_msgtype = nlh->nlmsg_type;
77
78         err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
79                           log_msg_policy);
80         if (err < 0)
81                 goto errout;
82
83         nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh));
84
85         attr = tb[NFULA_PACKET_HDR];
86         if (attr) {
87                 struct nfulnl_msg_packet_hdr *hdr = nla_data(attr);
88
89                 if (hdr->hw_protocol)
90                         nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol);
91                 nfnl_log_msg_set_hook(msg, hdr->hook);
92         }
93
94         attr = tb[NFULA_MARK];
95         if (attr)
96                 nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr)));
97
98         attr = tb[NFULA_TIMESTAMP];
99         if (attr) {
100                 struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
101                 struct timeval tv;
102
103                 tv.tv_sec = ntohll(timestamp->sec);
104                 tv.tv_usec = ntohll(timestamp->usec);
105                 nfnl_log_msg_set_timestamp(msg, &tv);
106         }
107
108         attr = tb[NFULA_IFINDEX_INDEV];
109         if (attr)
110                 nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr)));
111
112         attr = tb[NFULA_IFINDEX_OUTDEV];
113         if (attr)
114                 nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr)));
115
116         attr = tb[NFULA_IFINDEX_PHYSINDEV];
117         if (attr)
118                 nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr)));
119
120         attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
121         if (attr)
122                 nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr)));
123
124         attr = tb[NFULA_HWADDR];
125         if (attr) {
126                 struct nfulnl_msg_packet_hw *hw = nla_data(attr);
127
128                 nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen));
129         }
130
131         attr = tb[NFULA_PAYLOAD];
132         if (attr) {
133                 err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr));
134                 if (err < 0)
135                         goto errout;
136         }
137
138         attr = tb[NFULA_PREFIX];
139         if (attr) {
140                 err = nfnl_log_msg_set_prefix(msg, nla_data(attr));
141                 if (err < 0)
142                         goto errout;
143         }
144
145         attr = tb[NFULA_UID];
146         if (attr)
147                 nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr)));
148
149         attr = tb[NFULA_GID];
150         if (attr)
151                 nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr)));
152
153         attr = tb[NFULA_SEQ];
154         if (attr)
155                 nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr)));
156
157         attr = tb[NFULA_SEQ_GLOBAL];
158         if (attr)
159                 nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
160
161         *result = msg;
162         return 0;
163
164 errout:
165         nfnl_log_msg_put(msg);
166         return err;
167 }
168
169 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
170                           struct nlmsghdr *nlh, struct nl_parser_param *pp)
171 {
172         struct nfnl_log_msg *msg;
173         int err;
174
175         if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
176                 goto errout;
177
178         err = pp->pp_cb((struct nl_object *) msg, pp);
179 errout:
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 /** @} */