Tizen 2.1 base
[platform/upstream/libnl2.git] / lib / netfilter / ct.c
1 /*
2  * lib/netfilter/ct.c   Conntrack
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 ct Conntrack
18  * @brief
19  * @{
20  */
21
22 #include <byteswap.h>
23 #include <sys/types.h>
24 #include <linux/netfilter/nfnetlink_conntrack.h>
25
26 #include <netlink-local.h>
27 #include <netlink/attr.h>
28 #include <netlink/netfilter/nfnl.h>
29 #include <netlink/netfilter/ct.h>
30
31 static struct nl_cache_ops nfnl_ct_ops;
32
33 #if __BYTE_ORDER == __BIG_ENDIAN
34 static uint64_t ntohll(uint64_t x)
35 {
36         return x;
37 }
38 #elif __BYTE_ORDER == __LITTLE_ENDIAN
39 static uint64_t ntohll(uint64_t x)
40 {
41         return __bswap_64(x);
42 }
43 #endif
44
45 static struct nla_policy ct_policy[CTA_MAX+1] = {
46         [CTA_TUPLE_ORIG]        = { .type = NLA_NESTED },
47         [CTA_TUPLE_REPLY]       = { .type = NLA_NESTED },
48         [CTA_STATUS]            = { .type = NLA_U32 },
49         [CTA_PROTOINFO]         = { .type = NLA_NESTED },
50         //[CTA_HELP]
51         //[CTA_NAT_SRC]
52         [CTA_TIMEOUT]           = { .type = NLA_U32 },
53         [CTA_MARK]              = { .type = NLA_U32 },
54         [CTA_COUNTERS_ORIG]     = { .type = NLA_NESTED },
55         [CTA_COUNTERS_REPLY]    = { .type = NLA_NESTED },
56         [CTA_USE]               = { .type = NLA_U32 },
57         [CTA_ID]                = { .type = NLA_U32 },
58         //[CTA_NAT_DST]
59 };
60
61 static struct nla_policy ct_tuple_policy[CTA_TUPLE_MAX+1] = {
62         [CTA_TUPLE_IP]          = { .type = NLA_NESTED },
63         [CTA_TUPLE_PROTO]       = { .type = NLA_NESTED },
64 };
65
66 static struct nla_policy ct_ip_policy[CTA_IP_MAX+1] = {
67         [CTA_IP_V4_SRC]         = { .type = NLA_U32 },
68         [CTA_IP_V4_DST]         = { .type = NLA_U32 },
69         [CTA_IP_V6_SRC]         = { .minlen = 16 },
70         [CTA_IP_V6_DST]         = { .minlen = 16 },
71 };
72
73 static struct nla_policy ct_proto_policy[CTA_PROTO_MAX+1] = {
74         [CTA_PROTO_NUM]         = { .type = NLA_U8 },
75         [CTA_PROTO_SRC_PORT]    = { .type = NLA_U16 },
76         [CTA_PROTO_DST_PORT]    = { .type = NLA_U16 },
77         [CTA_PROTO_ICMP_ID]     = { .type = NLA_U16 },
78         [CTA_PROTO_ICMP_TYPE]   = { .type = NLA_U8 },
79         [CTA_PROTO_ICMP_CODE]   = { .type = NLA_U8 },
80         [CTA_PROTO_ICMPV6_ID]   = { .type = NLA_U16 },
81         [CTA_PROTO_ICMPV6_TYPE] = { .type = NLA_U8 },
82         [CTA_PROTO_ICMPV6_CODE] = { .type = NLA_U8 },
83 };
84
85 static struct nla_policy ct_protoinfo_policy[CTA_PROTOINFO_MAX+1] = {
86         [CTA_PROTOINFO_TCP]     = { .type = NLA_NESTED },
87 };
88
89 static struct nla_policy ct_protoinfo_tcp_policy[CTA_PROTOINFO_TCP_MAX+1] = {
90         [CTA_PROTOINFO_TCP_STATE]               = { .type = NLA_U8 },
91         [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]     = { .type = NLA_U8 },
92         [CTA_PROTOINFO_TCP_WSCALE_REPLY]        = { .type = NLA_U8 },
93         [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]      = { .minlen = 2 },
94         [CTA_PROTOINFO_TCP_FLAGS_REPLY]         = { .minlen = 2 },
95
96 };
97
98 static struct nla_policy ct_counters_policy[CTA_COUNTERS_MAX+1] = {
99         [CTA_COUNTERS_PACKETS]  = { .type = NLA_U64 },
100         [CTA_COUNTERS_BYTES]    = { .type = NLA_U64 },
101         [CTA_COUNTERS32_PACKETS]= { .type = NLA_U32 },
102         [CTA_COUNTERS32_BYTES]  = { .type = NLA_U32 },
103 };
104
105 static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr)
106 {
107         struct nlattr *tb[CTA_IP_MAX+1];
108         struct nl_addr *addr;
109         int err;
110
111         err = nla_parse_nested(tb, CTA_IP_MAX, attr, ct_ip_policy);
112         if (err < 0)
113                 goto errout;
114
115         if (tb[CTA_IP_V4_SRC]) {
116                 addr = nl_addr_alloc_attr(tb[CTA_IP_V4_SRC], AF_INET);
117                 if (addr == NULL)
118                         goto errout_enomem;
119                 err = nfnl_ct_set_src(ct, repl, addr);
120                 nl_addr_put(addr);
121                 if (err < 0)
122                         goto errout;
123         }
124         if (tb[CTA_IP_V4_DST]) {
125                 addr = nl_addr_alloc_attr(tb[CTA_IP_V4_DST], AF_INET);
126                 if (addr == NULL)
127                         goto errout_enomem;
128                 err = nfnl_ct_set_dst(ct, repl, addr);
129                 nl_addr_put(addr);
130                 if (err < 0)
131                         goto errout;
132         }
133         if (tb[CTA_IP_V6_SRC]) {
134                 addr = nl_addr_alloc_attr(tb[CTA_IP_V6_SRC], AF_INET6);
135                 if (addr == NULL)
136                         goto errout_enomem;
137                 err = nfnl_ct_set_src(ct, repl, addr);
138                 nl_addr_put(addr);
139                 if (err < 0)
140                         goto errout;
141         }
142         if (tb[CTA_IP_V6_DST]) {
143                 addr = nl_addr_alloc_attr(tb[CTA_IP_V6_DST], AF_INET6);
144                 if (addr == NULL)
145                         goto errout_enomem;
146                 err = nfnl_ct_set_dst(ct, repl, addr);
147                 nl_addr_put(addr);
148                 if (err < 0)
149                         goto errout;
150         }
151
152         return 0;
153
154 errout_enomem:
155         err = -NLE_NOMEM;
156 errout:
157         return err;
158 }
159
160 static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr)
161 {
162         struct nlattr *tb[CTA_PROTO_MAX+1];
163         int err;
164
165         err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, ct_proto_policy);
166         if (err < 0)
167                 return err;
168
169         if (!repl && tb[CTA_PROTO_NUM])
170                 nfnl_ct_set_proto(ct, nla_get_u8(tb[CTA_PROTO_NUM]));
171         if (tb[CTA_PROTO_SRC_PORT])
172                 nfnl_ct_set_src_port(ct, repl,
173                         ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT])));
174         if (tb[CTA_PROTO_DST_PORT])
175                 nfnl_ct_set_dst_port(ct, repl,
176                         ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])));
177         if (tb[CTA_PROTO_ICMP_ID])
178                 nfnl_ct_set_icmp_id(ct, repl,
179                         ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])));
180         if (tb[CTA_PROTO_ICMP_TYPE])
181                 nfnl_ct_set_icmp_type(ct, repl,
182                                 nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
183         if (tb[CTA_PROTO_ICMP_CODE])
184                 nfnl_ct_set_icmp_code(ct, repl,
185                                 nla_get_u8(tb[CTA_PROTO_ICMP_CODE]));
186
187         return 0;
188 }
189
190 static int ct_parse_tuple(struct nfnl_ct *ct, int repl, struct nlattr *attr)
191 {
192         struct nlattr *tb[CTA_TUPLE_MAX+1];
193         int err;
194
195         err = nla_parse_nested(tb, CTA_TUPLE_MAX, attr, ct_tuple_policy);
196         if (err < 0)
197                 return err;
198
199         if (tb[CTA_TUPLE_IP]) {
200                 err = ct_parse_ip(ct, repl, tb[CTA_TUPLE_IP]);
201                 if (err < 0)
202                         return err;
203         }
204
205         if (tb[CTA_TUPLE_PROTO]) {
206                 err = ct_parse_proto(ct, repl, tb[CTA_TUPLE_PROTO]);
207                 if (err < 0)
208                         return err;
209         }
210
211         return 0;
212 }
213
214 static int ct_parse_protoinfo_tcp(struct nfnl_ct *ct, struct nlattr *attr)
215 {
216         struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
217         int err;
218
219         err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr,
220                                ct_protoinfo_tcp_policy);
221         if (err < 0)
222                 return err;
223
224         if (tb[CTA_PROTOINFO_TCP_STATE])
225                 nfnl_ct_set_tcp_state(ct,
226                                 nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]));
227
228         return 0;
229 }
230
231 static int ct_parse_protoinfo(struct nfnl_ct *ct, struct nlattr *attr)
232 {
233         struct nlattr *tb[CTA_PROTOINFO_MAX+1];
234         int err;
235
236         err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr,
237                                ct_protoinfo_policy);
238         if (err < 0)
239                 return err;
240
241         if (tb[CTA_PROTOINFO_TCP]) {
242                 err = ct_parse_protoinfo_tcp(ct, tb[CTA_PROTOINFO_TCP]);
243                 if (err < 0)
244                         return err;
245         }
246
247         return 0;
248 }
249
250 static int ct_parse_counters(struct nfnl_ct *ct, int repl, struct nlattr *attr)
251 {
252         struct nlattr *tb[CTA_COUNTERS_MAX+1];
253         int err;
254
255         err = nla_parse_nested(tb, CTA_COUNTERS_MAX, attr, ct_counters_policy);
256         if (err < 0)
257                 return err;
258
259         if (tb[CTA_COUNTERS_PACKETS])
260                 nfnl_ct_set_packets(ct, repl,
261                         ntohll(nla_get_u64(tb[CTA_COUNTERS_PACKETS])));
262         if (tb[CTA_COUNTERS32_PACKETS])
263                 nfnl_ct_set_packets(ct, repl,
264                         ntohl(nla_get_u32(tb[CTA_COUNTERS32_PACKETS])));
265         if (tb[CTA_COUNTERS_BYTES])
266                 nfnl_ct_set_bytes(ct, repl,
267                         ntohll(nla_get_u64(tb[CTA_COUNTERS_BYTES])));
268         if (tb[CTA_COUNTERS32_BYTES])
269                 nfnl_ct_set_bytes(ct, repl,
270                         ntohl(nla_get_u32(tb[CTA_COUNTERS32_BYTES])));
271
272         return 0;
273 }
274
275 int nfnlmsg_ct_group(struct nlmsghdr *nlh)
276 {
277         switch (nfnlmsg_subtype(nlh)) {
278         case IPCTNL_MSG_CT_NEW:
279                 if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL))
280                         return NFNLGRP_CONNTRACK_NEW;
281                 else
282                         return NFNLGRP_CONNTRACK_UPDATE;
283         case IPCTNL_MSG_CT_DELETE:
284                 return NFNLGRP_CONNTRACK_DESTROY;
285         default:
286                 return NFNLGRP_NONE;
287         }
288 }
289
290 int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
291 {
292         struct nfnl_ct *ct;
293         struct nlattr *tb[CTA_MAX+1];
294         int err;
295
296         ct = nfnl_ct_alloc();
297         if (!ct)
298                 return -NLE_NOMEM;
299
300         ct->ce_msgtype = nlh->nlmsg_type;
301
302         err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX,
303                           ct_policy);
304         if (err < 0)
305                 goto errout;
306
307         nfnl_ct_set_family(ct, nfnlmsg_family(nlh));
308
309         if (tb[CTA_TUPLE_ORIG]) {
310                 err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]);
311                 if (err < 0)
312                         goto errout;
313         }
314         if (tb[CTA_TUPLE_REPLY]) {
315                 err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
316                 if (err < 0)
317                         goto errout;
318         }
319
320         if (tb[CTA_PROTOINFO]) {
321                 err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
322                 if (err < 0)
323                         goto errout;
324         }
325
326         if (tb[CTA_STATUS])
327                 nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS])));
328         if (tb[CTA_TIMEOUT])
329                 nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT])));
330         if (tb[CTA_MARK])
331                 nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK])));
332         if (tb[CTA_USE])
333                 nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE])));
334         if (tb[CTA_ID])
335                 nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID])));
336
337         if (tb[CTA_COUNTERS_ORIG]) {
338                 err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
339                 if (err < 0)
340                         goto errout;
341         }
342
343         if (tb[CTA_COUNTERS_REPLY]) {
344                 err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
345                 if (err < 0)
346                         goto errout;
347         }
348
349         *result = ct;
350         return 0;
351
352 errout:
353         nfnl_ct_put(ct);
354         return err;
355 }
356
357 static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
358                          struct nlmsghdr *nlh, struct nl_parser_param *pp)
359 {
360         struct nfnl_ct *ct;
361         int err;
362
363         if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0)
364                 goto errout;
365
366         err = pp->pp_cb((struct nl_object *) ct, pp);
367 errout:
368         nfnl_ct_put(ct);
369         return err;
370 }
371
372 int nfnl_ct_dump_request(struct nl_sock *sk)
373 {
374         return nfnl_send_simple(sk, NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET,
375                                 NLM_F_DUMP, AF_UNSPEC, 0);
376 }
377
378 static int ct_request_update(struct nl_cache *cache, struct nl_sock *sk)
379 {
380         return nfnl_ct_dump_request(sk);
381 }
382
383 static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
384                                int repl)
385 {
386         struct nlattr *tuple, *ip, *proto;
387         struct nl_addr *addr;
388         int family;
389
390         family = nfnl_ct_get_family(ct);
391
392         tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG);
393         if (!tuple)
394                 goto nla_put_failure;
395
396         ip = nla_nest_start(msg, CTA_TUPLE_IP);
397         if (!ip)
398                 goto nla_put_failure;
399
400         addr = nfnl_ct_get_src(ct, repl);
401         if (addr)
402                 NLA_PUT_ADDR(msg,
403                              family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC,
404                              addr);
405
406         addr = nfnl_ct_get_dst(ct, repl);
407         if (addr)
408                 NLA_PUT_ADDR(msg,
409                              family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST,
410                              addr);
411
412         nla_nest_end(msg, ip);
413
414         proto = nla_nest_start(msg, CTA_TUPLE_PROTO);
415         if (!proto)
416                 goto nla_put_failure;
417
418         if (nfnl_ct_test_proto(ct))
419                 NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct));
420
421         if (nfnl_ct_test_src_port(ct, repl))
422                 NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT,
423                         htons(nfnl_ct_get_src_port(ct, repl)));
424
425         if (nfnl_ct_test_dst_port(ct, repl))
426                 NLA_PUT_U16(msg, CTA_PROTO_DST_PORT,
427                         htons(nfnl_ct_get_dst_port(ct, repl)));
428
429         if (nfnl_ct_test_icmp_id(ct, repl))
430                 NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
431                         htons(nfnl_ct_get_icmp_id(ct, repl)));
432
433         if (nfnl_ct_test_icmp_type(ct, repl))
434                 NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
435                             nfnl_ct_get_icmp_type(ct, repl));
436
437         if (nfnl_ct_test_icmp_code(ct, repl))
438                 NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE,
439                             nfnl_ct_get_icmp_code(ct, repl));
440
441         nla_nest_end(msg, proto);
442
443         nla_nest_end(msg, tuple);
444         return 0;
445
446 nla_put_failure:
447         return -NLE_MSGSIZE;
448 }
449
450 static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags,
451                                  struct nl_msg **result)
452 {
453         struct nl_msg *msg;
454         int err;
455
456         msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags,
457                                    nfnl_ct_get_family(ct), 0);
458         if (msg == NULL)
459                 return -NLE_NOMEM;
460
461         if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0)
462                 goto err_out;
463
464         *result = msg;
465         return 0;
466
467 err_out:
468         nlmsg_free(msg);
469         return err;
470 }
471
472 int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags,
473                               struct nl_msg **result)
474 {
475         return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result);
476 }
477
478 int nfnl_ct_add(struct nl_sock *sk, const struct nfnl_ct *ct, int flags)
479 {
480         struct nl_msg *msg;
481         int err;
482
483         if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0)
484                 return err;
485
486         err = nl_send_auto_complete(sk, msg);
487         nlmsg_free(msg);
488         if (err < 0)
489                 return err;
490
491         return wait_for_ack(sk);
492 }
493
494 int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags,
495                                  struct nl_msg **result)
496 {
497         return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result);
498 }
499
500 int nfnl_ct_del(struct nl_sock *sk, const struct nfnl_ct *ct, int flags)
501 {
502         struct nl_msg *msg;
503         int err;
504
505         if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0)
506                 return err;
507
508         err = nl_send_auto_complete(sk, msg);
509         nlmsg_free(msg);
510         if (err < 0)
511                 return err;
512
513         return wait_for_ack(sk);
514 }
515
516 int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags,
517                                 struct nl_msg **result)
518 {
519         return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result);
520 }
521
522 int nfnl_ct_query(struct nl_sock *sk, const struct nfnl_ct *ct, int flags)
523 {
524         struct nl_msg *msg;
525         int err;
526
527         if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0)
528                 return err;
529
530         err = nl_send_auto_complete(sk, msg);
531         nlmsg_free(msg);
532         if (err < 0)
533                 return err;
534
535         return wait_for_ack(sk);
536 }
537
538 /**
539  * @name Cache Management
540  * @{
541  */
542
543 /**
544  * Build a conntrack cache holding all conntrack currently in the kernel
545  * @arg sk              Netlink socket.
546  * @arg result          Pointer to store resulting cache.
547  *
548  * Allocates a new cache, initializes it properly and updates it to
549  * contain all conntracks currently in the kernel.
550  *
551  * @return 0 on success or a negative error code.
552  */
553 int nfnl_ct_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
554 {
555         return nl_cache_alloc_and_fill(&nfnl_ct_ops, sk, result);
556 }
557
558 /** @} */
559
560 /**
561  * @name Conntrack Addition
562  * @{
563  */
564
565 /** @} */
566
567 static struct nl_af_group ct_groups[] = {
568         { AF_UNSPEC, NFNLGRP_CONNTRACK_NEW },
569         { AF_UNSPEC, NFNLGRP_CONNTRACK_UPDATE },
570         { AF_UNSPEC, NFNLGRP_CONNTRACK_DESTROY },
571         { END_OF_GROUP_LIST },
572 };
573
574 #define NFNLMSG_CT_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK, (type))
575 static struct nl_cache_ops nfnl_ct_ops = {
576         .co_name                = "netfilter/ct",
577         .co_hdrsize             = NFNL_HDRLEN,
578         .co_msgtypes            = {
579                 { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_NEW), NL_ACT_NEW, "new" },
580                 { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_GET), NL_ACT_GET, "get" },
581                 { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_DELETE), NL_ACT_DEL, "del" },
582                 END_OF_MSGTYPES_LIST,
583         },
584         .co_protocol            = NETLINK_NETFILTER,
585         .co_groups              = ct_groups,
586         .co_request_update      = ct_request_update,
587         .co_msg_parser          = ct_msg_parser,
588         .co_obj_ops             = &ct_obj_ops,
589 };
590
591 static void __init ct_init(void)
592 {
593         nl_cache_mngt_register(&nfnl_ct_ops);
594 }
595
596 static void __exit ct_exit(void)
597 {
598         nl_cache_mngt_unregister(&nfnl_ct_ops);
599 }
600
601 /** @} */