libnl 1.1
|
00001 /* 00002 * lib/netfilter/ct_obj.c Conntrack Object 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 00010 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 00011 * Copyright (c) 2007 Secure Computing Corporation 00012 */ 00013 00014 #include <sys/types.h> 00015 #include <linux/netfilter/nfnetlink_conntrack.h> 00016 #include <linux/netfilter/nf_conntrack_common.h> 00017 #include <linux/netfilter/nf_conntrack_tcp.h> 00018 00019 #include <netlink-local.h> 00020 #include <netlink/netfilter/nfnl.h> 00021 #include <netlink/netfilter/ct.h> 00022 00023 /** @cond SKIP */ 00024 #define CT_ATTR_FAMILY (1UL << 0) 00025 #define CT_ATTR_PROTO (1UL << 1) 00026 00027 #define CT_ATTR_TCP_STATE (1UL << 2) 00028 00029 #define CT_ATTR_STATUS (1UL << 3) 00030 #define CT_ATTR_TIMEOUT (1UL << 4) 00031 #define CT_ATTR_MARK (1UL << 5) 00032 #define CT_ATTR_USE (1UL << 6) 00033 #define CT_ATTR_ID (1UL << 7) 00034 00035 #define CT_ATTR_ORIG_SRC (1UL << 8) 00036 #define CT_ATTR_ORIG_DST (1UL << 9) 00037 #define CT_ATTR_ORIG_SRC_PORT (1UL << 10) 00038 #define CT_ATTR_ORIG_DST_PORT (1UL << 11) 00039 #define CT_ATTR_ORIG_ICMP_ID (1UL << 12) 00040 #define CT_ATTR_ORIG_ICMP_TYPE (1UL << 13) 00041 #define CT_ATTR_ORIG_ICMP_CODE (1UL << 14) 00042 #define CT_ATTR_ORIG_PACKETS (1UL << 15) 00043 #define CT_ATTR_ORIG_BYTES (1UL << 16) 00044 00045 #define CT_ATTR_REPL_SRC (1UL << 17) 00046 #define CT_ATTR_REPL_DST (1UL << 18) 00047 #define CT_ATTR_REPL_SRC_PORT (1UL << 19) 00048 #define CT_ATTR_REPL_DST_PORT (1UL << 20) 00049 #define CT_ATTR_REPL_ICMP_ID (1UL << 21) 00050 #define CT_ATTR_REPL_ICMP_TYPE (1UL << 22) 00051 #define CT_ATTR_REPL_ICMP_CODE (1UL << 23) 00052 #define CT_ATTR_REPL_PACKETS (1UL << 24) 00053 #define CT_ATTR_REPL_BYTES (1UL << 25) 00054 /** @endcond */ 00055 00056 static void ct_free_data(struct nl_object *c) 00057 { 00058 struct nfnl_ct *ct = (struct nfnl_ct *) c; 00059 00060 if (ct == NULL) 00061 return; 00062 00063 nl_addr_put(ct->ct_orig.src); 00064 nl_addr_put(ct->ct_orig.dst); 00065 nl_addr_put(ct->ct_repl.src); 00066 nl_addr_put(ct->ct_repl.dst); 00067 } 00068 00069 static int ct_clone(struct nl_object *_dst, struct nl_object *_src) 00070 { 00071 struct nfnl_ct *dst = (struct nfnl_ct *) _dst; 00072 struct nfnl_ct *src = (struct nfnl_ct *) _src; 00073 struct nl_addr *addr; 00074 00075 if (src->ct_orig.src) { 00076 addr = nl_addr_clone(src->ct_orig.src); 00077 if (!addr) 00078 goto errout; 00079 dst->ct_orig.src = addr; 00080 } 00081 00082 if (src->ct_orig.dst) { 00083 addr = nl_addr_clone(src->ct_orig.dst); 00084 if (!addr) 00085 goto errout; 00086 dst->ct_orig.dst = addr; 00087 } 00088 00089 if (src->ct_repl.src) { 00090 addr = nl_addr_clone(src->ct_repl.src); 00091 if (!addr) 00092 goto errout; 00093 dst->ct_repl.src = addr; 00094 } 00095 00096 if (src->ct_repl.dst) { 00097 addr = nl_addr_clone(src->ct_repl.dst); 00098 if (!addr) 00099 goto errout; 00100 dst->ct_repl.dst = addr; 00101 } 00102 00103 return 0; 00104 errout: 00105 return nl_get_errno(); 00106 } 00107 00108 static void ct_dump_dir(struct nfnl_ct *ct, int repl, 00109 struct nl_dump_params *p) 00110 { 00111 struct nl_addr *addr; 00112 char addrbuf[64]; 00113 00114 addr = nfnl_ct_get_src(ct, repl); 00115 if (addr) 00116 dp_dump(p, "src=%s ", 00117 nl_addr2str(addr, addrbuf, sizeof(addrbuf))); 00118 00119 addr = nfnl_ct_get_dst(ct, repl); 00120 if (addr) 00121 dp_dump(p, "dst=%s ", 00122 nl_addr2str(addr, addrbuf, sizeof(addrbuf))); 00123 00124 if (nfnl_ct_test_src_port(ct, repl)) 00125 dp_dump(p, "sport=%u ", ntohs(nfnl_ct_get_src_port(ct, repl))); 00126 if (nfnl_ct_test_dst_port(ct, repl)) 00127 dp_dump(p, "dport=%u ", ntohs(nfnl_ct_get_dst_port(ct, repl))); 00128 00129 if (nfnl_ct_test_icmp_type(ct, repl)) 00130 dp_dump(p, "type=%d ", nfnl_ct_get_icmp_type(ct, repl)); 00131 if (nfnl_ct_test_icmp_type(ct, repl)) 00132 dp_dump(p, "code=%d ", nfnl_ct_get_icmp_code(ct, repl)); 00133 if (nfnl_ct_test_icmp_type(ct, repl)) 00134 dp_dump(p, "id=%d ", ntohs(nfnl_ct_get_icmp_id(ct, repl))); 00135 00136 if (nfnl_ct_test_packets(ct, repl)) 00137 dp_dump(p, "packets=%llu ", nfnl_ct_get_packets(ct, repl)); 00138 if (nfnl_ct_test_bytes(ct, repl)) 00139 dp_dump(p, "bytes=%llu ", nfnl_ct_get_bytes(ct, repl)); 00140 } 00141 00142 /* Compatible with /proc/net/nf_conntrack */ 00143 static int ct_dump(struct nl_object *a, struct nl_dump_params *p) 00144 { 00145 struct nfnl_ct *ct = (struct nfnl_ct *) a; 00146 char buf[64]; 00147 uint32_t status; 00148 uint8_t family; 00149 uint8_t proto; 00150 00151 family = nfnl_ct_get_family(ct); 00152 dp_dump(p, "%-8s %u ", nl_af2str(family, buf, sizeof(buf)), family); 00153 00154 if (nfnl_ct_test_proto(ct)) { 00155 proto = nfnl_ct_get_proto(ct); 00156 dp_dump(p, "%-8s %u ", 00157 nl_ip_proto2str(proto, buf, sizeof(buf)), proto); 00158 } 00159 00160 if (nfnl_ct_test_timeout(ct)) 00161 dp_dump(p, "%ld ", nfnl_ct_get_timeout(ct)); 00162 00163 if (nfnl_ct_test_tcp_state(ct)) 00164 dp_dump(p, "%s ", 00165 nfnl_ct_tcp_state2str(nfnl_ct_get_tcp_state(ct), 00166 buf, sizeof(buf))); 00167 00168 ct_dump_dir(ct, 0, p); 00169 00170 status = nfnl_ct_get_status(ct); 00171 if (!(status & IPS_SEEN_REPLY)) 00172 dp_dump(p, "[UNREPLIED] "); 00173 00174 ct_dump_dir(ct, 1, p); 00175 00176 if (status & IPS_ASSURED) 00177 dp_dump(p, "[ASSURED] "); 00178 00179 if (nfnl_ct_test_mark(ct)) 00180 dp_dump(p, "mark=%u ", nfnl_ct_get_mark(ct)); 00181 00182 if (nfnl_ct_test_use(ct)) 00183 dp_dump(p, "use=%u ", nfnl_ct_get_use(ct)); 00184 00185 dp_dump(p, "\n"); 00186 00187 return 1; 00188 } 00189 00190 static int ct_compare(struct nl_object *_a, struct nl_object *_b, 00191 uint32_t attrs, int flags) 00192 { 00193 struct nfnl_ct *a = (struct nfnl_ct *) _a; 00194 struct nfnl_ct *b = (struct nfnl_ct *) _b; 00195 int diff = 0; 00196 00197 #define CT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, CT_ATTR_##ATTR, a, b, EXPR) 00198 #define CT_DIFF_VAL(ATTR, FIELD) CT_DIFF(ATTR, a->FIELD != b->FIELD) 00199 #define CT_DIFF_ADDR(ATTR, FIELD) \ 00200 ((flags & LOOSE_FLAG_COMPARISON) \ 00201 ? CT_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ 00202 : CT_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) 00203 00204 diff |= CT_DIFF_VAL(FAMILY, ct_family); 00205 diff |= CT_DIFF_VAL(PROTO, ct_proto); 00206 diff |= CT_DIFF_VAL(TCP_STATE, ct_protoinfo.tcp.state); 00207 diff |= CT_DIFF_VAL(TIMEOUT, ct_timeout); 00208 diff |= CT_DIFF_VAL(MARK, ct_mark); 00209 diff |= CT_DIFF_VAL(USE, ct_use); 00210 diff |= CT_DIFF_VAL(ID, ct_id); 00211 diff |= CT_DIFF_ADDR(ORIG_SRC, ct_orig.src); 00212 diff |= CT_DIFF_ADDR(ORIG_DST, ct_orig.dst); 00213 diff |= CT_DIFF_VAL(ORIG_SRC_PORT, ct_orig.proto.port.src); 00214 diff |= CT_DIFF_VAL(ORIG_DST_PORT, ct_orig.proto.port.dst); 00215 diff |= CT_DIFF_VAL(ORIG_ICMP_ID, ct_orig.proto.icmp.id); 00216 diff |= CT_DIFF_VAL(ORIG_ICMP_TYPE, ct_orig.proto.icmp.type); 00217 diff |= CT_DIFF_VAL(ORIG_ICMP_CODE, ct_orig.proto.icmp.code); 00218 diff |= CT_DIFF_VAL(ORIG_PACKETS, ct_orig.packets); 00219 diff |= CT_DIFF_VAL(ORIG_BYTES, ct_orig.bytes); 00220 diff |= CT_DIFF_ADDR(REPL_SRC, ct_repl.src); 00221 diff |= CT_DIFF_ADDR(REPL_DST, ct_repl.dst); 00222 diff |= CT_DIFF_VAL(REPL_SRC_PORT, ct_repl.proto.port.src); 00223 diff |= CT_DIFF_VAL(REPL_DST_PORT, ct_repl.proto.port.dst); 00224 diff |= CT_DIFF_VAL(REPL_ICMP_ID, ct_repl.proto.icmp.id); 00225 diff |= CT_DIFF_VAL(REPL_ICMP_TYPE, ct_repl.proto.icmp.type); 00226 diff |= CT_DIFF_VAL(REPL_ICMP_CODE, ct_repl.proto.icmp.code); 00227 diff |= CT_DIFF_VAL(REPL_PACKETS, ct_repl.packets); 00228 diff |= CT_DIFF_VAL(REPL_BYTES, ct_repl.bytes); 00229 00230 if (flags & LOOSE_FLAG_COMPARISON) 00231 diff |= CT_DIFF(STATUS, (a->ct_status ^ b->ct_status) & 00232 b->ct_status_mask); 00233 else 00234 diff |= CT_DIFF(STATUS, a->ct_status != b->ct_status); 00235 00236 #undef CT_DIFF 00237 #undef CT_DIFF_VAL 00238 #undef CT_DIFF_ADDR 00239 00240 return diff; 00241 } 00242 00243 static struct trans_tbl ct_attrs[] = { 00244 __ADD(CT_ATTR_FAMILY, family) 00245 __ADD(CT_ATTR_PROTO, proto) 00246 __ADD(CT_ATTR_TCP_STATE, tcpstate) 00247 __ADD(CT_ATTR_STATUS, status) 00248 __ADD(CT_ATTR_TIMEOUT, timeout) 00249 __ADD(CT_ATTR_MARK, mark) 00250 __ADD(CT_ATTR_USE, use) 00251 __ADD(CT_ATTR_ID, id) 00252 __ADD(CT_ATTR_ORIG_SRC, origsrc) 00253 __ADD(CT_ATTR_ORIG_DST, origdst) 00254 __ADD(CT_ATTR_ORIG_SRC_PORT, origsrcport) 00255 __ADD(CT_ATTR_ORIG_DST_PORT, origdstport) 00256 __ADD(CT_ATTR_ORIG_ICMP_ID, origicmpid) 00257 __ADD(CT_ATTR_ORIG_ICMP_TYPE, origicmptype) 00258 __ADD(CT_ATTR_ORIG_ICMP_CODE, origicmpcode) 00259 __ADD(CT_ATTR_ORIG_PACKETS, origpackets) 00260 __ADD(CT_ATTR_ORIG_BYTES, origbytes) 00261 __ADD(CT_ATTR_REPL_SRC, replysrc) 00262 __ADD(CT_ATTR_REPL_DST, replydst) 00263 __ADD(CT_ATTR_REPL_SRC_PORT, replysrcport) 00264 __ADD(CT_ATTR_REPL_DST_PORT, replydstport) 00265 __ADD(CT_ATTR_REPL_ICMP_ID, replyicmpid) 00266 __ADD(CT_ATTR_REPL_ICMP_TYPE, replyicmptype) 00267 __ADD(CT_ATTR_REPL_ICMP_CODE, replyicmpcode) 00268 __ADD(CT_ATTR_REPL_PACKETS, replypackets) 00269 __ADD(CT_ATTR_REPL_BYTES, replybytes) 00270 }; 00271 00272 static char *ct_attrs2str(int attrs, char *buf, size_t len) 00273 { 00274 return __flags2str(attrs, buf, len, ct_attrs, ARRAY_SIZE(ct_attrs)); 00275 } 00276 00277 /** 00278 * @name Allocation/Freeing 00279 * @{ 00280 */ 00281 00282 struct nfnl_ct *nfnl_ct_alloc(void) 00283 { 00284 return (struct nfnl_ct *) nl_object_alloc(&ct_obj_ops); 00285 } 00286 00287 void nfnl_ct_get(struct nfnl_ct *ct) 00288 { 00289 nl_object_get((struct nl_object *) ct); 00290 } 00291 00292 void nfnl_ct_put(struct nfnl_ct *ct) 00293 { 00294 nl_object_put((struct nl_object *) ct); 00295 } 00296 00297 /** @} */ 00298 00299 /** 00300 * @name Attributes 00301 * @{ 00302 */ 00303 00304 void nfnl_ct_set_family(struct nfnl_ct *ct, uint8_t family) 00305 { 00306 ct->ct_family = family; 00307 ct->ce_mask |= CT_ATTR_FAMILY; 00308 } 00309 00310 uint8_t nfnl_ct_get_family(const struct nfnl_ct *ct) 00311 { 00312 if (ct->ce_mask & CT_ATTR_FAMILY) 00313 return ct->ct_family; 00314 else 00315 return AF_UNSPEC; 00316 } 00317 00318 void nfnl_ct_set_proto(struct nfnl_ct *ct, uint8_t proto) 00319 { 00320 ct->ct_proto = proto; 00321 ct->ce_mask |= CT_ATTR_PROTO; 00322 } 00323 00324 int nfnl_ct_test_proto(const struct nfnl_ct *ct) 00325 { 00326 return !!(ct->ce_mask & CT_ATTR_PROTO); 00327 } 00328 00329 uint8_t nfnl_ct_get_proto(const struct nfnl_ct *ct) 00330 { 00331 return ct->ct_proto; 00332 } 00333 00334 void nfnl_ct_set_tcp_state(struct nfnl_ct *ct, uint8_t state) 00335 { 00336 ct->ct_protoinfo.tcp.state = state; 00337 ct->ce_mask |= CT_ATTR_TCP_STATE; 00338 } 00339 00340 int nfnl_ct_test_tcp_state(const struct nfnl_ct *ct) 00341 { 00342 return !!(ct->ce_mask & CT_ATTR_TCP_STATE); 00343 } 00344 00345 uint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *ct) 00346 { 00347 return ct->ct_protoinfo.tcp.state; 00348 } 00349 00350 static struct trans_tbl tcp_states[] = { 00351 __ADD(TCP_CONNTRACK_NONE,NONE) 00352 __ADD(TCP_CONNTRACK_SYN_SENT,SYN_SENT) 00353 __ADD(TCP_CONNTRACK_SYN_RECV,SYN_RECV) 00354 __ADD(TCP_CONNTRACK_ESTABLISHED,ESTABLISHED) 00355 __ADD(TCP_CONNTRACK_FIN_WAIT,FIN_WAIT) 00356 __ADD(TCP_CONNTRACK_CLOSE_WAIT,CLOSE_WAIT) 00357 __ADD(TCP_CONNTRACK_LAST_ACK,LAST_ACK) 00358 __ADD(TCP_CONNTRACK_TIME_WAIT,TIME_WAIT) 00359 __ADD(TCP_CONNTRACK_CLOSE,CLOSE) 00360 __ADD(TCP_CONNTRACK_LISTEN,LISTEN) 00361 }; 00362 00363 char *nfnl_ct_tcp_state2str(uint8_t state, char *buf, size_t len) 00364 { 00365 return __type2str(state, buf, len, tcp_states, ARRAY_SIZE(tcp_states)); 00366 } 00367 00368 int nfnl_ct_str2tcp_state(const char *name) 00369 { 00370 return __str2type(name, tcp_states, ARRAY_SIZE(tcp_states)); 00371 } 00372 00373 void nfnl_ct_set_status(struct nfnl_ct *ct, uint32_t status) 00374 { 00375 ct->ct_status_mask |= status; 00376 ct->ct_status |= status; 00377 ct->ce_mask |= CT_ATTR_STATUS; 00378 } 00379 00380 void nfnl_ct_unset_status(struct nfnl_ct *ct, uint32_t status) 00381 { 00382 ct->ct_status_mask |= status; 00383 ct->ct_status &= ~status; 00384 ct->ce_mask |= CT_ATTR_STATUS; 00385 } 00386 00387 uint32_t nfnl_ct_get_status(const struct nfnl_ct *ct) 00388 { 00389 return ct->ct_status; 00390 } 00391 00392 void nfnl_ct_set_timeout(struct nfnl_ct *ct, uint32_t timeout) 00393 { 00394 ct->ct_timeout = timeout; 00395 ct->ce_mask |= CT_ATTR_TIMEOUT; 00396 } 00397 00398 int nfnl_ct_test_timeout(const struct nfnl_ct *ct) 00399 { 00400 return !!(ct->ce_mask & CT_ATTR_TIMEOUT); 00401 } 00402 00403 uint32_t nfnl_ct_get_timeout(const struct nfnl_ct *ct) 00404 { 00405 return ct->ct_timeout; 00406 } 00407 00408 void nfnl_ct_set_mark(struct nfnl_ct *ct, uint32_t mark) 00409 { 00410 ct->ct_mark = mark; 00411 ct->ce_mask |= CT_ATTR_MARK; 00412 } 00413 00414 int nfnl_ct_test_mark(const struct nfnl_ct *ct) 00415 { 00416 return !!(ct->ce_mask & CT_ATTR_MARK); 00417 } 00418 00419 uint32_t nfnl_ct_get_mark(const struct nfnl_ct *ct) 00420 { 00421 return ct->ct_mark; 00422 } 00423 00424 void nfnl_ct_set_use(struct nfnl_ct *ct, uint32_t use) 00425 { 00426 ct->ct_use = use; 00427 ct->ce_mask |= CT_ATTR_USE; 00428 } 00429 00430 int nfnl_ct_test_use(const struct nfnl_ct *ct) 00431 { 00432 return !!(ct->ce_mask & CT_ATTR_USE); 00433 } 00434 00435 uint32_t nfnl_ct_get_use(const struct nfnl_ct *ct) 00436 { 00437 return ct->ct_use; 00438 } 00439 00440 void nfnl_ct_set_id(struct nfnl_ct *ct, uint32_t id) 00441 { 00442 ct->ct_id = id; 00443 ct->ce_mask |= CT_ATTR_ID; 00444 } 00445 00446 int nfnl_ct_test_id(const struct nfnl_ct *ct) 00447 { 00448 return !!(ct->ce_mask & CT_ATTR_ID); 00449 } 00450 00451 uint32_t nfnl_ct_get_id(const struct nfnl_ct *ct) 00452 { 00453 return ct->ct_id; 00454 } 00455 00456 static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, 00457 int attr, struct nl_addr ** ct_addr) 00458 { 00459 if (ct->ce_mask & CT_ATTR_FAMILY) { 00460 if (addr->a_family != ct->ct_family) 00461 return nl_error(EINVAL, "Address family mismatch"); 00462 } else 00463 nfnl_ct_set_family(ct, addr->a_family); 00464 00465 if (*ct_addr) 00466 nl_addr_put(*ct_addr); 00467 00468 nl_addr_get(addr); 00469 *ct_addr = addr; 00470 ct->ce_mask |= attr; 00471 00472 return 0; 00473 } 00474 00475 int nfnl_ct_set_src(struct nfnl_ct *ct, int repl, struct nl_addr *addr) 00476 { 00477 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00478 int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; 00479 return ct_set_addr(ct, addr, attr, &dir->src); 00480 } 00481 00482 int nfnl_ct_set_dst(struct nfnl_ct *ct, int repl, struct nl_addr *addr) 00483 { 00484 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00485 int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; 00486 return ct_set_addr(ct, addr, attr, &dir->dst); 00487 } 00488 00489 struct nl_addr *nfnl_ct_get_src(const struct nfnl_ct *ct, int repl) 00490 { 00491 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00492 int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; 00493 if (!(ct->ce_mask & attr)) 00494 return NULL; 00495 return dir->src; 00496 } 00497 00498 struct nl_addr *nfnl_ct_get_dst(const struct nfnl_ct *ct, int repl) 00499 { 00500 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00501 int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; 00502 if (!(ct->ce_mask & attr)) 00503 return NULL; 00504 return dir->dst; 00505 } 00506 00507 void nfnl_ct_set_src_port(struct nfnl_ct *ct, int repl, uint16_t port) 00508 { 00509 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00510 int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; 00511 00512 dir->proto.port.src = port; 00513 ct->ce_mask |= attr; 00514 } 00515 00516 int nfnl_ct_test_src_port(const struct nfnl_ct *ct, int repl) 00517 { 00518 int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; 00519 return !!(ct->ce_mask & attr); 00520 } 00521 00522 uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *ct, int repl) 00523 { 00524 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00525 00526 return dir->proto.port.src; 00527 } 00528 00529 void nfnl_ct_set_dst_port(struct nfnl_ct *ct, int repl, uint16_t port) 00530 { 00531 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00532 int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; 00533 00534 dir->proto.port.dst = port; 00535 ct->ce_mask |= attr; 00536 } 00537 00538 int nfnl_ct_test_dst_port(const struct nfnl_ct *ct, int repl) 00539 { 00540 int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; 00541 return !!(ct->ce_mask & attr); 00542 } 00543 00544 uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *ct, int repl) 00545 { 00546 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00547 00548 return dir->proto.port.dst; 00549 } 00550 00551 void nfnl_ct_set_icmp_id(struct nfnl_ct *ct, int repl, uint16_t id) 00552 { 00553 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00554 int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; 00555 00556 dir->proto.icmp.id = id; 00557 ct->ce_mask |= attr; 00558 } 00559 00560 int nfnl_ct_test_icmp_id(const struct nfnl_ct *ct, int repl) 00561 { 00562 int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; 00563 return !!(ct->ce_mask & attr); 00564 } 00565 00566 uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *ct, int repl) 00567 { 00568 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00569 00570 return dir->proto.icmp.id; 00571 } 00572 00573 void nfnl_ct_set_icmp_type(struct nfnl_ct *ct, int repl, uint8_t type) 00574 { 00575 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00576 int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; 00577 00578 dir->proto.icmp.type = type; 00579 ct->ce_mask |= attr; 00580 } 00581 00582 int nfnl_ct_test_icmp_type(const struct nfnl_ct *ct, int repl) 00583 { 00584 int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; 00585 return !!(ct->ce_mask & attr); 00586 } 00587 00588 uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *ct, int repl) 00589 { 00590 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00591 00592 return dir->proto.icmp.type; 00593 } 00594 00595 void nfnl_ct_set_icmp_code(struct nfnl_ct *ct, int repl, uint8_t code) 00596 { 00597 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00598 int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; 00599 00600 dir->proto.icmp.code = code; 00601 ct->ce_mask |= attr; 00602 } 00603 00604 int nfnl_ct_test_icmp_code(const struct nfnl_ct *ct, int repl) 00605 { 00606 int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; 00607 return !!(ct->ce_mask & attr); 00608 } 00609 00610 uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *ct, int repl) 00611 { 00612 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00613 00614 return dir->proto.icmp.code; 00615 } 00616 00617 void nfnl_ct_set_packets(struct nfnl_ct *ct, int repl, uint64_t packets) 00618 { 00619 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00620 int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; 00621 00622 dir->packets = packets; 00623 ct->ce_mask |= attr; 00624 } 00625 00626 int nfnl_ct_test_packets(const struct nfnl_ct *ct, int repl) 00627 { 00628 int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; 00629 return !!(ct->ce_mask & attr); 00630 } 00631 00632 uint64_t nfnl_ct_get_packets(const struct nfnl_ct *ct, int repl) 00633 { 00634 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00635 00636 return dir->packets; 00637 } 00638 00639 void nfnl_ct_set_bytes(struct nfnl_ct *ct, int repl, uint64_t bytes) 00640 { 00641 struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00642 int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; 00643 00644 dir->bytes = bytes; 00645 ct->ce_mask |= attr; 00646 } 00647 00648 int nfnl_ct_test_bytes(const struct nfnl_ct *ct, int repl) 00649 { 00650 int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; 00651 return !!(ct->ce_mask & attr); 00652 } 00653 00654 uint64_t nfnl_ct_get_bytes(const struct nfnl_ct *ct, int repl) 00655 { 00656 const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 00657 00658 return dir->bytes; 00659 } 00660 00661 /** @} */ 00662 00663 struct nl_object_ops ct_obj_ops = { 00664 .oo_name = "netfilter/ct", 00665 .oo_size = sizeof(struct nfnl_ct), 00666 .oo_free_data = ct_free_data, 00667 .oo_clone = ct_clone, 00668 .oo_dump[NL_DUMP_BRIEF] = ct_dump, 00669 .oo_dump[NL_DUMP_FULL] = ct_dump, 00670 .oo_dump[NL_DUMP_STATS] = ct_dump, 00671 .oo_compare = ct_compare, 00672 .oo_attrs2str = ct_attrs2str, 00673 }; 00674 00675 /** @} */