首页 文章

如何在linux内核模块中获取下一个TCP段?

提问于
浏览
0

我知道我可以得到这样的TCP数据包指针:

char *data = (char *)tcphdr + 4 * tcph->doff;

但是一旦数据被分段,我就无法获得完整的数据 . 那么如何获得下一个段的下一个 sk_buff

我的简单代码:

#include ...

static struct nf_hook_ops nfho;

unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct
                          nf_hook_state *state)
{

    // check if it is TCP packet

    char *data = (char *)tcphdr + 4 * tcph->doff;

    // do something here

    return NF_ACCEPT;
}

static int __init hook_init(void)
{
    int ret;

    nfho.hook = hook_funcion;
    nfho.pf = NFPROTO_IPV4;
    nfho.hooknum = NF_INET_POST_ROUTING;
    nfho.priority = NF_IP_PRI_LAST;
    ret = nf_register_hook(&nfho);
    printk("xmurp-test start\n");
    printk("nf_register_hook returnd %d\n", ret);

    return 0;
}

static void __exit hook_exit(void)
{
    nf_unregister_hook(&nfho);
    printk("xmurp-test stop\n");
}

module_init(hook_init);
module_exit(hook_exit);

1 回答

  • 0

    你的问题有点复杂,因为在TCP中没有像"full data"这样的东西,因为TCP是 stream 协议而不是 datagram 协议(与UDP相反) . 这意味着数据没有特定的结束(除非连接被关闭/重置) .

    如果您正在处理将TCP流分段为大小的消息(例如:HTTP)的应用层协议,则应按以下步骤操作:

    • 解析TCP有效负载并确定当前消息的大小 .

    • 只有这样,您才能在到达网络堆栈时处理以下数据包/段作为同一消息的延续 .

    • 最后,在您预期的所有数据到达之后,您可以重新组合它们,然后才在应用程序层上使用它们的数据 .

    请记住,网络在 datagrams 中工作,TCP是 stream 协议 . 因此,在您的第一个细分处理时,其余数据尚未到达可能是非常有可能的 . 因此,您必须通过此特定流管理此分段和未来分组的分段(碎片整理),然后才解析上层协议 .

相关问题