00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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
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
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
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