summaryrefslogtreecommitdiffstats
path: root/lib/base/dns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/base/dns.cpp')
-rw-r--r--lib/base/dns.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/lib/base/dns.cpp b/lib/base/dns.cpp
new file mode 100644
index 00000000..f9e38886
--- /dev/null
+++ b/lib/base/dns.cpp
@@ -0,0 +1,176 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+ * dns.c: DNS resolution routines
+ *
+ * Rob McCool
+ */
+#define DNS_GUESSING
+
+#include "netsite.h"
+#ifdef XP_UNIX
+#include "systems.h"
+#else /* XP_WIN32 */
+#include "base/systems.h"
+#endif /* XP_WIN32 */
+
+#include "net.h" /* SYS_NETFD, various headers to do DNS */
+
+/* Under NT, these are taken care of by net.h including winsock.h */
+#ifdef XP_UNIX
+#include <arpa/inet.h> /* inet_ntoa */
+#include <netdb.h> /* struct hostent */
+#ifdef NEED_GHN_PROTO
+extern "C" int gethostname (char *name, size_t namelen);
+#endif
+#endif
+#ifdef DNS_CACHE
+#include "base/dns_cache.h"
+#include "base/ereport.h"
+#endif /* DNS_CACHE */
+#include <stdio.h>
+#include <nspr.h>
+#include "frame/conf.h"
+
+/* ---------------------------- dns_find_fqdn ----------------------------- */
+
+
+/* defined in dnsdmain.c */
+extern "C" NSAPI_PUBLIC char *dns_guess_domain(char * hname);
+
+char *net_find_fqdn(PRHostEnt *p)
+{
+ int x;
+
+ if((!p->h_name) || (!p->h_aliases))
+ return NULL;
+
+ if(!strchr(p->h_name, '.')) {
+ for(x = 0; p->h_aliases[x]; ++x) {
+ if((strchr(p->h_aliases[x], '.')) &&
+ (!strncmp(p->h_aliases[x], p->h_name, strlen(p->h_name))))
+ {
+ return STRDUP(p->h_aliases[x]);
+ }
+ }
+#ifdef DNS_GUESSING
+ return dns_guess_domain(p->h_name);
+#else
+ return NULL;
+#endif /* DNS_GUESSING */
+ }
+ else
+ return STRDUP(p->h_name);
+}
+
+
+/* ----------------------------- dns_ip2host ------------------------------ */
+
+
+char *dns_ip2host(char *ip, int verify)
+{
+ /* struct in_addr iaddr; */
+ PRNetAddr iaddr;
+ char *hn;
+#ifdef DNS_CACHE
+ dns_cache_entry_t *dns_entry;
+#endif
+ static unsigned long laddr = 0;
+ static char myhostname[256];
+ PRHostEnt hent;
+ char buf[PR_NETDB_BUF_SIZE];
+ PRStatus err;
+
+
+ err = PR_InitializeNetAddr(PR_IpAddrNull, 0, &iaddr);
+
+ if((iaddr.inet.ip = inet_addr(ip)) == -1)
+ goto bong;
+
+#ifdef DNS_CACHE
+ if ( (dns_entry = dns_cache_lookup_ip((unsigned int)iaddr.inet.ip)) ) {
+ hn = NULL;
+ if ( dns_entry->host &&
+ /* Only use entry if the cache entry has been verified or if
+ * verify is off...
+ */
+ (dns_entry->verified || !verify) ) {
+ hn = STRDUP( dns_entry->host );
+ (void)dns_cache_use_decrement(dns_entry);
+ return hn;
+ }
+ dns_cache_delete(dns_entry);
+ dns_entry = 0;
+ }
+#endif
+
+ /*
+ * See if it happens to be the localhost IP address, and try
+ * the local host name if so.
+ */
+ if (laddr == 0) {
+ laddr = inet_addr("127.0.0.1");
+ myhostname[0] = 0;
+ PR_GetSystemInfo(PR_SI_HOSTNAME, myhostname, sizeof(myhostname));
+ }
+
+ /* Have to match the localhost IP address and have a hostname */
+ if ((iaddr.inet.ip == laddr) && (myhostname[0] != 0)) {
+ /*
+ * Now try for a fully-qualified domain name, starting with
+ * the local hostname.
+ */
+ err = PR_GetHostByName(myhostname,
+ buf,
+ PR_NETDB_BUF_SIZE,
+ &hent);
+
+ /* Don't verify if we get a fully-qualified name this way */
+ verify = 0;
+ }
+ else {
+ err = PR_GetHostByAddr(&iaddr,
+ buf,
+ PR_NETDB_BUF_SIZE,
+ &hent);
+ }
+
+ if ((err == PR_FAILURE) || !(hn = net_find_fqdn(&hent))) goto bong;
+
+
+ if(verify) {
+ char **haddr = 0;
+ err = PR_GetHostByName(hn,
+ buf,
+ PR_NETDB_BUF_SIZE,
+ &hent);
+
+ if(err == PR_SUCCESS) {
+ for(haddr = hent.h_addr_list; *haddr; haddr++) {
+ if(((struct in_addr *)(*haddr))->s_addr == iaddr.inet.ip)
+ break;
+ }
+ }
+
+ if((err == PR_FAILURE) || (!(*haddr)))
+ goto bong;
+ }
+
+#ifdef DNS_CACHE
+ if ( (dns_entry = dns_cache_insert(hn, (unsigned int)iaddr.inet.ip, verify)) ) {
+ (void) dns_cache_use_decrement(dns_entry);
+ }
+#endif /* DNS_CACHE */
+ return hn;
+ bong:
+#ifdef DNS_CACHE
+ /* Insert the lookup failure */
+ if ( (dns_entry = dns_cache_insert(NULL, (unsigned int)iaddr.inet.ip, verify)) ) {
+ (void) dns_cache_use_decrement(dns_entry);
+ }
+#endif /* DNS_CACHE */
+ return NULL;
+}