我正在用c语言在Arch Linux中编写内核模块。我想将网络IP转换为ip4格式的主机IP:127.0.0.1
我知道在用户程序中可以使用以下功能:
inetntoa()
ntohs()
ntohl()
我尝试包括 socket.h
, in.h
等,并使用以下功能,但它们对我都不起作用。< / p>
因此在内核模块中,我无权访问此功能。 内核模块中是否可以替代此功能?
答案 0 :(得分:2)
您有权访问ntohl()
和朋友。仅#include <linux/byteorder/generic.h>
。
照常使用它:
__le32 le_ipaddr = ntohl(be_ipaddr); /* to flip big-endian IP to little-endian */
此外,您还可以通过%pI4
中的特殊格式说明符printk()
打印所需的IPv4地址,而不会遇到任何困难,例如这样的方式:
__be32 ipaddr /*= gain from somewhere IP in network byte order (__be32 means big endian)*/;
printk(KERN_INFO "Got IP: %pI4\n", &ipaddr); /* in network byte order */
printk(KERN_INFO "Got IP: %pI4h\n", &ipaddr); /* in host byte order */
另请参阅:
How to get printk format specifiers right(来自Kernel.org):
通过引用。
IPv4地址
==============
::
%pI4 1.2.3.4
%pi4 001.002.003.004
...
附加的
h
,n
,b
和l
说明符用于 指定主机,网络,大端或小端顺序地址 分别。如果未提供说明符,则默认网络/大 使用字节顺序。
...
通过引用。
IPv6地址
==============
::
%pI6 0001:0002:0003:0004:0005:0006:0007:0008
%pi6 00010002000300040005000600070008
%pI6c 1:2:3:4:5:6:7:8
P.S。您可以在Linux内核源代码中搜索所需的功能,例如在此网站上:https://elixir.bootlin.com/linux/latest/ident/
答案 1 :(得分:-1)
如果用“网络IP”表示要转换为点分十进制字符串表示形式的32位大端整数,表示IPv4,则可以用sprintf()
完成。
int32_t ipv4 = 1234567890; // random example
unsigned char *ptr = (unsigned char *)&ipv4;
char ipstr[16];
sprintf(ipstr, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
ipstr
将包含带有IP地址的字符串。