diff --git a/resolv/inet_ntop.c b/resolv/inet_ntop.c
index acf5f3cb88..3f2a9ddd87 100644
--- a/resolv/inet_ntop.c
+++ b/resolv/inet_ntop.c
@@ -26,45 +26,44 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-
-#ifdef SPRINTF_CHAR
-# define SPRINTF(x) strlen(sprintf/**/x)
-#else
-# define SPRINTF(x) ((size_t)sprintf x)
-#endif
+#include <intprops.h>
+#include <_itoa.h>
 
 /*
  * WARNING: Don't even consider trying to compile this on a system where
  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
  */
 
-static const char *inet_ntop4 (const u_char *src, char *dst, socklen_t size);
-static const char *inet_ntop6 (const u_char *src, char *dst, socklen_t size);
-
-/* char *
- * __inet_ntop(af, src, dst, size)
- *	convert a network format address to presentation format.
- * return:
- *	pointer to presentation format address (`dst'), or NULL (see errno).
- * author:
- *	Paul Vixie, 1996.
- */
-const char *
-__inet_ntop (int af, const void *src, char *dst, socklen_t size)
+static inline char *put_uint8 (uint8_t word, char *tp)
 {
-	switch (af) {
-	case AF_INET:
-		return (inet_ntop4(src, dst, size));
-	case AF_INET6:
-		return (inet_ntop6(src, dst, size));
-	default:
-		__set_errno (EAFNOSUPPORT);
-		return (NULL);
-	}
-	/* NOTREACHED */
+  intptr_t s = 1;
+  if (word >= 100)
+    {
+      tp[2] = _itoa_lower_digits[word % 10];
+      word /= 10;
+      s += 1;
+    }
+  if (word >= 10)
+    {
+      tp[1] = _itoa_lower_digits[word % 10];
+      word /= 10;
+      s += 1;
+    }
+  *tp = _itoa_lower_digits[word % 10];
+  return tp + s;
+}
+
+static inline char *put_uint16 (uint16_t word, char *tp)
+{
+  if (word >= 0x1000)
+    *tp++ = _itoa_lower_digits[(word >> 12) & 0xf];
+  if (word >= 0x100)
+    *tp++ = _itoa_lower_digits[(word >> 8) & 0xf];
+  if (word >= 0x10)
+    *tp++ = _itoa_lower_digits[(word >> 4) & 0xf];
+  *tp++ = _itoa_lower_digits[word & 0xf];
+  return tp;
 }
-libc_hidden_def (__inet_ntop)
-weak_alias (__inet_ntop, inet_ntop)
 
 /* const char *
  * inet_ntop4(src, dst, size)
@@ -74,20 +73,36 @@ weak_alias (__inet_ntop, inet_ntop)
  * notes:
  *	(1) uses no statics
  *	(2) takes a u_char* not an in_addr as input
- * author:
- *	Paul Vixie, 1996.
  */
-static const char *
+static __always_inline const char *
 inet_ntop4 (const u_char *src, char *dst, socklen_t size)
 {
-	static const char fmt[] = "%u.%u.%u.%u";
-	char tmp[sizeof "255.255.255.255"];
+  enum
+    {
+      oct_size = INT_BUFSIZE_BOUND (u_char),
+      tmp_size = 4 * oct_size + 3 /* '.' */ + 1 /* '\0' */
+    };
+  char tmp[tmp_size];
+  char *tmp_r = tmp;
 
-	if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) {
-		__set_errno (ENOSPC);
-		return (NULL);
-	}
-	return strcpy(dst, tmp);
+  tmp_r = put_uint8 (src[0], tmp_r);
+  *(tmp_r++) = '.';
+  tmp_r = put_uint8 (src[1], tmp_r);
+  *(tmp_r++) = '.';
+  tmp_r = put_uint8 (src[2], tmp_r);
+  *(tmp_r++) = '.';
+  tmp_r = put_uint8 (src[3], tmp_r);
+  *tmp_r++ = '\0';
+
+  socklen_t tmp_s = tmp_r - tmp;
+  if (tmp_s > size)
+    {
+      __set_errno (ENOSPC);
+      return NULL;
+    }
+  memcpy (dst, tmp, tmp_s);
+
+  return dst;
 }
 
 /* const char *
@@ -96,7 +111,7 @@ inet_ntop4 (const u_char *src, char *dst, socklen_t size)
  * author:
  *	Paul Vixie, 1996.
  */
-static const char *
+static inline const char *
 inet_ntop6 (const u_char *src, char *dst, socklen_t size)
 {
 	/*
@@ -108,7 +123,7 @@ inet_ntop6 (const u_char *src, char *dst, socklen_t size)
 	 */
 	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
 	struct { int base, len; } best, cur;
-	u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
+	uint16_t words[NS_IN6ADDRSZ / NS_INT16SZ] = { 0 };
 	int i;
 
 	/*
@@ -116,7 +131,6 @@ inet_ntop6 (const u_char *src, char *dst, socklen_t size)
 	 *	Copy the input (bytewise) array into a wordwise array.
 	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
 	 */
-	memset(words, '\0', sizeof words);
 	for (i = 0; i < NS_IN6ADDRSZ; i += 2)
 		words[i / 2] = (src[i] << 8) | src[i + 1];
 	best.base = -1;
@@ -167,7 +181,7 @@ inet_ntop6 (const u_char *src, char *dst, socklen_t size)
 			tp += strlen(tp);
 			break;
 		}
-		tp += SPRINTF((tp, "%x", words[i]));
+		tp = put_uint16 (words[i], tp);
 	}
 	/* Was it a trailing run of 0x00's? */
 	if (best.base != -1 && (best.base + best.len) ==
@@ -178,9 +192,35 @@ inet_ntop6 (const u_char *src, char *dst, socklen_t size)
 	/*
 	 * Check for overflow, copy, and we're done.
 	 */
-	if ((socklen_t)(tp - tmp) > size) {
+	socklen_t tmp_s = tp - tmp;
+	if (tmp_s > size) {
 		__set_errno (ENOSPC);
 		return (NULL);
 	}
-	return strcpy(dst, tmp);
+	return memcpy(dst, tmp, tmp_s);
 }
+
+/* char *
+ * __inet_ntop(af, src, dst, size)
+ *	convert a network format address to presentation format.
+ * return:
+ *	pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *	Paul Vixie, 1996.
+ */
+const char *
+__inet_ntop (int af, const void *src, char *dst, socklen_t size)
+{
+	switch (af) {
+	case AF_INET:
+		return (inet_ntop4(src, dst, size));
+	case AF_INET6:
+		return (inet_ntop6(src, dst, size));
+	default:
+		__set_errno (EAFNOSUPPORT);
+		return (NULL);
+	}
+	/* NOTREACHED */
+}
+libc_hidden_def (__inet_ntop)
+weak_alias (__inet_ntop, inet_ntop)
