新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux raw_sendmsg原始套接字与IP_HDRINCL控制

发布时间:2026/9/2 17:53:39来源:尧图网络
Linux raw_sendmsg原始套接字与IP_HDRINCL控制
Linux raw_sendmsg原始套接字与IP_HDRINCL控制原始套接字AF_INET, SOCK_RAW允许用户空间直接构造和发送IP数据报。raw_sendmsg是内核中处理原始套接字发送的核心函数位于net/ipv4/raw.c。它的关键设计围绕两个核心问题是否由用户填充IP头IP_HDRINCL控制以及如何校验和处理用户输入。一、 IP_HDRINCL选项与路径分岔用户通过 setsockopt(IP_HDRINCL) 控制IP头填充责任的归属。当 IP_HDRINCL 为1时用户必须在sendmsg的缓冲区中包含完整的IP头当 IP_HDRINCL 为0默认时内核自动构造IP头。raw_sendmsg的入口首先要检查此选项static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len){struct inet_sock *inet inet_sk(sk);struct ipcm_cookie ipc;struct rtable *rt NULL;int hdrincl;int err;struct flowi4 fl4;int free_len;hdrincl inet-hdrincl;if (hdrincl) {/* 用户提供了IP头len必须至少20字节 */if (len sizeof(struct iphdr))return -EINVAL;free_len len - sizeof(struct iphdr);} else {/* 内核构造IP头整个payload都是数据 */free_len len;}/* 路由查找 */err ipc_parse_header(sk, ipc, msg);if (err 0)return err;/* 根据hdrincl决定是否校验源地址等 */if (!hdrincl) {/* 内核构造IP头时需要获取源地址 */if (!ipc.addr)ipc.addr inet-inet_saddr;}/* 路由查找 */if (ipc.oif)fl4.flowi4_oif ipc.oif;elsefl4.flowi4_oif sk-sk_bound_dev_if;security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));rt ip_route_output_flow(net, fl4, sk);if (IS_ERR(rt))goto done;}二、 IP_HDRINCL1的精确实现在ip_reply_append当IP_HDRINCL 打开时用户数据的前20字节被视为IP头。内核需要对这个假IP头进行合法性校验。关键的校验逻辑在 raw_send_hdrincl 函数中static int raw_send_hdrincl(struct sock *sk, struct flowi4 *fl4,struct msghdr *msg, size_t len,struct rtable **rtp, int flags){struct iphdr *iph;int err;int offset sizeof(struct iphdr);/* 从用户态拷贝IP头以便校验 */iph (struct iphdr *)msg-msg_iter.iov-iov_base;/* 校验IP头版本号必须为4 */if (iph-version ! 4)return -EINVAL;/* 校验IP头长度不小于20字节 */if (iph-ihl 5)return -EINVAL;/* 校验总长度是否和用户提供的数据长度一致 */if (ntohs(iph-tot_len) 0) {/* tot_len为0表示由内核计算 */} else if (ntohs(iph-tot_len) len) {return -EINVAL;}/* 拷贝协议字段用于路由查找 */fl4-fl4_icmp_type 0;fl4-fl4_icmp_code 0;/* 从用户提供的IP头中提取目的地址 */fl4-daddr iph-daddr;fl4-saddr iph-saddr;/* 检查用户是否设置了一些危险选项 */if (iph-frag_off htons(IP_MF | IP_OFFSET)) {/* 如果启用了分片需要确保分片偏移合法 */}return offset;}注意这里内核会对IP头中的关键字段做基本验证但不做完整验证——因为RAW套接字本身就是设计来给特权用户完全控制IP头的。三、 skb构建与发送raw_sendmsg 在完成路由查找后通过 ip_append_data 或直接调用 ip_push_pending_frames 来发送数据err ip_append_data(sk, fl4, raw_send_hdrinc, ipc, rt,msg-msg_iov, free_len, ipc.transhdrlen,(hdrincl ? IP_HDRINCL : 0) | msg-msg_flags,first_skb, err);if (err)goto error;if (first_skb) {err ip_local_out(net, sk, first_skb);if (err)goto error;}当IP_HDRINCL为1时ip_append_data通过回调raw_send_hdrinc将用户提供的完整IP头连同数据一起拷贝到skb中。当IP_HDRINCL为0时ip_append_data内部构造IP头。四、 checksum校验与ICMP特殊处理对于RAW套接字IP头的校验和由硬件决定。用户提供的IP头中 checksum 字段的填充规则是if (hdrincl) {if (inet-cork.flags IPCORK_OPT)ip_options_build(skb, inet-cork.opt, inet-cork.addr, rt, 0);elseip_options_build(skb, NULL, fl4-daddr, rt, 0);/* 计算IP头校验和 */iph ip_hdr(skb);iph-check 0;ip_send_check(iph);}ip_send_check 计算IP头checksum并写入 iph-check 字段。该函数定义在 net/ipv4/ip_output.cvoid ip_send_check(struct iphdr *iph){iph-check 0;iph-check ip_fast_csum((unsigned char *)iph, iph-ihl);}无论IP_HDRINCL是否开启IP头校验和总是由内核计算。用户设置的值被内核覆盖。五、 分片处理与IP_MF标志raw_sendmsg 在两种模式下有不同的分片行为。IP_HDRINCL0时由 ip_append_data 的常规分片逻辑处理超过MTU的数据被分片成多个skb。IP_HDRINCL1且用户设置了分片相关字段时情况更复杂if (hdrincl iph-frag_off htons(IP_DF)) {/* 用户设置了DF标志禁止分片 */if (free_len dst_mtu(rt-dst)) {err -EMSGSIZE;goto error;}}当用户设置IP_DF且数据长度超过MTU时内核返回EMSGSIZE错误这是PMTU发现机制的基础。用户也可以自行设置IP_MF和偏移字段来控制分片行为此时内核基本上信任用户的设置。六、 安全校验与capability检查原始套接字的使用受到严格的权限控制。在 raw_sendmsg 的入口处需要检查 CAP_NET_RAW 权限static int raw_create(struct net *net, struct socket *sock, int protocol, int kern){struct sock *sk;if (kern)return raw_sk_create(net, sock, protocol, kern);/* 非内核创建的RAW套接字需要CAP_NET_RAW */if (!ns_capable(net-user_ns, CAP_NET_RAW))return -EPERM;return raw_sk_create(net, sock, protocol, kern);}此外内核还通过 security_sock_rcv_skb 和 iptable_raw 等安全模块对raw套接字的数据包进行过滤。即使拥有CAP_NET_RAW权限用户也可能被iptables规则限制。raw_sendmsg 的整个发送路径可以概括为权限检查 - IP_HDRINCL路径选择 - 路由查找 - ip_append_data(skb构建) - ip_local_out(路由输出) - dst_output - neigh_output - dev_queue_xmit。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

算法(48):Union Find-2.0(以及review) 2026/9/2 21:27:08

算法(48):Union Find-2.0(以及review)

Q:好,我们转回module 2去看union find,我想知道union find它的这章都是在干嘛以及它能够做什么?我不太明白为什么要提出他,因为后面不是还有search吗?以及昨天的这里:这与 Union-Find&#xff0…

阅读更多 →
中文AIML语料库实战:从基础语法到调优技巧 2026/9/2 21:27:08

中文AIML语料库实战:从基础语法到调优技巧

简介:一套整理好的中文人工智能标记语言(AIML)语料包,面向需要训练中文聊天机器人或研究自然语言处理的开发者与学习者。压缩包共91个文件,以56个可扩展标记语言(XML)文件和35个AIML文件两种格式…

阅读更多 →
LEAP-1A26发动机性能模型搭建:从QAR数据清洗到部件级验证 2026/9/2 21:27:08

LEAP-1A26发动机性能模型搭建:从QAR数据清洗到部件级验证

简介:面向CFM LEAP-1A26发动机性能建模与FADEC控制研究的FlyByWire项目文件集,对应A320neo系列机型,适合模拟飞行插件开发者、航空发动机建模爱好者及航电系统学习者。内容覆盖真实LEAP-1A26发动机数据收集、物理/理论建模与参数模拟&#xf…

阅读更多 →
小白程序员必备:一张图看懂大模型,收藏这份学习路线图! 2026/9/2 21:27:08

小白程序员必备:一张图看懂大模型,收藏这份学习路线图!

本文以图文形式梳理了大模型应用的核心趋势,从Chatbot到AI Application再到Agent的发展路径,介绍了LLM基础、Prompt工程、RAG、Tool Calling、AI Agent、AI Coding、Model Router等关键概念,并针对企业级应用提出了技术选型和风险控制建议。文…

阅读更多 →
Apache Doris 4.0.8 写入排障(第 6 篇):从第一批小文件到 -235,正常写入怎样拖死 Tablet 2026/9/2 21:27:08

Apache Doris 4.0.8 写入排障(第 6 篇):从第一批小文件到 -235,正常写入怎样拖死 Tablet

每次 Stream Load 都成功,每批只有几十 KB,CPU 和磁盘也没有立刻打满。几小时后导入突然报 -235,业务以为遇到了随机故障。 它不是突然发生的。每个成功小批都在给同一批 Tablet 增加版本,Compaction 还债速度长期低于造债速度&a…

阅读更多 →
超详细!Python中 pip 常用命令 2026/9/2 21:24:08

超详细!Python中 pip 常用命令

对于多数熟悉的个人而言, 肯定都听闻且运用过pip此工具, 然而对其的知悉或许并非极为深入, 今日小编便来为大伙介绍10个运用pip的小窍门, 相信对大伙往后日常管理与运用里的标准库会有益处。安装当然, 在3.4版本之后, 在2.7.9版本之后, 官网的安装包当中就已经自带了pip, 用户在…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞