]> git.ipfire.org Git - thirdparty/sarg.git/blame - ip2name.c
Fix compilation error on Windows
[thirdparty/sarg.git] / ip2name.c
CommitLineData
25697a35 1/*
94ff9470 2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
61d965f3 3 * 1998, 2012
25697a35
GS
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
1164c474
FM
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
25697a35
GS
9 * ---------------------------------------------------------------------
10 *
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.
15 *
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.
20 *
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.
24 *
25 */
26
27#include "include/conf.h"
5f3cfd1d 28#include "include/defs.h"
51b166d4 29#include "include/ip2name.h"
0326d73b 30#include "include/dichotomic.h"
25697a35 31
51b166d4
FM
32//! Associate a name or alias to a module.
33struct Ip2NameModules
2846a495 34{
51b166d4
FM
35 //! The name of the module
36 const char *Name;
37 //! The structure to access the module functions.
38 struct Ip2NameProcess *Process;
2846a495
FM
39};
40
51b166d4
FM
41extern struct Ip2NameProcess Ip2NameDns;
42
43//! The list of the modules available to resolve an IP address into a name.
44static const struct Ip2NameModules ModulesList[]=
45{
46 {"dns",&Ip2NameDns},
47 {"yes",&Ip2NameDns},//for historical compatibility
48 {"no",NULL},//does nothing for compatibility with previous versions
49};
50
51//! The chain of the configured modules to try to resolve an IP.
52static struct Ip2NameProcess *FirstModule=NULL;
0326d73b
FM
53//! The list of the names found so far.
54static DichotomicObject KnownIp=NULL;
51b166d4 55
2846a495 56/*!
51b166d4
FM
57Add a new module to the list of the configured modules.
58*/
59static void ip2name_chainmodule(struct Ip2NameProcess *Module)
60{
61 struct Ip2NameProcess *Chain;
62 struct Ip2NameProcess *Last;
63
64 if (debug) debuga(_("Chaining IP resolving module \"%s\"\n"),Module->Name);
65
66 Last=NULL;
67 for (Chain=FirstModule ; Chain ; Chain=Chain->Next) {
68 if (Chain==Module) {
69 debuga(_("Ignoring duplicate module \"%s\" to resolve an IP address\n"),Module->Name);
70 return;
71 }
72 Last=Chain;
73 }
74
75 if (Last)
76 Last->Next=Module;
77 else {
78 FirstModule=Module;
79 Ip2Name=true;
80 }
81}
2846a495 82
51b166d4
FM
83/*!
84Add a new module to the list of the configured modules.
2846a495 85
51b166d4 86\param list The list of the modules name to chain.
2846a495 87*/
51b166d4 88static void ip2name_buildmoduleslist(const char *list)
9c7c6346 89{
51b166d4
FM
90 const char *candidate;
91 int length;
92 int ModuleIdx;
93
94 while (*list) {
95 candidate=list;
96 while (*candidate && (unsigned char)*candidate<=' ') candidate++;
97 for (length=0 ; (unsigned char)candidate[length]>' ' ; length++);
98 for (ModuleIdx=0 ; ModuleIdx<sizeof(ModulesList)/sizeof(*ModulesList) ; ModuleIdx++) {
99 if (strncasecmp(candidate,ModulesList[ModuleIdx].Name,length)==0 && ModulesList[ModuleIdx].Name[length]=='\0') {
100 // module found
101 if (ModulesList[ModuleIdx].Process)
102 ip2name_chainmodule(ModulesList[ModuleIdx].Process);
103 break;
104 }
105 }
106 if (ModuleIdx>=sizeof(ModulesList)/sizeof(*ModulesList)) {
107 debuga(_("Unknown module \"%.*s\" to resolve the IP addresses\n"),length,candidate);
108 exit(EXIT_FAILURE);
109 }
110 list=candidate+length;
111 }
112}
113
114/*!
115Configure a module to resolve an IP address into a name.
72c27633 116
51b166d4
FM
117\param param The parameter found in the configuration file.
118It always begins after the "resolv_ip".
119
120\retval 1 Parameter processed.
121\retval 0 Parameter ignored.
122*/
123int ip2name_config(const char *param)
124{
125 // module to add to the list
126 if (*param==' ') {
127 ip2name_buildmoduleslist(param);
128 return(1);
129 }
130
131 // parameter for a module?
132 if (*param=='_') {
9bd92830 133 }
51b166d4
FM
134
135 return(0);
136}
137
138/*!
139Require the use of the DNS to resolve the IP addresses.
140*/
141void ip2name_forcedns(void)
142{
143 struct Ip2NameProcess *DnsModule=NULL;
144 int i;
145 struct Ip2NameProcess *Chain;
146 struct Ip2NameProcess *Last;
147
148 // find the dns module
149 for (i=0 ; i<sizeof(ModulesList)/sizeof(*ModulesList) ; i++) {
150 if (strcmp("dns",ModulesList[i].Name)==0) {
151 // module found
152 DnsModule=ModulesList[i].Process;
153 break;
154 }
8fa27cb0 155 }
51b166d4
FM
156 if (!DnsModule) {
157 if (debugz) debuga(_("No known module to resolve an IP address using the DNS\n"));
158 exit(EXIT_FAILURE);
9bd92830 159 }
51b166d4
FM
160
161 // add the module to the list if it isn't there yet
162 Last=NULL;
163 for (Chain=FirstModule ; Chain && Chain!=DnsModule ; Chain=Chain->Next) {
164 Last=Chain;
2846a495 165 }
51b166d4
FM
166 if (debug) debuga(_("Chaining IP resolving module \"%s\"\n"),DnsModule->Name);
167 if (Last)
168 Last->Next=DnsModule;
169 else {
170 FirstModule=DnsModule;
171 Ip2Name=true;
9bd92830 172 }
2846a495
FM
173}
174
175/*!
176Convert an IP address into a name.
177
178\param ip The IP address. It is replaced by the corresponding name if one
179can be found.
180\param ip_len The length of the \c ip buffer.
51b166d4
FM
181
182The function does nothing if no module are configured.
2846a495
FM
183*/
184void ip2name(char *ip,int ip_len)
185{
51b166d4 186 struct Ip2NameProcess *Module;
2846a495 187 enum ip2name_retcode Status;
0326d73b
FM
188 const char *Name;
189 char OrigIp[80];
190
191 if (!KnownIp) {
192 KnownIp=Dichotomic_Create();
193 if (!KnownIp) {
194 debuga(_("Not enough memory to store the names corresponding to the IP address\n"));
195 exit(EXIT_FAILURE);
196 }
197 }
198
199 Name=Dichotomic_Search(KnownIp,ip);
200 if (Name) {
201 safe_strcpy(ip,Name,ip_len);
202 return;
203 }
2846a495 204
0326d73b 205 safe_strcpy(OrigIp,ip,sizeof(OrigIp));
51b166d4
FM
206 for (Module=FirstModule ; Module ; Module=Module->Next) {
207 if (Module->Resolve) {
208 Status=Module->Resolve(ip,ip_len);
0326d73b 209 if (Status==INRC_Found) break;
51b166d4
FM
210 }
211 }
0326d73b
FM
212 Dichotomic_Insert(KnownIp,OrigIp,ip);
213}
214
215/*!
216Release the memory allocated to resolve the IP addresses
217into names.
218*/
219void ip2name_cleanup(void)
220{
221 Dichotomic_Destroy(&KnownIp);
936c9905 222}
25697a35 223
4afbb7a5 224void name2ip(char *name,int name_size)
9c7c6346 225{
4afbb7a5
FM
226#ifdef HAVE_GETADDRINFO
227 int error;
228 char *port;
229 struct addrinfo *res;
230 char *addr;
231
232 addr=name;
233 if (name[0]=='[') { //IPv6 address
234 port=strchr(name,']');
235 if (port) { //confirmed IPv6 address
236 *port='\0';
237 addr++;
238 }
239 } else { //IPv4 address
240 port=strchr(name,':');
241 if (port) *port='\0';
242 }
243
244 error=getaddrinfo(addr,NULL,NULL,&res);
245 if (error) {
246 freeaddrinfo(res);
247 debuga(_("Cannot resolve host name %s: %s\n"),name,gai_strerror(error));
248 exit(EXIT_FAILURE);
249 }
250 if (res->ai_family==AF_INET) {
251 struct sockaddr_in *s4=(struct sockaddr_in *)res->ai_addr;
252 struct in_addr *sa=&s4->sin_addr;
253 if (res->ai_addrlen<sizeof(*s4)) {
45d00862 254 debuga(_("Short structure returned by getaddrinfo for an IPv4 address: %d bytes instead of %d\n"),res->ai_addrlen,(int)sizeof(*s4));
4afbb7a5
FM
255 exit(EXIT_FAILURE);
256 }
257 inet_ntop(res->ai_family,sa,name,name_size);
258 } else if (res->ai_family==AF_INET6) {
259 struct sockaddr_in6 *s6=(struct sockaddr_in6 *)res->ai_addr;
260 struct in6_addr *sa6=&s6->sin6_addr;
261 if (res->ai_addrlen<sizeof(*s6)) {
45d00862 262 debuga(_("Short structure returned by getaddrinfo for an IPv6 address: %d bytes instead of %d\n"),res->ai_addrlen,(int)sizeof(*s6));
4afbb7a5
FM
263 exit(EXIT_FAILURE);
264 }
265 inet_ntop(res->ai_family,sa6,name,name_size);
266 } else {
267 debuga(_("Invalid address type %d returned when resolving host name \"%s\"\n"),res->ai_family,name);
268 }
269 freeaddrinfo(res);
270#else
9bd92830
FM
271 struct in_addr ia;
272 struct hostent *hp;
273 char *port;
274 char n1[4];
275 char n2[4];
276 char n3[4];
277 char n4[4];
278 struct getwordstruct gwarea;
25697a35 279
9bd92830 280 port=strchr(name,':');
4afbb7a5 281 if (port) *port='\0';
25697a35 282
9bd92830
FM
283 if((hp=gethostbyname(name))==NULL)
284 return;
9c7c6346 285
9bd92830
FM
286 memcpy(&ia.s_addr,hp->h_addr_list[0],sizeof(ia.s_addr));
287 ia.s_addr=ntohl(ia.s_addr);
288 getword_start(&gwarea,inet_ntoa(ia));
289 if (getword(n4,sizeof(n4),&gwarea,'.')<0 || getword(n3,sizeof(n3),&gwarea,'.')<0 ||
007905af 290 getword(n2,sizeof(n2),&gwarea,'.')<0 || getword(n1,sizeof(n1),&gwarea,0)<0) {
9bd92830
FM
291 printf("SARG: Maybe you have a broken record or garbage in your %s ip address.\n",gwarea.beginning);
292 exit(EXIT_FAILURE);
293 }
4afbb7a5
FM
294 snprintf(name,name_size,"%s.%s.%s.%s",n1,n2,n3,n4);
295#endif
25697a35 296
9bd92830 297 return;
9c7c6346 298}