Converting network byte order IP to host byte order with ip4 format in kernel module

Viewed 4385

I am writing a kernel module in Arch Linux with language. I want to convert the network IP to host IP with ip4 format: 127.0.0.1

I know it is possible in user program to use these functions:

inetntoa()
ntohs()
ntohl()

I tried to include the socket.h, in.h, etc and use the below functions, but none of them worked for me.

So in kernel module I don't have access to this functions. Is there in kernel module a replacement for this functions?

2 Answers

You have access to ntohl() and friends. Just #include <linux/byteorder/generic.h>. Use it as usual:

__le32 le_ipaddr = ntohl(be_ipaddr); /* to flip big-endian IP to little-endian */

Also you can print IPv4 address as you want without any difficulties through the special format specifier %pI4 in printk() e.g. such way:

__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 */

Read also:

IP-address from sk_buff

How to get printk format specifiers right (from 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. you can search the functions you need in Linux kernel sources, e.g. on this site: https://elixir.bootlin.com/linux/latest/ident/

If by "network IP" you mean a 32-bit big-endian integer representing a IPv4 that you wish to convert to a dotted-decimal string representation, then it can be done with 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 will contain the string with the IP address.

Related