Patchwork [7/7] cifs.upcall: fix IPv6 addrs sent to upcall to have colon delimiters

login
register
mail settings
Submitter Jeff Layton
Date Aug. 7, 2009, 7:43 p.m.
Message ID <1249674197-1065-8-git-send-email-jlayton@redhat.com>
Download mbox | patch
Permalink /patch/30969/
State New
Headers show

Comments

Jeff Layton - Aug. 7, 2009, 7:43 p.m.
Current kernels don't send IPv6 addresses with the colon delimiters, add
a routine to add them when they're not present.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 client/cifs.upcall.c |   33 +++++++++++++++++++++++++++++----
 1 files changed, 29 insertions(+), 4 deletions(-)

Patch

diff --git a/client/cifs.upcall.c b/client/cifs.upcall.c
index 1e58503..0cc72fc 100644
--- a/client/cifs.upcall.c
+++ b/client/cifs.upcall.c
@@ -296,18 +296,43 @@  cifs_resolver(const key_serial_t key, const char *key_descr)
 	return 0;
 }
 
+/*
+ * Older kernels sent IPv6 addresses without colons. Well, at least
+ * they're fixed-length strings. Convert these addresses to have colon
+ * delimiters to make getaddrinfo happy.
+ */
+static void
+convert_inet6_addr(const char *from, char *to)
+{
+	int i = 1;
+
+	while (*from) {
+		*to++ = *from++;
+		if (!(i++ % 4) && *from)
+			*to++ = ':';
+	}
+	*to = 0;
+}
+
 static int
-ip_to_fqdn(const char *ipaddr, char *host, size_t hostlen)
+ip_to_fqdn(const char *addrstr, char *host, size_t hostlen)
 {
 	int rc;
 	struct addrinfo hints = { .ai_flags = AI_NUMERICHOST };
 	struct addrinfo *res;
+	const char *ipaddr = addrstr;
+	char converted[INET6_ADDRSTRLEN + 1];
+
+	if ((strlen(ipaddr) > INET_ADDRSTRLEN) && !strchr(ipaddr, ':')) {
+		convert_inet6_addr(ipaddr, converted);
+		ipaddr = converted;
+	}
 
 	rc = getaddrinfo(ipaddr, NULL, &hints, &res);
 	if (rc) {
-		syslog(LOG_DEBUG, "%s: failed to resolve %s to ipaddr: %s",
-			__func__, ipaddr,
-			rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
+		syslog(LOG_DEBUG, "%s: failed to resolve %s to "
+			"ipaddr: %s", __func__, ipaddr,
+		rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
 		return rc;
 	}