【问题标题】:Capture all packages in kernel module with netfilter hooks after v4.13.x在 v4.13.x 之后使用 netfilter 钩子捕获内核模块中的所有包
【发布时间】:2019-11-28 21:12:23
【问题描述】:

我为运行 OpenWrt 的路由器编写了一个内核模块,用于修改所有转发的 HTTP 包中的用户代理。在内核 v4.9 中运行良好,但在内核 v4.14.63 中无法捕获目标端口小于 1024 的包。

对于内核 v4.14.63,我写 nf_register_net_hook(&init_net, &nfho) 而不是 nf_register_hook(&nfho)。该函数也返回0,但我只能捕获目标端口大于1024的包。 我猜这可能是由于错误使用了新的参数 *net 造成的。所以我尝试了这个:

for_each_net(n) nf_unregister_net_hook(n, &nfho);

当我输入 insmod xmurp-test 时,它给了我:

failed to insert /lib/modules/4.14.63/xmurp-test.ko

我的测试代码是这样的:

static struct nf_hook_ops nfho;

unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    register struct tcphdr *tcph;
    register struct iphdr *iph;

    // check if it is TCP package here
    if(skb == 0)
        return NF_ACCEPT;
    iph = ip_hdr(skb);
    if(iph->protocol != IPPROTO_TCP)
        return NF_ACCEPT;
    tcph = tcp_hdr(skb);

    // debug here
    printk("tcph->dest = %d", tcph->dest);
    if(tcph->dest != 80)
        return NF_ACCEPT;

    return NF_ACCEPT;
}

static int __init hook_init(void)
{
    int ret = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
    struct net *n;
#endif

    nfho.hook = hook_funcion;
    nfho.pf = NFPROTO_IPV4;
    nfho.hooknum = NF_INET_FORWARD;
    nfho.priority = NF_IP_PRI_MANGLE;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
    for_each_net(n)
        ret += nf_register_net_hook(n, &nfho);
#else
    ret = nf_register_hook(&nfho);
#endif
    printk("xmurp-ua start\n");
    printk("nf_register_hook returnd %d\n", ret);

    return 0;
}

static void __exit hook_exit(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
    struct net *n;
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
    for_each_net(n)
        nf_unregister_net_hook(n, &nfho);
#else
    nf_unregister_hook(&nfho);
#endif
    printk("xmurp-ua stop\n");
}

module_init(hook_init);
module_exit(hook_exit);

这是我的内核日志的一部分: (未找到小于 1024 的目的端口)

[ 1596.601063] tcph->dest = 15380
[ 1596.619027] tcph->dest = 2067
[ 1596.622388] tcph->dest = 14115
[ 1596.649652] tcph->dest = 47873
[ 1596.903875] tcph->dest = 1044
[ 1596.907796] tcph->dest = 20480
[ 1596.950417] tcph->dest = 20480
[ 1596.953985] tcph->dest = 1044
[ 1597.051657] tcph->dest = 20480
[ 1597.061290] tcph->dest = 29205
[ 1597.109917] tcph->dest = 1044
[ 1597.129058] tcph->dest = 20480
[ 1597.132366] tcph->dest = 1044
[ 1597.151498] tcph->dest = 20480
[ 1597.513850] tcph->dest = 1044
[ 1597.517715] tcph->dest = 20480
[ 1597.904445] tcph->dest = 1044
[ 1597.911922] tcph->dest = 20480
[ 1598.277374] tcph->dest = 1044
[ 1598.281972] tcph->dest = 20480
[ 1598.390774] tcph->dest = 47873
[ 1598.405492] tcph->dest = 14115
[ 1598.428335] tcph->dest = 11029
[ 1598.431651] tcph->dest = 11029
[ 1598.451623] tcph->dest = 14115
[ 1598.496708] tcph->dest = 2067
[ 1598.515683] tcph->dest = 47873
[ 1598.671040] tcph->dest = 1044
[ 1598.676368] tcph->dest = 20480
[ 1598.781044] tcph->dest = 20480
[ 1598.784667] tcph->dest = 1044
[ 1598.935491] tcph->dest = 1044
[ 1598.970062] tcph->dest = 20480
[ 1598.973473] tcph->dest = 1044
[ 1598.999175] tcph->dest = 20480
[ 1599.372445] tcph->dest = 1044
[ 1599.376848] tcph->dest = 20480
[ 1599.746570] tcph->dest = 1044
[ 1599.754935] tcph->dest = 20480
[ 1600.023671] tcph->dest = 47873
[ 1600.027202] tcph->dest = 32021
[ 1600.128045] tcph->dest = 1044

【问题讨论】:

    标签: linux-kernel netfilter


    【解决方案1】:

    原来字节序是关键。

    // wrong
    printk("tcph->dest = %d", tcph->dest);
    // right
    printk("tcph->dest = %d", ntohs(tcph->dest));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      • 2022-08-03
      • 2015-04-06
      • 2012-03-07
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      相关资源
      最近更新 更多