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 (at) suug.ch> 10 * Copyright (c) 2007 Philip Craig <philipc (at) snapgear.com> 11 * Copyright (c) 2007 Secure Computing Corporation 12 * Copyright (c= 2008 Patrick McHardy <kaber (at) 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 /** @} */ 602