Blame view
fs/cifs/dns_resolve.c
2.85 KB
197c183f3
|
1 2 3 4 5 6 |
/* * fs/cifs/dns_resolve.c * * Copyright (c) 2007 Igor Mammedov * Author(s): Igor Mammedov (niallain@gmail.com) * Steve French (sfrench@us.ibm.com) |
1a4240f47
|
7 8 |
* Wang Lei (wang840925@gmail.com) * David Howells (dhowells@redhat.com) |
197c183f3
|
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
* * Contains the CIFS DFS upcall routines used for hostname to * IP address translation. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
5a0e3ad6a
|
27 |
#include <linux/slab.h> |
1a4240f47
|
28 |
#include <linux/dns_resolver.h> |
197c183f3
|
29 30 31 32 |
#include "dns_resolve.h" #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" |
1a4240f47
|
33 34 |
/** * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address. |
d9deef0a3
|
35 |
* @unc: UNC path specifying the server (with '/' as delimiter) |
1a4240f47
|
36 37 38 39 40 41 |
* @ip_addr: Where to return the IP address. * * The IP address will be returned in string form, and the caller is * responsible for freeing it. * * Returns length of result on success, -ve on error. |
197c183f3
|
42 43 |
*/ int |
366781c19
|
44 45 |
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) { |
1a4240f47
|
46 47 |
struct sockaddr_storage ss; const char *hostname, *sep; |
197c183f3
|
48 |
char *name; |
1a4240f47
|
49 |
int len, rc; |
197c183f3
|
50 |
|
366781c19
|
51 |
if (!ip_addr || !unc) |
197c183f3
|
52 |
return -EINVAL; |
197c183f3
|
53 54 |
len = strlen(unc); if (len < 3) { |
f96637be0
|
55 56 |
cifs_dbg(FYI, "%s: unc is too short: %s ", __func__, unc); |
197c183f3
|
57 58 |
return -EINVAL; } |
d09e860cf
|
59 |
|
1a4240f47
|
60 61 62 |
/* Discount leading slashes for cifs */ len -= 2; hostname = unc + 2; |
197c183f3
|
63 |
|
1a4240f47
|
64 |
/* Search for server name delimiter */ |
d9deef0a3
|
65 |
sep = memchr(hostname, '/', len); |
1a4240f47
|
66 |
if (sep) |
ba0386487
|
67 |
len = sep - hostname; |
1a4240f47
|
68 |
else |
f96637be0
|
69 70 71 |
cifs_dbg(FYI, "%s: probably server name is whole unc: %s ", __func__, unc); |
1a4240f47
|
72 73 74 75 76 77 78 79 80 |
/* Try to interpret hostname as an IPv4 or IPv6 address */ rc = cifs_convert_address((struct sockaddr *)&ss, hostname, len); if (rc > 0) goto name_is_IP_address; /* Perform the upcall */ rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL); if (rc < 0) |
f96637be0
|
81 82 83 |
cifs_dbg(FYI, "%s: unable to resolve: %*.*s ", __func__, len, len, hostname); |
1a4240f47
|
84 |
else |
f96637be0
|
85 86 87 |
cifs_dbg(FYI, "%s: resolved: %*.*s to %s ", __func__, len, len, hostname, *ip_addr); |
197c183f3
|
88 |
return rc; |
197c183f3
|
89 |
|
1a4240f47
|
90 91 92 |
name_is_IP_address: name = kmalloc(len + 1, GFP_KERNEL); if (!name) |
4c0c03ca5
|
93 |
return -ENOMEM; |
1a4240f47
|
94 95 |
memcpy(name, hostname, len); name[len] = 0; |
f96637be0
|
96 97 98 |
cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %s ", __func__, name); |
1a4240f47
|
99 |
*ip_addr = name; |
4c0c03ca5
|
100 |
return 0; |
4c0c03ca5
|
101 |
} |