brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · 8bf8978 Raw
89 lines · c
1// SPDX-License-Identifier: LGPL-2.12/*3 *4 *   Copyright (c) 2007 Igor Mammedov5 *   Author(s): Igor Mammedov (niallain@gmail.com)6 *              Steve French (sfrench@us.ibm.com)7 *              Wang Lei (wang840925@gmail.com)8 *		David Howells (dhowells@redhat.com)9 *10 *   Contains the CIFS DFS upcall routines used for hostname to11 *   IP address translation.12 *13 */14 15#include <linux/inet.h>16#include <linux/slab.h>17#include <linux/dns_resolver.h>18#include "dns_resolve.h"19#include "cifsglob.h"20#include "cifsproto.h"21#include "cifs_debug.h"22 23/**24 * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address.25 * @unc: UNC path specifying the server (with '/' as delimiter)26 * @ip_addr: Where to return the IP address.27 * @expiry: Where to return the expiry time for the dns record.28 *29 * Returns zero success, -ve on error.30 */31int32dns_resolve_server_name_to_ip(const char *unc, struct sockaddr *ip_addr, time64_t *expiry)33{34	const char *hostname, *sep;35	char *ip;36	int len, rc;37 38	if (!ip_addr || !unc)39		return -EINVAL;40 41	len = strlen(unc);42	if (len < 3) {43		cifs_dbg(FYI, "%s: unc is too short: %s\n", __func__, unc);44		return -EINVAL;45	}46 47	/* Discount leading slashes for cifs */48	len -= 2;49	hostname = unc + 2;50 51	/* Search for server name delimiter */52	sep = memchr(hostname, '/', len);53	if (sep)54		len = sep - hostname;55	else56		cifs_dbg(FYI, "%s: probably server name is whole unc: %s\n",57			 __func__, unc);58 59	/* Try to interpret hostname as an IPv4 or IPv6 address */60	rc = cifs_convert_address(ip_addr, hostname, len);61	if (rc > 0) {62		cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %*.*s\n", __func__, len, len,63			 hostname);64		return 0;65	}66 67	/* Perform the upcall */68	rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len,69		       NULL, &ip, expiry, false);70	if (rc < 0) {71		cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",72			 __func__, len, len, hostname);73	} else {74		cifs_dbg(FYI, "%s: resolved: %*.*s to %s expiry %llu\n",75			 __func__, len, len, hostname, ip,76			 expiry ? (*expiry) : 0);77 78		rc = cifs_convert_address(ip_addr, ip, strlen(ip));79		kfree(ip);80 81		if (!rc) {82			cifs_dbg(FYI, "%s: unable to determine ip address\n", __func__);83			rc = -EHOSTUNREACH;84		} else85			rc = 0;86	}87	return rc;88}89