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