在内核模块中将网络字节序IP转换为ip4格式的主机字节序
Converting network byte order IP to host byte order with ip4 format in kernel module
我正在使用 c 语言在 Arch Linux 中编写内核模块。我想将网络IP转换为ip4格式的主机IP:127.0.0.1
我知道在用户程序中可以使用这些函数:
inetntoa()
ntohs()
ntohl()
我尝试包含 socket.h
、in.h
等并使用以下函数,但是none 其中对我有用。
所以在内核模块中我无法访问这个函数。
内核模块中是否有此功能的替代品?
如果 "network IP" 是指表示 IPv4 的 32 位大端整数,您希望将其转换为点分十进制字符串表示形式,则可以使用 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 地址的字符串。
您可以访问 ntohl()
和朋友。就 #include <linux/byteorder/generic.h>
。
照常使用:
__le32 le_ipaddr = ntohl(be_ipaddr); /* to flip big-endian IP to little-endian */
您还可以通过 printk()
中的特殊格式说明符 %pI4
轻松打印 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 */
另请阅读:
IP-address from sk_buff
How to get printk format specifiers right(来自Kernel.org):
Passed by reference.
IPv4 addresses
==============
::
%pI4 1.2.3.4
%pi4 001.002.003.004
...
The additional h
, n
, b
, and l
specifiers are used to
specify host, network, big or little endian order addresses
respectively. Where no specifier is provided the default network/big
endian order is used.
...
Passed by reference.
IPv6 addresses
==============
::
%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/
我正在使用 c 语言在 Arch Linux 中编写内核模块。我想将网络IP转换为ip4格式的主机IP:127.0.0.1
我知道在用户程序中可以使用这些函数:
inetntoa()
ntohs()
ntohl()
我尝试包含 socket.h
、in.h
等并使用以下函数,但是none 其中对我有用。
所以在内核模块中我无法访问这个函数。 内核模块中是否有此功能的替代品?
如果 "network IP" 是指表示 IPv4 的 32 位大端整数,您希望将其转换为点分十进制字符串表示形式,则可以使用 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 地址的字符串。
您可以访问 ntohl()
和朋友。就 #include <linux/byteorder/generic.h>
。
照常使用:
__le32 le_ipaddr = ntohl(be_ipaddr); /* to flip big-endian IP to little-endian */
您还可以通过 printk()
中的特殊格式说明符 %pI4
轻松打印 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 */
另请阅读:
IP-address from sk_buff
How to get printk format specifiers right(来自Kernel.org):
Passed by reference.
IPv4 addresses
==============
::
%pI4 1.2.3.4
%pi4 001.002.003.004
...
The additional
h
,n
,b
, andl
specifiers are used to specify host, network, big or little endian order addresses respectively. Where no specifier is provided the default network/big endian order is used.
...
Passed by reference.
IPv6 addresses
==============
::
%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/