linux/net/netfilter/xt_connbytes.c
<<
>>
Prefs
   1/* Kernel module to match connection tracking byte counter.
   2 * GPL (C) 2002 Martin Devera (devik@cdi.cz).
   3 */
   4#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   5#include <linux/module.h>
   6#include <linux/bitops.h>
   7#include <linux/skbuff.h>
   8#include <linux/math64.h>
   9#include <linux/netfilter/x_tables.h>
  10#include <linux/netfilter/xt_connbytes.h>
  11#include <net/netfilter/nf_conntrack.h>
  12#include <net/netfilter/nf_conntrack_acct.h>
  13
  14MODULE_LICENSE("GPL");
  15MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  16MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching");
  17MODULE_ALIAS("ipt_connbytes");
  18MODULE_ALIAS("ip6t_connbytes");
  19
  20static bool
  21connbytes_mt(const struct sk_buff *skb, struct xt_action_param *par)
  22{
  23        const struct xt_connbytes_info *sinfo = par->matchinfo;
  24        const struct nf_conn *ct;
  25        enum ip_conntrack_info ctinfo;
  26        u_int64_t what = 0;     /* initialize to make gcc happy */
  27        u_int64_t bytes = 0;
  28        u_int64_t pkts = 0;
  29        const struct nf_conn_counter *counters;
  30
  31        ct = nf_ct_get(skb, &ctinfo);
  32        if (!ct)
  33                return false;
  34
  35        counters = nf_conn_acct_find(ct);
  36        if (!counters)
  37                return false;
  38
  39        switch (sinfo->what) {
  40        case XT_CONNBYTES_PKTS:
  41                switch (sinfo->direction) {
  42                case XT_CONNBYTES_DIR_ORIGINAL:
  43                        what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
  44                        break;
  45                case XT_CONNBYTES_DIR_REPLY:
  46                        what = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
  47                        break;
  48                case XT_CONNBYTES_DIR_BOTH:
  49                        what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
  50                        what += atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
  51                        break;
  52                }
  53                break;
  54        case XT_CONNBYTES_BYTES:
  55                switch (sinfo->direction) {
  56                case XT_CONNBYTES_DIR_ORIGINAL:
  57                        what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
  58                        break;
  59                case XT_CONNBYTES_DIR_REPLY:
  60                        what = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
  61                        break;
  62                case XT_CONNBYTES_DIR_BOTH:
  63                        what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
  64                        what += atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
  65                        break;
  66                }
  67                break;
  68        case XT_CONNBYTES_AVGPKT:
  69                switch (sinfo->direction) {
  70                case XT_CONNBYTES_DIR_ORIGINAL:
  71                        bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
  72                        pkts  = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
  73                        break;
  74                case XT_CONNBYTES_DIR_REPLY:
  75                        bytes = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
  76                        pkts  = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
  77                        break;
  78                case XT_CONNBYTES_DIR_BOTH:
  79                        bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes) +
  80                                atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
  81                        pkts  = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets) +
  82                                atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
  83                        break;
  84                }
  85                if (pkts != 0)
  86                        what = div64_u64(bytes, pkts);
  87                break;
  88        }
  89
  90        if (sinfo->count.to >= sinfo->count.from)
  91                return what <= sinfo->count.to && what >= sinfo->count.from;
  92        else /* inverted */
  93                return what < sinfo->count.to || what > sinfo->count.from;
  94}
  95
  96static int connbytes_mt_check(const struct xt_mtchk_param *par)
  97{
  98        const struct xt_connbytes_info *sinfo = par->matchinfo;
  99        int ret;
 100
 101        if (sinfo->what != XT_CONNBYTES_PKTS &&
 102            sinfo->what != XT_CONNBYTES_BYTES &&
 103            sinfo->what != XT_CONNBYTES_AVGPKT)
 104                return -EINVAL;
 105
 106        if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
 107            sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
 108            sinfo->direction != XT_CONNBYTES_DIR_BOTH)
 109                return -EINVAL;
 110
 111        ret = nf_ct_l3proto_try_module_get(par->family);
 112        if (ret < 0)
 113                pr_info("cannot load conntrack support for proto=%u\n",
 114                        par->family);
 115
 116        /*
 117         * This filter cannot function correctly unless connection tracking
 118         * accounting is enabled, so complain in the hope that someone notices.
 119lass="line" name="L118"> 118/
 115family0count             " class1tt/a>}
ss="line" name="L118"> 118/
<2* This filter cannot function corr"L83" 1atomic6.es. href="net/netfilter/xt_connbytes.c#L109/a>-&fo" class="n>
directionbytesd" e="L118"> 118/IR_ORIGINAL" class="sref">XT_CONNBYTESoo becode=ato" id="L115" cla="L117" class="line" name="L117"> 117 = 12);
}
ss="line" name="L118"> 118/
<2* This filter cannot functiofilter/xt_connbyttruhref="+code=whattruh" id="L117" class="line" name="L117"> 117matchi1nfo;
ip12href="net/netfilter/xt_connbytes.c#L36" id="L1   u_int64_tsinfo-&ga href="+code=what" class="sref">what !=   271/a>   t u_int64_t<1/a> <1 href=  118nf_co" name=void7">  97{
  98        dtorst struct xt_connbytes_info *sinfo
ret < 0)
 113                pr_info(  98       t_couct   97{
directionhref="net/netre".c#L8">  97{
   ="st>                _/a>   ="st> "L112">orr"L83" 1atomic6.es. href="net/netfilter/>de=ip_co1e=ct" class="sref">ct);
<13 class="line"96" class="line"">ctss="sref">retctclass="line=filter/xt_connbytes.c#L6" idnet/netfiid="L115" class="line" name="L115"> 115
  36<1/a>  1     if (!;
 115
                 115
  39        switch1 ( 112       href="net/netfilter/xt_connbytes.c#L98" id="L98" class=fs="line" name="L115"> 115
 118 115
XT1CONNBYTES_PKTS96" class="line"de_ORoer/xt_connbytes.de_ORoeass=line=fi" class="line"c#L98" id="Ltde_ORoer/xt_connbytes.href="net/netde_ORoeass=fs="line" name="L115"> 115
si1nfo->ret  99        int  115
retret 115
wha1t1= pr_info(IP_CT_DIR_ORIGINAL1]14name="L15">  15MODULE_AUTHOR();
<1 id="L" name="L97">  97{
  97{
sinfowhat 1= IP_CT_DIR_REPLY].1sinfo-&gxetre"is hr  t_couct directionhref="net/netre".c#Lcode=pr_info" class="sref">pr_info(what = 1  40        case IP_CT_DIR_ORIGINAL1]1  97{
  97{
sinfoIP_CT_DIR_REPLY]1.directionhref="net/netre".c#Lcode=pr_info" class="sref">pr_info(  151sinfo->&quo="net/nbyte               ="net/nbyteilter/xt_connbytes.chref="net/netbyte               href="net/netbyteiltecode=pr_info" class="sref">pr_info(M="net/nexte               ="net/nexteilter/xt_connbytes.chref="net/netexte               href="net/netexteiltecode=pr_info" class="sref">pr_info(wha1t1= 
The original LXR software by15LXR ad2 uyteeass=f  onc experi    al versAL< by1e=pr_infoma"sro:lxf@ltes..no">lxf@ltes..noass=.
acking yte cat" clasubfooref">
lxf.ltes..no kindly hosa hrby1e=pr_infohttp://www.redpill-ltepro.no">Redpill Ltepro ss="sr,nbytvidf="netLtes.s.c#LulBYTESand opera"L11s serv=ato since 1995.
acking by/bodyg y/html n