1 /*
2    webresolve.c
3 
4    Copyright (C) 2000-2002  Ulric Eriksson <ulric@siag.nu>
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19    MA 02111-1307, USA.
20  */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <netdb.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
31 
32 /* The cache is implemented as a linked list, based on the assumption that
33    we will usually want to get the most recently inserted items.
34 */
35 typedef struct ip_cache {
36 	char *ip;
37 	char *host;
38 	struct ip_cache *next;
39 } ip_cache;
40 
41 static ip_cache *cache = NULL;
42 
mmalloc(size_t n)43 static void *mmalloc(size_t n)
44 {
45 	void *p = malloc(n);
46 	if (!p) {
47 		fprintf(stderr, "Can't allocate %ld bytes\n", (long)n);
48 		exit(1);
49 	}
50 	return p;
51 }
52 
lookup_ip(char * ip)53 static ip_cache *lookup_ip(char *ip)
54 {
55 	ip_cache *c;
56 
57 	for (c = cache; c; c = c->next)
58 		if (!strcmp(ip, c->ip)) return c;
59 	return NULL;
60 }
61 
reverse_lookup(char * ip)62 static char *reverse_lookup(char *ip)
63 {
64 	char *host;
65 	struct hostent *hp;
66 #ifdef HAVE_INET_ATON
67 	struct in_addr in;
68 #endif
69 	ip_cache *c;
70 	if (!isdigit((int)*ip)) return ip;
71 	c = lookup_ip(ip);
72 	if (c) return c->host;
73 #ifdef HAVE_INET_ATON
74 	inet_aton(ip, &in);
75 	hp = gethostbyaddr((char *)&in.s_addr, sizeof(in.s_addr), AF_INET);
76 #else
77 	hp = gethostbyname(ip);
78 	hp = gethostbyaddr(hp->h_addr, hp->h_length, AF_INET);
79 #endif
80 	if (hp) host = hp->h_name;
81 	else host = ip;
82 	c = mmalloc(sizeof *c);
83 	c->host = mmalloc(strlen(host)+1);
84 	c->ip = mmalloc(strlen(ip)+1);
85 	strcpy(c->host, host);
86 	strcpy(c->ip, ip);
87 	c->next = cache;
88 	cache = c;
89 	return c->host;
90 }
91 
main(void)92 int main(void)
93 {
94 	char b[1024], ip[1024], rest[1024];
95 
96 	while (fgets(b, sizeof b, stdin)) {
97 		sscanf(b, "%s %[^\n]", ip, rest);
98 		printf("%s %s\n", reverse_lookup(ip), rest);
99 	}
100 	return 0;
101 }
102 
103