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 31static struct nl_cache_ops nfnl_ct_ops; 32 33#if __BYTE_ORDER == __BIG_ENDIAN 34static uint64_t ntohll(uint64_t x) 35{ 36 return x; 37} 38#elif __BYTE_ORDER == __LITTLE_ENDIAN 39static uint64_t ntohll(uint64_t x) 40{ 41 return __bswap_64(x); 42} 43#endif 44 45static 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 61static 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 66static 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 73static 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 85static struct nla_policy ct_protoinfo_policy[CTA_PROTOINFO_MAX+1] = { 86 [CTA_PROTOINFO_TCP] = { .type = NLA_NESTED }, 87}; 88 89static 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 98static 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 105static 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 154errout_enomem: 155 err = -NLE_NOMEM; 156errout: 157 return err; 158} 159 160static 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 190static 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 214static 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 231static 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 250static 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 275int 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 290int 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 352errout: 353 nfnl_ct_put(ct); 354 return err; 355} 356 357static 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); 367errout: 368 nfnl_ct_put(ct); 369 return err; 370} 371 372int 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 378static int ct_request_update(struct nl_cache *cache, struct nl_sock *sk) 379{ 380 return nfnl_ct_dump_request(sk); 381} 382 383static 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 446nla_put_failure: 447 return -NLE_MSGSIZE; 448} 449 450static 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 467err_out: 468 nlmsg_free(msg); 469 return err; 470} 471 472int 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 478int 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 494int 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 500int 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 516int 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 522int 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 */ 553int 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 567static 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)) 575static 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 591static void __init ct_init(void) 592{ 593 nl_cache_mngt_register(&nfnl_ct_ops); 594} 595 596static void __exit ct_exit(void) 597{ 598 nl_cache_mngt_unregister(&nfnl_ct_ops); 599} 600 601/** @} */ 602