• Main Page
  • Modules
  • Data Structures
  • Files
  • File List

objopt.c

00001 /*
00002  * (C) 2006 by Pablo Neira Ayuso <pablo@netfilter.org>
00003  *
00004  * This software may be used and distributed according to the terms
00005  * of the GNU General Public License, incorporated herein by reference.
00006  */
00007 
00008 #include "internal/internal.h"
00009 
00010 static void __autocomplete(struct nf_conntrack *ct, int dir)
00011 {
00012         int other = (dir == __DIR_ORIG) ? __DIR_REPL : __DIR_ORIG;
00013 
00014         ct->tuple[dir].l3protonum = ct->tuple[other].l3protonum;
00015         ct->tuple[dir].protonum = ct->tuple[other].protonum;
00016 
00017         memcpy(&ct->tuple[dir].src.v6, 
00018                &ct->tuple[other].dst.v6,
00019                sizeof(union __nfct_address));
00020         memcpy(&ct->tuple[dir].dst.v6, 
00021                &ct->tuple[other].src.v6,
00022                sizeof(union __nfct_address));
00023 
00024         switch(ct->tuple[dir].protonum) {
00025         case IPPROTO_UDP:
00026         case IPPROTO_TCP:
00027         case IPPROTO_SCTP:
00028         case IPPROTO_DCCP:
00029         case IPPROTO_GRE:
00030         case IPPROTO_UDPLITE:
00031                 ct->tuple[dir].l4src.all = ct->tuple[other].l4dst.all;
00032                 ct->tuple[dir].l4dst.all = ct->tuple[other].l4src.all;
00033                 break;
00034         case IPPROTO_ICMP:
00035         case IPPROTO_ICMPV6:
00036                 /* the setter already autocompletes the reply tuple. */
00037                 break;
00038         }
00039 
00040         /* XXX: this is safe but better convert bitset to uint64_t */
00041         ct->set[0] |= TS_ORIG | TS_REPL;
00042 }
00043 
00044 static void setobjopt_undo_snat(struct nf_conntrack *ct)
00045 {
00046         ct->snat.min_ip = ct->tuple[__DIR_REPL].dst.v4;
00047         ct->snat.max_ip = ct->snat.min_ip;
00048         ct->tuple[__DIR_REPL].dst.v4 = ct->tuple[__DIR_ORIG].src.v4;
00049         set_bit(ATTR_SNAT_IPV4, ct->set);
00050 }
00051 
00052 static void setobjopt_undo_dnat(struct nf_conntrack *ct)
00053 {
00054         ct->dnat.min_ip = ct->tuple[__DIR_REPL].src.v4;
00055         ct->dnat.max_ip = ct->dnat.min_ip;
00056         ct->tuple[__DIR_REPL].src.v4 = ct->tuple[__DIR_ORIG].dst.v4;
00057         set_bit(ATTR_DNAT_IPV4, ct->set);
00058 }
00059 
00060 static void setobjopt_undo_spat(struct nf_conntrack *ct)
00061 {
00062         ct->snat.l4min.all = ct->tuple[__DIR_REPL].l4dst.tcp.port;
00063         ct->snat.l4max.all = ct->snat.l4max.all;
00064         ct->tuple[__DIR_REPL].l4dst.tcp.port =
00065                         ct->tuple[__DIR_ORIG].l4src.tcp.port;
00066         set_bit(ATTR_SNAT_PORT, ct->set);
00067 }
00068 
00069 static void setobjopt_undo_dpat(struct nf_conntrack *ct)
00070 {
00071         ct->dnat.l4min.all = ct->tuple[__DIR_REPL].l4src.tcp.port;
00072         ct->dnat.l4max.all = ct->dnat.l4min.all;
00073         ct->tuple[__DIR_REPL].l4src.tcp.port =
00074                         ct->tuple[__DIR_ORIG].l4dst.tcp.port;
00075         set_bit(ATTR_DNAT_PORT, ct->set);
00076 }
00077 
00078 static void setobjopt_setup_orig(struct nf_conntrack *ct)
00079 {
00080         __autocomplete(ct, __DIR_ORIG);
00081 }
00082 
00083 static void setobjopt_setup_repl(struct nf_conntrack *ct)
00084 {
00085         __autocomplete(ct, __DIR_REPL);
00086 }
00087 
00088 static const setobjopt setobjopt_array[__NFCT_SOPT_MAX] = {
00089         [NFCT_SOPT_UNDO_SNAT]           = setobjopt_undo_snat,
00090         [NFCT_SOPT_UNDO_DNAT]           = setobjopt_undo_dnat,
00091         [NFCT_SOPT_UNDO_SPAT]           = setobjopt_undo_spat,
00092         [NFCT_SOPT_UNDO_DPAT]           = setobjopt_undo_dpat,
00093         [NFCT_SOPT_SETUP_ORIGINAL]      = setobjopt_setup_orig,
00094         [NFCT_SOPT_SETUP_REPLY]         = setobjopt_setup_repl,
00095 };
00096 
00097 int __setobjopt(struct nf_conntrack *ct, unsigned int option)
00098 {
00099         if (unlikely(option > NFCT_SOPT_MAX))
00100                 return -1;
00101 
00102         setobjopt_array[option](ct);
00103         return 0;
00104 }
00105 
00106 static int getobjopt_is_snat(const struct nf_conntrack *ct)
00107 {
00108         return ((test_bit(ATTR_STATUS, ct->set) ?
00109                 ct->status & IPS_SRC_NAT_DONE : 1) &&
00110                 ct->tuple[__DIR_REPL].dst.v4 != 
00111                 ct->tuple[__DIR_ORIG].src.v4);
00112 }
00113 
00114 static int getobjopt_is_dnat(const struct nf_conntrack *ct)
00115 {
00116         return ((test_bit(ATTR_STATUS, ct->set) ?
00117                 ct->status & IPS_DST_NAT_DONE : 1) &&
00118                 ct->tuple[__DIR_REPL].src.v4 !=
00119                 ct->tuple[__DIR_ORIG].dst.v4);
00120 }
00121 
00122 static int getobjopt_is_spat(const struct nf_conntrack *ct)
00123 {
00124         return ((test_bit(ATTR_STATUS, ct->set) ?
00125                 ct->status & IPS_SRC_NAT_DONE : 1) &&
00126                 ct->tuple[__DIR_REPL].l4dst.tcp.port !=
00127                 ct->tuple[__DIR_ORIG].l4src.tcp.port);
00128 }
00129 
00130 static int getobjopt_is_dpat(const struct nf_conntrack *ct)
00131 {
00132         return ((test_bit(ATTR_STATUS, ct->set) ?
00133                 ct->status & IPS_DST_NAT_DONE : 1) &&
00134                 ct->tuple[__DIR_REPL].l4src.tcp.port !=
00135                 ct->tuple[__DIR_ORIG].l4dst.tcp.port);
00136 }
00137 
00138 static const getobjopt getobjopt_array[__NFCT_GOPT_MAX] = {
00139         [NFCT_GOPT_IS_SNAT] = getobjopt_is_snat,
00140         [NFCT_GOPT_IS_DNAT] = getobjopt_is_dnat,
00141         [NFCT_GOPT_IS_SPAT] = getobjopt_is_spat,
00142         [NFCT_GOPT_IS_DPAT] = getobjopt_is_dpat,
00143 };
00144 
00145 int __getobjopt(const struct nf_conntrack *ct, unsigned int option)
00146 {
00147         if (unlikely(option > NFCT_GOPT_MAX))
00148                 return -1;
00149 
00150         return getobjopt_array[option](ct);
00151 }

Generated on Wed Jan 26 2011 23:11:37 for libnetfilter_conntrack by  doxygen 1.7.1