Bug #34030 | inet_ntoa/inet_nton do not convert from/to network byte order | ||
---|---|---|---|
Submitted: | 24 Jan 2008 9:45 | Modified: | 18 Nov 2008 20:31 |
Reporter: | Erik Romijn | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Documentation | Severity: | S3 (Non-critical) |
Version: | 5.0.45 | OS: | Any |
Assigned to: | Paul DuBois | CPU Architecture: | Any |
Tags: | byte order, documentation, inet_aton, inet_ntoa |
[24 Jan 2008 9:45]
Erik Romijn
[24 Jan 2008 13:14]
Erik Romijn
I wrote: 4.23.113.0 fed through inet_ntoa(3) from my libc results in 7411460. When read by INET_NTOA, I get 0.113.23.4. When read by inet_aton(3) I get 4.23.113.0. This should however say: 4.23.113.0 fed through inet_aton(3) from my libc results in 7411460. When read by INET_NTOA, I get 0.113.23.4. When read by inet_ntoa(3) I get 4.23.113.0. Whereas inet_aton/ntoa(3) refer to libc, and INET_NTOA refers to the MySQL built-in function.
[24 Jan 2008 15:10]
Domas Mituzas
Taking endianness into account would produce different output on different platforms - what would limit platform portability. MySQL is known to have platform-independent data storage and behavior, so imposing such endianness would be harming overall model.
[24 Jan 2008 15:27]
Erik Romijn
In that case this would be a bug in the documentation :-)
[24 Jan 2008 17:41]
Valeriy Kravchuk
We should clearly describe intended behaviour and possible outcomes in the manual.
[25 Jan 2008 14:42]
Erik Romijn
I'm afraid I've mixed up host and network byte order here: inet_ntoa & friends from libc give host byte order, MySQL INET_NTOA() & friend are always network byte order. So, I would conclude that the manual is correct here.
[25 Jan 2008 14:52]
Erik Romijn
(apologies for adding another comment) However, I would suggest that the manual is clarified in this sense: that INET_NTOA from MySQL is not directly compatible with inet_ntoa from libc - the latter should be converted to network byte order before being placed in the database, if using INET_NTOA from MySQL is desirable.
[13 Nov 2008 17:06]
Paul DuBois
I don't see the issue here. The bug report says: inet_ntoa & friends from libc give host byte order But the man page for these functions says: inet_aton() converts the Internet host address cp from the IPv4 numbers-and-dots notation into binary form (in network byte order) and stores it in the structure that inp points to. inet_aton() returns non-zero if the address is valid, zero if not. The address supplied in cp can have one of the following forms: The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation. The string is returned in a statically allocated buffer, which subsequent calls will overwrite. In other words, both sets of functions use network byte order.
[18 Nov 2008 20:31]
Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant products. I've added a minor clarification that the argument to INET_NTOA() should be in network byte order. Otherwise, I see no issues to be addressed.
[21 Nov 2008 17:02]
Clay McClure
IMHO, the MySQL documentation is still misleading. The INET_ATON() documentation states: mysql> SELECT INET_ATON('209.207.224.40'); -> 3520061480 The generated number is always in network byte order. For the example just shown, the number is calculated as 209×256^3 + 207×256^2 + 224×256 + 40. The math listed in the documentation is irrelevant because computers don't treat IP addresses as sequences of bytes; they treat them as 32-bit integers. Any platform (little- or big-endian) will correctly represent an IP address internally when constructed as a sequence of bytes, as in the documentation, but the in-memory representation of the 32-bit integer will differ between little- and big-endian machines. In C and other languages, inet_aton() does not return a sequence of bytes; it returns an unsigned 32-bit integer in network byte order (big endian). From the libc documentation: inet_aton(const char *cp, struct in_addr *pin); All Internet addresses are returned in network order (bytes ordered from left to right). struct in_addr is defined as: struct in_addr { in_addr_t s_addr; }; and in_addr_t is defined as: typedef __uint32_t in_addr_t; /* base type for internet address */ So we can see that in C, an IP address is just an unsigned 32-bit integer in network byte order. When we get a big-endian integer from inet_aton() and print it on a little-endian machine, the resulting decimal is not what we expect. On little-endian machines, we first need to swap the integer to host byte order with ntohl() before we can print it. This is because computers interpret integers as atomic 32-bit entities instead of as a sequence of bytes. Contrast that with MySQL, which performs byte order translation behind the scenes. The sequence of bytes produced by INET_NTOA() may very well be in network byte order, but the decimal number that is returned by the SELECT is represented as if it were in host byte order. It is this behind-the-scenes byte order translation that makes MySQL database files portable between little- and big-endian machines, and I think that point should be spelled out in the documentation.