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 358053080cSYoshinobu Inoue #ifdef INET6 36b208ff84SHajimu UMEMOTO #ifndef NI_WITHSCOPEID 37b208ff84SHajimu UMEMOTO #define NI_WITHSCOPEID 0 388053080cSYoshinobu Inoue #endif 39b208ff84SHajimu UMEMOTO #else 402aef6930SMark Murray extern char *inet_ntoa(); 41b208ff84SHajimu UMEMOTO #endif 422aef6930SMark Murray 432aef6930SMark Murray /* Local stuff. */ 442aef6930SMark Murray 452aef6930SMark Murray #include "tcpd.h" 462aef6930SMark Murray 472aef6930SMark Murray /* Forward declarations. */ 482aef6930SMark Murray 492aef6930SMark Murray static void sock_sink(); 502aef6930SMark Murray 512aef6930SMark Murray #ifdef APPEND_DOT 522aef6930SMark Murray 532aef6930SMark Murray /* 542aef6930SMark Murray * Speed up DNS lookups by terminating the host name with a dot. Should be 552aef6930SMark Murray * done with care. The speedup can give problems with lookups from sources 562aef6930SMark Murray * that lack DNS-style trailing dot magic, such as local files or NIS maps. 572aef6930SMark Murray */ 582aef6930SMark Murray 592aef6930SMark Murray static struct hostent *gethostbyname_dot(name) 602aef6930SMark Murray char *name; 612aef6930SMark Murray { 622aef6930SMark Murray char dot_name[MAXHOSTNAMELEN + 1]; 632aef6930SMark Murray 642aef6930SMark Murray /* 652aef6930SMark Murray * Don't append dots to unqualified names. Such names are likely to come 662aef6930SMark Murray * from local hosts files or from NIS. 672aef6930SMark Murray */ 682aef6930SMark Murray 692aef6930SMark Murray if (strchr(name, '.') == 0 || strlen(name) >= MAXHOSTNAMELEN - 1) { 702aef6930SMark Murray return (gethostbyname(name)); 712aef6930SMark Murray } else { 722aef6930SMark Murray sprintf(dot_name, "%s.", name); 732aef6930SMark Murray return (gethostbyname(dot_name)); 742aef6930SMark Murray } 752aef6930SMark Murray } 762aef6930SMark Murray 772aef6930SMark Murray #define gethostbyname gethostbyname_dot 782aef6930SMark Murray #endif 792aef6930SMark Murray 802aef6930SMark Murray /* sock_host - look up endpoint addresses and install conversion methods */ 812aef6930SMark Murray 822aef6930SMark Murray void sock_host(request) 832aef6930SMark Murray struct request_info *request; 842aef6930SMark Murray { 858053080cSYoshinobu Inoue #ifdef INET6 868053080cSYoshinobu Inoue static struct sockaddr_storage client; 878053080cSYoshinobu Inoue static struct sockaddr_storage server; 888053080cSYoshinobu Inoue #else 892aef6930SMark Murray static struct sockaddr_in client; 902aef6930SMark Murray static struct sockaddr_in server; 918053080cSYoshinobu Inoue #endif 922aef6930SMark Murray int len; 932aef6930SMark Murray char buf[BUFSIZ]; 942aef6930SMark Murray int fd = request->fd; 952aef6930SMark Murray 962aef6930SMark Murray sock_methods(request); 972aef6930SMark Murray 982aef6930SMark Murray /* 992aef6930SMark Murray * Look up the client host address. Hal R. Brand <BRAND@addvax.llnl.gov> 1002aef6930SMark Murray * suggested how to get the client host info in case of UDP connections: 1012aef6930SMark Murray * peek at the first message without actually looking at its contents. We 1022aef6930SMark Murray * really should verify that client.sin_family gets the value AF_INET, 1032aef6930SMark Murray * but this program has already caused too much grief on systems with 1042aef6930SMark Murray * broken library code. 1052aef6930SMark Murray */ 1062aef6930SMark Murray 1072aef6930SMark Murray len = sizeof(client); 1082aef6930SMark Murray if (getpeername(fd, (struct sockaddr *) & client, &len) < 0) { 1092aef6930SMark Murray request->sink = sock_sink; 1102aef6930SMark Murray len = sizeof(client); 1112aef6930SMark Murray if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK, 1122aef6930SMark Murray (struct sockaddr *) & client, &len) < 0) { 1132aef6930SMark Murray tcpd_warn("can't get client address: %m"); 1142aef6930SMark Murray return; /* give up */ 1152aef6930SMark Murray } 1162aef6930SMark Murray #ifdef really_paranoid 1172aef6930SMark Murray memset(buf, 0 sizeof(buf)); 1182aef6930SMark Murray #endif 1192aef6930SMark Murray } 1208053080cSYoshinobu Inoue #ifdef INET6 1218053080cSYoshinobu Inoue request->client->sin = (struct sockaddr *)&client; 1228053080cSYoshinobu Inoue #else 1232aef6930SMark Murray request->client->sin = &client; 1248053080cSYoshinobu Inoue #endif 1252aef6930SMark Murray 1262aef6930SMark Murray /* 1272aef6930SMark Murray * Determine the server binding. This is used for client username 1282aef6930SMark Murray * lookups, and for access control rules that trigger on the server 1292aef6930SMark Murray * address or name. 1302aef6930SMark Murray */ 1312aef6930SMark Murray 1322aef6930SMark Murray len = sizeof(server); 1332aef6930SMark Murray if (getsockname(fd, (struct sockaddr *) & server, &len) < 0) { 1342aef6930SMark Murray tcpd_warn("getsockname: %m"); 1352aef6930SMark Murray return; 1362aef6930SMark Murray } 1378053080cSYoshinobu Inoue #ifdef INET6 1388053080cSYoshinobu Inoue request->server->sin = (struct sockaddr *)&server; 1398053080cSYoshinobu Inoue #else 1402aef6930SMark Murray request->server->sin = &server; 1418053080cSYoshinobu Inoue #endif 1422aef6930SMark Murray } 1432aef6930SMark Murray 1442aef6930SMark Murray /* sock_hostaddr - map endpoint address to printable form */ 1452aef6930SMark Murray 1462aef6930SMark Murray void sock_hostaddr(host) 1472aef6930SMark Murray struct host_info *host; 1482aef6930SMark Murray { 1498053080cSYoshinobu Inoue #ifdef INET6 1508053080cSYoshinobu Inoue struct sockaddr *sin = host->sin; 151b208ff84SHajimu UMEMOTO int salen; 1528053080cSYoshinobu Inoue 1538053080cSYoshinobu Inoue if (!sin) 1548053080cSYoshinobu Inoue return; 155b208ff84SHajimu UMEMOTO #ifdef SIN6_LEN 156b208ff84SHajimu UMEMOTO salen = sin->sa_len; 157b208ff84SHajimu UMEMOTO #else 158b208ff84SHajimu UMEMOTO salen = (sin->sa_family == AF_INET) ? sizeof(struct sockaddr_in) 159b208ff84SHajimu UMEMOTO : sizeof(struct sockaddr_in6); 160b208ff84SHajimu UMEMOTO #endif 161b208ff84SHajimu UMEMOTO getnameinfo(sin, salen, host->addr, sizeof(host->addr), 162b208ff84SHajimu UMEMOTO NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); 1638053080cSYoshinobu Inoue #else 1642aef6930SMark Murray struct sockaddr_in *sin = host->sin; 1652aef6930SMark Murray 1662aef6930SMark Murray if (sin != 0) 1672aef6930SMark Murray STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr)); 1688053080cSYoshinobu Inoue #endif 1692aef6930SMark Murray } 1702aef6930SMark Murray 1712aef6930SMark Murray /* sock_hostname - map endpoint address to host name */ 1722aef6930SMark Murray 1732aef6930SMark Murray void sock_hostname(host) 1742aef6930SMark Murray struct host_info *host; 1752aef6930SMark Murray { 1768053080cSYoshinobu Inoue #ifdef INET6 1778053080cSYoshinobu Inoue struct sockaddr *sin = host->sin; 178b208ff84SHajimu UMEMOTO struct sockaddr_in sin4; 179b208ff84SHajimu UMEMOTO struct addrinfo hints, *res, *res0 = NULL; 180b208ff84SHajimu UMEMOTO int salen, alen, err = 1; 181b208ff84SHajimu UMEMOTO char *ap = NULL, *rap, hname[NI_MAXHOST]; 1822aef6930SMark Murray 1838053080cSYoshinobu Inoue if (sin != NULL) { 184b208ff84SHajimu UMEMOTO if (sin->sa_family == AF_INET6) { 185b208ff84SHajimu UMEMOTO struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin; 186b208ff84SHajimu UMEMOTO 187b208ff84SHajimu UMEMOTO if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 188b208ff84SHajimu UMEMOTO memset(&sin4, 0, sizeof(sin4)); 189b208ff84SHajimu UMEMOTO #ifdef SIN6_LEN 190b208ff84SHajimu UMEMOTO sin4.sin_len = sizeof(sin4); 191b208ff84SHajimu UMEMOTO #endif 192b208ff84SHajimu UMEMOTO sin4.sin_family = AF_INET; 193b208ff84SHajimu UMEMOTO sin4.sin_port = sin6->sin6_port; 194b208ff84SHajimu UMEMOTO sin4.sin_addr.s_addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; 195b208ff84SHajimu UMEMOTO sin = (struct sockaddr *)&sin4; 196b208ff84SHajimu UMEMOTO } 197b208ff84SHajimu UMEMOTO } 1988053080cSYoshinobu Inoue switch (sin->sa_family) { 1998053080cSYoshinobu Inoue case AF_INET: 2008053080cSYoshinobu Inoue ap = (char *)&((struct sockaddr_in *)sin)->sin_addr; 2018053080cSYoshinobu Inoue alen = sizeof(struct in_addr); 202b208ff84SHajimu UMEMOTO salen = sizeof(struct sockaddr_in); 2038053080cSYoshinobu Inoue break; 2048053080cSYoshinobu Inoue case AF_INET6: 2058053080cSYoshinobu Inoue ap = (char *)&((struct sockaddr_in6 *)sin)->sin6_addr; 2068053080cSYoshinobu Inoue alen = sizeof(struct in6_addr); 207b208ff84SHajimu UMEMOTO salen = sizeof(struct sockaddr_in6); 2088053080cSYoshinobu Inoue break; 209b208ff84SHajimu UMEMOTO default: 210b208ff84SHajimu UMEMOTO break; 2118053080cSYoshinobu Inoue } 212b208ff84SHajimu UMEMOTO if (ap) 213b208ff84SHajimu UMEMOTO err = getnameinfo(sin, salen, hname, sizeof(hname), 214b208ff84SHajimu UMEMOTO NULL, 0, NI_WITHSCOPEID | NI_NAMEREQD); 2158053080cSYoshinobu Inoue } 216b208ff84SHajimu UMEMOTO if (!err) { 2172aef6930SMark Murray 218b208ff84SHajimu UMEMOTO STRN_CPY(host->name, hname, sizeof(host->name)); 2192aef6930SMark Murray 22065688488SHajimu UMEMOTO /* reject numeric addresses */ 22165688488SHajimu UMEMOTO memset(&hints, 0, sizeof(hints)); 22265688488SHajimu UMEMOTO hints.ai_family = sin->sa_family; 22365688488SHajimu UMEMOTO hints.ai_socktype = SOCK_STREAM; 22465688488SHajimu UMEMOTO hints.ai_flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST; 22565688488SHajimu UMEMOTO if ((err = getaddrinfo(host->name, NULL, &hints, &res0) == 0)) { 22665688488SHajimu UMEMOTO freeaddrinfo(res0); 22765688488SHajimu UMEMOTO tcpd_warn("host name/name mismatch: " 22865688488SHajimu UMEMOTO "reverse lookup results in non-FQDN %s", 22965688488SHajimu UMEMOTO host->name); 23065688488SHajimu UMEMOTO strcpy(host->name, paranoid); /* name is bad, clobber it */ 23165688488SHajimu UMEMOTO } 23265688488SHajimu UMEMOTO err = !err; 23365688488SHajimu UMEMOTO } 23465688488SHajimu UMEMOTO if (!err) { 23565688488SHajimu UMEMOTO /* we are now sure that this is non-numeric */ 23665688488SHajimu UMEMOTO 2372aef6930SMark Murray /* 2382aef6930SMark Murray * Verify that the address is a member of the address list returned 2392aef6930SMark Murray * by gethostbyname(hostname). 2402aef6930SMark Murray * 2412aef6930SMark Murray * Verify also that gethostbyaddr() and gethostbyname() return the same 2422aef6930SMark Murray * hostname, or rshd and rlogind may still end up being spoofed. 2432aef6930SMark Murray * 2442aef6930SMark Murray * On some sites, gethostbyname("localhost") returns "localhost.domain". 2452aef6930SMark Murray * This is a DNS artefact. We treat it as a special case. When we 2462aef6930SMark Murray * can't believe the address list from gethostbyname("localhost") 2472aef6930SMark Murray * we're in big trouble anyway. 2482aef6930SMark Murray */ 2492aef6930SMark Murray 250b208ff84SHajimu UMEMOTO memset(&hints, 0, sizeof(hints)); 251b208ff84SHajimu UMEMOTO hints.ai_family = sin->sa_family; 252b208ff84SHajimu UMEMOTO hints.ai_socktype = SOCK_STREAM; 253b208ff84SHajimu UMEMOTO hints.ai_flags = AI_PASSIVE | AI_CANONNAME; 254b208ff84SHajimu UMEMOTO if (getaddrinfo(host->name, NULL, &hints, &res0) != 0) { 2552aef6930SMark Murray 2562aef6930SMark Murray /* 2572aef6930SMark Murray * Unable to verify that the host name matches the address. This 2582aef6930SMark Murray * may be a transient problem or a botched name server setup. 2592aef6930SMark Murray */ 2602aef6930SMark Murray 261b208ff84SHajimu UMEMOTO tcpd_warn("can't verify hostname: getaddrinfo(%s, %s) failed", 2628053080cSYoshinobu Inoue host->name, 2638053080cSYoshinobu Inoue (sin->sa_family == AF_INET) ? "AF_INET" : "AF_INET6"); 264b208ff84SHajimu UMEMOTO 2652f0cc2fdSHajimu UMEMOTO } else if ((res0->ai_canonname == NULL 2662f0cc2fdSHajimu UMEMOTO || STR_NE(host->name, res0->ai_canonname)) 267b208ff84SHajimu UMEMOTO && STR_NE(host->name, "localhost")) { 268b208ff84SHajimu UMEMOTO 269b208ff84SHajimu UMEMOTO /* 270b208ff84SHajimu UMEMOTO * The gethostbyaddr() and gethostbyname() calls did not return 271b208ff84SHajimu UMEMOTO * the same hostname. This could be a nameserver configuration 272b208ff84SHajimu UMEMOTO * problem. It could also be that someone is trying to spoof us. 273b208ff84SHajimu UMEMOTO */ 274b208ff84SHajimu UMEMOTO 275b208ff84SHajimu UMEMOTO tcpd_warn("host name/name mismatch: %s != %.*s", 2762f0cc2fdSHajimu UMEMOTO host->name, STRING_LENGTH, 2772f0cc2fdSHajimu UMEMOTO (res0->ai_canonname == NULL) ? "" : res0->ai_canonname); 278b208ff84SHajimu UMEMOTO 279b208ff84SHajimu UMEMOTO } else { 280b208ff84SHajimu UMEMOTO 281b208ff84SHajimu UMEMOTO /* 282b208ff84SHajimu UMEMOTO * The address should be a member of the address list returned by 283b208ff84SHajimu UMEMOTO * gethostbyname(). We should first verify that the h_addrtype 284b208ff84SHajimu UMEMOTO * field is AF_INET, but this program has already caused too much 285b208ff84SHajimu UMEMOTO * grief on systems with broken library code. 286b208ff84SHajimu UMEMOTO */ 287b208ff84SHajimu UMEMOTO 288b208ff84SHajimu UMEMOTO for (res = res0; res; res = res->ai_next) { 289b208ff84SHajimu UMEMOTO if (res->ai_family != sin->sa_family) 290b208ff84SHajimu UMEMOTO continue; 291b208ff84SHajimu UMEMOTO switch (res->ai_family) { 292b208ff84SHajimu UMEMOTO case AF_INET: 293b208ff84SHajimu UMEMOTO rap = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr; 294b208ff84SHajimu UMEMOTO break; 295b208ff84SHajimu UMEMOTO case AF_INET6: 29665688488SHajimu UMEMOTO /* need to check scope_id */ 29765688488SHajimu UMEMOTO if (((struct sockaddr_in6 *)sin)->sin6_scope_id != 29865688488SHajimu UMEMOTO ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) { 29965688488SHajimu UMEMOTO continue; 30065688488SHajimu UMEMOTO } 301b208ff84SHajimu UMEMOTO rap = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; 302b208ff84SHajimu UMEMOTO break; 303b208ff84SHajimu UMEMOTO default: 304b208ff84SHajimu UMEMOTO continue; 305b208ff84SHajimu UMEMOTO } 306b208ff84SHajimu UMEMOTO if (memcmp(rap, ap, alen) == 0) { 307b208ff84SHajimu UMEMOTO freeaddrinfo(res0); 308b208ff84SHajimu UMEMOTO return; /* name is good, keep it */ 309b208ff84SHajimu UMEMOTO } 310b208ff84SHajimu UMEMOTO } 311b208ff84SHajimu UMEMOTO 312b208ff84SHajimu UMEMOTO /* 313b208ff84SHajimu UMEMOTO * The host name does not map to the initial address. Perhaps 314b208ff84SHajimu UMEMOTO * someone has messed up. Perhaps someone compromised a name 315b208ff84SHajimu UMEMOTO * server. 316b208ff84SHajimu UMEMOTO */ 317b208ff84SHajimu UMEMOTO 318b208ff84SHajimu UMEMOTO getnameinfo(sin, salen, hname, sizeof(hname), 319b208ff84SHajimu UMEMOTO NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); 320b208ff84SHajimu UMEMOTO tcpd_warn("host name/address mismatch: %s != %.*s", 3212f0cc2fdSHajimu UMEMOTO hname, STRING_LENGTH, 3222f0cc2fdSHajimu UMEMOTO (res0->ai_canonname == NULL) ? "" : res0->ai_canonname); 323b208ff84SHajimu UMEMOTO } 324b208ff84SHajimu UMEMOTO strcpy(host->name, paranoid); /* name is bad, clobber it */ 325b208ff84SHajimu UMEMOTO if (res0) 326b208ff84SHajimu UMEMOTO freeaddrinfo(res0); 327b208ff84SHajimu UMEMOTO } 328b208ff84SHajimu UMEMOTO #else /* INET6 */ 329b208ff84SHajimu UMEMOTO struct sockaddr_in *sin = host->sin; 330b208ff84SHajimu UMEMOTO struct hostent *hp; 331b208ff84SHajimu UMEMOTO int i; 332b208ff84SHajimu UMEMOTO 333b208ff84SHajimu UMEMOTO /* 334b208ff84SHajimu UMEMOTO * On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does 335b208ff84SHajimu UMEMOTO * not fail. Instead it returns "INADDR_ANY". Unfortunately, this does 336b208ff84SHajimu UMEMOTO * not work the other way around: gethostbyname("INADDR_ANY") fails. We 337b208ff84SHajimu UMEMOTO * have to special-case 0.0.0.0, in order to avoid false alerts from the 338b208ff84SHajimu UMEMOTO * host name/address checking code below. 339b208ff84SHajimu UMEMOTO */ 340b208ff84SHajimu UMEMOTO if (sin != 0 && sin->sin_addr.s_addr != 0 341b208ff84SHajimu UMEMOTO && (hp = gethostbyaddr((char *) &(sin->sin_addr), 342b208ff84SHajimu UMEMOTO sizeof(sin->sin_addr), AF_INET)) != 0) { 343b208ff84SHajimu UMEMOTO 344b208ff84SHajimu UMEMOTO STRN_CPY(host->name, hp->h_name, sizeof(host->name)); 345b208ff84SHajimu UMEMOTO 346b208ff84SHajimu UMEMOTO /* 347b208ff84SHajimu UMEMOTO * Verify that the address is a member of the address list returned 348b208ff84SHajimu UMEMOTO * by gethostbyname(hostname). 349b208ff84SHajimu UMEMOTO * 350b208ff84SHajimu UMEMOTO * Verify also that gethostbyaddr() and gethostbyname() return the same 351b208ff84SHajimu UMEMOTO * hostname, or rshd and rlogind may still end up being spoofed. 352b208ff84SHajimu UMEMOTO * 353b208ff84SHajimu UMEMOTO * On some sites, gethostbyname("localhost") returns "localhost.domain". 354b208ff84SHajimu UMEMOTO * This is a DNS artefact. We treat it as a special case. When we 355b208ff84SHajimu UMEMOTO * can't believe the address list from gethostbyname("localhost") 356b208ff84SHajimu UMEMOTO * we're in big trouble anyway. 357b208ff84SHajimu UMEMOTO */ 358b208ff84SHajimu UMEMOTO 359b208ff84SHajimu UMEMOTO if ((hp = gethostbyname(host->name)) == 0) { 360b208ff84SHajimu UMEMOTO 361b208ff84SHajimu UMEMOTO /* 362b208ff84SHajimu UMEMOTO * Unable to verify that the host name matches the address. This 363b208ff84SHajimu UMEMOTO * may be a transient problem or a botched name server setup. 364b208ff84SHajimu UMEMOTO */ 365b208ff84SHajimu UMEMOTO 3662aef6930SMark Murray tcpd_warn("can't verify hostname: gethostbyname(%s) failed", 3672aef6930SMark Murray host->name); 3682aef6930SMark Murray 3692aef6930SMark Murray } else if (STR_NE(host->name, hp->h_name) 3702aef6930SMark Murray && STR_NE(host->name, "localhost")) { 3712aef6930SMark Murray 3722aef6930SMark Murray /* 3732aef6930SMark Murray * The gethostbyaddr() and gethostbyname() calls did not return 3742aef6930SMark Murray * the same hostname. This could be a nameserver configuration 3752aef6930SMark Murray * problem. It could also be that someone is trying to spoof us. 3762aef6930SMark Murray */ 3772aef6930SMark Murray 3782aef6930SMark Murray tcpd_warn("host name/name mismatch: %s != %.*s", 3792aef6930SMark Murray host->name, STRING_LENGTH, hp->h_name); 3802aef6930SMark Murray 3812aef6930SMark Murray } else { 3822aef6930SMark Murray 3832aef6930SMark Murray /* 3842aef6930SMark Murray * The address should be a member of the address list returned by 3852aef6930SMark Murray * gethostbyname(). We should first verify that the h_addrtype 3862aef6930SMark Murray * field is AF_INET, but this program has already caused too much 3872aef6930SMark Murray * grief on systems with broken library code. 3882aef6930SMark Murray */ 3892aef6930SMark Murray 3902aef6930SMark Murray for (i = 0; hp->h_addr_list[i]; i++) { 3912aef6930SMark Murray if (memcmp(hp->h_addr_list[i], 3922aef6930SMark Murray (char *) &sin->sin_addr, 3932aef6930SMark Murray sizeof(sin->sin_addr)) == 0) 3942aef6930SMark Murray return; /* name is good, keep it */ 3952aef6930SMark Murray } 3962aef6930SMark Murray 3972aef6930SMark Murray /* 3982aef6930SMark Murray * The host name does not map to the initial address. Perhaps 3992aef6930SMark Murray * someone has messed up. Perhaps someone compromised a name 4002aef6930SMark Murray * server. 4012aef6930SMark Murray */ 4022aef6930SMark Murray 4032aef6930SMark Murray tcpd_warn("host name/address mismatch: %s != %.*s", 4042aef6930SMark Murray inet_ntoa(sin->sin_addr), STRING_LENGTH, hp->h_name); 4052aef6930SMark Murray } 4062aef6930SMark Murray strcpy(host->name, paranoid); /* name is bad, clobber it */ 4072aef6930SMark Murray } 408b208ff84SHajimu UMEMOTO #endif /* INET6 */ 4092aef6930SMark Murray } 4102aef6930SMark Murray 4112aef6930SMark Murray /* sock_sink - absorb unreceived IP datagram */ 4122aef6930SMark Murray 4132aef6930SMark Murray static void sock_sink(fd) 4142aef6930SMark Murray int fd; 4152aef6930SMark Murray { 4162aef6930SMark Murray char buf[BUFSIZ]; 4178053080cSYoshinobu Inoue #ifdef INET6 4188053080cSYoshinobu Inoue struct sockaddr_storage sin; 4198053080cSYoshinobu Inoue #else 4202aef6930SMark Murray struct sockaddr_in sin; 4218053080cSYoshinobu Inoue #endif 4222aef6930SMark Murray int size = sizeof(sin); 4232aef6930SMark Murray 4242aef6930SMark Murray /* 4252aef6930SMark Murray * Eat up the not-yet received datagram. Some systems insist on a 4262aef6930SMark Murray * non-zero source address argument in the recvfrom() call below. 4272aef6930SMark Murray */ 4282aef6930SMark Murray 4292aef6930SMark Murray (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *) & sin, &size); 4302aef6930SMark Murray } 431