📄 dns_resolv.c
字号:
/* webalizer - a web server log analysis program Copyright (C) 1997-2001 Bradford L. Barrett (brad@mrunix.net) 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, and provided that the above copyright and permission notice is included with all distributed copies of this or derived software. 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 This software uses the gd graphics library, which is copyright by Quest Protein Database Center, Cold Spring Harbor Labs. Please see the documentation supplied with the library for additional information and license terms, or visit www.boutell.com/gd/ for the most recent version of the library and supporting documentation. dns_resolv.c - based on the dns-resolver code submitted by Henning P. Schmiedehausen <hps@tanstaafl.de> and modified for inclusion in the Webalizer directly. Enabled with -DUSE_DNS.*//*********************************************//* STANDARD INCLUDES *//*********************************************/#include <time.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h> /* normal stuff */#include <ctype.h>#include <sys/utsname.h>#include <sys/times.h>#include <zlib.h>/* Need socket header? */#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif/* ensure getopt */#ifdef HAVE_GETOPT_H#include <getopt.h>#endif/* ensure sys/types */#ifndef _SYS_TYPES_H#include <sys/types.h>#endif/* some systems need this */#ifdef HAVE_MATH_H#include <math.h>#endif/* SunOS 4.x Fix */#ifndef CLK_TCK#define CLK_TCK _SC_CLK_TCK#endif#ifdef USE_DNS /* skip everything in this file if no DNS */#include <netinet/in.h> /* include stuff we need for dns lookups, */#include <arpa/inet.h> /* DB access, file control, etc... */#include <fcntl.h>#include <netdb.h>#include <signal.h>#include <sys/signal.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/wait.h>#ifdef HAVE_DB_185_H#include <db_185.h> /* on my RH6.0 system ?!? */#else#include <db.h> /* DB header ****************/#endif /* HAVE_DB_185_H */#include "webalizer.h" /* main header */#include "lang.h" /* language declares */#include "hashtab.h" /* hash table functions */#include "parser.h" /* log parser functions */#include "dns_resolv.h" /* our header *//* local data */#ifndef HAVE_ERRNO_Hint errno; /* errno for those in need */#endifDB *dns_db = NULL; /* DNS cache database */int dns_fd = 0;struct dns_child child[MAXCHILD]; /* DNS child pipe data */DNODEPTR host_table[MAXHASH]; /* hostname/ip hash table */char buffer[BUFSIZE]; /* log file record buffer */char tmp_buf[BUFSIZE]; /* used to temp save above */struct utsname system_info; /* system info structure */int raiseSigChild = 1;time_t runtime;time_t start_time, end_time;float temp_time;extern char *our_gzgets(gzFile, char *, int); /* external our_gzgets func *//* internal function prototypes */static void process_list(DNODEPTR);static void sigChild(int);static void db_put(char *, char *, int);void set_fl(int, int);void clr_fl(int, int);/*********************************************//* RESOLVE_DNS - lookup IP in cache *//*********************************************/void resolve_dns(struct log_struct *log_rec){ DBT query, response; /* aligned dnsRecord to prevent Solaris from doing a dump */ /* (not found in debugger, as it can dereference it :( */ struct dnsRecord alignedRecord; if (!dns_db) return; /* ensure we have a dns db */ query.data = log_rec->hostname; query.size = strlen(log_rec->hostname); if (debug_mode) fprintf(stderr,"Checking %s...", log_rec->hostname); switch((dns_db->get)(dns_db, &query, &response, 0)) { case -1: if (debug_mode) fprintf(stderr," Lookup error\n"); break; case 1: if (debug_mode) fprintf(stderr," not found\n"); break; case 0: { memcpy(&alignedRecord, response.data, sizeof(struct dnsRecord)); strncpy (log_rec->hostname, ((struct dnsRecord *)response.data)->hostName, MAXHOST); log_rec->hostname[MAXHOST]=0; if (debug_mode) fprintf(stderr," found: %s (%ld)\n", log_rec->hostname, alignedRecord.timeStamp); break; } default: if (debug_mode) fprintf(stderr," Invalid response\n"); }}/*********************************************//* DNS_RESOLVER - read log and lookup IP's *//*********************************************/int dns_resolver(void *log_fp){ DNODEPTR h_entries; DNODEPTR l_list = NULL; int i; int save_verbose=verbose; u_long listEntries = 0; struct sigaction sigPipeAction; struct stat dbStat; struct tms mytms; /* aligned dnsRecord to prevent Solaris from doing a dump */ /* (not found in debugger, as it can dereference it :( */ struct dnsRecord alignedRecord; struct flock tmp_flock; tmp_flock.l_whence=SEEK_SET; /* default flock fields */ tmp_flock.l_start=0; tmp_flock.l_len=0; tmp_flock.l_pid=0; time(&runtime); start_time = times(&mytms); /* get start time */ /* minimal sanity check on it */ if(stat(dns_cache, &dbStat) < 0) { if(errno != ENOENT) { dns_cache=NULL; dns_db=NULL; return 0; /* disable cache */ } } else { if(!dbStat.st_size) /* bogus file, probably from a crash */ { unlink(dns_cache); /* remove it so we can recreate... */ } } /* open cache file */ if(!(dns_db = dbopen(dns_cache, O_RDWR|O_CREAT, 0664, DB_HASH, NULL))) { /* Error: Unable to open DNS cache file <filename> */ if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nodb,dns_cache); dns_cache=NULL; dns_db=NULL; return 0; /* disable cache */ } /* get file descriptor */ dns_fd = dns_db->fd(dns_db); tmp_flock.l_type=F_WRLCK; /* set read/write lock type */ if (fcntl(dns_fd,F_SETLK,&tmp_flock) < 0) /* and barf if we cant lock */ { /* Error: Unable to lock DNS cache file <filename> */ if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nolk,dns_cache); dns_db->close(dns_db); dns_cache=NULL; dns_db=NULL; return 0; /* disable cache */ } /* Setup signal handlers */ sigPipeAction.sa_handler = SIG_IGN; sigPipeAction.sa_flags = SA_RESTART; sigemptyset(&sigPipeAction.sa_mask); sigaction(SIGPIPE, &sigPipeAction, NULL); /* disable warnings/errors for this run... */ verbose=0; /* Main loop to read log records (either regular or zipped) */ while ( (gz_log)?(our_gzgets((gzFile)log_fp,buffer,BUFSIZE) != Z_NULL): (fgets(buffer,BUFSIZE,log_fname?(FILE *)log_fp:stdin) != NULL)) { if (strlen(buffer) == (BUFSIZE-1)) { /* get the rest of the record */ while ( (gz_log)?(our_gzgets((gzFile)log_fp,buffer,BUFSIZE)!=Z_NULL): (fgets(buffer,BUFSIZE,log_fname?(FILE *)log_fp:stdin)!=NULL)) { if (strlen(buffer) < BUFSIZE-1) break; } continue; /* go get next record if any */ } strcpy(tmp_buf, buffer); /* save buffer in case of error */ if(parse_record(buffer)) /* parse the record */ { if((log_rec.addr.s_addr = inet_addr(log_rec.hostname)) != INADDR_NONE) { DBT q, r; q.data = log_rec.hostname; q.size = strlen(log_rec.hostname); switch((dns_db->get)(dns_db, &q, &r, 0)) { case -1: break; /* Error while retrieving .. just ignore */ case 1: /* No record on file, queue up for resolving */ { put_dnode(log_rec.hostname, &log_rec.addr, host_table); break; } case 0: /* We have a record for this address */ { memcpy(&alignedRecord, r.data, sizeof(struct dnsRecord)); if((runtime - alignedRecord.timeStamp ) < DNS_CACHE_TTL) { if(!alignedRecord.numeric) /* It is a name. Do nothing */ break; /* otherise, it a number.. fall through */ } else { /* queue up stale entry for retrieval */ put_dnode(log_rec.hostname, &log_rec.addr, host_table); break; } } } } } } verbose = save_verbose; /* restore verbosity level... */ listEntries = 0; /* build our linked list l_list */ for(i=0;i < MAXHASH; i++) { for(h_entries=host_table[i]; h_entries ; h_entries = h_entries->next) { h_entries->llist = l_list; l_list = h_entries; listEntries++; } } if(!l_list) { /* No valid addresses found... */ if (verbose>1) printf("%s\n",msg_dns_none); tmp_flock.l_type=F_UNLCK; fcntl(dns_fd, F_SETLK, &tmp_flock); dns_db->close(dns_db); return 0; } /* process our list now... */ process_list(l_list); /* display timing totals ? */ end_time = times(&mytms); /* display timing totals? */ if (time_me || (verbose>1)) { if (verbose<2 && time_me) printf("DNS: "); printf("%lu %s ",listEntries, msg_addresses); /* get processing time (end-start) */ temp_time = (float)(end_time-start_time)/CLK_TCK; printf("%s %.2f %s", msg_in, temp_time, msg_seconds); /* calculate records per second */ if (temp_time) i=( (int)((float)listEntries/temp_time) ); else i=0; if ( (i>0) && (i<=listEntries) ) printf(", %d/sec\n", i); else printf("\n"); } /* processing done, exit */ tmp_flock.l_type=F_UNLCK; fcntl(dns_fd, F_SETLK, &tmp_flock); dns_db->close(dns_db); return 0;}/*********************************************//* PROCESS_LIST - do the resoluton... *//*********************************************/static void process_list(DNODEPTR l_list){ DNODEPTR trav; char child_buf[MAXHOST]; char dns_buf[MAXHOST]; int i; int pid; int nof_children = 0; fd_set rd_set; struct sigaction sigChildAction; sigChildAction.sa_handler = sigChild; sigChildAction.sa_flags = SA_NOCLDSTOP|SA_RESTART; sigemptyset(&sigChildAction.sa_mask); raiseSigChild = 0; sigaction(SIGCHLD, &sigChildAction, NULL); /* fire up our child processes */ for(i=0; i < dns_children; i++) { if(pipe(child[i].inpipe)) { if (verbose) fprintf(stderr,"INPIPE creation error"); return; /* exit(1) */ } if(pipe(child[i].outpipe)) { if (verbose) fprintf(stderr,"OUTPIPE creation error"); return; /* exit(1); */ } /* fork it off */ switch(pid=fork()) { case -1: { if (verbose) fprintf(stderr,"FORK error"); return; /* exit(1); */ } case 0: /* Child */ { int size; struct hostent *res_ent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -