【问题标题】:How to get next TCP segment in linux kernel module?如何在 linux 内核模块中获取下一个 TCP 段?
【发布时间】:2019-05-10 13:58:59
【问题描述】:

我知道我可以像这样获取 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);

【问题讨论】:

  • 对于那些在 nf_register_hook 部分出现编译错误的人,我尝试了 nf_register_net_hook(&init_net,&rk_pre_routing);参考:unix.stackexchange.com/questions/413797/… 而且,这(对我而言;在我的情况下)它也可以与 SE url 中提到的 nf_unregister 一起使用。如果我在某些方面错了,请纠正我,谢谢! //愿望

标签: c tcp linux-kernel network-programming


【解决方案1】:

您的问题有点复杂,因为 TCP 中没有“完整数据”之类的东西,因为 TCP 是 stream 协议而不是 datagram 协议(在UDP的对比)。这意味着数据没有特定的结束(除非连接被关闭/重置)。

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

  1. 解析 TCP 负载并计算当前消息的大小。
  2. 只有这样,您才能在以下数据包/段到达网络堆栈时处理它们作为同一消息的延续。
  3. 最后,在您期望的所有数据都到达后,您可以重新组装它们,然后才能在应用层使用它们的数据。

请记住,网络以 数据报 工作,而 TCP 是 协议。因此,很有可能在您处理第一个段时,其余数据尚未到达。因此,您必须在此特定流上管理此数据包和未来数据包的分段(碎片整理),然后才能解析上层协议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 2023-03-14
    • 2013-09-04
    • 1970-01-01
    • 2012-09-01
    • 2014-09-03
    相关资源
    最近更新 更多