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