如何在Linux内核模块中从char*填充sockaddr_in结构体?
内核空间替代inet_addr的IP地址转换方法
在内核编程中确实无法直接使用用户态的inet_addr()函数,你可以通过以下两种内核原生函数实现相同的IP地址转换需求:
方法1:使用in_aton()(IPv4快速转换)
in_aton()是内核专为IPv4设计的轻量转换函数,能直接将点分十进制字符串转为网络字节序的32位地址,返回值可直接赋值给sockaddr_in.sin_addr.s_addr。
示例代码:
#include <linux/in.h> // 必须包含该头文件 struct sockaddr_in txAddr; txAddr.sin_addr.s_addr = in_aton("192.168.2.10");
该函数适合硬编码固定IP的场景,无需额外字节序转换,用法简洁。
方法2:使用inet_pton()(通用地址解析)
如果需要支持更严格的格式校验,或后续可能扩展到IPv6,可以使用内核版inet_pton(),其行为和用户态版本基本一致:
示例代码:
#include <linux/inet.h> // 必须包含该头文件 struct sockaddr_in txAddr; int ret; // 解析IPv4地址:成功返回1,格式错误返回0,地址族无效返回-1 ret = inet_pton(AF_INET, "192.168.2.10", &txAddr.sin_addr); if (ret != 1) { pr_err("IP address parse failed\n"); // 内核日志打印错误 }
注意事项
- 若IP字符串来自用户空间,必须先用
copy_from_user()将其拷贝到内核空间后再解析,禁止直接操作用户态内存。 - 编译内核模块时需确保链接对应头文件,避免函数未定义错误。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

