X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=ip2name.c;h=d30f3f787d73c798a3a87b76d7f0bcbeaedda227;hb=ffc9b006b8358644c054c5e4c2929791efec7475;hp=205574ee813bbdcb10ee09e9f8db49e978d5b2b7;hpb=51b166d4eaa0b9966465a9adff1f4bfb2b5c8f42;p=thirdparty%2Fsarg.git diff --git a/ip2name.c b/ip2name.c index 205574e..d30f3f7 100644 --- a/ip2name.c +++ b/ip2name.c @@ -1,6 +1,6 @@ /* * SARG Squid Analysis Report Generator http://sarg.sourceforge.net - * 1998, 2012 + * 1998, 2015 * * SARG donations: * please look at http://sarg.sourceforge.net/donations.php @@ -27,6 +27,7 @@ #include "include/conf.h" #include "include/defs.h" #include "include/ip2name.h" +#include "include/dichotomic.h" //! Associate a name or alias to a module. struct Ip2NameModules @@ -38,17 +39,21 @@ struct Ip2NameModules }; extern struct Ip2NameProcess Ip2NameDns; +extern struct Ip2NameProcess Ip2NameExec; //! The list of the modules available to resolve an IP address into a name. static const struct Ip2NameModules ModulesList[]= { {"dns",&Ip2NameDns}, + {"exec",&Ip2NameExec}, {"yes",&Ip2NameDns},//for historical compatibility {"no",NULL},//does nothing for compatibility with previous versions }; //! The chain of the configured modules to try to resolve an IP. static struct Ip2NameProcess *FirstModule=NULL; +//! The list of the names found so far. +static DichotomicObject KnownIp=NULL; /*! Add a new module to the list of the configured modules. @@ -57,18 +62,18 @@ static void ip2name_chainmodule(struct Ip2NameProcess *Module) { struct Ip2NameProcess *Chain; struct Ip2NameProcess *Last; - - if (debug) debuga(_("Chaining IP resolving module \"%s\"\n"),Module->Name); - + + if (debug) debuga(__FILE__,__LINE__,_("Chaining IP resolving module \"%s\"\n"),Module->Name); + Last=NULL; for (Chain=FirstModule ; Chain ; Chain=Chain->Next) { if (Chain==Module) { - debuga(_("Ignoring duplicate module \"%s\" to resolve an IP address\n"),Module->Name); + debuga(__FILE__,__LINE__,_("Ignoring duplicate module \"%s\" to resolve an IP address\n"),Module->Name); return; } Last=Chain; } - + if (Last) Last->Next=Module; else { @@ -87,7 +92,7 @@ static void ip2name_buildmoduleslist(const char *list) const char *candidate; int length; int ModuleIdx; - + while (*list) { candidate=list; while (*candidate && (unsigned char)*candidate<=' ') candidate++; @@ -101,13 +106,41 @@ static void ip2name_buildmoduleslist(const char *list) } } if (ModuleIdx>=sizeof(ModulesList)/sizeof(*ModulesList)) { - debuga(_("Unknown module \"%.*s\" to resolve the IP addresses\n"),length,candidate); + debuga(__FILE__,__LINE__,_("Unknown module \"%.*s\" to resolve the IP addresses\n"),length,candidate); exit(EXIT_FAILURE); } list=candidate+length; } } +/*! +Configure a module whose name is given as an argument. The parameters to configure +follow the module name after one or more space or tabs. + +\param module The name of the module, a space and the configuration options. +*/ +static void ip2name_configmodule(const char *module) +{ + int length; + unsigned int ModuleIdx; + + for (length=0 ; module[length] && (unsigned char)module[length]>' ' ; length++); + for (ModuleIdx=0 ; ModuleIdxConfigure) { + debuga(__FILE__,__LINE__,_("No option to configure for module %s\n"),ModulesList[ModuleIdx].Name); + exit(EXIT_FAILURE); + } + while (module[length] && (unsigned char)module[length]<=' ') length++; + ModulesList[ModuleIdx].Process->Configure(ModulesList[ModuleIdx].Name,module+length); + } + break; + } + } +} + /*! Configure a module to resolve an IP address into a name. @@ -124,11 +157,13 @@ int ip2name_config(const char *param) ip2name_buildmoduleslist(param); return(1); } - + // parameter for a module? if (*param=='_') { + ip2name_configmodule(param+1); + return(1); } - + return(0); } @@ -141,7 +176,7 @@ void ip2name_forcedns(void) int i; struct Ip2NameProcess *Chain; struct Ip2NameProcess *Last; - + // find the dns module for (i=0 ; i=LogLevel_Process) debuga(__FILE__,__LINE__,_("No known module to resolve an IP address using the DNS\n")); exit(EXIT_FAILURE); } - + // add the module to the list if it isn't there yet Last=NULL; for (Chain=FirstModule ; Chain && Chain!=DnsModule ; Chain=Chain->Next) { Last=Chain; } - if (debug) debuga(_("Chaining IP resolving module \"%s\"\n"),DnsModule->Name); + if (debug) debuga(__FILE__,__LINE__,_("Chaining IP resolving module \"%s\"\n"),DnsModule->Name); if (Last) Last->Next=DnsModule; else { @@ -182,13 +217,40 @@ void ip2name(char *ip,int ip_len) { struct Ip2NameProcess *Module; enum ip2name_retcode Status; - + const char *Name; + char OrigIp[80]; + + if (!KnownIp) { + KnownIp=Dichotomic_Create(); + if (!KnownIp) { + debuga(__FILE__,__LINE__,_("Not enough memory to store the names corresponding to the IP address\n")); + exit(EXIT_FAILURE); + } + } + + Name=Dichotomic_Search(KnownIp,ip); + if (Name) { + safe_strcpy(ip,Name,ip_len); + return; + } + + safe_strcpy(OrigIp,ip,sizeof(OrigIp)); for (Module=FirstModule ; Module ; Module=Module->Next) { if (Module->Resolve) { Status=Module->Resolve(ip,ip_len); - if (Status==INRC_Found) return; + if (Status==INRC_Found) break; } } + Dichotomic_Insert(KnownIp,OrigIp,ip); +} + +/*! +Release the memory allocated to resolve the IP addresses +into names. +*/ +void ip2name_cleanup(void) +{ + Dichotomic_Destroy(&KnownIp); } void name2ip(char *name,int name_size) @@ -214,14 +276,14 @@ void name2ip(char *name,int name_size) error=getaddrinfo(addr,NULL,NULL,&res); if (error) { freeaddrinfo(res); - debuga(_("Cannot resolve host name %s: %s\n"),name,gai_strerror(error)); + debuga(__FILE__,__LINE__,_("Cannot resolve host name %s: %s\n"),name,gai_strerror(error)); exit(EXIT_FAILURE); } if (res->ai_family==AF_INET) { struct sockaddr_in *s4=(struct sockaddr_in *)res->ai_addr; struct in_addr *sa=&s4->sin_addr; if (res->ai_addrlenai_addrlen,(int)sizeof(*s4)); + debuga(__FILE__,__LINE__,_("Short structure returned by getaddrinfo for an IPv4 address: %d bytes instead of %d\n"),res->ai_addrlen,(int)sizeof(*s4)); exit(EXIT_FAILURE); } inet_ntop(res->ai_family,sa,name,name_size); @@ -229,12 +291,12 @@ void name2ip(char *name,int name_size) struct sockaddr_in6 *s6=(struct sockaddr_in6 *)res->ai_addr; struct in6_addr *sa6=&s6->sin6_addr; if (res->ai_addrlenai_addrlen,(int)sizeof(*s6)); + debuga(__FILE__,__LINE__,_("Short structure returned by getaddrinfo for an IPv6 address: %d bytes instead of %d\n"),res->ai_addrlen,(int)sizeof(*s6)); exit(EXIT_FAILURE); } inet_ntop(res->ai_family,sa6,name,name_size); } else { - debuga(_("Invalid address type %d returned when resolving host name \"%s\"\n"),res->ai_family,name); + debuga(__FILE__,__LINE__,_("Invalid address type %d returned when resolving host name \"%s\"\n"),res->ai_family,name); } freeaddrinfo(res); #else @@ -258,7 +320,7 @@ void name2ip(char *name,int name_size) getword_start(&gwarea,inet_ntoa(ia)); if (getword(n4,sizeof(n4),&gwarea,'.')<0 || getword(n3,sizeof(n3),&gwarea,'.')<0 || getword(n2,sizeof(n2),&gwarea,'.')<0 || getword(n1,sizeof(n1),&gwarea,0)<0) { - printf("SARG: Maybe you have a broken record or garbage in your %s ip address.\n",gwarea.beginning); + debuga(__FILE__,__LINE__,_("Invalid IPv4 address \"%s\"\n"),gwarea.beginning); exit(EXIT_FAILURE); } snprintf(name,name_size,"%s.%s.%s.%s",n1,n2,n3,n4);