00001
00002
00003
00004
00005
00006
00007
00008 #include "internal/internal.h"
00009
00010 static void __build_tuple_ip(struct nfnlhdr *req,
00011 size_t size,
00012 const struct __nfct_tuple *t)
00013 {
00014 struct nfattr *nest;
00015
00016 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
00017
00018 switch(t->l3protonum) {
00019 case AF_INET:
00020 nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4,
00021 sizeof(u_int32_t));
00022 nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4,
00023 sizeof(u_int32_t));
00024 break;
00025 case AF_INET6:
00026 nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_SRC, &t->src.v6,
00027 sizeof(struct in6_addr));
00028 nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_DST, &t->dst.v6,
00029 sizeof(struct in6_addr));
00030 break;
00031 default:
00032 break;
00033 }
00034
00035 nfnl_nest_end(&req->nlh, nest);
00036 }
00037
00038 static void __build_tuple_proto(struct nfnlhdr *req,
00039 size_t size,
00040 const struct __nfct_tuple *t)
00041 {
00042 struct nfattr *nest;
00043
00044 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO);
00045
00046 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum,
00047 sizeof(u_int8_t));
00048
00049 switch(t->protonum) {
00050 case IPPROTO_UDP:
00051 case IPPROTO_TCP:
00052 case IPPROTO_SCTP:
00053 case IPPROTO_DCCP:
00054 case IPPROTO_GRE:
00055 case IPPROTO_UDPLITE:
00056 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT,
00057 &t->l4src.tcp.port, sizeof(u_int16_t));
00058 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_DST_PORT,
00059 &t->l4dst.tcp.port, sizeof(u_int16_t));
00060 break;
00061
00062 case IPPROTO_ICMP:
00063 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_CODE,
00064 &t->l4dst.icmp.code, sizeof(u_int8_t));
00065 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_TYPE,
00066 &t->l4dst.icmp.type, sizeof(u_int8_t));
00067 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_ID,
00068 &t->l4src.icmp.id, sizeof(u_int16_t));
00069 break;
00070
00071 case IPPROTO_ICMPV6:
00072 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMPV6_CODE,
00073 &t->l4dst.icmp.code, sizeof(u_int8_t));
00074 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMPV6_TYPE,
00075 &t->l4dst.icmp.type, sizeof(u_int8_t));
00076 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMPV6_ID,
00077 &t->l4src.icmp.id, sizeof(u_int16_t));
00078 break;
00079
00080 default:
00081 break;
00082 }
00083
00084 nfnl_nest_end(&req->nlh, nest);
00085 }
00086
00087 void __build_tuple(struct nfnlhdr *req,
00088 size_t size,
00089 const struct __nfct_tuple *t,
00090 const int type)
00091 {
00092 struct nfattr *nest;
00093
00094 nest = nfnl_nest(&req->nlh, size, type);
00095
00096 __build_tuple_ip(req, size, t);
00097 __build_tuple_proto(req, size, t);
00098
00099 nfnl_nest_end(&req->nlh, nest);
00100 }
00101
00102 static void __build_protoinfo(struct nfnlhdr *req, size_t size,
00103 const struct nf_conntrack *ct)
00104 {
00105 struct nfattr *nest, *nest_proto;
00106
00107 switch(ct->tuple[__DIR_ORIG].protonum) {
00108 case IPPROTO_TCP:
00109
00110
00111
00112 if (!(test_bit(ATTR_TCP_STATE, ct->set) ||
00113 test_bit(ATTR_TCP_FLAGS_ORIG, ct->set) ||
00114 test_bit(ATTR_TCP_FLAGS_REPL, ct->set) ||
00115 test_bit(ATTR_TCP_MASK_ORIG, ct->set) ||
00116 test_bit(ATTR_TCP_MASK_REPL, ct->set) ||
00117 test_bit(ATTR_TCP_WSCALE_ORIG, ct->set) ||
00118 test_bit(ATTR_TCP_WSCALE_REPL, ct->set))) {
00119 break;
00120 }
00121 nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
00122 nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP);
00123 if (test_bit(ATTR_TCP_STATE, ct->set))
00124 nfnl_addattr_l(&req->nlh, size,
00125 CTA_PROTOINFO_TCP_STATE,
00126 &ct->protoinfo.tcp.state,
00127 sizeof(u_int8_t));
00128 if (test_bit(ATTR_TCP_FLAGS_ORIG, ct->set) &&
00129 test_bit(ATTR_TCP_MASK_ORIG, ct->set))
00130 nfnl_addattr_l(&req->nlh, size,
00131 CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
00132 &ct->protoinfo.tcp.flags[0],
00133 sizeof(u_int16_t));
00134 if (test_bit(ATTR_TCP_FLAGS_REPL, ct->set) &&
00135 test_bit(ATTR_TCP_MASK_REPL, ct->set))
00136 nfnl_addattr_l(&req->nlh, size,
00137 CTA_PROTOINFO_TCP_FLAGS_REPLY,
00138 &ct->protoinfo.tcp.flags[1],
00139 sizeof(u_int16_t));
00140 if (test_bit(ATTR_TCP_WSCALE_ORIG, ct->set))
00141 nfnl_addattr_l(&req->nlh, size,
00142 CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
00143 &ct->protoinfo.tcp.wscale[__DIR_ORIG],
00144 sizeof(u_int8_t));
00145 if (test_bit(ATTR_TCP_WSCALE_REPL, ct->set))
00146 nfnl_addattr_l(&req->nlh, size,
00147 CTA_PROTOINFO_TCP_WSCALE_REPLY,
00148 &ct->protoinfo.tcp.wscale[__DIR_REPL],
00149 sizeof(u_int8_t));
00150 nfnl_nest_end(&req->nlh, nest_proto);
00151 nfnl_nest_end(&req->nlh, nest);
00152 break;
00153 case IPPROTO_SCTP:
00154
00155 if (!(test_bit(ATTR_SCTP_STATE, ct->set) ||
00156 test_bit(ATTR_SCTP_VTAG_ORIG, ct->set) ||
00157 test_bit(ATTR_SCTP_VTAG_REPL, ct->set))) {
00158 break;
00159 }
00160 nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
00161 nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_SCTP);
00162 if (test_bit(ATTR_SCTP_STATE, ct->set))
00163 nfnl_addattr_l(&req->nlh, size,
00164 CTA_PROTOINFO_SCTP_STATE,
00165 &ct->protoinfo.sctp.state,
00166 sizeof(u_int8_t));
00167 if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->set))
00168 nfnl_addattr32(&req->nlh, size,
00169 CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
00170 htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG]));
00171 if (test_bit(ATTR_SCTP_VTAG_REPL, ct->set))
00172 nfnl_addattr32(&req->nlh, size,
00173 CTA_PROTOINFO_SCTP_VTAG_REPLY,
00174 htonl(ct->protoinfo.sctp.vtag[__DIR_REPL]));
00175 nfnl_nest_end(&req->nlh, nest_proto);
00176 nfnl_nest_end(&req->nlh, nest);
00177 break;
00178 case IPPROTO_DCCP:
00179
00180 if (!(test_bit(ATTR_DCCP_STATE, ct->set) ||
00181 test_bit(ATTR_DCCP_ROLE, ct->set) ||
00182 test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->set))) {
00183 break;
00184 }
00185 nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
00186 nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_DCCP);
00187 if (test_bit(ATTR_DCCP_STATE, ct->set))
00188 nfnl_addattr_l(&req->nlh, size,
00189 CTA_PROTOINFO_DCCP_STATE,
00190 &ct->protoinfo.dccp.state,
00191 sizeof(u_int8_t));
00192 if (test_bit(ATTR_DCCP_ROLE, ct->set))
00193 nfnl_addattr_l(&req->nlh, size,
00194 CTA_PROTOINFO_DCCP_ROLE,
00195 &ct->protoinfo.dccp.role,
00196 sizeof(u_int8_t));
00197 if (test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->set)) {
00198
00199
00200
00201 u_int64_t handshake_seq =
00202 __be64_to_cpu(ct->protoinfo.dccp.handshake_seq);
00203
00204 nfnl_addattr_l(&req->nlh, size,
00205 CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
00206 &handshake_seq,
00207 sizeof(u_int64_t));
00208 }
00209 nfnl_nest_end(&req->nlh, nest_proto);
00210 nfnl_nest_end(&req->nlh, nest);
00211 default:
00212 break;
00213 }
00214 }
00215
00216 static inline void
00217 __nat_seq_adj(struct nfnlhdr *req,
00218 size_t size,
00219 const struct nf_conntrack *ct,
00220 int dir)
00221 {
00222 nfnl_addattr32(&req->nlh,
00223 size,
00224 CTA_NAT_SEQ_CORRECTION_POS,
00225 htonl(ct->tuple[dir].natseq.correction_pos));
00226 nfnl_addattr32(&req->nlh,
00227 size,
00228 CTA_NAT_SEQ_OFFSET_BEFORE,
00229 htonl(ct->tuple[dir].natseq.offset_before));
00230 nfnl_addattr32(&req->nlh,
00231 size,
00232 CTA_NAT_SEQ_OFFSET_AFTER,
00233 htonl(ct->tuple[dir].natseq.offset_after));
00234 }
00235
00236 static void
00237 __build_nat_seq_adj(struct nfnlhdr *req,
00238 size_t size,
00239 const struct nf_conntrack *ct,
00240 int dir)
00241 {
00242 struct nfattr *nest;
00243 int type = (dir == __DIR_ORIG) ? CTA_NAT_SEQ_ADJ_ORIG :
00244 CTA_NAT_SEQ_ADJ_REPLY;
00245
00246 nest = nfnl_nest(&req->nlh, size, type);
00247 __nat_seq_adj(req, size, ct, dir);
00248 nfnl_nest_end(&req->nlh, nest);
00249 }
00250
00251 static void __build_protonat(struct nfnlhdr *req,
00252 size_t size,
00253 const struct nf_conntrack *ct,
00254 const struct __nfct_nat *nat)
00255 {
00256 struct nfattr *nest;
00257
00258 nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO);
00259
00260 switch (ct->tuple[__DIR_ORIG].protonum) {
00261 case IPPROTO_TCP:
00262 case IPPROTO_UDP:
00263 nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MIN,
00264 &nat->l4min.tcp.port, sizeof(u_int16_t));
00265 nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MAX,
00266 &nat->l4max.tcp.port, sizeof(u_int16_t));
00267 break;
00268 }
00269 nfnl_nest_end(&req->nlh, nest);
00270 }
00271
00272 static void __build_nat(struct nfnlhdr *req,
00273 size_t size,
00274 const struct __nfct_nat *nat)
00275 {
00276 nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
00277 &nat->min_ip, sizeof(u_int32_t));
00278 }
00279
00280 static void __build_snat(struct nfnlhdr *req,
00281 size_t size,
00282 const struct nf_conntrack *ct)
00283 {
00284 struct nfattr *nest;
00285
00286 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
00287 __build_nat(req, size, &ct->snat);
00288 __build_protonat(req, size, ct, &ct->snat);
00289 nfnl_nest_end(&req->nlh, nest);
00290 }
00291
00292 static void __build_snat_ipv4(struct nfnlhdr *req,
00293 size_t size,
00294 const struct nf_conntrack *ct)
00295 {
00296 struct nfattr *nest;
00297
00298 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
00299 __build_nat(req, size, &ct->snat);
00300 nfnl_nest_end(&req->nlh, nest);
00301 }
00302
00303 static void __build_snat_port(struct nfnlhdr *req,
00304 size_t size,
00305 const struct nf_conntrack *ct)
00306 {
00307 struct nfattr *nest;
00308
00309 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
00310 __build_protonat(req, size, ct, &ct->snat);
00311 nfnl_nest_end(&req->nlh, nest);
00312 }
00313
00314 static void __build_dnat(struct nfnlhdr *req,
00315 size_t size,
00316 const struct nf_conntrack *ct)
00317 {
00318 struct nfattr *nest;
00319
00320 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
00321 __build_nat(req, size, &ct->dnat);
00322 __build_protonat(req, size, ct, &ct->dnat);
00323 nfnl_nest_end(&req->nlh, nest);
00324 }
00325
00326 static void __build_dnat_ipv4(struct nfnlhdr *req,
00327 size_t size,
00328 const struct nf_conntrack *ct)
00329 {
00330 struct nfattr *nest;
00331
00332 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
00333 __build_nat(req, size, &ct->dnat);
00334 nfnl_nest_end(&req->nlh, nest);
00335 }
00336
00337 static void __build_dnat_port(struct nfnlhdr *req,
00338 size_t size,
00339 const struct nf_conntrack *ct)
00340 {
00341 struct nfattr *nest;
00342
00343 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
00344 __build_protonat(req, size, ct, &ct->dnat);
00345 nfnl_nest_end(&req->nlh, nest);
00346 }
00347
00348 static void __build_status(struct nfnlhdr *req,
00349 size_t size,
00350 const struct nf_conntrack *ct)
00351 {
00352 nfnl_addattr32(&req->nlh, size, CTA_STATUS,
00353 htonl(ct->status | IPS_CONFIRMED));
00354 }
00355
00356 static void __build_timeout(struct nfnlhdr *req,
00357 size_t size,
00358 const struct nf_conntrack *ct)
00359 {
00360 nfnl_addattr32(&req->nlh, size, CTA_TIMEOUT, htonl(ct->timeout));
00361 }
00362
00363 static void __build_mark(struct nfnlhdr *req,
00364 size_t size,
00365 const struct nf_conntrack *ct)
00366 {
00367 nfnl_addattr32(&req->nlh, size, CTA_MARK, htonl(ct->mark));
00368 }
00369
00370 static void __build_secmark(struct nfnlhdr *req,
00371 size_t size,
00372 const struct nf_conntrack *ct)
00373 {
00374 nfnl_addattr32(&req->nlh, size, CTA_SECMARK, htonl(ct->secmark));
00375 }
00376
00377 static void __build_helper_name(struct nfnlhdr *req,
00378 size_t size,
00379 const struct nf_conntrack *ct)
00380 {
00381 struct nfattr *nest;
00382
00383 nest = nfnl_nest(&req->nlh, size, CTA_HELP);
00384 nfnl_addattr_l(&req->nlh,
00385 size,
00386 CTA_HELP_NAME,
00387 ct->helper_name,
00388 strlen(ct->helper_name)+1);
00389 nfnl_nest_end(&req->nlh, nest);
00390 }
00391
00392 static void __build_zone(struct nfnlhdr *req,
00393 size_t size,
00394 const struct nf_conntrack *ct)
00395 {
00396 nfnl_addattr16(&req->nlh, size, CTA_ZONE, htons(ct->zone));
00397 }
00398
00399 int __build_conntrack(struct nfnl_subsys_handle *ssh,
00400 struct nfnlhdr *req,
00401 size_t size,
00402 u_int16_t type,
00403 u_int16_t flags,
00404 const struct nf_conntrack *ct)
00405 {
00406 u_int8_t l3num = ct->tuple[__DIR_ORIG].l3protonum;
00407
00408 if (!test_bit(ATTR_ORIG_L3PROTO, ct->set)) {
00409 errno = EINVAL;
00410 return -1;
00411 }
00412
00413 memset(req, 0, size);
00414
00415 nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags);
00416
00417 if (test_bit(ATTR_ORIG_IPV4_SRC, ct->set) ||
00418 test_bit(ATTR_ORIG_IPV4_DST, ct->set) ||
00419 test_bit(ATTR_ORIG_IPV6_SRC, ct->set) ||
00420 test_bit(ATTR_ORIG_IPV6_DST, ct->set) ||
00421 test_bit(ATTR_ORIG_PORT_SRC, ct->set) ||
00422 test_bit(ATTR_ORIG_PORT_DST, ct->set) ||
00423 test_bit(ATTR_ORIG_L3PROTO, ct->set) ||
00424 test_bit(ATTR_ORIG_L4PROTO, ct->set) ||
00425 test_bit(ATTR_ICMP_TYPE, ct->set) ||
00426 test_bit(ATTR_ICMP_CODE, ct->set) ||
00427 test_bit(ATTR_ICMP_ID, ct->set))
00428 __build_tuple(req, size,
00429 &ct->tuple[__DIR_ORIG],
00430 CTA_TUPLE_ORIG);
00431
00432 if (test_bit(ATTR_REPL_IPV4_SRC, ct->set) ||
00433 test_bit(ATTR_REPL_IPV4_DST, ct->set) ||
00434 test_bit(ATTR_REPL_IPV6_SRC, ct->set) ||
00435 test_bit(ATTR_REPL_IPV6_DST, ct->set) ||
00436 test_bit(ATTR_REPL_PORT_SRC, ct->set) ||
00437 test_bit(ATTR_REPL_PORT_DST, ct->set) ||
00438 test_bit(ATTR_REPL_L3PROTO, ct->set) ||
00439 test_bit(ATTR_REPL_L4PROTO, ct->set) ||
00440 test_bit(ATTR_ICMP_TYPE, ct->set) ||
00441 test_bit(ATTR_ICMP_CODE, ct->set) ||
00442 test_bit(ATTR_ICMP_ID, ct->set))
00443 __build_tuple(req, size,
00444 &ct->tuple[__DIR_REPL],
00445 CTA_TUPLE_REPLY);
00446
00447 if (test_bit(ATTR_MASTER_IPV4_SRC, ct->set) ||
00448 test_bit(ATTR_MASTER_IPV4_DST, ct->set) ||
00449 test_bit(ATTR_MASTER_IPV6_SRC, ct->set) ||
00450 test_bit(ATTR_MASTER_IPV6_DST, ct->set) ||
00451 test_bit(ATTR_MASTER_PORT_SRC, ct->set) ||
00452 test_bit(ATTR_MASTER_PORT_DST, ct->set) ||
00453 test_bit(ATTR_MASTER_L3PROTO, ct->set) ||
00454 test_bit(ATTR_MASTER_L4PROTO, ct->set))
00455 __build_tuple(req, size,
00456 &ct->tuple[__DIR_MASTER], CTA_TUPLE_MASTER);
00457
00458 if (test_bit(ATTR_STATUS, ct->set))
00459 __build_status(req, size, ct);
00460 else {
00461
00462 if (type == IPCTNL_MSG_CT_NEW && flags & NLM_F_CREATE)
00463 __build_status(req, size, ct);
00464 }
00465
00466 if (test_bit(ATTR_TIMEOUT, ct->set))
00467 __build_timeout(req, size, ct);
00468
00469 if (test_bit(ATTR_MARK, ct->set))
00470 __build_mark(req, size, ct);
00471
00472 if (test_bit(ATTR_SECMARK, ct->set))
00473 __build_secmark(req, size, ct);
00474
00475 __build_protoinfo(req, size, ct);
00476
00477 if (test_bit(ATTR_SNAT_IPV4, ct->set) &&
00478 test_bit(ATTR_SNAT_PORT, ct->set))
00479 __build_snat(req, size, ct);
00480 else if (test_bit(ATTR_SNAT_IPV4, ct->set))
00481 __build_snat_ipv4(req, size, ct);
00482 else if (test_bit(ATTR_SNAT_PORT, ct->set))
00483 __build_snat_port(req, size, ct);
00484
00485 if (test_bit(ATTR_DNAT_IPV4, ct->set) &&
00486 test_bit(ATTR_DNAT_PORT, ct->set))
00487 __build_dnat(req, size, ct);
00488 else if (test_bit(ATTR_DNAT_IPV4, ct->set))
00489 __build_dnat_ipv4(req, size, ct);
00490 else if (test_bit(ATTR_DNAT_PORT, ct->set))
00491 __build_dnat_port(req, size, ct);
00492
00493 if (test_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->set) &&
00494 test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->set) &&
00495 test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->set))
00496 __build_nat_seq_adj(req, size, ct, __DIR_ORIG);
00497
00498 if (test_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->set) &&
00499 test_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->set) &&
00500 test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->set))
00501 __build_nat_seq_adj(req, size, ct, __DIR_REPL);
00502
00503 if (test_bit(ATTR_HELPER_NAME, ct->set))
00504 __build_helper_name(req, size, ct);
00505
00506 if (test_bit(ATTR_ZONE, ct->set))
00507 __build_zone(req, size, ct);
00508
00509 return 0;
00510 }