2 * support/export/hostname.c
4 * Functions for hostname.
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
23 #define xmalloc malloc
29 #define ALIGNMENT sizeof (char *)
32 align (int len, int al)
42 get_hostent (const char *addr, int len, int type)
49 int len_aliases = sizeof (char *);
50 int num_addr_list = 1;
51 int len_addr_list = sizeof (char *);
58 ipv4 = (struct in_addr *) addr;
59 name = inet_ntoa (*ipv4);
66 len_ent = align (sizeof (*cp), ALIGNMENT);
67 len_name = align (strlen (name) + 1, ALIGNMENT);
70 len_addr_list += align (len, ALIGNMENT) + sizeof (char *);
72 cp = (struct hostent *) xmalloc (len_ent + len_name + len_aliases
75 cp->h_addrtype = type;
78 cp->h_name = (char *) &(((char *) cp) [pos]);
79 strcpy (cp->h_name, name);
82 cp->h_aliases = (char **) &(((char *) cp) [pos]);
83 pos += num_aliases * sizeof (char *);
84 cp->h_aliases [0] = NULL;
86 pos = len_ent + len_name + len_aliases;
87 cp->h_addr_list = (char **) &(((char *) cp) [pos]);
88 pos += num_addr_list * sizeof (char *);
89 cp->h_addr_list [0] = (char *) &(((char *) cp) [pos]);
90 memcpy (cp->h_addr_list [0], addr, cp->h_length);
91 pos += align (cp->h_length, ALIGNMENT);
92 cp->h_addr_list [1] = NULL;
98 hostent_dup (struct hostent *hp)
100 int len_ent = align (sizeof (*hp), ALIGNMENT);
101 int len_name = align (strlen (hp->h_name) + 1, ALIGNMENT);
103 int len_aliases = sizeof (char *);
104 int num_addr_list = 1;
105 int len_addr_list = sizeof (char *);
110 for (sp = hp->h_aliases; sp && *sp; sp++)
113 len_aliases += align (strlen (*sp) + 1, ALIGNMENT)
117 for (sp = hp->h_addr_list; *sp; sp++)
120 len_addr_list += align (hp->h_length, ALIGNMENT)
124 cp = (struct hostent *) xmalloc (len_ent + len_name + len_aliases
129 cp->h_name = (char *) &(((char *) cp) [pos]);
130 strcpy (cp->h_name, hp->h_name);
133 cp->h_aliases = (char **) &(((char *) cp) [pos]);
134 pos += num_aliases * sizeof (char *);
135 for (sp = hp->h_aliases, i = 0; i < num_aliases; i++, sp++)
138 cp->h_aliases [i] = (char *) &(((char *) cp) [pos]);
139 strcpy (cp->h_aliases [i], *sp);
140 pos += align (strlen (*sp) + 1, ALIGNMENT);
143 cp->h_aliases [i] = NULL;
145 pos = len_ent + len_name + len_aliases;
146 cp->h_addr_list = (char **) &(((char *) cp) [pos]);
147 pos += num_addr_list * sizeof (char *);
148 for (sp = hp->h_addr_list, i = 0; i < num_addr_list; i++, sp++)
151 cp->h_addr_list [i] = (char *) &(((char *) cp) [pos]);
152 memcpy (cp->h_addr_list [i], *sp, hp->h_length);
153 pos += align (hp->h_length, ALIGNMENT);
156 cp->h_addr_list [i] = *sp;
162 is_hostname(const char *sp)
164 if (*sp == '\0' || *sp == '@')
169 if (*sp == '*' || *sp == '?' || *sp == '[' || *sp == '/')
171 if (*sp == '\\' && sp[1])
179 matchhostname (const char *h1, const char *h2)
181 struct hostent *hp1, *hp2;
184 if (strcasecmp (h1, h2) == 0)
187 if (!is_hostname (h1) || !is_hostname (h2))
190 hp1 = gethostbyname (h1);
194 hp1 = hostent_dup (hp1);
196 hp2 = gethostbyname (h2);
199 if (strcasecmp (hp1->h_name, hp2->h_name) == 0)
206 for (ap1 = hp1->h_addr_list; *ap1 && status == 0; ap1++)
207 for (ap2 = hp2->h_addr_list; *ap2; ap2++)
208 if (memcmp (*ap1, *ap2, sizeof (struct in_addr)) == 0)
223 /* Map IP to hostname, and then map back to addr to make sure it is a
227 get_reliable_hostbyaddr(const char *addr, int len, int type)
229 struct hostent *hp = NULL;
231 struct hostent *reverse;
232 struct hostent *forward;
235 reverse = gethostbyaddr (addr, len, type);
239 /* must make sure the hostent is authorative. */
241 reverse = hostent_dup (reverse);
242 forward = gethostbyname (reverse->h_name);
245 /* now make sure the "addr" is in the list */
246 for (sp = forward->h_addr_list ; *sp ; sp++) {
247 if (memcmp (*sp, addr, forward->h_length) == 0)
253 hp = hostent_dup (forward);
257 xlog (L_WARNING, "Fake hostname %s for %s - forward lookup doesn't match reverse",
258 reverse->h_name, inet_ntoa(*(struct in_addr*)addr));
262 /* never heard of it. misconfigured DNS? */
263 xlog (L_WARNING, "Fake hostname %s for %s - forward lookup doesn't exist",
264 reverse->h_name, inet_ntoa(*(struct in_addr*)addr));
274 print_host (struct hostent *hp)
280 printf ("official hostname: %s\n", hp->h_name);
281 printf ("aliases:\n");
282 for (sp = hp->h_aliases; *sp; sp++)
283 printf (" %s\n", *sp);
284 printf ("IP addresses:\n");
285 for (sp = hp->h_addr_list; *sp; sp++)
286 printf (" %s\n", inet_ntoa (*(struct in_addr *) *sp));
289 printf ("Not host information\n");
293 main (int argc, char **argv)
295 struct hostent *hp = gethostbyname (argv [1]);
303 cp = hostent_dup (hp);
307 printf ("127.0.0.1 == %s: %d\n", argv [1],
308 matchhostname ("127.0.0.1", argv [1]));
309 addr.s_addr = inet_addr(argv [2]);
310 printf ("%s\n", inet_ntoa (addr));
311 cp = get_hostent ((const char *)&addr, sizeof(addr), AF_INET);