Print this page
inet_pton
@@ -21,12 +21,13 @@
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/cmn_err.h>
#include <sys/systm.h>
#include <sys/socket.h>
@@ -231,29 +232,31 @@
str2inet_addr(char *cp, ipaddr_t *addrp)
{
char *end;
long byte;
int i;
- ipaddr_t addr = 0;
+ uint8_t *addr = (uint8_t *)addrp;
+
+ *addrp = 0;
for (i = 0; i < 4; i++) {
if (ddi_strtol(cp, &end, 10, &byte) != 0 || byte < 0 ||
byte > 255) {
return (0);
}
- addr = (addr << 8) | (uint8_t)byte;
+ addr[i] = (uint8_t)byte;
if (i < 3) {
if (*end != '.') {
return (0);
} else {
cp = end + 1;
}
} else {
cp = end;
}
}
- *addrp = addr;
+
return (1);
}
/*
* inet_pton: This function takes string format IPv4 or IPv6 address and
@@ -262,19 +265,25 @@
* It returns 0 for invalid IPv4 and IPv6 address
* 1 when successfully converts ascii to binary
* -1 when af is not AF_INET or AF_INET6
*/
int
-inet_pton(int af, char *inp, void *outp)
+m_inet_pton(int af, char *inp, void *outp, int revert)
{
int i;
long byte;
char *end;
switch (af) {
case AF_INET:
- return (str2inet_addr(inp, (ipaddr_t *)outp));
+ if (str2inet_addr(inp, (ipaddr_t *)outp)) {
+ if (! revert)
+ *(uint32_t *)outp = ntohl(*(uint32_t *)outp);
+ return (1);
+ } else {
+ return (0);
+ }
case AF_INET6: {
union v6buf_u {
uint16_t v6words_u[8];
in6_addr_t v6addr_u;
} v6buf, *v6outp;
@@ -314,11 +323,15 @@
byte = 0;
}
if (byte < 0 || byte > 0x0ffff) {
return (0);
}
+ if (revert) {
+ v6buf.v6words_u[i] = htons((uint16_t)byte);
+ } else {
v6buf.v6words_u[i] = (uint16_t)byte;
+ }
if (*end == NULL || i == 7) {
inp = end;
break;
}
if (inp == end) { /* not a number must be */
@@ -386,5 +399,26 @@
return (1); /* Success */
}
} /* switch */
return (-1); /* return -1 for default case */
}
+
+
+int
+_inet_pton(int af, char *inp, void *outp)
+{
+ return (m_inet_pton(af, inp, outp, 1));
+}
+
+/*
+ * We need this inet_pton to preserve compatibility with old closed binaries.
+ * Earlier, inet_pton returned address in hardware native order,
+ * not in network one. (See http://www.illumos.org/issue/3105).
+ * Having fixed that, we still need to support binaries, that use bad inet_pton
+ * and reverse returned address manually. All new inet_pton calls will be
+ * redirected to _inet_pton with #define in the header file.
+ */
+int
+inet_pton(int af, char *inp, void *outp)
+{
+ return (m_inet_pton(af, inp, outp, 0));
+}