12aef6930SMark Murray /*
22aef6930SMark Murray * This module determines the type of socket (datagram, stream), the client
32aef6930SMark Murray * socket address and port, the server socket address and port. In addition,
42aef6930SMark Murray * it provides methods to map a transport address to a printable host name
52aef6930SMark Murray * or address. Socket address information results are in static memory.
62aef6930SMark Murray *
72aef6930SMark Murray * The result from the hostname lookup method is STRING_PARANOID when a host
82aef6930SMark Murray * pretends to have someone elses name, or when a host name is available but
92aef6930SMark Murray * could not be verified.
102aef6930SMark Murray *
112aef6930SMark Murray * When lookup or conversion fails the result is set to STRING_UNKNOWN.
122aef6930SMark Murray *
132aef6930SMark Murray * Diagnostics are reported through syslog(3).
142aef6930SMark Murray *
152aef6930SMark Murray * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
168053080cSYoshinobu Inoue *
178053080cSYoshinobu Inoue * $FreeBSD$
182aef6930SMark Murray */
192aef6930SMark Murray
202aef6930SMark Murray #ifndef lint
212aef6930SMark Murray static char sccsid[] = "@(#) socket.c 1.15 97/03/21 19:27:24";
222aef6930SMark Murray #endif
232aef6930SMark Murray
242aef6930SMark Murray /* System libraries. */
252aef6930SMark Murray
262aef6930SMark Murray #include <sys/types.h>
272aef6930SMark Murray #include <sys/param.h>
282aef6930SMark Murray #include <sys/socket.h>
292aef6930SMark Murray #include <netinet/in.h>
302aef6930SMark Murray #include <netdb.h>
312aef6930SMark Murray #include <stdio.h>
322aef6930SMark Murray #include <syslog.h>
332aef6930SMark Murray #include <string.h>
342aef6930SMark Murray
354f101318SHajimu UMEMOTO #ifndef INET6
362aef6930SMark Murray extern char *inet_ntoa();
37b208ff84SHajimu UMEMOTO #endif
382aef6930SMark Murray
392aef6930SMark Murray /* Local stuff. */
402aef6930SMark Murray
412aef6930SMark Murray #include "tcpd.h"
422aef6930SMark Murray
432aef6930SMark Murray /* Forward declarations. */
442aef6930SMark Murray
45068ad27dSBrooks Davis static void sock_sink(int);
462aef6930SMark Murray
472aef6930SMark Murray #ifdef APPEND_DOT
482aef6930SMark Murray
492aef6930SMark Murray /*
502aef6930SMark Murray * Speed up DNS lookups by terminating the host name with a dot. Should be
512aef6930SMark Murray * done with care. The speedup can give problems with lookups from sources
522aef6930SMark Murray * that lack DNS-style trailing dot magic, such as local files or NIS maps.
532aef6930SMark Murray */
542aef6930SMark Murray
gethostbyname_dot(char * name)55*14f102eaSEd Maste static struct hostent *gethostbyname_dot(char *name)
562aef6930SMark Murray {
572aef6930SMark Murray char dot_name[MAXHOSTNAMELEN + 1];
582aef6930SMark Murray
592aef6930SMark Murray /*
602aef6930SMark Murray * Don't append dots to unqualified names. Such names are likely to come
612aef6930SMark Murray * from local hosts files or from NIS.
622aef6930SMark Murray */
632aef6930SMark Murray
642aef6930SMark Murray if (strchr(name, '.') == 0 || strlen(name) >= MAXHOSTNAMELEN - 1) {
652aef6930SMark Murray return (gethostbyname(name));
662aef6930SMark Murray } else {
672aef6930SMark Murray sprintf(dot_name, "%s.", name);
682aef6930SMark Murray return (gethostbyname(dot_name));
692aef6930SMark Murray }
702aef6930SMark Murray }
712aef6930SMark Murray
722aef6930SMark Murray #define gethostbyname gethostbyname_dot
732aef6930SMark Murray #endif
742aef6930SMark Murray
752aef6930SMark Murray /* sock_host - look up endpoint addresses and install conversion methods */
762aef6930SMark Murray
sock_host(struct request_info * request)77*14f102eaSEd Maste void sock_host(struct request_info *request)
782aef6930SMark Murray {
798053080cSYoshinobu Inoue #ifdef INET6
808053080cSYoshinobu Inoue static struct sockaddr_storage client;
818053080cSYoshinobu Inoue static struct sockaddr_storage server;
828053080cSYoshinobu Inoue #else
832aef6930SMark Murray static struct sockaddr_in client;
842aef6930SMark Murray static struct sockaddr_in server;
858053080cSYoshinobu Inoue #endif
862aef6930SMark Murray int len;
872aef6930SMark Murray char buf[BUFSIZ];
882aef6930SMark Murray int fd = request->fd;
892aef6930SMark Murray
902aef6930SMark Murray sock_methods(request);
912aef6930SMark Murray
922aef6930SMark Murray /*
932aef6930SMark Murray * Look up the client host address. Hal R. Brand <BRAND@addvax.llnl.gov>
942aef6930SMark Murray * suggested how to get the client host info in case of UDP connections:
952aef6930SMark Murray * peek at the first message without actually looking at its contents. We
962aef6930SMark Murray * really should verify that client.sin_family gets the value AF_INET,
972aef6930SMark Murray * but this program has already caused too much grief on systems with
982aef6930SMark Murray * broken library code.
992aef6930SMark Murray */
1002aef6930SMark Murray
1012aef6930SMark Murray len = sizeof(client);
1022aef6930SMark Murray if (getpeername(fd, (struct sockaddr *) & client, &len) < 0) {
1032aef6930SMark Murray request->sink = sock_sink;
1042aef6930SMark Murray len = sizeof(client);
1052aef6930SMark Murray if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK,
1062aef6930SMark Murray (struct sockaddr *) & client, &len) < 0) {
1072aef6930SMark Murray tcpd_warn("can't get client address: %m");
1082aef6930SMark Murray return; /* give up */
1092aef6930SMark Murray }
1102aef6930SMark Murray #ifdef really_paranoid
111c0b3834dSCeri Davies memset(buf, 0, sizeof(buf));
1122aef6930SMark Murray #endif
1132aef6930SMark Murray }
1148053080cSYoshinobu Inoue #ifdef INET6
1158053080cSYoshinobu Inoue request->client->sin = (struct sockaddr *)&client;
1168053080cSYoshinobu Inoue #else
1172aef6930SMark Murray request->client->sin = &client;
1188053080cSYoshinobu Inoue #endif
1192aef6930SMark Murray
1202aef6930SMark Murray /*
1212aef6930SMark Murray * Determine the server binding. This is used for client username
1222aef6930SMark Murray * lookups, and for access control rules that trigger on the server
1232aef6930SMark Murray * address or name.
1242aef6930SMark Murray */
1252aef6930SMark Murray
1262aef6930SMark Murray len = sizeof(server);
1272aef6930SMark Murray if (getsockname(fd, (struct sockaddr *) & server, &len) < 0) {
1282aef6930SMark Murray tcpd_warn("getsockname: %m");
1292aef6930SMark Murray return;
1302aef6930SMark Murray }
1318053080cSYoshinobu Inoue #ifdef INET6
1328053080cSYoshinobu Inoue request->server->sin = (struct sockaddr *)&server;
1338053080cSYoshinobu Inoue #else
1342aef6930SMark Murray request->server->sin = &server;
1358053080cSYoshinobu Inoue #endif
1362aef6930SMark Murray }
1372aef6930SMark Murray
1382aef6930SMark Murray /* sock_hostaddr - map endpoint address to printable form */
1392aef6930SMark Murray
sock_hostaddr(struct host_info * host)140*14f102eaSEd Maste void sock_hostaddr(struct host_info *host)
1412aef6930SMark Murray {
1428053080cSYoshinobu Inoue #ifdef INET6
1438053080cSYoshinobu Inoue struct sockaddr *sin = host->sin;
144b208ff84SHajimu UMEMOTO int salen;
1458053080cSYoshinobu Inoue
1468053080cSYoshinobu Inoue if (!sin)
1478053080cSYoshinobu Inoue return;
148b208ff84SHajimu UMEMOTO #ifdef SIN6_LEN
149b208ff84SHajimu UMEMOTO salen = sin->sa_len;
150b208ff84SHajimu UMEMOTO #else
151b208ff84SHajimu UMEMOTO salen = (sin->sa_family == AF_INET) ? sizeof(struct sockaddr_in)
152b208ff84SHajimu UMEMOTO : sizeof(struct sockaddr_in6);
153b208ff84SHajimu UMEMOTO #endif
154b208ff84SHajimu UMEMOTO getnameinfo(sin, salen, host->addr, sizeof(host->addr),
1554f101318SHajimu UMEMOTO NULL, 0, NI_NUMERICHOST);
1568053080cSYoshinobu Inoue #else
1572aef6930SMark Murray struct sockaddr_in *sin = host->sin;
1582aef6930SMark Murray
1592aef6930SMark Murray if (sin != 0)
1602aef6930SMark Murray STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr));
1618053080cSYoshinobu Inoue #endif
1622aef6930SMark Murray }
1632aef6930SMark Murray
1642aef6930SMark Murray /* sock_hostname - map endpoint address to host name */
1652aef6930SMark Murray
sock_hostname(struct host_info * host)166*14f102eaSEd Maste void sock_hostname(struct host_info *host)
1672aef6930SMark Murray {
1688053080cSYoshinobu Inoue #ifdef INET6
1698053080cSYoshinobu Inoue struct sockaddr *sin = host->sin;
170b208ff84SHajimu UMEMOTO struct sockaddr_in sin4;
171b208ff84SHajimu UMEMOTO struct addrinfo hints, *res, *res0 = NULL;
172b208ff84SHajimu UMEMOTO int salen, alen, err = 1;
173b208ff84SHajimu UMEMOTO char *ap = NULL, *rap, hname[NI_MAXHOST];
1742aef6930SMark Murray
1758053080cSYoshinobu Inoue if (sin != NULL) {
176b208ff84SHajimu UMEMOTO if (sin->sa_family == AF_INET6) {
177b208ff84SHajimu UMEMOTO struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin;
178b208ff84SHajimu UMEMOTO
179b208ff84SHajimu UMEMOTO if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
180b208ff84SHajimu UMEMOTO memset(&sin4, 0, sizeof(sin4));
181b208ff84SHajimu UMEMOTO #ifdef SIN6_LEN
182b208ff84SHajimu UMEMOTO sin4.sin_len = sizeof(sin4);
183b208ff84SHajimu UMEMOTO #endif
184b208ff84SHajimu UMEMOTO sin4.sin_family = AF_INET;
185b208ff84SHajimu UMEMOTO sin4.sin_port = sin6->sin6_port;
186b208ff84SHajimu UMEMOTO sin4.sin_addr.s_addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12];
187b208ff84SHajimu UMEMOTO sin = (struct sockaddr *)&sin4;
188b208ff84SHajimu UMEMOTO }
189b208ff84SHajimu UMEMOTO }
1908053080cSYoshinobu Inoue switch (sin->sa_family) {
1918053080cSYoshinobu Inoue case AF_INET:
1928053080cSYoshinobu Inoue ap = (char *)&((struct sockaddr_in *)sin)->sin_addr;
1938053080cSYoshinobu Inoue alen = sizeof(struct in_addr);
194b208ff84SHajimu UMEMOTO salen = sizeof(struct sockaddr_in);
1958053080cSYoshinobu Inoue break;
1968053080cSYoshinobu Inoue case AF_INET6:
1978053080cSYoshinobu Inoue ap = (char *)&((struct sockaddr_in6 *)sin)->sin6_addr;
1988053080cSYoshinobu Inoue alen = sizeof(struct in6_addr);
199b208ff84SHajimu UMEMOTO salen = sizeof(struct sockaddr_in6);
2008053080cSYoshinobu Inoue break;
201b208ff84SHajimu UMEMOTO default:
202b208ff84SHajimu UMEMOTO break;
2038053080cSYoshinobu Inoue }
204b208ff84SHajimu UMEMOTO if (ap)
205b208ff84SHajimu UMEMOTO err = getnameinfo(sin, salen, hname, sizeof(hname),
2064f101318SHajimu UMEMOTO NULL, 0, NI_NAMEREQD);
2078053080cSYoshinobu Inoue }
208b208ff84SHajimu UMEMOTO if (!err) {
2092aef6930SMark Murray
210b208ff84SHajimu UMEMOTO STRN_CPY(host->name, hname, sizeof(host->name));
2112aef6930SMark Murray
21265688488SHajimu UMEMOTO /* reject numeric addresses */
21365688488SHajimu UMEMOTO memset(&hints, 0, sizeof(hints));
21465688488SHajimu UMEMOTO hints.ai_family = sin->sa_family;
21565688488SHajimu UMEMOTO hints.ai_socktype = SOCK_STREAM;
21665688488SHajimu UMEMOTO hints.ai_flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST;
217c16e19ceSKris Kennaway if ((err = getaddrinfo(host->name, NULL, &hints, &res0)) == 0) {
21865688488SHajimu UMEMOTO freeaddrinfo(res0);
21965688488SHajimu UMEMOTO tcpd_warn("host name/name mismatch: "
22065688488SHajimu UMEMOTO "reverse lookup results in non-FQDN %s",
22165688488SHajimu UMEMOTO host->name);
22265688488SHajimu UMEMOTO strcpy(host->name, paranoid); /* name is bad, clobber it */
22365688488SHajimu UMEMOTO }
22465688488SHajimu UMEMOTO err = !err;
22565688488SHajimu UMEMOTO }
22665688488SHajimu UMEMOTO if (!err) {
22765688488SHajimu UMEMOTO /* we are now sure that this is non-numeric */
22865688488SHajimu UMEMOTO
2292aef6930SMark Murray /*
2302aef6930SMark Murray * Verify that the address is a member of the address list returned
2312aef6930SMark Murray * by gethostbyname(hostname).
2322aef6930SMark Murray *
2332aef6930SMark Murray * Verify also that gethostbyaddr() and gethostbyname() return the same
2342aef6930SMark Murray * hostname, or rshd and rlogind may still end up being spoofed.
2352aef6930SMark Murray *
2362aef6930SMark Murray * On some sites, gethostbyname("localhost") returns "localhost.domain".
2372aef6930SMark Murray * This is a DNS artefact. We treat it as a special case. When we
2382aef6930SMark Murray * can't believe the address list from gethostbyname("localhost")
2392aef6930SMark Murray * we're in big trouble anyway.
2402aef6930SMark Murray */
2412aef6930SMark Murray
242b208ff84SHajimu UMEMOTO memset(&hints, 0, sizeof(hints));
243b208ff84SHajimu UMEMOTO hints.ai_family = sin->sa_family;
244b208ff84SHajimu UMEMOTO hints.ai_socktype = SOCK_STREAM;
245b208ff84SHajimu UMEMOTO hints.ai_flags = AI_PASSIVE | AI_CANONNAME;
246b208ff84SHajimu UMEMOTO if (getaddrinfo(host->name, NULL, &hints, &res0) != 0) {
2472aef6930SMark Murray
2482aef6930SMark Murray /*
2492aef6930SMark Murray * Unable to verify that the host name matches the address. This
2502aef6930SMark Murray * may be a transient problem or a botched name server setup.
2512aef6930SMark Murray */
2522aef6930SMark Murray
253b208ff84SHajimu UMEMOTO tcpd_warn("can't verify hostname: getaddrinfo(%s, %s) failed",
2548053080cSYoshinobu Inoue host->name,
2558053080cSYoshinobu Inoue (sin->sa_family == AF_INET) ? "AF_INET" : "AF_INET6");
256b208ff84SHajimu UMEMOTO
2572f0cc2fdSHajimu UMEMOTO } else if ((res0->ai_canonname == NULL
2582f0cc2fdSHajimu UMEMOTO || STR_NE(host->name, res0->ai_canonname))
259b208ff84SHajimu UMEMOTO && STR_NE(host->name, "localhost")) {
260b208ff84SHajimu UMEMOTO
261b208ff84SHajimu UMEMOTO /*
262b208ff84SHajimu UMEMOTO * The gethostbyaddr() and gethostbyname() calls did not return
263b208ff84SHajimu UMEMOTO * the same hostname. This could be a nameserver configuration
264b208ff84SHajimu UMEMOTO * problem. It could also be that someone is trying to spoof us.
265b208ff84SHajimu UMEMOTO */
266b208ff84SHajimu UMEMOTO
267b208ff84SHajimu UMEMOTO tcpd_warn("host name/name mismatch: %s != %.*s",
2682f0cc2fdSHajimu UMEMOTO host->name, STRING_LENGTH,
2692f0cc2fdSHajimu UMEMOTO (res0->ai_canonname == NULL) ? "" : res0->ai_canonname);
270b208ff84SHajimu UMEMOTO
271b208ff84SHajimu UMEMOTO } else {
272b208ff84SHajimu UMEMOTO
273b208ff84SHajimu UMEMOTO /*
274b208ff84SHajimu UMEMOTO * The address should be a member of the address list returned by
275b208ff84SHajimu UMEMOTO * gethostbyname(). We should first verify that the h_addrtype
276b208ff84SHajimu UMEMOTO * field is AF_INET, but this program has already caused too much
277b208ff84SHajimu UMEMOTO * grief on systems with broken library code.
278b208ff84SHajimu UMEMOTO */
279b208ff84SHajimu UMEMOTO
280b208ff84SHajimu UMEMOTO for (res = res0; res; res = res->ai_next) {
281b208ff84SHajimu UMEMOTO if (res->ai_family != sin->sa_family)
282b208ff84SHajimu UMEMOTO continue;
283b208ff84SHajimu UMEMOTO switch (res->ai_family) {
284b208ff84SHajimu UMEMOTO case AF_INET:
285b208ff84SHajimu UMEMOTO rap = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
286b208ff84SHajimu UMEMOTO break;
287b208ff84SHajimu UMEMOTO case AF_INET6:
28865688488SHajimu UMEMOTO /* need to check scope_id */
28965688488SHajimu UMEMOTO if (((struct sockaddr_in6 *)sin)->sin6_scope_id !=
29065688488SHajimu UMEMOTO ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) {
29165688488SHajimu UMEMOTO continue;
29265688488SHajimu UMEMOTO }
293b208ff84SHajimu UMEMOTO rap = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
294b208ff84SHajimu UMEMOTO break;
295b208ff84SHajimu UMEMOTO default:
296b208ff84SHajimu UMEMOTO continue;
297b208ff84SHajimu UMEMOTO }
298b208ff84SHajimu UMEMOTO if (memcmp(rap, ap, alen) == 0) {
299b208ff84SHajimu UMEMOTO freeaddrinfo(res0);
300b208ff84SHajimu UMEMOTO return; /* name is good, keep it */
301b208ff84SHajimu UMEMOTO }
302b208ff84SHajimu UMEMOTO }
303b208ff84SHajimu UMEMOTO
304b208ff84SHajimu UMEMOTO /*
305b208ff84SHajimu UMEMOTO * The host name does not map to the initial address. Perhaps
306b208ff84SHajimu UMEMOTO * someone has messed up. Perhaps someone compromised a name
307b208ff84SHajimu UMEMOTO * server.
308b208ff84SHajimu UMEMOTO */
309b208ff84SHajimu UMEMOTO
310b208ff84SHajimu UMEMOTO getnameinfo(sin, salen, hname, sizeof(hname),
3114f101318SHajimu UMEMOTO NULL, 0, NI_NUMERICHOST);
312b208ff84SHajimu UMEMOTO tcpd_warn("host name/address mismatch: %s != %.*s",
3132f0cc2fdSHajimu UMEMOTO hname, STRING_LENGTH,
3142f0cc2fdSHajimu UMEMOTO (res0->ai_canonname == NULL) ? "" : res0->ai_canonname);
315b208ff84SHajimu UMEMOTO }
316b208ff84SHajimu UMEMOTO strcpy(host->name, paranoid); /* name is bad, clobber it */
317b208ff84SHajimu UMEMOTO if (res0)
318b208ff84SHajimu UMEMOTO freeaddrinfo(res0);
319b208ff84SHajimu UMEMOTO }
320b208ff84SHajimu UMEMOTO #else /* INET6 */
321b208ff84SHajimu UMEMOTO struct sockaddr_in *sin = host->sin;
322b208ff84SHajimu UMEMOTO struct hostent *hp;
323b208ff84SHajimu UMEMOTO int i;
324b208ff84SHajimu UMEMOTO
325b208ff84SHajimu UMEMOTO /*
326b208ff84SHajimu UMEMOTO * On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does
327b208ff84SHajimu UMEMOTO * not fail. Instead it returns "INADDR_ANY". Unfortunately, this does
328b208ff84SHajimu UMEMOTO * not work the other way around: gethostbyname("INADDR_ANY") fails. We
329b208ff84SHajimu UMEMOTO * have to special-case 0.0.0.0, in order to avoid false alerts from the
330b208ff84SHajimu UMEMOTO * host name/address checking code below.
331b208ff84SHajimu UMEMOTO */
332b208ff84SHajimu UMEMOTO if (sin != 0 && sin->sin_addr.s_addr != 0
333b208ff84SHajimu UMEMOTO && (hp = gethostbyaddr((char *) &(sin->sin_addr),
334b208ff84SHajimu UMEMOTO sizeof(sin->sin_addr), AF_INET)) != 0) {
335b208ff84SHajimu UMEMOTO
336b208ff84SHajimu UMEMOTO STRN_CPY(host->name, hp->h_name, sizeof(host->name));
337b208ff84SHajimu UMEMOTO
338b208ff84SHajimu UMEMOTO /*
339b208ff84SHajimu UMEMOTO * Verify that the address is a member of the address list returned
340b208ff84SHajimu UMEMOTO * by gethostbyname(hostname).
341b208ff84SHajimu UMEMOTO *
342b208ff84SHajimu UMEMOTO * Verify also that gethostbyaddr() and gethostbyname() return the same
343b208ff84SHajimu UMEMOTO * hostname, or rshd and rlogind may still end up being spoofed.
344b208ff84SHajimu UMEMOTO *
345b208ff84SHajimu UMEMOTO * On some sites, gethostbyname("localhost") returns "localhost.domain".
346b208ff84SHajimu UMEMOTO * This is a DNS artefact. We treat it as a special case. When we
347b208ff84SHajimu UMEMOTO * can't believe the address list from gethostbyname("localhost")
348b208ff84SHajimu UMEMOTO * we're in big trouble anyway.
349b208ff84SHajimu UMEMOTO */
350b208ff84SHajimu UMEMOTO
351b208ff84SHajimu UMEMOTO if ((hp = gethostbyname(host->name)) == 0) {
352b208ff84SHajimu UMEMOTO
353b208ff84SHajimu UMEMOTO /*
354b208ff84SHajimu UMEMOTO * Unable to verify that the host name matches the address. This
355b208ff84SHajimu UMEMOTO * may be a transient problem or a botched name server setup.
356b208ff84SHajimu UMEMOTO */
357b208ff84SHajimu UMEMOTO
3582aef6930SMark Murray tcpd_warn("can't verify hostname: gethostbyname(%s) failed",
3592aef6930SMark Murray host->name);
3602aef6930SMark Murray
3612aef6930SMark Murray } else if (STR_NE(host->name, hp->h_name)
3622aef6930SMark Murray && STR_NE(host->name, "localhost")) {
3632aef6930SMark Murray
3642aef6930SMark Murray /*
3652aef6930SMark Murray * The gethostbyaddr() and gethostbyname() calls did not return
3662aef6930SMark Murray * the same hostname. This could be a nameserver configuration
3672aef6930SMark Murray * problem. It could also be that someone is trying to spoof us.
3682aef6930SMark Murray */
3692aef6930SMark Murray
3702aef6930SMark Murray tcpd_warn("host name/name mismatch: %s != %.*s",
3712aef6930SMark Murray host->name, STRING_LENGTH, hp->h_name);
3722aef6930SMark Murray
3732aef6930SMark Murray } else {
3742aef6930SMark Murray
3752aef6930SMark Murray /*
3762aef6930SMark Murray * The address should be a member of the address list returned by
3772aef6930SMark Murray * gethostbyname(). We should first verify that the h_addrtype
3782aef6930SMark Murray * field is AF_INET, but this program has already caused too much
3792aef6930SMark Murray * grief on systems with broken library code.
3802aef6930SMark Murray */
3812aef6930SMark Murray
3822aef6930SMark Murray for (i = 0; hp->h_addr_list[i]; i++) {
3832aef6930SMark Murray if (memcmp(hp->h_addr_list[i],
3842aef6930SMark Murray (char *) &sin->sin_addr,
3852aef6930SMark Murray sizeof(sin->sin_addr)) == 0)
3862aef6930SMark Murray return; /* name is good, keep it */
3872aef6930SMark Murray }
3882aef6930SMark Murray
3892aef6930SMark Murray /*
3902aef6930SMark Murray * The host name does not map to the initial address. Perhaps
3912aef6930SMark Murray * someone has messed up. Perhaps someone compromised a name
3922aef6930SMark Murray * server.
3932aef6930SMark Murray */
3942aef6930SMark Murray
3952aef6930SMark Murray tcpd_warn("host name/address mismatch: %s != %.*s",
3962aef6930SMark Murray inet_ntoa(sin->sin_addr), STRING_LENGTH, hp->h_name);
3972aef6930SMark Murray }
3982aef6930SMark Murray strcpy(host->name, paranoid); /* name is bad, clobber it */
3992aef6930SMark Murray }
400b208ff84SHajimu UMEMOTO #endif /* INET6 */
4012aef6930SMark Murray }
4022aef6930SMark Murray
4032aef6930SMark Murray /* sock_sink - absorb unreceived IP datagram */
4042aef6930SMark Murray
sock_sink(int fd)405068ad27dSBrooks Davis static void sock_sink(int fd)
4062aef6930SMark Murray {
4072aef6930SMark Murray char buf[BUFSIZ];
4088053080cSYoshinobu Inoue #ifdef INET6
4098053080cSYoshinobu Inoue struct sockaddr_storage sin;
4108053080cSYoshinobu Inoue #else
4112aef6930SMark Murray struct sockaddr_in sin;
4128053080cSYoshinobu Inoue #endif
4132aef6930SMark Murray int size = sizeof(sin);
4142aef6930SMark Murray
4152aef6930SMark Murray /*
4162aef6930SMark Murray * Eat up the not-yet received datagram. Some systems insist on a
4172aef6930SMark Murray * non-zero source address argument in the recvfrom() call below.
4182aef6930SMark Murray */
4192aef6930SMark Murray
4202aef6930SMark Murray (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *) & sin, &size);
4212aef6930SMark Murray }
422