• Linux-2.6.32内核编译流量计数器nfacct


    最近一直想看到一本书《一个Jiegeng华》。而技术不依赖书。但是,这并不表示我IT技术没有兴趣。事实证明,,当我无法理解的沧桑。肮脏的领导者无法理解的心理。自我可惜无法理解它处处感受到脏迹的每一步营。无法理解不起作用儿却总是显得很疲惫本人。我无法理解后,寡言少语的位置。拉窗帘无法理解,解由于寂寥而加班从而博彩,无法理解省去了租住房的电费后又得到了功勋,无法理解.......等等之后。我TMD能蹂躏的就是:把Linux-3.17的功能移植到Linux-0.01上!
           我的时间为我掌控。这是我最大的財富。早上9点多到公司。一直到下班,这段时间有偿的坐班。我不会预计自己的事情。下班到家直到家人睡去。这段时间有偿的坐班,我不会顾及自己的事情。之后就是急促的喘息的夜,我的愿望刻在上帝的喉咙,希望通过推翻身边的拿人性做抵押的否认之墙,来从容面对恐惧(这是形容死亡金属的)!
           好了。受虐自是开端!

    且看且珍惜:
    Netfilter早在xtables-addons-1.46(更早的版本号我没有亲自试验,因此不便述说)中就内置了一个ACCOUNT模块,用来在iptables的框架内支持流量计数,它的使用方法例如以下:

    iptables -A XXX (any matches) -j ACCOUNT  --addr 0.0.0.0/0  --tname $acctname
    作用是凡是匹配any matches的流量均计入acctname这个计数器。能够通过:
    iptaccount -l $acctname
    来显示流量信息。可是它有一个缺点。那就是ACCOUNT作为iptables的一个target存在,这就是说流量统计之外,一条iptables规则不能再做别的了。有时候。你总是希望流量计数是作为一个“额外”的动作而存在。比方在DROP的同一时候记录一下,或者在NAT的同一时候记录一下等。将流量计数作为match会更好,由于match能够有多个!另外。ipset-6.23也支持流量计数,可是本文不谈那个。

    本文谈的是nfacct。


           nfacct是Netfilter的一个项目。我不得不再次怒发冲冠。Netfilter上的凄凉项目不少。nfacct真不算凄凉,可是起码它在Linux 2.6.32上是不能用的。其实。由于nfacct项目根本就没有内置kernel模块,也就是说。Netfilter现在仅仅负责用户态的模块。至于kernel那部分。仅仅好等Linux kernel的trunk树给与支持了,而我查了资料后。发现在3.3以及之后的版本号才给了nfacct内核态的支持。

    至于nfacct用户态的代码,例行的configure/make install就能够直接编译通过并安装,给人一种它已经可用的假象。可是当你使用nfacct add test的时候,便会报错:错误的參数。
           2.6.32根本就没有nfacct内核部分的支持,所以netlink报错。接下来的事就是移植3.3版本号的nfnetlink_acct内核模块到2.6.32版本号内核了。

    我选择3.3版本号是由于它是离2.6.32版本号近期的支持nfacct的内核。尽管内核API可能发生变化,可是起码移植工作量能够最小化。
    .       在开工之前,我给出我编译环境的文件夹树结构:
    |-- iptables-1.4.21.tar.bz2
    |-- kernel
    |   |-- net
    |   |   `-- netfilter
    |   |       |-- Makefile
    |   |       |-- nfnetlink_acct.c
    |   |       |-- nfnetlinkacct.h
    |   |       |-- nfnetlink.c
    |   |       |-- nfnetlink.h
    |   |       |-- xt_nfacct.c
    |   |       `-- xt_nfacct.h
    |   `-- README
    |-- libnetfilter_acct-1.0.2.tar.bz2
    `-- nfacct-1.0.1.tar.bz2

    iptables-1.4.21.tar.bz2是眼下最新的iptables版本号,2.6.32直接能够编译安装。nfacct-1.0.1.tar.bz2是nfacct的用户态部分,依赖libnetfilter_acct-1.0.2.tar.bz2。这两者均能够成功编译安装,剩下的就是内核态的工作了。置于我新建的kernel文件夹,当中的文件来自Linux 3.3内核:
    nfnetlink_acct.c:cp $3.3/net/netfilter/nfnetlink_acct.c net/netfilter/nfnetlink_acct.c
    此文件须要改动的地方有:
    1.将include文件nfnetlink.h绝对路径改为相对路径。即本文件夹。
    2.将include文件nfnetlink_acct.h绝对路径改为相对路径。即本文件夹的nfnetlinkacct.h
    3.将kfree_rcu改为kfree,或者又一次定义kfree_rcu

    nfnetlinkacct.h:cp $3.3/include/linux/netfilter/nfnetlink_acct.h net/netfilter/nfnetlinkacct.h
    nfnetlink.c:cp /lib/modules/`uname -r`/build/net/netfilter/nfnetlink.c net/netfilter/nfnetlink.c
    此文件须要改动的地方有:
    1.将include文件nfnetlink.h绝对路径改为相对路径,即本文件夹。
    nfnetlink.h:cp /lib/modules/`uname -r`/build/include/linux/netfilter/nfnetlink.h net/netfilter/nfnetlink.h
    此文件须要改动的地方有:
    1.定义新的netlink子系统:

    #define NFNL_SUBSYS_IPSET               6
    #define NFNL_SUBSYS_ACCT                7
    #define NFNL_SUBSYS_COUNT              8
    注意,移植此文件到当前编译文件夹的目的是为了不影响系统头文件,要知道,由于nfnetlink模块要又一次编译,我将nfnetlink也移了过来,它们都是2.6.32内核的文件。
    xt_nfacct.c:cp $3.3/net/netfilter/xt_nfacct.c net/netfilter/xt_nfacct.c
    此文件须要改动的地方有:
    1.定义xt_action_param:
    #define xt_action_param xt_match_param
    这是由于2.6.32中match和target在接口上是分开的。不像3.X内核上将其作为union封装进xt_action_param结构体。
    2.改变checkentry的返回值:
    /* 万分注意!从3.x移植过来的checkentry的返回值是int,0为成功,非0为失败,
     * 然则2.6.32的相应返回值是bool,0为失败。非0为成功。
     * 全然相反的API规范,弄反了就panic吧 :(
     **/
    static int
    nfacct_mt_checkentry(const struct xt_mtchk_param *par)
    {
        struct xt_nfacct_match_info *info = par->matchinfo;
        struct nf_acct *nfacct;
    
        nfacct = nfnl_acct_find_get(info->name);
        if (nfacct == NULL) {
            pr_info("xt_nfacct: accounting object with name `%s' "
                "does not exists
    ", info->name);
            return 0;
        }
        info->nfacct = nfacct;
        return 1;
    }

    xt_nfacct.h:cp $3.3/include/linux/netfilter/xt_nfacct.h net/netfilter/xt_nfacct.h

    至此,移植空间完毕,Makefile的内容为:
    obj-m   += nfnetlink_acct.o
    obj-m   += nfnetlink.o
    obj-m   += xt_nfacct.o
    进入net/netfilter文件夹,通过以下的命令编译:
    make -C /lib/modules/`uname -r`/build SUBDIRS=`pwd` modules
    然后依次载入nfnetlink.ko,nfnetlink_acct.ko,xt_acct.ko
    如此。再次运行nfacct命令试一下吧:
    nfacct add test
    iptables -A INPUT -s 192.168.0.0/24 -m nfacct --nfacct-name test -j ACCEPT
    停顿片刻。保持网络传输,查看流量计数器:
    nfacct get test
    { pkts = 00000000000000188016, bytes = 00000000000250825515 } = aa;
    OK了!


    当然,你也能够将结果保存为xml文件的格式,在必要时也能够reset计数器的数值为0。


           你相信吗?旋转升降椅真的会爆炸。

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    JavaScript数据结构和算法----队列
    JavaScript数据结构和算法----栈
    ES6箭头函数
    JavaScript的错误处理
    easing--缓动函数--贝塞尔函数--圆盘转动抽奖应用
    node之子线程child_process模块
    node上传文件并在网页中展示
    Python内置函数之int()
    从Python的角度来看编码与解码
    关于.pyc文件
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4805580.html
Copyright © 2020-2023  润新知