/* $Id: resolve.c,v 1.4 2003/02/22 23:17:09 d3august Exp $
*/
/* xtraceroute - graphically show traceroute information.
* Copyright (C) 1996-1998 Björn Augustsson
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "xt.h"
#include <ctype.h>
#include <string.h>
extern const countrycode countries[];
extern const int n_countries;
static int
scanHostDB(database *db, site* key)
{
int i;
if(!db || db->n_entries == 0) /* No database */
return FALSE;
/* Future: Hash here. Or tree, or whatever.
Make it faster anyway. */
for(i=0 ; i<db->n_entries ; i++)
if(!strcasecmp(key->name, db->entries[i].name) ||
!strcmp(key->ip, db->entries[i].ip))
{
key->lat = db->entries[i].lat;
key->lon = db->entries[i].lon;
key->draw = 1;
return TRUE;
}
return FALSE;
}
static int
scanNetDB(database *db, site* key)
{
char tmp[20];
int j;
if(!db || db->n_entries == 0) /* No database */
return FALSE;
strcpy(tmp, key->ip);
for(j=0 ; j<3 ; j++)
{
int i, ii;
/* There should be some hashing here instead of this
O(n) stuff... */
/* Remove the last number (and dot) in the IP-nr. */
for(ii=strlen(tmp) ; tmp[ii] != '.' ; ii--)
;
tmp[ii] = '\0';
for(i=0 ; i<db->n_entries ; i++)
{
if(!strcasecmp(tmp, db->entries[i].ip))
{
key->lat = db->entries[i].lat;
key->lon = db->entries[i].lon;
strcpy(key->info, db->entries[i].info);
key->draw = 1;
return TRUE;
}
}
}
return FALSE;
}
static int
scanGenericDB(database *db, site* key)
{
int i;
if(!db || db->n_entries == 0) /* No database */
return FALSE;
for(i=0 ; i<db->n_entries ; i++)
if(isin(db->entries[i].name, key->name))
{
key->lat = db->entries[i].lat;
key->lon = db->entries[i].lon;
key->draw = 1;
strcpy(key->info, db->entries[i].info);
return TRUE;
}
return FALSE;
}
/**
* resolve() tries to associate a site with a position.
*/
void
resolve(site* site)
{
int i;
char suffix[6];
if(!isdigit((int)site->name[0]))
{
/* Call external program to look up RFC1876 data if it isn't an
IP number, but a proper DNS name.
Names can't begin with a digit. */
callExternalDNS(site);
}
/* Check for the name/IP in the user files */
if(scanHostDB(local_user_hosts, site))
{
site->accuracy = ACC_LOCAL_USER;
return;
}
if(scanNetDB(local_user_nets, site))
{
site->accuracy = ACC_LOCAL_USER;
return;
}
/// GENERIC
/* Check for the name/IP in the site-wide files */
if(scanHostDB(local_site_hosts, site))
{
site->accuracy = ACC_LOCAL_SITE;
return;
}
if(scanNetDB(local_site_nets, site))
{
site->accuracy = ACC_LOCAL_SITE;
return;
}
// GENERIC
/* Check for the name/IP in the NDG host cache. */
if(scanHostDB(ndg_hosts, site))
{
site->accuracy = ACC_NDG_HOST;
return;
}
/* Check for the IP in the NDG net cache. */
if(scanNetDB(ndg_nets, site))
{
site->accuracy = ACC_NDG_NET;
return;
}
/* Is this the "home" site? */
/*
if(site_nr == 0)
tell_user(_("You should enter better\ndata for your site!"));
*/
/* OK, let's see if we can find a name we know in the name
of the site. (Search the internal database.) */
/* First search the user generic database */
if(scanGenericDB(local_user_generic, site))
{
site->accuracy = ACC_LOCAL_USER;
return;
}
/* Then search the internal database */
if(scanGenericDB(internal, site))
{
site->accuracy = ACC_INCLUDED;
return;
}
/* As a last resort, give it a location based on the suffix. */
getsuff(site->name, suffix);
for(i=0;i<n_countries;i++)
if(!strcasecmp(suffix, countries[i].suffix))
{
site->lat = countries[i].lat;
site->lon = countries[i].lon;
site->draw = 1;
site->accuracy = ACC_SUFFIX;
strcpy(site->info, _(countries[i].name));
return;
}
/* OK, admit failure then... */
site->lat = 0.0;
site->lon = 0.0;
site->draw = 1;
site->accuracy = ACC_NONE;
strcpy(site->info,_("I don't know where this is!"));
return;
}
void
resolve_by_id(int site_nr)
{
site* site;
static int user_nagged = FALSE;
site = &(sites[site_nr]);
resolve(site);
if(site_nr == 0 && site->accuracy < ACC_INCLUDED &&
user_nagged == FALSE)
{
tell_user(_("You should enter better\ndata for your site!"));
user_nagged = TRUE;
}
if(site->accuracy == ACC_NONE) /* If it didn't find anything. */
{
/* Set the location to the same as the previous site. */
site->lat = sites[site_nr-1].lat;
site->lon = sites[site_nr-1].lon;
}
return;
}
/**
* Goes over the sites and (re)arranges the locations of unknown sites
* (Useful if the prevoius site was relocated for some reason.)
*/
void
arrangeUnknownSites(void)
{
int i;
for(i=0 ; i<MAX_SITES ; i++)
{
if(sites[i].accuracy == ACC_NONE)
{
/* Set the location to the same as the previous site. */
sites[i].lat = sites[i-1].lat;
sites[i].lon = sites[i-1].lon;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1