如何在 linux 内核模块中获取下一个 TCP 段?
How to get next TCP segment in linux kernel module?
我知道我可以这样获取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);
你的问题有点复杂,因为 TCP 中没有 "full data" 这样的东西,因为 TCP 是 stream 协议而不是 datagram 协议(与 UDP 对比)。这意味着数据没有特定的结束(除非关闭/重置连接)。
如果您处理的应用层协议将 TCP 流分割成一定大小的消息(例如:HTTP),您应该按以下步骤操作:
- 解析 TCP 负载并计算出当前消息有多大。
- 只有这样,您才能在以下数据包/段作为同一消息的延续到达网络堆栈时对其进行处理。
- 最后,当你期望的数据全部到达后,你就可以将它们重新组装起来,然后才能在应用层使用它们的数据。
请记住,网络在 数据报 中工作,TCP 是一种 流 协议。因此,很有可能在处理第一个段时,其余数据尚未到达。因此,您必须通过此特定流管理此数据包和未来数据包的去分段(碎片整理),然后才解析上层协议。
我知道我可以这样获取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);
你的问题有点复杂,因为 TCP 中没有 "full data" 这样的东西,因为 TCP 是 stream 协议而不是 datagram 协议(与 UDP 对比)。这意味着数据没有特定的结束(除非关闭/重置连接)。
如果您处理的应用层协议将 TCP 流分割成一定大小的消息(例如:HTTP),您应该按以下步骤操作:
- 解析 TCP 负载并计算出当前消息有多大。
- 只有这样,您才能在以下数据包/段作为同一消息的延续到达网络堆栈时对其进行处理。
- 最后,当你期望的数据全部到达后,你就可以将它们重新组装起来,然后才能在应用层使用它们的数据。
请记住,网络在 数据报 中工作,TCP 是一种 流 协议。因此,很有可能在处理第一个段时,其余数据尚未到达。因此,您必须通过此特定流管理此数据包和未来数据包的去分段(碎片整理),然后才解析上层协议。