KlugyTools/CheckResolv/checkresolv.c

239 lines
4.8 KiB
C

/*
* CheckResolv
* ===========
*
* quick and dirty debugging hack.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define __USE_BSD
#include <string.h>
/* #undef __USE_BSD */
#include <sys/time.h>
#include <getopt.h>
#define __USE_MISC
#include <netdb.h> /* herror ? */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "fonctions.h"
char * strdup(char *); /* DIRTY HACK */
/* ------------------------------------------------------------ */
/* quick and dirty global variables */
int verbose = 0;
int do_reverse = 0;
int do_environ = 0;
int do_timing = 0;
/* ------------------------------------------------------------ */
/* parameter '*txt' is not used */
int print_hostent(struct hostent *ph, char *txt)
{
char *ptr, **pptr;
printf("h_name: %s\n", ph->h_name);
pptr = ph->h_aliases;
if (verbose) {
printf("h_aliases: %p -> %p\n", pptr, *pptr);
}
while ( (ptr = *(pptr)) != NULL ) {
printf(" alias: %s\n", ptr);
pptr++;
}
if (verbose) {
printf("h_addrtype: %d\n", ph->h_addrtype);
printf("h_length: %d\n", ph->h_length);
}
print_ip((struct in_addr **)ph->h_addr_list); /* strange cast */
return 0;
}
/* ------------------------------------------------------------ */
/*
* If we have a list of IP addr, we can try a
* reverse lookup, no ?
*/
int check_reverse(struct hostent *ph)
{
struct in_addr **liste;
struct in_addr *addr;
struct in_addr l_addr; /* Jules */
struct hostent *revph;
int nbre;
double t1 , t2;
char *ptmp;
if (do_timing) t1 = chronometre();
nbre = 0;
liste = (struct in_addr **)ph->h_addr_list;
while (NULL != (addr = *liste++)) {
l_addr = *addr; /* Jules */
#if TRACE
fprintf(stderr, "---> %p %p\n", addr, l_addr);
#endif
revph = gethostbyaddr(&l_addr, ph->h_length, ph->h_addrtype);
if (NULL != revph) {
/* taking over hidden string vars */
ptmp = strdup(inet_ntoa(l_addr));
if (NULL == ptmp) {
fprintf(stderr, "no memory in %s, line %d\n",
__FILE__, __LINE__);
abort();
}
#if TRACE
fprintf(stderr, "%s:%d %p %p\n", __func__, __LINE__,
ptmp, revph->h_name);
#endif
printf("reverse %-16s -> %s\n", ptmp, revph->h_name);
free(ptmp);
}
else {
/* fprintf(stderr, "reverse ? wtf ?\n"); */
herror("reverse lookup"); /* this func is obsolete ! */
}
nbre++;
}
if (do_timing) {
t2 = chronometre();
if (nbre > 1)
printf("reverse take %.3f s (%.3f s)\n", t2-t1, (t2-t1)/nbre);
else
printf("reverse take %.3f s.\n", t2-t1);
}
return 0;
}
/* ------------------------------------------------------------ */
struct hostent *direct_lookup(char *hostname)
{
struct hostent *p_host;
double t1 , t2;
int foo;
if (do_timing) t1 = chronometre();
p_host = gethostbyname(hostname);
if (do_timing) t2 = chronometre();
if (p_host==NULL)
{
fprintf(stderr, "error %d on '%s'", h_errno, hostname);
herror(" ");
return NULL;
}
foo = print_hostent(p_host, NULL);
if (do_timing) printf("gethostbyname take %.3f s.\n", t2 - t1);
return p_host;
}
/* ------------------------------------------------------------ */
int analyse(char *nom, int flag)
{
struct hostent *p_host;
p_host = direct_lookup(nom);
/*
* new, 31 jan 2005, v 0.19
* if the requested 'hostname' seems to be an ip address, can we
* force a valid reverse lookup ?
*/
if (is_IP_addr(nom) && !do_reverse)
{
fprintf(stderr, "* if %s is a valid ip addr, try the '-r' switch.\n",
nom);
}
if (do_reverse && (p_host!=NULL))
check_reverse(p_host);
return 0;
}
/* ------------------------------------------------------------ */
/*
* Set some global flags, based on our environment
* variable.
*/
void analyze_environ(void)
{
char *ptr;
ptr = getenv("CHECKRESOLV");
if (ptr == NULL)
return;
if ( ! strcmp("tech", ptr) ) {
do_reverse = 1;
do_timing = 1;
}
if ( ! strcmp("all", ptr) ) {
do_reverse = 1;
do_timing = 1;
verbose = 1;
do_environ = 1;
}
}
/* ------------------------------------------------------------ */
int main (int argc, char *argv[])
{
int foo;
char * liste_opt = "vrhteV";
int option;
if (argc == 1) help_options();
while ((option=getopt(argc, argv, liste_opt)) != -1)
{
switch(option)
{
case 'v': verbose++; break;
case 'r': do_reverse=1; break;
case 'e': do_environ=1; break;
case 't': do_timing=1; break;
case 'h': usage(); break;
case 'V': version(); break;
}
}
#if TRACE
fprintf(stderr, "argc %d optind %d\n", argc, optind);
for (foo=optind; foo<argc; foo++)
{
fprintf(stderr, " %4d %s\n", foo, argv[foo]);
}
#endif
/*
* env vars can override command line options.
*/
analyze_environ();
for (foo=optind; foo<argc; foo++)
{
printf("------------( %s \n", argv[foo]);
analyse(argv[foo], 0);
}
if (do_environ) print_envvars(0);
return 0;
}
/* ------------------------------------------------------------ */