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