Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/cifs/dns_resolve.c
15109 views
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])
7
* Wang Lei ([email protected])
8
* David Howells ([email protected])
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
28
#include <linux/slab.h>
29
#include <linux/dns_resolver.h>
30
#include "dns_resolve.h"
31
#include "cifsglob.h"
32
#include "cifsproto.h"
33
#include "cifs_debug.h"
34
35
/**
36
* dns_resolve_server_name_to_ip - Resolve UNC server name to ip address.
37
* @unc: UNC path specifying the server
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.
44
*/
45
int
46
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
47
{
48
struct sockaddr_storage ss;
49
const char *hostname, *sep;
50
char *name;
51
int len, rc;
52
53
if (!ip_addr || !unc)
54
return -EINVAL;
55
56
len = strlen(unc);
57
if (len < 3) {
58
cFYI(1, "%s: unc is too short: %s", __func__, unc);
59
return -EINVAL;
60
}
61
62
/* Discount leading slashes for cifs */
63
len -= 2;
64
hostname = unc + 2;
65
66
/* Search for server name delimiter */
67
sep = memchr(hostname, '\\', len);
68
if (sep)
69
len = sep - hostname;
70
else
71
cFYI(1, "%s: probably server name is whole unc: %s",
72
__func__, unc);
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)
82
cERROR(1, "%s: unable to resolve: %*.*s",
83
__func__, len, len, hostname);
84
else
85
cFYI(1, "%s: resolved: %*.*s to %s",
86
__func__, len, len, hostname, *ip_addr);
87
return rc;
88
89
name_is_IP_address:
90
name = kmalloc(len + 1, GFP_KERNEL);
91
if (!name)
92
return -ENOMEM;
93
memcpy(name, hostname, len);
94
name[len] = 0;
95
cFYI(1, "%s: unc is IP, skipping dns upcall: %s", __func__, name);
96
*ip_addr = name;
97
return 0;
98
}
99
100