在内核模块

时间:2018-12-19 22:50:59

标签: c networking module linux-kernel ip-address

我正在用语言在Arch Linux中编写内核模块。我想将网络IP转换为ip4格式的主机IP:127.0.0.1

我知道在用户程序中可以使用以下功能:

inetntoa()
ntohs()
ntohl()

我尝试包括 socket.h in.h 等,并使用以下功能,但它们对我都不起作用。< / p>

因此在内核模块中,我无权访问此功能。 内核模块中是否可以替代此功能?

2 个答案:

答案 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 */

另请参阅:

IP-address from sk_buff

How to get printk format specifiers right(来自Kernel.org):

  

通过引用。

     

IPv4地址

     

==============

     

::

     

%pI4 1.2.3.4

     

%pi4 001.002.003.004

     

...

     

附加的hnbl说明符用于   指定主机,网络,大端或小端顺序地址   分别。如果未提供说明符,则默认网络/大   使用字节顺序。

...

  

通过引用。

     

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地址的字符串。