2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "DNSNameCache.h"
22 #include "threads/SingleLock.h"
23 #include "utils/log.h"
24 #include "utils/StringUtils.h"
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
30 CDNSNameCache g_DNSCache;
32 CCriticalSection CDNSNameCache::m_critical;
34 CDNSNameCache::CDNSNameCache(void)
37 CDNSNameCache::~CDNSNameCache(void)
40 bool CDNSNameCache::Lookup(const CStdString& strHostName, CStdString& strIpAddress)
42 if (strHostName.empty() && strIpAddress.empty())
45 // first see if this is already an ip address
46 unsigned long address = inet_addr(strHostName.c_str());
49 if (address != INADDR_NONE)
51 strIpAddress = StringUtils::Format("%d.%d.%d.%d", (address & 0xFF), (address & 0xFF00) >> 8, (address & 0xFF0000) >> 16, (address & 0xFF000000) >> 24 );
55 // check if there's a custom entry or if it's already cached
56 if(g_DNSCache.GetCached(strHostName, strIpAddress))
59 #ifndef TARGET_WINDOWS
60 // perform netbios lookup (win32 is handling this via gethostbyname)
64 CStdString cmd = "nmblookup " + strHostName;
65 FILE* fp = popen(cmd, "r");
68 while (fgets(line, sizeof line, fp))
70 if (sscanf(line, "%99s *<00>\n", nmb_ip))
72 if (inet_addr(nmb_ip) != INADDR_NONE)
73 strIpAddress = nmb_ip;
79 if (!strIpAddress.empty())
81 g_DNSCache.Add(strHostName, strIpAddress);
87 struct hostent *host = gethostbyname(strHostName.c_str());
88 if (host && host->h_addr_list[0])
90 strIpAddress = StringUtils::Format("%d.%d.%d.%d",
91 (unsigned char)host->h_addr_list[0][0],
92 (unsigned char)host->h_addr_list[0][1],
93 (unsigned char)host->h_addr_list[0][2],
94 (unsigned char)host->h_addr_list[0][3]);
95 g_DNSCache.Add(strHostName, strIpAddress);
99 CLog::Log(LOGERROR, "Unable to lookup host: '%s'", strHostName.c_str());
103 bool CDNSNameCache::GetCached(const CStdString& strHostName, CStdString& strIpAddress)
105 CSingleLock lock(m_critical);
107 // loop through all DNSname entries and see if strHostName is cached
108 for (int i = 0; i < (int)g_DNSCache.m_vecDNSNames.size(); ++i)
110 CDNSName& DNSname = g_DNSCache.m_vecDNSNames[i];
111 if ( DNSname.m_strHostName == strHostName )
113 strIpAddress = DNSname.m_strIpAddress;
122 void CDNSNameCache::Add(const CStdString &strHostName, const CStdString &strIpAddress)
126 dnsName.m_strHostName = strHostName;
127 dnsName.m_strIpAddress = strIpAddress;
129 CSingleLock lock(m_critical);
130 g_DNSCache.m_vecDNSNames.push_back(dnsName);