summary refs log tree commit diff
path: root/fs/cifs/dns_resolve.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-04-26 00:22:23 +0000
committerSteve French <sfrench@us.ibm.com>2008-04-26 00:22:23 +0000
commitd09e860cf07e7c9ee12920a09f5080e30a12a23a (patch)
tree576e2626128ab5d1d147a397a8914c2b4ce3d4fa /fs/cifs/dns_resolve.c
parent404e86e1550cc2c84bb57a372af784585c732f9a (diff)
downloadlinux-d09e860cf07e7c9ee12920a09f5080e30a12a23a.tar.gz
[CIFS] Adds to dns_resolver checking if the server name is an IP addr and skipping upcall in this case.
Signed-off-by: Igor Mammedov <niallain@gmail.com>
Signed-off-by: sfrench@us.ibm.com
Diffstat (limited to 'fs/cifs/dns_resolve.c')
-rw-r--r--fs/cifs/dns_resolve.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 7cc86c418182..939e256f8497 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -55,6 +55,32 @@ struct key_type key_type_dns_resolver = {
 	.match       = user_match,
 };
 
+/* Checks if supplied name is IP address
+ * returns:
+ * 		1 - name is IP
+ * 		0 - name is not IP
+ */
+static int is_ip(const char *name)
+{
+	int rc;
+	struct sockaddr_in sin_server;
+	struct sockaddr_in6 sin_server6;
+
+	rc = cifs_inet_pton(AF_INET, name,
+			&sin_server.sin_addr.s_addr);
+
+	if (rc <= 0) {
+		/* not ipv4 address, try ipv6 */
+		rc = cifs_inet_pton(AF_INET6, name,
+				&sin_server6.sin6_addr.in6_u);
+		if (rc > 0)
+			return 1;
+	} else {
+		return 1;
+	}
+	/* we failed translating address */
+	return 0;
+}
 
 /* Resolves server name to ip address.
  * input:
@@ -67,8 +93,9 @@ int
 dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
 {
 	int rc = -EAGAIN;
-	struct key *rkey;
+	struct key *rkey = ERR_PTR(-EAGAIN);
 	char *name;
+	char *data = NULL;
 	int len;
 
 	if (!ip_addr || !unc)
@@ -97,26 +124,41 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
 	memcpy(name, unc+2, len);
 	name[len] = 0;
 
+	if (is_ip(name)) {
+		cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
+					__func__, name));
+		data = name;
+		goto skip_upcall;
+	}
+
 	rkey = request_key(&key_type_dns_resolver, name, "");
 	if (!IS_ERR(rkey)) {
-		len = strlen(rkey->payload.data);
-		*ip_addr = kmalloc(len+1, GFP_KERNEL);
-		if (*ip_addr) {
-			memcpy(*ip_addr, rkey->payload.data, len);
-			(*ip_addr)[len] = '\0';
-			cFYI(1, ("%s: resolved: %s to %s", __func__,
+		data = rkey->payload.data;
+		cFYI(1, ("%s: resolved: %s to %s", __func__,
 					rkey->description,
 					*ip_addr
 				));
+	} else {
+		cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+		goto out;
+	}
+
+skip_upcall:
+	if (data) {
+		len = strlen(data);
+		*ip_addr = kmalloc(len+1, GFP_KERNEL);
+		if (*ip_addr) {
+			memcpy(*ip_addr, data, len);
+			(*ip_addr)[len] = '\0';
 			rc = 0;
 		} else {
 			rc = -ENOMEM;
 		}
-		key_put(rkey);
-	} else {
-		cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+		if (!IS_ERR(rkey))
+			key_put(rkey);
 	}
 
+out:
 	kfree(name);
 	return rc;
 }