2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
27 #include "include/conf.h"
28 #include "include/defs.h"
29 #include "include/ip2name.h"
30 #include "include/dichotomic.h"
32 //! Associate a name or alias to a module.
35 //! The name of the module
37 //! The structure to access the module functions.
38 struct Ip2NameProcess
*Process
;
41 extern struct Ip2NameProcess Ip2NameDns
;
42 extern struct Ip2NameProcess Ip2NameExec
;
44 //! The list of the modules available to resolve an IP address into a name.
45 static const struct Ip2NameModules ModulesList
[]=
48 {"exec",&Ip2NameExec
},
49 {"yes",&Ip2NameDns
},//for historical compatibility
50 {"no",NULL
},//does nothing for compatibility with previous versions
53 //! The chain of the configured modules to try to resolve an IP.
54 static struct Ip2NameProcess
*FirstModule
=NULL
;
55 //! The list of the names found so far.
56 static DichotomicObject KnownIp
=NULL
;
59 Add a new module to the list of the configured modules.
61 static void ip2name_chainmodule(struct Ip2NameProcess
*Module
)
63 struct Ip2NameProcess
*Chain
;
64 struct Ip2NameProcess
*Last
;
66 if (debug
) debuga(_("Chaining IP resolving module \"%s\"\n"),Module
->Name
);
69 for (Chain
=FirstModule
; Chain
; Chain
=Chain
->Next
) {
71 debuga(_("Ignoring duplicate module \"%s\" to resolve an IP address\n"),Module
->Name
);
86 Add a new module to the list of the configured modules.
88 \param list The list of the modules name to chain.
90 static void ip2name_buildmoduleslist(const char *list
)
92 const char *candidate
;
98 while (*candidate
&& (unsigned char)*candidate
<=' ') candidate
++;
99 for (length
=0 ; (unsigned char)candidate
[length
]>' ' ; length
++);
100 for (ModuleIdx
=0 ; ModuleIdx
<sizeof(ModulesList
)/sizeof(*ModulesList
) ; ModuleIdx
++) {
101 if (strncasecmp(candidate
,ModulesList
[ModuleIdx
].Name
,length
)==0 && ModulesList
[ModuleIdx
].Name
[length
]=='\0') {
103 if (ModulesList
[ModuleIdx
].Process
)
104 ip2name_chainmodule(ModulesList
[ModuleIdx
].Process
);
108 if (ModuleIdx
>=sizeof(ModulesList
)/sizeof(*ModulesList
)) {
109 debuga(_("Unknown module \"%.*s\" to resolve the IP addresses\n"),length
,candidate
);
112 list
=candidate
+length
;
117 Configure a module whose name is given as an argument. The parameters to configure
118 follow the module name after one or more space or tabs.
120 \param module The name of the module, a space and the configuration options.
122 static void ip2name_configmodule(const char *module
)
125 unsigned int ModuleIdx
;
127 for (length
=0 ; module
[length
] && (unsigned char)module
[length
]>' ' ; length
++);
128 for (ModuleIdx
=0 ; ModuleIdx
<sizeof(ModulesList
)/sizeof(*ModulesList
) ; ModuleIdx
++) {
129 if (strncasecmp(module
,ModulesList
[ModuleIdx
].Name
,length
)==0 && ModulesList
[ModuleIdx
].Name
[length
]=='\0') {
131 if (ModulesList
[ModuleIdx
].Process
) {
132 if (!ModulesList
[ModuleIdx
].Process
->Configure
) {
133 debuga(_("No option to configure for module %s\n"),ModulesList
[ModuleIdx
].Name
);
136 while (module
[length
] && (unsigned char)module
[length
]<=' ') length
++;
137 ModulesList
[ModuleIdx
].Process
->Configure(ModulesList
[ModuleIdx
].Name
,module
+length
);
145 Configure a module to resolve an IP address into a name.
147 \param param The parameter found in the configuration file.
148 It always begins after the "resolv_ip".
150 \retval 1 Parameter processed.
151 \retval 0 Parameter ignored.
153 int ip2name_config(const char *param
)
155 // module to add to the list
157 ip2name_buildmoduleslist(param
);
161 // parameter for a module?
163 ip2name_configmodule(param
+1);
171 Require the use of the DNS to resolve the IP addresses.
173 void ip2name_forcedns(void)
175 struct Ip2NameProcess
*DnsModule
=NULL
;
177 struct Ip2NameProcess
*Chain
;
178 struct Ip2NameProcess
*Last
;
180 // find the dns module
181 for (i
=0 ; i
<sizeof(ModulesList
)/sizeof(*ModulesList
) ; i
++) {
182 if (strcmp("dns",ModulesList
[i
].Name
)==0) {
184 DnsModule
=ModulesList
[i
].Process
;
189 if (debugz
) debuga(_("No known module to resolve an IP address using the DNS\n"));
193 // add the module to the list if it isn't there yet
195 for (Chain
=FirstModule
; Chain
&& Chain
!=DnsModule
; Chain
=Chain
->Next
) {
198 if (debug
) debuga(_("Chaining IP resolving module \"%s\"\n"),DnsModule
->Name
);
200 Last
->Next
=DnsModule
;
202 FirstModule
=DnsModule
;
208 Convert an IP address into a name.
210 \param ip The IP address. It is replaced by the corresponding name if one
212 \param ip_len The length of the \c ip buffer.
214 The function does nothing if no module are configured.
216 void ip2name(char *ip
,int ip_len
)
218 struct Ip2NameProcess
*Module
;
219 enum ip2name_retcode Status
;
224 KnownIp
=Dichotomic_Create();
226 debuga(_("Not enough memory to store the names corresponding to the IP address\n"));
231 Name
=Dichotomic_Search(KnownIp
,ip
);
233 safe_strcpy(ip
,Name
,ip_len
);
237 safe_strcpy(OrigIp
,ip
,sizeof(OrigIp
));
238 for (Module
=FirstModule
; Module
; Module
=Module
->Next
) {
239 if (Module
->Resolve
) {
240 Status
=Module
->Resolve(ip
,ip_len
);
241 if (Status
==INRC_Found
) break;
244 Dichotomic_Insert(KnownIp
,OrigIp
,ip
);
248 Release the memory allocated to resolve the IP addresses
251 void ip2name_cleanup(void)
253 Dichotomic_Destroy(&KnownIp
);
256 void name2ip(char *name
,int name_size
)
258 #ifdef HAVE_GETADDRINFO
261 struct addrinfo
*res
;
265 if (name
[0]=='[') { //IPv6 address
266 port
=strchr(name
,']');
267 if (port
) { //confirmed IPv6 address
271 } else { //IPv4 address
272 port
=strchr(name
,':');
273 if (port
) *port
='\0';
276 error
=getaddrinfo(addr
,NULL
,NULL
,&res
);
279 debuga(_("Cannot resolve host name %s: %s\n"),name
,gai_strerror(error
));
282 if (res
->ai_family
==AF_INET
) {
283 struct sockaddr_in
*s4
=(struct sockaddr_in
*)res
->ai_addr
;
284 struct in_addr
*sa
=&s4
->sin_addr
;
285 if (res
->ai_addrlen
<sizeof(*s4
)) {
286 debuga(_("Short structure returned by getaddrinfo for an IPv4 address: %d bytes instead of %d\n"),res
->ai_addrlen
,(int)sizeof(*s4
));
289 inet_ntop(res
->ai_family
,sa
,name
,name_size
);
290 } else if (res
->ai_family
==AF_INET6
) {
291 struct sockaddr_in6
*s6
=(struct sockaddr_in6
*)res
->ai_addr
;
292 struct in6_addr
*sa6
=&s6
->sin6_addr
;
293 if (res
->ai_addrlen
<sizeof(*s6
)) {
294 debuga(_("Short structure returned by getaddrinfo for an IPv6 address: %d bytes instead of %d\n"),res
->ai_addrlen
,(int)sizeof(*s6
));
297 inet_ntop(res
->ai_family
,sa6
,name
,name_size
);
299 debuga(_("Invalid address type %d returned when resolving host name \"%s\"\n"),res
->ai_family
,name
);
310 struct getwordstruct gwarea
;
312 port
=strchr(name
,':');
313 if (port
) *port
='\0';
315 if((hp
=gethostbyname(name
))==NULL
)
318 memcpy(&ia
.s_addr
,hp
->h_addr_list
[0],sizeof(ia
.s_addr
));
319 ia
.s_addr
=ntohl(ia
.s_addr
);
320 getword_start(&gwarea
,inet_ntoa(ia
));
321 if (getword(n4
,sizeof(n4
),&gwarea
,'.')<0 || getword(n3
,sizeof(n3
),&gwarea
,'.')<0 ||
322 getword(n2
,sizeof(n2
),&gwarea
,'.')<0 || getword(n1
,sizeof(n1
),&gwarea
,0)<0) {
323 printf("SARG: Maybe you have a broken record or garbage in your %s ip address.\n",gwarea
.beginning
);
326 snprintf(name
,name_size
,"%s.%s.%s.%s",n1
,n2
,n3
,n4
);