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

compare.c

00001 /*
00002  * (C) 2007 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 int __cmp(int attr,
00011                  const struct nf_conntrack *ct1, 
00012                  const struct nf_conntrack *ct2,
00013                  unsigned int flags,
00014                  int (*cmp)(const struct nf_conntrack *ct1,
00015                             const struct nf_conntrack *ct2,
00016                             unsigned int flags))
00017 {
00018         if (test_bit(attr, ct1->set) && test_bit(attr, ct2->set)) {
00019                 return cmp(ct1, ct2, flags);
00020         } else if (flags & NFCT_CMP_MASK &&
00021                    test_bit(attr, ct1->set)) {
00022                 return 0;
00023         } else if (flags & NFCT_CMP_STRICT) {
00024                 return 0;
00025         }
00026         return 1;
00027 }
00028 
00029 static int
00030 cmp_orig_l3proto(const struct nf_conntrack *ct1,
00031                  const struct nf_conntrack *ct2,
00032                  unsigned int flags)
00033 {
00034         return (ct1->tuple[__DIR_ORIG].l3protonum ==
00035                 ct2->tuple[__DIR_ORIG].l3protonum);
00036 }
00037 
00038 static int
00039 cmp_icmp_id(const struct nf_conntrack *ct1,
00040             const struct nf_conntrack *ct2,
00041             unsigned int flags)
00042 {
00043         return (ct1->tuple[__DIR_ORIG].l4src.icmp.id ==
00044                 ct2->tuple[__DIR_ORIG].l4src.icmp.id);
00045 }
00046 
00047 static int
00048 cmp_icmp_type(const struct nf_conntrack *ct1,
00049               const struct nf_conntrack *ct2,
00050               unsigned int flags)
00051 {
00052         return (ct1->tuple[__DIR_ORIG].l4dst.icmp.type ==
00053                 ct2->tuple[__DIR_ORIG].l4dst.icmp.type);
00054 }
00055 
00056 static int
00057 cmp_icmp_code(const struct nf_conntrack *ct1,
00058               const struct nf_conntrack *ct2,
00059               unsigned int flags)
00060 {
00061         return (ct1->tuple[__DIR_ORIG].l4dst.icmp.code ==
00062                 ct2->tuple[__DIR_ORIG].l4dst.icmp.code);
00063 }
00064 
00065 static int
00066 cmp_orig_port_src(const struct nf_conntrack *ct1,
00067                   const struct nf_conntrack *ct2,
00068                   unsigned int flags)
00069 {
00070         return (ct1->tuple[__DIR_ORIG].l4src.all ==
00071                 ct2->tuple[__DIR_ORIG].l4src.all);
00072 }
00073 
00074 static int
00075 cmp_orig_port_dst(const struct nf_conntrack *ct1,
00076                   const struct nf_conntrack *ct2,
00077                   unsigned int flags)
00078 {
00079         return (ct1->tuple[__DIR_ORIG].l4dst.all ==
00080                 ct2->tuple[__DIR_ORIG].l4dst.all);
00081 }
00082 
00083 static int 
00084 cmp_orig_l4proto(const struct nf_conntrack *ct1,
00085                  const struct nf_conntrack *ct2,
00086                  unsigned int flags)
00087 {
00088         if (ct1->tuple[__DIR_ORIG].protonum != ct2->tuple[__DIR_ORIG].protonum)
00089                 return 0;
00090 
00091         switch(ct1->tuple[__DIR_ORIG].protonum) {
00092         case IPPROTO_ICMP:
00093         case IPPROTO_ICMPV6:
00094                 if (!__cmp(ATTR_ICMP_ID, ct1, ct2, flags, cmp_icmp_id))
00095                         return 0;
00096                 if (!__cmp(ATTR_ICMP_CODE, ct1, ct2, flags, cmp_icmp_code))
00097                         return 0;
00098                 if (!__cmp(ATTR_ICMP_TYPE, ct1, ct2, flags, cmp_icmp_type))
00099                         return 0;
00100                 break;
00101         case IPPROTO_TCP:
00102         case IPPROTO_UDP:
00103         case IPPROTO_UDPLITE:
00104         case IPPROTO_DCCP:
00105         case IPPROTO_SCTP:
00106                 if (!__cmp(ATTR_ORIG_PORT_SRC, ct1, ct2, 
00107                                flags, cmp_orig_port_src))
00108                         return 0;
00109                 if (!__cmp(ATTR_ORIG_PORT_DST, ct1, ct2,
00110                                flags, cmp_orig_port_dst))
00111                         return 0;
00112                 break;
00113         }
00114         return 1;
00115 }
00116 
00117 static int 
00118 cmp_orig_ipv4_src(const struct nf_conntrack *ct1,
00119                   const struct nf_conntrack *ct2,
00120                   unsigned int flags)
00121 {
00122         return (ct1->tuple[__DIR_ORIG].src.v4 == ct2->tuple[__DIR_ORIG].src.v4);}
00123 
00124 static int 
00125 cmp_orig_ipv4_dst(const struct nf_conntrack *ct1,
00126                   const struct nf_conntrack *ct2,
00127                   unsigned int flags)
00128 {
00129         return (ct1->tuple[__DIR_ORIG].dst.v4 == ct2->tuple[__DIR_ORIG].dst.v4);}
00130 
00131 static int 
00132 cmp_orig_ipv6_src(const struct nf_conntrack *ct1,
00133                   const struct nf_conntrack *ct2,
00134                   unsigned int flags)
00135 {
00136         return (memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
00137                 &ct2->tuple[__DIR_ORIG].src.v6,
00138                 sizeof(struct in6_addr)) == 0);
00139 }
00140 
00141 static int 
00142 cmp_orig_ipv6_dst(const struct nf_conntrack *ct1,
00143                   const struct nf_conntrack *ct2,
00144                   unsigned int flags)
00145 {
00146         return (memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
00147                 &ct2->tuple[__DIR_ORIG].dst.v6,
00148                 sizeof(struct in6_addr)) == 0);
00149 }
00150 
00151 static int cmp_orig(const struct nf_conntrack *ct1,
00152                     const struct nf_conntrack *ct2,
00153                     unsigned int flags)
00154 {
00155         if (!__cmp(ATTR_ORIG_L3PROTO, ct1, ct2, flags, cmp_orig_l3proto))
00156                 return 0;
00157         if (!__cmp(ATTR_ORIG_L4PROTO, ct1, ct2, flags, cmp_orig_l4proto))
00158                 return 0;
00159         if (!__cmp(ATTR_ORIG_IPV4_SRC, ct1, ct2, flags, cmp_orig_ipv4_src))
00160                 return 0;
00161         if (!__cmp(ATTR_ORIG_IPV4_DST, ct1, ct2, flags, cmp_orig_ipv4_dst))
00162                 return 0;
00163         if (!__cmp(ATTR_ORIG_IPV6_SRC, ct1, ct2, flags, cmp_orig_ipv6_src))
00164                 return 0;
00165         if (!__cmp(ATTR_ORIG_IPV6_DST, ct1, ct2, flags, cmp_orig_ipv6_dst))
00166                 return 0;
00167 
00168         return 1;
00169 }
00170 
00171 static int
00172 cmp_repl_l3proto(const struct nf_conntrack *ct1,
00173                  const struct nf_conntrack *ct2,
00174                  unsigned int flags)
00175 {
00176         return (ct1->tuple[__DIR_REPL].l3protonum ==
00177                 ct2->tuple[__DIR_REPL].l3protonum);
00178 }
00179 
00180 static int
00181 cmp_repl_port_src(const struct nf_conntrack *ct1,
00182                   const struct nf_conntrack *ct2,
00183                   unsigned int flags)
00184 {
00185         return (ct1->tuple[__DIR_REPL].l4src.all ==
00186                 ct2->tuple[__DIR_REPL].l4src.all);
00187 }
00188 
00189 static int
00190 cmp_repl_port_dst(const struct nf_conntrack *ct1,
00191                   const struct nf_conntrack *ct2,
00192                   unsigned int flags)
00193 {
00194         return (ct1->tuple[__DIR_REPL].l4dst.all ==
00195                 ct2->tuple[__DIR_REPL].l4dst.all);
00196 }
00197 
00198 static int 
00199 cmp_repl_l4proto(const struct nf_conntrack *ct1,
00200                  const struct nf_conntrack *ct2,
00201                  unsigned int flags)
00202 {
00203         if (ct1->tuple[__DIR_REPL].protonum != ct2->tuple[__DIR_REPL].protonum)
00204                 return 0;
00205 
00206         switch(ct1->tuple[__DIR_REPL].protonum) {
00207         case IPPROTO_ICMP:
00208         case IPPROTO_ICMPV6:
00209                 if (!__cmp(ATTR_ICMP_ID, ct1, ct2, flags, cmp_icmp_id))
00210                         return 0;
00211                 if (!__cmp(ATTR_ICMP_CODE, ct1, ct2, flags, cmp_icmp_code))
00212                         return 0;
00213                 if (!__cmp(ATTR_ICMP_TYPE, ct1, ct2, flags, cmp_icmp_type))
00214                         return 0;
00215                 break;
00216         case IPPROTO_TCP:
00217         case IPPROTO_UDP:
00218         case IPPROTO_UDPLITE:
00219         case IPPROTO_DCCP:
00220         case IPPROTO_SCTP:
00221                 if (!__cmp(ATTR_REPL_PORT_SRC, ct1, ct2, 
00222                                flags, cmp_repl_port_src))
00223                         return 0;
00224                 if (!__cmp(ATTR_REPL_PORT_DST, ct1, ct2,
00225                                flags, cmp_repl_port_dst))
00226                         return 0;
00227                 break;
00228         }
00229         return 1;
00230 }
00231 
00232 static int 
00233 cmp_repl_ipv4_src(const struct nf_conntrack *ct1,
00234                   const struct nf_conntrack *ct2,
00235                   unsigned int flags)
00236 {
00237         return (ct1->tuple[__DIR_REPL].src.v4 == ct2->tuple[__DIR_REPL].src.v4);}
00238 
00239 static int 
00240 cmp_repl_ipv4_dst(const struct nf_conntrack *ct1,
00241                   const struct nf_conntrack *ct2,
00242                   unsigned int flags)
00243 {
00244         return (ct1->tuple[__DIR_REPL].dst.v4 == ct2->tuple[__DIR_REPL].dst.v4);}
00245 
00246 static int 
00247 cmp_repl_ipv6_src(const struct nf_conntrack *ct1,
00248                   const struct nf_conntrack *ct2,
00249                   unsigned int flags)
00250 {
00251         return (memcmp(&ct1->tuple[__DIR_REPL].src.v6,
00252                 &ct2->tuple[__DIR_REPL].src.v6,
00253                 sizeof(struct in6_addr)) == 0);
00254 }
00255 
00256 static int 
00257 cmp_repl_ipv6_dst(const struct nf_conntrack *ct1,
00258                   const struct nf_conntrack *ct2,
00259                   unsigned int flags)
00260 {
00261         return (memcmp(&ct1->tuple[__DIR_REPL].dst.v6,
00262                 &ct2->tuple[__DIR_REPL].dst.v6,
00263                 sizeof(struct in6_addr)) == 0);
00264 }
00265 
00266 static int cmp_repl(const struct nf_conntrack *ct1,
00267                     const struct nf_conntrack *ct2,
00268                     unsigned int flags)
00269 {
00270         if (!__cmp(ATTR_REPL_L3PROTO, ct1, ct2, flags, cmp_repl_l3proto))
00271                 return 0;
00272         if (!__cmp(ATTR_REPL_L4PROTO, ct1, ct2, flags, cmp_repl_l4proto))
00273                 return 0;
00274         if (!__cmp(ATTR_REPL_IPV4_SRC, ct1, ct2, flags, cmp_repl_ipv4_src))
00275                 return 0;
00276         if (!__cmp(ATTR_REPL_IPV4_DST, ct1, ct2, flags, cmp_repl_ipv4_dst))
00277                 return 0;
00278         if (!__cmp(ATTR_REPL_IPV6_SRC, ct1, ct2, flags, cmp_repl_ipv6_src))
00279                 return 0;
00280         if (!__cmp(ATTR_REPL_IPV6_DST, ct1, ct2, flags, cmp_repl_ipv6_dst))
00281                 return 0;
00282 
00283         return 1;
00284 }
00285 
00286 static int 
00287 cmp_id(const struct nf_conntrack *ct1,
00288        const struct nf_conntrack *ct2,
00289        unsigned int flags)
00290 {
00291         return (ct1->id == ct2->id);
00292 }
00293 
00294 static int 
00295 cmp_mark(const struct nf_conntrack *ct1,
00296          const struct nf_conntrack *ct2,
00297          unsigned int flags)
00298 {
00299         return (ct1->mark == ct2->mark);
00300 }
00301 
00302 static int 
00303 cmp_timeout(const struct nf_conntrack *ct1,
00304             const struct nf_conntrack *ct2,
00305             unsigned int flags)
00306 {
00307         int ret = 0;
00308 
00309 #define __NFCT_CMP_TIMEOUT (NFCT_CMP_TIMEOUT_LE | NFCT_CMP_TIMEOUT_GT)
00310 
00311         if (!(flags & __NFCT_CMP_TIMEOUT) &&
00312             ct1->timeout != ct2->timeout)
00313                 return 0;
00314         else {
00315                 if (flags & NFCT_CMP_TIMEOUT_GT &&
00316                     ct1->timeout > ct2->timeout)
00317                         ret = 1;
00318                 else if (flags & NFCT_CMP_TIMEOUT_LT &&
00319                          ct1->timeout < ct2->timeout)
00320                         ret = 1;
00321                 else if (flags & NFCT_CMP_TIMEOUT_EQ &&
00322                          ct1->timeout == ct2->timeout)
00323                         ret = 1;
00324 
00325                 if (ret == 0)
00326                         return 0;
00327         }
00328         return ret;
00329 }
00330 
00331 static int 
00332 cmp_status(const struct nf_conntrack *ct1,
00333            const struct nf_conntrack *ct2,
00334            unsigned int flags)
00335 {
00336         return ((ct1->status & ct2->status) == ct1->status);
00337 }
00338 
00339 static int 
00340 cmp_tcp_state(const struct nf_conntrack *ct1,
00341               const struct nf_conntrack *ct2,
00342               unsigned int flags)
00343 {
00344         return (ct1->protoinfo.tcp.state == ct2->protoinfo.tcp.state);
00345 }
00346 
00347 static int 
00348 cmp_sctp_state(const struct nf_conntrack *ct1,
00349                const struct nf_conntrack *ct2,
00350                unsigned int flags)
00351 {
00352         return (ct1->protoinfo.sctp.state == ct2->protoinfo.sctp.state);
00353 }
00354 
00355 static int
00356 cmp_dccp_state(const struct nf_conntrack *ct1,
00357                const struct nf_conntrack *ct2,
00358                unsigned int flags)
00359 {
00360         return (ct1->protoinfo.dccp.state == ct2->protoinfo.dccp.state);
00361 }
00362 
00363 static int 
00364 cmp_zone(const struct nf_conntrack *ct1,
00365          const struct nf_conntrack *ct2,
00366          unsigned int flags)
00367 {
00368         return (ct1->zone == ct2->zone);
00369 }
00370 
00371 static int
00372 cmp_secctx(const struct nf_conntrack *ct1,
00373            const struct nf_conntrack *ct2,
00374            unsigned int flags)
00375 {
00376         return strcmp(ct1->secctx, ct2->secctx) == 0;
00377 }
00378 
00379 static int cmp_meta(const struct nf_conntrack *ct1,
00380                     const struct nf_conntrack *ct2,
00381                     unsigned int flags)
00382 {
00383         if (!__cmp(ATTR_ID, ct1, ct2, flags, cmp_id))
00384                 return 0;
00385         if (!__cmp(ATTR_MARK, ct1, ct2, flags, cmp_mark))
00386                 return 0;
00387         if (!__cmp(ATTR_TIMEOUT, ct1, ct2, flags, cmp_timeout))
00388                 return 0;
00389         if (!__cmp(ATTR_STATUS, ct1, ct2, flags, cmp_status))
00390                 return 0;
00391         if (!__cmp(ATTR_TCP_STATE, ct1, ct2, flags, cmp_tcp_state))
00392                 return 0;
00393         if (!__cmp(ATTR_SCTP_STATE, ct1, ct2, flags, cmp_sctp_state))
00394                 return 0;
00395         if (!__cmp(ATTR_DCCP_STATE, ct1, ct2, flags, cmp_dccp_state))
00396                 return 0;
00397         if (!__cmp(ATTR_ZONE, ct1, ct2, flags, cmp_zone))
00398                 return 0;
00399         if (!__cmp(ATTR_SECCTX, ct1, ct2, flags, cmp_secctx))
00400                 return 0;
00401 
00402         return 1;
00403 }
00404 
00405 int __compare(const struct nf_conntrack *ct1,
00406               const struct nf_conntrack *ct2,
00407               unsigned int flags)
00408 {
00409         if ((flags & ~(NFCT_CMP_MASK|NFCT_CMP_STRICT)) == NFCT_CMP_ALL)
00410                 return cmp_meta(ct1, ct2, flags) &&
00411                        cmp_orig(ct1, ct2, flags) &&
00412                        cmp_repl(ct1, ct2, flags);
00413 
00414         if (flags & NFCT_CMP_ORIG && !cmp_orig(ct1, ct2, flags))
00415                 return 0;
00416 
00417         if (flags & NFCT_CMP_REPL && !cmp_repl(ct1, ct2, flags))
00418                 return 0;
00419 
00420         return 1;
00421 }

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