]> git.ipfire.org Git - thirdparty/sarg.git/blob - ip2name.c
59840050e6a88de0fc4b28d67157521b7c529d62
[thirdparty/sarg.git] / ip2name.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2011
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
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"
28 #include "include/defs.h"
29 #ifdef HAVE_WS2TCPIP_H
30 #include <ws2tcpip.h> //define getnameinfo on windows
31 #endif
32
33 void ip2name(char *ip,int ip_len)
34 {
35 #ifdef HAVE_GETNAMEINFO
36 struct sockaddr_storage sa;
37 int sockaddr_size;
38 char host[NI_MAXHOST];
39 int n1,n2,n3,n4,next=0;
40 int error;
41
42 memset(&sa,0,sizeof(sa));
43 if (sscanf(ip,"%d.%d.%d.%d%n",&n1,&n2,&n3,&n4,&next)==4 && ip[next]=='\0') {
44 struct sockaddr_in *s4=(struct sockaddr_in *)&sa;
45 if (inet_pton(AF_INET,ip,&s4->sin_addr)!=1) return;
46 sa.ss_family=AF_INET;
47 sockaddr_size=sizeof(*s4);
48 } else {
49 struct sockaddr_in6 *s6=(struct sockaddr_in6 *)&sa;
50 if (inet_pton(AF_INET6,ip,&s6->sin6_addr)!=1) return;
51 sa.ss_family=AF_INET6;
52 sockaddr_size=sizeof(*s6);
53 }
54 #ifdef HAVE_SOCKADDR_SA_LEN
55 sa.ss_len=sockaddr_size;
56 #endif
57 error=getnameinfo((struct sockaddr *)&sa,sockaddr_size,host,sizeof(host),NULL,0,0);
58 if (error==EAI_AGAIN) {
59 /*
60 This is a temporary failure. According to the man page we should try again but
61 it doesn't say if the program should wait before trying again nor how many attempts
62 before it becomes a fatal error. I could find no clues on internet so I try once and
63 leave it at that. Considering the number of IP addresses to resolve and the absence
64 of serious consequences should some IP fail to be resolved properly, it is best
65 not waste too much time on this.
66 */
67 error=getnameinfo((struct sockaddr *)&sa,sizeof(sa),host,sizeof(host),NULL,0,0);
68 }
69 if (error==0) {
70 safe_strcpy(ip,host,ip_len);
71 } else {
72 debuga(_("IP to name resolution (getnameinfo) on IP address %s failed with error %d - %s\n"),ip,error,gai_strerror(error));
73 }
74 #else
75 struct in_addr addr;
76 struct hostent *hp;
77 char **p;
78
79 #ifdef HAVE_INET_ATON
80 if (inet_aton(ip,&addr) == 0)
81 return;
82 #else
83 addr.s_addr=inet_addr(ip);
84 if (addr.s_addr==-1) return;
85 #endif
86
87 hp = gethostbyaddr((void *)&addr, sizeof (addr), AF_INET);
88 if (hp == NULL)
89 return;
90
91 for (p = hp->h_addr_list; *p != 0; p++) {
92 struct in_addr in;
93
94 (void) memcpy(&in.s_addr, *p, sizeof (in.s_addr));
95 safe_strcpy(ip,hp->h_name,ip_len);
96 }
97 #endif
98 return;
99 }
100
101 void name2ip(char *name,int name_size)
102 {
103 #ifdef HAVE_GETADDRINFO
104 int error;
105 char *port;
106 struct addrinfo *res;
107 char *addr;
108
109 addr=name;
110 if (name[0]=='[') { //IPv6 address
111 port=strchr(name,']');
112 if (port) { //confirmed IPv6 address
113 *port='\0';
114 addr++;
115 }
116 } else { //IPv4 address
117 port=strchr(name,':');
118 if (port) *port='\0';
119 }
120
121 error=getaddrinfo(addr,NULL,NULL,&res);
122 if (error) {
123 freeaddrinfo(res);
124 debuga(_("Cannot resolve host name %s: %s\n"),name,gai_strerror(error));
125 exit(EXIT_FAILURE);
126 }
127 if (res->ai_family==AF_INET) {
128 struct sockaddr_in *s4=(struct sockaddr_in *)res->ai_addr;
129 struct in_addr *sa=&s4->sin_addr;
130 if (res->ai_addrlen<sizeof(*s4)) {
131 debuga(_("Short structure returned by getaddrinfo for an IPv4 address: %d bytes instead of %d\n"),res->ai_addrlen,(int)sizeof(*s4));
132 exit(EXIT_FAILURE);
133 }
134 inet_ntop(res->ai_family,sa,name,name_size);
135 } else if (res->ai_family==AF_INET6) {
136 struct sockaddr_in6 *s6=(struct sockaddr_in6 *)res->ai_addr;
137 struct in6_addr *sa6=&s6->sin6_addr;
138 if (res->ai_addrlen<sizeof(*s6)) {
139 debuga(_("Short structure returned by getaddrinfo for an IPv6 address: %d bytes instead of %d\n"),res->ai_addrlen,(int)sizeof(*s6));
140 exit(EXIT_FAILURE);
141 }
142 inet_ntop(res->ai_family,sa6,name,name_size);
143 } else {
144 debuga(_("Invalid address type %d returned when resolving host name \"%s\"\n"),res->ai_family,name);
145 }
146 freeaddrinfo(res);
147 #else
148 struct in_addr ia;
149 struct hostent *hp;
150 char *port;
151 char n1[4];
152 char n2[4];
153 char n3[4];
154 char n4[4];
155 struct getwordstruct gwarea;
156
157 port=strchr(name,':');
158 if (port) *port='\0';
159
160 if((hp=gethostbyname(name))==NULL)
161 return;
162
163 memcpy(&ia.s_addr,hp->h_addr_list[0],sizeof(ia.s_addr));
164 ia.s_addr=ntohl(ia.s_addr);
165 getword_start(&gwarea,inet_ntoa(ia));
166 if (getword(n4,sizeof(n4),&gwarea,'.')<0 || getword(n3,sizeof(n3),&gwarea,'.')<0 ||
167 getword(n2,sizeof(n2),&gwarea,'.')<0 || getword(n1,sizeof(n1),&gwarea,0)<0) {
168 printf("SARG: Maybe you have a broken record or garbage in your %s ip address.\n",gwarea.beginning);
169 exit(EXIT_FAILURE);
170 }
171 snprintf(name,name_size,"%s.%s.%s.%s",n1,n2,n3,n4);
172 #endif
173
174 return;
175 }