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。

相关新闻

DeepSeek V4实测:MoE架构如何让1.6T参数真正落地

DeepSeek V4实测:MoE架构如何让1.6T参数真正落地

1. 项目概述:当“1.6T参数”不再只是营销话术,MoE架构如何让DeepSeek V4真正跑起来最近刷技术社区,几乎每三条帖子就有一条在提“DeepSeek V4实测”,标题里那个醒目的“1.6T参数”像块磁铁,把所有关注大模型演进的人全…

2026/6/22 7:41:37阅读更多 →
Vuex实战手册:中大型Vue项目状态管理五把安全锁

Vuex实战手册:中大型Vue项目状态管理五把安全锁

1. 这不是“又一个状态管理教程”,而是我在三个中大型 Vue 项目里踩坑、重构、再推翻后总结出的 Vuex 实战手册你点开这个标题,大概率正被以下某个场景困扰:组件间传参像击鼓传花,props 深度嵌套到第 5 层,子组件想改个…

2026/6/22 7:36:36阅读更多 →
动物森友会存档编辑器NHSE:从新手到专家的完整指南

动物森友会存档编辑器NHSE:从新手到专家的完整指南

动物森友会存档编辑器NHSE:从新手到专家的完整指南 【免费下载链接】NHSE Animal Crossing: New Horizons save editor 项目地址: https://gitcode.com/gh_mirrors/nh/NHSE 还在为《集合啦!动物森友会》中漫长的物品收集和岛屿改造而烦恼吗&#…

2026/6/22 7:36:36阅读更多 →
GroupDPO:内存高效的组级偏好优化算法原理与实现

GroupDPO:内存高效的组级偏好优化算法原理与实现

1. 项目概述:当偏好学习遇上内存瓶颈在深度学习的模型对齐领域,直接偏好优化(Direct Preference Optimization, DPO)已经成为连接人类反馈与模型微调的一座关键桥梁。它绕过了传统基于强化学习的复杂流程,直接将偏好数…

2026/6/22 9:17:29阅读更多 →
MaxBot抢票机器人:高效自动化购票解决方案

MaxBot抢票机器人:高效自动化购票解决方案

MaxBot抢票机器人:高效自动化购票解决方案 【免费下载链接】tix_bot Max搶票機器人(maxbot) help you quickly buy your tickets 项目地址: https://gitcode.com/gh_mirrors/ti/tix_bot 在热门演唱会、体育赛事和大型活动门票销售中,秒杀式的抢票…

2026/6/22 9:17:29阅读更多 →
Seedance 2.0:基于运动先验的端到端AI动作生成技术解析

Seedance 2.0:基于运动先验的端到端AI动作生成技术解析

1. 项目概述:Seedance 2.0 不是“又一个AI跳舞工具”,而是动作生成范式的实质性跃迁最近在几个创意工作者小群里,几乎每天都有人甩出一段3秒短视频:一个穿白T恤的虚拟人,在极简灰背景前,突然甩头、跨步、旋…

2026/6/22 9:17:29阅读更多 →
DeepSeek-V4架构解析:Hybrid Attention与Hash-MoE如何破解长程依赖与计算效率矛盾

DeepSeek-V4架构解析:Hybrid Attention与Hash-MoE如何破解长程依赖与计算效率矛盾

1. 项目概述:这不是又一个MoE模型,而是一次对“长程依赖”与“计算效率”根本矛盾的系统性破局“DeepSeek-V4架构与性能评估报告:基于英法德多语言技术社区数据的全景审查”——这个标题里藏着三个关键信号:第一,“V4”…

2026/6/22 9:17:29阅读更多 →
大模型知识遗忘实战:基于反事实推理与迭代偏好优化的CiPO方法详解

大模型知识遗忘实战:基于反事实推理与迭代偏好优化的CiPO方法详解

1. 项目概述:当大模型需要“选择性失忆” 最近在折腾大模型微调和部署时,我遇到了一个挺有意思的难题:怎么让一个已经训练好的大模型,忘掉某些我们不希望它记住的特定知识?这听起来有点反直觉,毕竟我们通常…

2026/6/22 9:17:29阅读更多 →
从博弈论到机制设计:构建AI系统评估准则的20条核心原则

从博弈论到机制设计:构建AI系统评估准则的20条核心原则

1. 项目概述:当AI成为“玩家”,我们如何制定游戏规则?最近和几个做AI产品落地的朋友聊天,大家普遍有个头疼的问题:我们手里有一堆看起来很厉害的AI模型,但真要把它们放到一个具体的业务系统里,比…

2026/6/22 9:12:26阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/22 6:01:42阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/22 1:15:34阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/22 5:42:46阅读更多 →
Codex本地AI编码代理与CC Switch协议适配实战

Codex本地AI编码代理与CC Switch协议适配实战

1. Codex不是“另一个VS Code插件”,而是本地AI编码代理的临界点Codex这个名字,现在被太多人误读了。它不是ChatGPT那个早已停更的旧模型代号,也不是某个新出的VS Code扩展图标——它是2024年中后期悄然浮出水面的一类本地化AI编码代理&#…

2026/6/22 0:04:18阅读更多 →
从MSP430到Flexis QE128:8/32位MCU无缝迁移与低功耗设计实战

从MSP430到Flexis QE128:8/32位MCU无缝迁移与低功耗设计实战

1. 项目概述:当8位MCU遇到性能瓶颈,我们如何优雅升级?在嵌入式开发领域,尤其是电池供电的便携式设备、工业传感器节点或智能家居终端中,我们常常面临一个经典的两难选择:是选择功耗极低但性能有限的8位微控…

2026/6/22 0:04:18阅读更多 →
大语言模型空间推理能力提升:TEXT2SPACE数据集与ASCII增强技术解析

大语言模型空间推理能力提升:TEXT2SPACE数据集与ASCII增强技术解析

1. 项目缘起:当大语言模型“看”不懂空间 最近在折腾大语言模型(LLM)的各种应用时,我发现一个挺有意思的现象:你让模型写首诗、写代码、甚至做逻辑推理,它可能都表现得有模有样。但一旦涉及到需要理解“空间…

2026/6/22 0:04:18阅读更多 →