1*0Sstevel@tonic-gate*** socket.c.org Fri Mar 21 19:27:25 1997 2*0Sstevel@tonic-gate--- socket.c Mon Sep 27 17:21:46 1999 3*0Sstevel@tonic-gate*************** 4*0Sstevel@tonic-gate*** 74,82 **** 5*0Sstevel@tonic-gate void sock_host(request) 6*0Sstevel@tonic-gate struct request_info *request; 7*0Sstevel@tonic-gate { 8*0Sstevel@tonic-gate! static struct sockaddr_in client; 9*0Sstevel@tonic-gate! static struct sockaddr_in server; 10*0Sstevel@tonic-gate! int len; 11*0Sstevel@tonic-gate char buf[BUFSIZ]; 12*0Sstevel@tonic-gate int fd = request->fd; 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gate--- 74,81 ---- 15*0Sstevel@tonic-gate void sock_host(request) 16*0Sstevel@tonic-gate struct request_info *request; 17*0Sstevel@tonic-gate { 18*0Sstevel@tonic-gate! static struct sockaddr_gen client; 19*0Sstevel@tonic-gate! static struct sockaddr_gen server; 20*0Sstevel@tonic-gate char buf[BUFSIZ]; 21*0Sstevel@tonic-gate int fd = request->fd; 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate*************** 24*0Sstevel@tonic-gate*** 91,102 **** 25*0Sstevel@tonic-gate * broken library code. 26*0Sstevel@tonic-gate */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate! len = sizeof(client); 29*0Sstevel@tonic-gate! if (getpeername(fd, (struct sockaddr *) & client, &len) < 0) { 30*0Sstevel@tonic-gate request->sink = sock_sink; 31*0Sstevel@tonic-gate! len = sizeof(client); 32*0Sstevel@tonic-gate if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK, 33*0Sstevel@tonic-gate! (struct sockaddr *) & client, &len) < 0) { 34*0Sstevel@tonic-gate tcpd_warn("can't get client address: %m"); 35*0Sstevel@tonic-gate return; /* give up */ 36*0Sstevel@tonic-gate } 37*0Sstevel@tonic-gate--- 90,102 ---- 38*0Sstevel@tonic-gate * broken library code. 39*0Sstevel@tonic-gate */ 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate! client.sg_len = sizeof(client.sg_addr); 42*0Sstevel@tonic-gate! if (getpeername(fd, (struct sockaddr *) ADDRP(client), 43*0Sstevel@tonic-gate! &client.sg_len) < 0) { 44*0Sstevel@tonic-gate request->sink = sock_sink; 45*0Sstevel@tonic-gate! client.sg_len = sizeof(client.sg_addr); 46*0Sstevel@tonic-gate if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK, 47*0Sstevel@tonic-gate! (struct sockaddr *) ADDRP(client), &client.sg_len) < 0) { 48*0Sstevel@tonic-gate tcpd_warn("can't get client address: %m"); 49*0Sstevel@tonic-gate return; /* give up */ 50*0Sstevel@tonic-gate } 51*0Sstevel@tonic-gate*************** 52*0Sstevel@tonic-gate*** 104,110 **** 53*0Sstevel@tonic-gate memset(buf, 0 sizeof(buf)); 54*0Sstevel@tonic-gate #endif 55*0Sstevel@tonic-gate } 56*0Sstevel@tonic-gate! request->client->sin = &client; 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate /* 59*0Sstevel@tonic-gate * Determine the server binding. This is used for client username 60*0Sstevel@tonic-gate--- 104,111 ---- 61*0Sstevel@tonic-gate memset(buf, 0 sizeof(buf)); 62*0Sstevel@tonic-gate #endif 63*0Sstevel@tonic-gate } 64*0Sstevel@tonic-gate! sockgen_simplify(&client); 65*0Sstevel@tonic-gate! request->client->sag = &client; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate /* 68*0Sstevel@tonic-gate * Determine the server binding. This is used for client username 69*0Sstevel@tonic-gate*************** 70*0Sstevel@tonic-gate*** 112,123 **** 71*0Sstevel@tonic-gate * address or name. 72*0Sstevel@tonic-gate */ 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate! len = sizeof(server); 75*0Sstevel@tonic-gate! if (getsockname(fd, (struct sockaddr *) & server, &len) < 0) { 76*0Sstevel@tonic-gate tcpd_warn("getsockname: %m"); 77*0Sstevel@tonic-gate return; 78*0Sstevel@tonic-gate } 79*0Sstevel@tonic-gate! request->server->sin = &server; 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate /* sock_hostaddr - map endpoint address to printable form */ 83*0Sstevel@tonic-gate--- 113,126 ---- 84*0Sstevel@tonic-gate * address or name. 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate! server.sg_len = sizeof(server.sg_addr); 88*0Sstevel@tonic-gate! if (getsockname(fd, (struct sockaddr *) ADDRP(server), 89*0Sstevel@tonic-gate! &server.sg_len) < 0) { 90*0Sstevel@tonic-gate tcpd_warn("getsockname: %m"); 91*0Sstevel@tonic-gate return; 92*0Sstevel@tonic-gate } 93*0Sstevel@tonic-gate! sockgen_simplify(&server); 94*0Sstevel@tonic-gate! request->server->sag = &server; 95*0Sstevel@tonic-gate } 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate /* sock_hostaddr - map endpoint address to printable form */ 98*0Sstevel@tonic-gate*************** 99*0Sstevel@tonic-gate*** 125,134 **** 100*0Sstevel@tonic-gate void sock_hostaddr(host) 101*0Sstevel@tonic-gate struct host_info *host; 102*0Sstevel@tonic-gate { 103*0Sstevel@tonic-gate! struct sockaddr_in *sin = host->sin; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate! if (sin != 0) 106*0Sstevel@tonic-gate! STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr)); 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate /* sock_hostname - map endpoint address to host name */ 110*0Sstevel@tonic-gate--- 128,142 ---- 111*0Sstevel@tonic-gate void sock_hostaddr(host) 112*0Sstevel@tonic-gate struct host_info *host; 113*0Sstevel@tonic-gate { 114*0Sstevel@tonic-gate! struct sockaddr_gen *sag = host->sag; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate! if (sag != 0) 117*0Sstevel@tonic-gate! #ifdef HAVE_IPV6 118*0Sstevel@tonic-gate! 119*0Sstevel@tonic-gate! (void) inet_ntop(FAMILY(*sag), FADDRP(*sag), host->addr, sizeof(host->addr)); 120*0Sstevel@tonic-gate! #else 121*0Sstevel@tonic-gate! STRN_CPY(host->addr, inet_ntoa(sag->sg_sin.sin_addr), sizeof(host->addr)); 122*0Sstevel@tonic-gate! #endif 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate /* sock_hostname - map endpoint address to host name */ 126*0Sstevel@tonic-gate*************** 127*0Sstevel@tonic-gate*** 136,142 **** 128*0Sstevel@tonic-gate void sock_hostname(host) 129*0Sstevel@tonic-gate struct host_info *host; 130*0Sstevel@tonic-gate { 131*0Sstevel@tonic-gate! struct sockaddr_in *sin = host->sin; 132*0Sstevel@tonic-gate struct hostent *hp; 133*0Sstevel@tonic-gate int i; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate--- 144,150 ---- 136*0Sstevel@tonic-gate void sock_hostname(host) 137*0Sstevel@tonic-gate struct host_info *host; 138*0Sstevel@tonic-gate { 139*0Sstevel@tonic-gate! struct sockaddr_gen *sag = host->sag; 140*0Sstevel@tonic-gate struct hostent *hp; 141*0Sstevel@tonic-gate int i; 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate*************** 144*0Sstevel@tonic-gate*** 146,155 **** 145*0Sstevel@tonic-gate * not work the other way around: gethostbyname("INADDR_ANY") fails. We 146*0Sstevel@tonic-gate * have to special-case 0.0.0.0, in order to avoid false alerts from the 147*0Sstevel@tonic-gate * host name/address checking code below. 148*0Sstevel@tonic-gate */ 149*0Sstevel@tonic-gate! if (sin != 0 && sin->sin_addr.s_addr != 0 150*0Sstevel@tonic-gate! && (hp = gethostbyaddr((char *) &(sin->sin_addr), 151*0Sstevel@tonic-gate! sizeof(sin->sin_addr), AF_INET)) != 0) { 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate STRN_CPY(host->name, hp->h_name, sizeof(host->name)); 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate--- 154,165 ---- 156*0Sstevel@tonic-gate * not work the other way around: gethostbyname("INADDR_ANY") fails. We 157*0Sstevel@tonic-gate * have to special-case 0.0.0.0, in order to avoid false alerts from the 158*0Sstevel@tonic-gate * host name/address checking code below. 159*0Sstevel@tonic-gate+ * 160*0Sstevel@tonic-gate+ * We assume this works correctly in the INET6 case. 161*0Sstevel@tonic-gate */ 162*0Sstevel@tonic-gate! if (sag != 0 163*0Sstevel@tonic-gate! && (FAMILY(*sag) != AF_INET || sag->sg_sin.sin_addr.s_addr != 0) 164*0Sstevel@tonic-gate! && (hp = gethostbyaddr(FADDRP(*sag), FSIZE(*sag), FAMILY(*sag))) != 0) { 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate STRN_CPY(host->name, hp->h_name, sizeof(host->name)); 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate*************** 169*0Sstevel@tonic-gate*** 166,172 **** 170*0Sstevel@tonic-gate * we're in big trouble anyway. 171*0Sstevel@tonic-gate */ 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate! if ((hp = gethostbyname(host->name)) == 0) { 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate /* 176*0Sstevel@tonic-gate * Unable to verify that the host name matches the address. This 177*0Sstevel@tonic-gate--- 176,188 ---- 178*0Sstevel@tonic-gate * we're in big trouble anyway. 179*0Sstevel@tonic-gate */ 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate! #ifdef HAVE_IPV6 182*0Sstevel@tonic-gate! if (FAMILY(*sag) != AF_INET) 183*0Sstevel@tonic-gate! hp = getipnodebyname(host->name, FAMILY(*sag), AI_DEFAULT, 0); 184*0Sstevel@tonic-gate! else 185*0Sstevel@tonic-gate! #endif 186*0Sstevel@tonic-gate! hp = gethostbyname(host->name); 187*0Sstevel@tonic-gate! if (hp == 0) { 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * Unable to verify that the host name matches the address. This 191*0Sstevel@tonic-gate*************** 192*0Sstevel@tonic-gate*** 189,194 **** 193*0Sstevel@tonic-gate--- 205,213 ---- 194*0Sstevel@tonic-gate host->name, STRING_LENGTH, hp->h_name); 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate } else { 197*0Sstevel@tonic-gate+ #ifdef HAVE_IPV6 198*0Sstevel@tonic-gate+ char buf[INET6_ADDRSTRLEN]; 199*0Sstevel@tonic-gate+ #endif 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate /* 202*0Sstevel@tonic-gate * The address should be a member of the address list returned by 203*0Sstevel@tonic-gate*************** 204*0Sstevel@tonic-gate*** 199,207 **** 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate for (i = 0; hp->h_addr_list[i]; i++) { 207*0Sstevel@tonic-gate if (memcmp(hp->h_addr_list[i], 208*0Sstevel@tonic-gate! (char *) &sin->sin_addr, 209*0Sstevel@tonic-gate! sizeof(sin->sin_addr)) == 0) 210*0Sstevel@tonic-gate return; /* name is good, keep it */ 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate /* 214*0Sstevel@tonic-gate--- 218,231 ---- 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate for (i = 0; hp->h_addr_list[i]; i++) { 217*0Sstevel@tonic-gate if (memcmp(hp->h_addr_list[i], 218*0Sstevel@tonic-gate! (char *) FADDRP(*sag), 219*0Sstevel@tonic-gate! FSIZE(*sag)) == 0) { 220*0Sstevel@tonic-gate! #ifdef HAVE_IPV6 221*0Sstevel@tonic-gate! if (hp != 0 && FAMILY(*sag) != AF_INET) 222*0Sstevel@tonic-gate! freehostent(hp); 223*0Sstevel@tonic-gate! #endif 224*0Sstevel@tonic-gate return; /* name is good, keep it */ 225*0Sstevel@tonic-gate+ } 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate /* 229*0Sstevel@tonic-gate*************** 230*0Sstevel@tonic-gate*** 209,218 **** 231*0Sstevel@tonic-gate * someone has messed up. Perhaps someone compromised a name 232*0Sstevel@tonic-gate * server. 233*0Sstevel@tonic-gate */ 234*0Sstevel@tonic-gate- 235*0Sstevel@tonic-gate tcpd_warn("host name/address mismatch: %s != %.*s", 236*0Sstevel@tonic-gate! inet_ntoa(sin->sin_addr), STRING_LENGTH, hp->h_name); 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate strcpy(host->name, paranoid); /* name is bad, clobber it */ 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate--- 233,250 ---- 242*0Sstevel@tonic-gate * someone has messed up. Perhaps someone compromised a name 243*0Sstevel@tonic-gate * server. 244*0Sstevel@tonic-gate */ 245*0Sstevel@tonic-gate tcpd_warn("host name/address mismatch: %s != %.*s", 246*0Sstevel@tonic-gate! #ifdef HAVE_IPV6 247*0Sstevel@tonic-gate! inet_ntop(FAMILY(*sag), FADDRP(*sag), buf, sizeof(buf)), 248*0Sstevel@tonic-gate! #else 249*0Sstevel@tonic-gate! inet_ntoa(sag->sg_sin.sin_addr), 250*0Sstevel@tonic-gate! #endif 251*0Sstevel@tonic-gate! STRING_LENGTH, hp->h_name); 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate+ #ifdef HAVE_IPV6 254*0Sstevel@tonic-gate+ if (hp != 0 && FAMILY(*sag) != AF_INET) 255*0Sstevel@tonic-gate+ freehostent(hp); 256*0Sstevel@tonic-gate+ #endif 257*0Sstevel@tonic-gate strcpy(host->name, paranoid); /* name is bad, clobber it */ 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate*************** 261*0Sstevel@tonic-gate*** 232,235 **** 262*0Sstevel@tonic-gate--- 264,290 ---- 263*0Sstevel@tonic-gate */ 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *) & sin, &size); 266*0Sstevel@tonic-gate+ } 267*0Sstevel@tonic-gate+ 268*0Sstevel@tonic-gate+ void sockgen_simplify(sg) 269*0Sstevel@tonic-gate+ sockaddr_gen *sg; 270*0Sstevel@tonic-gate+ { 271*0Sstevel@tonic-gate+ #ifdef HAVE_IPV6 272*0Sstevel@tonic-gate+ if (sg->sg_family == AF_INET6 && 273*0Sstevel@tonic-gate+ IN6_IS_ADDR_V4MAPPED(&sg->sg_sin6.sin6_addr)) { 274*0Sstevel@tonic-gate+ struct sockaddr_in v4_addr; 275*0Sstevel@tonic-gate+ 276*0Sstevel@tonic-gate+ #ifdef IN6_V4MAPPED_TO_INADDR 277*0Sstevel@tonic-gate+ IN6_V4MAPPED_TO_INADDR(&sg->sg_sin6.sin6_addr, &v4_addr.sin_addr); 278*0Sstevel@tonic-gate+ #else 279*0Sstevel@tonic-gate+ IN6_MAPPED_TO_V4(&sg->sg_sin6.sin6_addr, &v4_addr.sin_addr); 280*0Sstevel@tonic-gate+ #endif 281*0Sstevel@tonic-gate+ v4_addr.sin_port = sg->sg_sin6.sin6_port; 282*0Sstevel@tonic-gate+ v4_addr.sin_family = AF_INET; 283*0Sstevel@tonic-gate+ memcpy(&sg->sg_sin,&v4_addr, sizeof(v4_addr)); 284*0Sstevel@tonic-gate+ sg->sg_len = sizeof(struct in_addr); 285*0Sstevel@tonic-gate+ } 286*0Sstevel@tonic-gate+ #else 287*0Sstevel@tonic-gate+ return; 288*0Sstevel@tonic-gate+ #endif 289*0Sstevel@tonic-gate } 290