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 452aef6930SMark Murray static void sock_sink(); 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 552aef6930SMark Murray static struct hostent *gethostbyname_dot(name) 562aef6930SMark Murray char *name; 572aef6930SMark Murray { 582aef6930SMark Murray char dot_name[MAXHOSTNAMELEN + 1]; 592aef6930SMark Murray 602aef6930SMark Murray /* 612aef6930SMark Murray * Don't append dots to unqualified names. Such names are likely to come 622aef6930SMark Murray * from local hosts files or from NIS. 632aef6930SMark Murray */ 642aef6930SMark Murray 652aef6930SMark Murray if (strchr(name, '.') == 0 || strlen(name) >= MAXHOSTNAMELEN - 1) { 662aef6930SMark Murray return (gethostbyname(name)); 672aef6930SMark Murray } else { 682aef6930SMark Murray sprintf(dot_name, "%s.", name); 692aef6930SMark Murray return (gethostbyname(dot_name)); 702aef6930SMark Murray } 712aef6930SMark Murray } 722aef6930SMark Murray 732aef6930SMark Murray #define gethostbyname gethostbyname_dot 742aef6930SMark Murray #endif 752aef6930SMark Murray 762aef6930SMark Murray /* sock_host - look up endpoint addresses and install conversion methods */ 772aef6930SMark Murray 782aef6930SMark Murray void sock_host(request) 792aef6930SMark Murray struct request_info *request; 802aef6930SMark Murray { 818053080cSYoshinobu Inoue #ifdef INET6 828053080cSYoshinobu Inoue static struct sockaddr_storage client; 838053080cSYoshinobu Inoue static struct sockaddr_storage server; 848053080cSYoshinobu Inoue #else 852aef6930SMark Murray static struct sockaddr_in client; 862aef6930SMark Murray static struct sockaddr_in server; 878053080cSYoshinobu Inoue #endif 882aef6930SMark Murray int len; 892aef6930SMark Murray char buf[BUFSIZ]; 902aef6930SMark Murray int fd = request->fd; 912aef6930SMark Murray 922aef6930SMark Murray sock_methods(request); 932aef6930SMark Murray 942aef6930SMark Murray /* 952aef6930SMark Murray * Look up the client host address. Hal R. Brand <BRAND@addvax.llnl.gov> 962aef6930SMark Murray * suggested how to get the client host info in case of UDP connections: 972aef6930SMark Murray * peek at the first message without actually looking at its contents. We 982aef6930SMark Murray * really should verify that client.sin_family gets the value AF_INET, 992aef6930SMark Murray * but this program has already caused too much grief on systems with 1002aef6930SMark Murray * broken library code. 1012aef6930SMark Murray */ 1022aef6930SMark Murray 1032aef6930SMark Murray len = sizeof(client); 1042aef6930SMark Murray if (getpeername(fd, (struct sockaddr *) & client, &len) < 0) { 1052aef6930SMark Murray request->sink = sock_sink; 1062aef6930SMark Murray len = sizeof(client); 1072aef6930SMark Murray if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK, 1082aef6930SMark Murray (struct sockaddr *) & client, &len) < 0) { 1092aef6930SMark Murray tcpd_warn("can't get client address: %m"); 1102aef6930SMark Murray return; /* give up */ 1112aef6930SMark Murray } 1122aef6930SMark Murray #ifdef really_paranoid 113c0b3834dSCeri Davies memset(buf, 0, sizeof(buf)); 1142aef6930SMark Murray #endif 1152aef6930SMark Murray } 1168053080cSYoshinobu Inoue #ifdef INET6 1178053080cSYoshinobu Inoue request->client->sin = (struct sockaddr *)&client; 1188053080cSYoshinobu Inoue #else 1192aef6930SMark Murray request->client->sin = &client; 1208053080cSYoshinobu Inoue #endif 1212aef6930SMark Murray 1222aef6930SMark Murray /* 1232aef6930SMark Murray * Determine the server binding. This is used for client username 1242aef6930SMark Murray * lookups, and for access control rules that trigger on the server 1252aef6930SMark Murray * address or name. 1262aef6930SMark Murray */ 1272aef6930SMark Murray 1282aef6930SMark Murray len = sizeof(server); 1292aef6930SMark Murray if (getsockname(fd, (struct sockaddr *) & server, &len) < 0) { 1302aef6930SMark Murray tcpd_warn("getsockname: %m"); 1312aef6930SMark Murray return; 1322aef6930SMark Murray } 1338053080cSYoshinobu Inoue #ifdef INET6 1348053080cSYoshinobu Inoue request->server->sin = (struct sockaddr *)&server; 1358053080cSYoshinobu Inoue #else 1362aef6930SMark Murray request->server->sin = &server; 1378053080cSYoshinobu Inoue #endif 1382aef6930SMark Murray } 1392aef6930SMark Murray 1402aef6930SMark Murray /* sock_hostaddr - map endpoint address to printable form */ 1412aef6930SMark Murray 1422aef6930SMark Murray void sock_hostaddr(host) 1432aef6930SMark Murray struct host_info *host; 1442aef6930SMark Murray { 1458053080cSYoshinobu Inoue #ifdef INET6 1468053080cSYoshinobu Inoue struct sockaddr *sin = host->sin; 147b208ff84SHajimu UMEMOTO int salen; 1488053080cSYoshinobu Inoue 1498053080cSYoshinobu Inoue if (!sin) 1508053080cSYoshinobu Inoue return; 151b208ff84SHajimu UMEMOTO #ifdef SIN6_LEN 152b208ff84SHajimu UMEMOTO salen = sin->sa_len; 153b208ff84SHajimu UMEMOTO #else 154b208ff84SHajimu UMEMOTO salen = (sin->sa_family == AF_INET) ? sizeof(struct sockaddr_in) 155b208ff84SHajimu UMEMOTO : sizeof(struct sockaddr_in6); 156b208ff84SHajimu UMEMOTO #endif 157b208ff84SHajimu UMEMOTO getnameinfo(sin, salen, host->addr, sizeof(host->addr), 1584f101318SHajimu UMEMOTO NULL, 0, NI_NUMERICHOST); 1598053080cSYoshinobu Inoue #else 1602aef6930SMark Murray struct sockaddr_in *sin = host->sin; 1612aef6930SMark Murray 1622aef6930SMark Murray if (sin != 0) 1632aef6930SMark Murray STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr)); 1648053080cSYoshinobu Inoue #endif 1652aef6930SMark Murray } 1662aef6930SMark Murray 1672aef6930SMark Murray /* sock_hostname - map endpoint address to host name */ 1682aef6930SMark Murray 1692aef6930SMark Murray void sock_hostname(host) 1702aef6930SMark Murray struct host_info *host; 1712aef6930SMark Murray { 1728053080cSYoshinobu Inoue #ifdef INET6 1738053080cSYoshinobu Inoue struct sockaddr *sin = host->sin; 174b208ff84SHajimu UMEMOTO struct sockaddr_in sin4; 175b208ff84SHajimu UMEMOTO struct addrinfo hints, *res, *res0 = NULL; 176b208ff84SHajimu UMEMOTO int salen, alen, err = 1; 177b208ff84SHajimu UMEMOTO char *ap = NULL, *rap, hname[NI_MAXHOST]; 1782aef6930SMark Murray 1798053080cSYoshinobu Inoue if (sin != NULL) { 180b208ff84SHajimu UMEMOTO if (sin->sa_family == AF_INET6) { 181b208ff84SHajimu UMEMOTO struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin; 182b208ff84SHajimu UMEMOTO 183b208ff84SHajimu UMEMOTO if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 184b208ff84SHajimu UMEMOTO memset(&sin4, 0, sizeof(sin4)); 185b208ff84SHajimu UMEMOTO #ifdef SIN6_LEN 186b208ff84SHajimu UMEMOTO sin4.sin_len = sizeof(sin4); 187b208ff84SHajimu UMEMOTO #endif 188b208ff84SHajimu UMEMOTO sin4.sin_family = AF_INET; 189b208ff84SHajimu UMEMOTO sin4.sin_port = sin6->sin6_port; 190b208ff84SHajimu UMEMOTO sin4.sin_addr.s_addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; 191b208ff84SHajimu UMEMOTO sin = (struct sockaddr *)&sin4; 192b208ff84SHajimu UMEMOTO } 193b208ff84SHajimu UMEMOTO } 1948053080cSYoshinobu Inoue switch (sin->sa_family) { 1958053080cSYoshinobu Inoue case AF_INET: 1968053080cSYoshinobu Inoue ap = (char *)&((struct sockaddr_in *)sin)->sin_addr; 1978053080cSYoshinobu Inoue alen = sizeof(struct in_addr); 198b208ff84SHajimu UMEMOTO salen = sizeof(struct sockaddr_in); 1998053080cSYoshinobu Inoue break; 2008053080cSYoshinobu Inoue case AF_INET6: 2018053080cSYoshinobu Inoue ap = (char *)&((struct sockaddr_in6 *)sin)->sin6_addr; 2028053080cSYoshinobu Inoue alen = sizeof(struct in6_addr); 203b208ff84SHajimu UMEMOTO salen = sizeof(struct sockaddr_in6); 2048053080cSYoshinobu Inoue break; 205b208ff84SHajimu UMEMOTO default: 206b208ff84SHajimu UMEMOTO break; 2078053080cSYoshinobu Inoue } 208b208ff84SHajimu UMEMOTO if (ap) 209b208ff84SHajimu UMEMOTO err = getnameinfo(sin, salen, hname, sizeof(hname), 2104f101318SHajimu UMEMOTO NULL, 0, NI_NAMEREQD); 2118053080cSYoshinobu Inoue } 212b208ff84SHajimu UMEMOTO if (!err) { 2132aef6930SMark Murray 214b208ff84SHajimu UMEMOTO STRN_CPY(host->name, hname, sizeof(host->name)); 2152aef6930SMark Murray 21665688488SHajimu UMEMOTO /* reject numeric addresses */ 21765688488SHajimu UMEMOTO memset(&hints, 0, sizeof(hints)); 21865688488SHajimu UMEMOTO hints.ai_family = sin->sa_family; 21965688488SHajimu UMEMOTO hints.ai_socktype = SOCK_STREAM; 22065688488SHajimu UMEMOTO hints.ai_flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST; 221c16e19ceSKris Kennaway if ((err = getaddrinfo(host->name, NULL, &hints, &res0)) == 0) { 22265688488SHajimu UMEMOTO freeaddrinfo(res0); 22365688488SHajimu UMEMOTO tcpd_warn("host name/name mismatch: " 22465688488SHajimu UMEMOTO "reverse lookup results in non-FQDN %s", 22565688488SHajimu UMEMOTO host->name); 22665688488SHajimu UMEMOTO strcpy(host->name, paranoid); /* name is bad, clobber it */ 22765688488SHajimu UMEMOTO } 22865688488SHajimu UMEMOTO err = !err; 22965688488SHajimu UMEMOTO } 23065688488SHajimu UMEMOTO if (!err) { 23165688488SHajimu UMEMOTO /* we are now sure that this is non-numeric */ 23265688488SHajimu UMEMOTO 2332aef6930SMark Murray /* 2342aef6930SMark Murray * Verify that the address is a member of the address list returned 2352aef6930SMark Murray * by gethostbyname(hostname). 2362aef6930SMark Murray * 2372aef6930SMark Murray * Verify also that gethostbyaddr() and gethostbyname() return the same 2382aef6930SMark Murray * hostname, or rshd and rlogind may still end up being spoofed. 2392aef6930SMark Murray * 2402aef6930SMark Murray * On some sites, gethostbyname("localhost") returns "localhost.domain". 2412aef6930SMark Murray * This is a DNS artefact. We treat it as a special case. When we 2422aef6930SMark Murray * can't believe the address list from gethostbyname("localhost") 2432aef6930SMark Murray * we're in big trouble anyway. 2442aef6930SMark Murray */ 2452aef6930SMark Murray 246b208ff84SHajimu UMEMOTO memset(&hints, 0, sizeof(hints)); 247b208ff84SHajimu UMEMOTO hints.ai_family = sin->sa_family; 248b208ff84SHajimu UMEMOTO hints.ai_socktype = SOCK_STREAM; 249b208ff84SHajimu UMEMOTO hints.ai_flags = AI_PASSIVE | AI_CANONNAME; 250b208ff84SHajimu UMEMOTO if (getaddrinfo(host->name, NULL, &hints, &res0) != 0) { 2512aef6930SMark Murray 2522aef6930SMark Murray /* 2532aef6930SMark Murray * Unable to verify that the host name matches the address. This 2542aef6930SMark Murray * may be a transient problem or a botched name server setup. 2552aef6930SMark Murray */ 2562aef6930SMark Murray 257b208ff84SHajimu UMEMOTO tcpd_warn("can't verify hostname: getaddrinfo(%s, %s) failed", 2588053080cSYoshinobu Inoue host->name, 2598053080cSYoshinobu Inoue (sin->sa_family == AF_INET) ? "AF_INET" : "AF_INET6"); 260b208ff84SHajimu UMEMOTO 2612f0cc2fdSHajimu UMEMOTO } else if ((res0->ai_canonname == NULL 2622f0cc2fdSHajimu UMEMOTO || STR_NE(host->name, res0->ai_canonname)) 263b208ff84SHajimu UMEMOTO && STR_NE(host->name, "localhost")) { 264b208ff84SHajimu UMEMOTO 265b208ff84SHajimu UMEMOTO /* 266b208ff84SHajimu UMEMOTO * The gethostbyaddr() and gethostbyname() calls did not return 267b208ff84SHajimu UMEMOTO * the same hostname. This could be a nameserver configuration 268b208ff84SHajimu UMEMOTO * problem. It could also be that someone is trying to spoof us. 269b208ff84SHajimu UMEMOTO */ 270b208ff84SHajimu UMEMOTO 271b208ff84SHajimu UMEMOTO tcpd_warn("host name/name mismatch: %s != %.*s", 2722f0cc2fdSHajimu UMEMOTO host->name, STRING_LENGTH, 2732f0cc2fdSHajimu UMEMOTO (res0->ai_canonname == NULL) ? "" : res0->ai_canonname); 274b208ff84SHajimu UMEMOTO 275b208ff84SHajimu UMEMOTO } else { 276b208ff84SHajimu UMEMOTO 277b208ff84SHajimu UMEMOTO /* 278b208ff84SHajimu UMEMOTO * The address should be a member of the address list returned by 279b208ff84SHajimu UMEMOTO * gethostbyname(). We should first verify that the h_addrtype 280b208ff84SHajimu UMEMOTO * field is AF_INET, but this program has already caused too much 281b208ff84SHajimu UMEMOTO * grief on systems with broken library code. 282b208ff84SHajimu UMEMOTO */ 283b208ff84SHajimu UMEMOTO 284b208ff84SHajimu UMEMOTO for (res = res0; res; res = res->ai_next) { 285b208ff84SHajimu UMEMOTO if (res->ai_family != sin->sa_family) 286b208ff84SHajimu UMEMOTO continue; 287b208ff84SHajimu UMEMOTO switch (res->ai_family) { 288b208ff84SHajimu UMEMOTO case AF_INET: 289b208ff84SHajimu UMEMOTO rap = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr; 290b208ff84SHajimu UMEMOTO break; 291b208ff84SHajimu UMEMOTO case AF_INET6: 29265688488SHajimu UMEMOTO /* need to check scope_id */ 29365688488SHajimu UMEMOTO if (((struct sockaddr_in6 *)sin)->sin6_scope_id != 29465688488SHajimu UMEMOTO ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) { 29565688488SHajimu UMEMOTO continue; 29665688488SHajimu UMEMOTO } 297b208ff84SHajimu UMEMOTO rap = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; 298b208ff84SHajimu UMEMOTO break; 299b208ff84SHajimu UMEMOTO default: 300b208ff84SHajimu UMEMOTO continue; 301b208ff84SHajimu UMEMOTO } 302b208ff84SHajimu UMEMOTO if (memcmp(rap, ap, alen) == 0) { 303b208ff84SHajimu UMEMOTO freeaddrinfo(res0); 304b208ff84SHajimu UMEMOTO return; /* name is good, keep it */ 305b208ff84SHajimu UMEMOTO } 306b208ff84SHajimu UMEMOTO } 307b208ff84SHajimu UMEMOTO 308b208ff84SHajimu UMEMOTO /* 309b208ff84SHajimu UMEMOTO * The host name does not map to the initial address. Perhaps 310b208ff84SHajimu UMEMOTO * someone has messed up. Perhaps someone compromised a name 311b208ff84SHajimu UMEMOTO * server. 312b208ff84SHajimu UMEMOTO */ 313b208ff84SHajimu UMEMOTO 314b208ff84SHajimu UMEMOTO getnameinfo(sin, salen, hname, sizeof(hname), 3154f101318SHajimu UMEMOTO NULL, 0, NI_NUMERICHOST); 316b208ff84SHajimu UMEMOTO tcpd_warn("host name/address mismatch: %s != %.*s", 3172f0cc2fdSHajimu UMEMOTO hname, STRING_LENGTH, 3182f0cc2fdSHajimu UMEMOTO (res0->ai_canonname == NULL) ? "" : res0->ai_canonname); 319b208ff84SHajimu UMEMOTO } 320b208ff84SHajimu UMEMOTO strcpy(host->name, paranoid); /* name is bad, clobber it */ 321b208ff84SHajimu UMEMOTO if (res0) 322b208ff84SHajimu UMEMOTO freeaddrinfo(res0); 323b208ff84SHajimu UMEMOTO } 324b208ff84SHajimu UMEMOTO #else /* INET6 */ 325b208ff84SHajimu UMEMOTO struct sockaddr_in *sin = host->sin; 326b208ff84SHajimu UMEMOTO struct hostent *hp; 327b208ff84SHajimu UMEMOTO int i; 328b208ff84SHajimu UMEMOTO 329b208ff84SHajimu UMEMOTO /* 330b208ff84SHajimu UMEMOTO * On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does 331b208ff84SHajimu UMEMOTO * not fail. Instead it returns "INADDR_ANY". Unfortunately, this does 332b208ff84SHajimu UMEMOTO * not work the other way around: gethostbyname("INADDR_ANY") fails. We 333b208ff84SHajimu UMEMOTO * have to special-case 0.0.0.0, in order to avoid false alerts from the 334b208ff84SHajimu UMEMOTO * host name/address checking code below. 335b208ff84SHajimu UMEMOTO */ 336b208ff84SHajimu UMEMOTO if (sin != 0 && sin->sin_addr.s_addr != 0 337b208ff84SHajimu UMEMOTO && (hp = gethostbyaddr((char *) &(sin->sin_addr), 338b208ff84SHajimu UMEMOTO sizeof(sin->sin_addr), AF_INET)) != 0) { 339b208ff84SHajimu UMEMOTO 340b208ff84SHajimu UMEMOTO STRN_CPY(host->name, hp->h_name, sizeof(host->name)); 341b208ff84SHajimu UMEMOTO 342b208ff84SHajimu UMEMOTO /* 343b208ff84SHajimu UMEMOTO * Verify that the address is a member of the address list returned 344b208ff84SHajimu UMEMOTO * by gethostbyname(hostname). 345b208ff84SHajimu UMEMOTO * 346b208ff84SHajimu UMEMOTO * Verify also that gethostbyaddr() and gethostbyname() return the same 347b208ff84SHajimu UMEMOTO * hostname, or rshd and rlogind may still end up being spoofed. 348b208ff84SHajimu UMEMOTO * 349b208ff84SHajimu UMEMOTO * On some sites, gethostbyname("localhost") returns "localhost.domain". 350b208ff84SHajimu UMEMOTO * This is a DNS artefact. We treat it as a special case. When we 351b208ff84SHajimu UMEMOTO * can't believe the address list from gethostbyname("localhost") 352b208ff84SHajimu UMEMOTO * we're in big trouble anyway. 353b208ff84SHajimu UMEMOTO */ 354b208ff84SHajimu UMEMOTO 355b208ff84SHajimu UMEMOTO if ((hp = gethostbyname(host->name)) == 0) { 356b208ff84SHajimu UMEMOTO 357b208ff84SHajimu UMEMOTO /* 358b208ff84SHajimu UMEMOTO * Unable to verify that the host name matches the address. This 359b208ff84SHajimu UMEMOTO * may be a transient problem or a botched name server setup. 360b208ff84SHajimu UMEMOTO */ 361b208ff84SHajimu UMEMOTO 3622aef6930SMark Murray tcpd_warn("can't verify hostname: gethostbyname(%s) failed", 3632aef6930SMark Murray host->name); 3642aef6930SMark Murray 3652aef6930SMark Murray } else if (STR_NE(host->name, hp->h_name) 3662aef6930SMark Murray && STR_NE(host->name, "localhost")) { 3672aef6930SMark Murray 3682aef6930SMark Murray /* 3692aef6930SMark Murray * The gethostbyaddr() and gethostbyname() calls did not return 3702aef6930SMark Murray * the same hostname. This could be a nameserver configuration 3712aef6930SMark Murray * problem. It could also be that someone is trying to spoof us. 3722aef6930SMark Murray */ 3732aef6930SMark Murray 3742aef6930SMark Murray tcpd_warn("host name/name mismatch: %s != %.*s", 3752aef6930SMark Murray host->name, STRING_LENGTH, hp->h_name); 3762aef6930SMark Murray 3772aef6930SMark Murray } else { 3782aef6930SMark Murray 3792aef6930SMark Murray /* 3802aef6930SMark Murray * The address should be a member of the address list returned by 3812aef6930SMark Murray * gethostbyname(). We should first verify that the h_addrtype 3822aef6930SMark Murray * field is AF_INET, but this program has already caused too much 3832aef6930SMark Murray * grief on systems with broken library code. 3842aef6930SMark Murray */ 3852aef6930SMark Murray 3862aef6930SMark Murray for (i = 0; hp->h_addr_list[i]; i++) { 3872aef6930SMark Murray if (memcmp(hp->h_addr_list[i], 3882aef6930SMark Murray (char *) &sin->sin_addr, 3892aef6930SMark Murray sizeof(sin->sin_addr)) == 0) 3902aef6930SMark Murray return; /* name is good, keep it */ 3912aef6930SMark Murray } 3922aef6930SMark Murray 3932aef6930SMark Murray /* 3942aef6930SMark Murray * The host name does not map to the initial address. Perhaps 3952aef6930SMark Murray * someone has messed up. Perhaps someone compromised a name 3962aef6930SMark Murray * server. 3972aef6930SMark Murray */ 3982aef6930SMark Murray 3992aef6930SMark Murray tcpd_warn("host name/address mismatch: %s != %.*s", 4002aef6930SMark Murray inet_ntoa(sin->sin_addr), STRING_LENGTH, hp->h_name); 4012aef6930SMark Murray } 4022aef6930SMark Murray strcpy(host->name, paranoid); /* name is bad, clobber it */ 4032aef6930SMark Murray } 404b208ff84SHajimu UMEMOTO #endif /* INET6 */ 4052aef6930SMark Murray } 4062aef6930SMark Murray 4072aef6930SMark Murray /* sock_sink - absorb unreceived IP datagram */ 4082aef6930SMark Murray 4092aef6930SMark Murray static void sock_sink(fd) 4102aef6930SMark Murray int fd; 4112aef6930SMark Murray { 4122aef6930SMark Murray char buf[BUFSIZ]; 4138053080cSYoshinobu Inoue #ifdef INET6 4148053080cSYoshinobu Inoue struct sockaddr_storage sin; 4158053080cSYoshinobu Inoue #else 4162aef6930SMark Murray struct sockaddr_in sin; 4178053080cSYoshinobu Inoue #endif 4182aef6930SMark Murray int size = sizeof(sin); 4192aef6930SMark Murray 4202aef6930SMark Murray /* 4212aef6930SMark Murray * Eat up the not-yet received datagram. Some systems insist on a 4222aef6930SMark Murray * non-zero source address argument in the recvfrom() call below. 4232aef6930SMark Murray */ 4242aef6930SMark Murray 4252aef6930SMark Murray (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *) & sin, &size); 4262aef6930SMark Murray } 427