socket.c.diff revision 7c478bd95313f5f23a4c958a745db2134aa03244
*** socket.c.org Fri Mar 21 19:27:25 1997
--- socket.c Mon Sep 27 17:21:46 1999
***************
*** 74,82 ****
void sock_host(request)
struct request_info *request;
{
! static struct sockaddr_in client;
! static struct sockaddr_in server;
! int len;
char buf[BUFSIZ];
int fd = request->fd;
--- 74,81 ----
void sock_host(request)
struct request_info *request;
{
! static struct sockaddr_gen client;
! static struct sockaddr_gen server;
char buf[BUFSIZ];
int fd = request->fd;
***************
*** 91,102 ****
* broken library code.
*/
! len = sizeof(client);
! if (getpeername(fd, (struct sockaddr *) & client, &len) < 0) {
request->sink = sock_sink;
! len = sizeof(client);
if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK,
! (struct sockaddr *) & client, &len) < 0) {
tcpd_warn("can't get client address: %m");
return; /* give up */
}
--- 90,102 ----
* broken library code.
*/
! client.sg_len = sizeof(client.sg_addr);
! if (getpeername(fd, (struct sockaddr *) ADDRP(client),
! &client.sg_len) < 0) {
request->sink = sock_sink;
! client.sg_len = sizeof(client.sg_addr);
if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK,
! (struct sockaddr *) ADDRP(client), &client.sg_len) < 0) {
tcpd_warn("can't get client address: %m");
return; /* give up */
}
***************
*** 104,110 ****
memset(buf, 0 sizeof(buf));
#endif
}
! request->client->sin = &client;
/*
* Determine the server binding. This is used for client username
--- 104,111 ----
memset(buf, 0 sizeof(buf));
#endif
}
! sockgen_simplify(&client);
! request->client->sag = &client;
/*
* Determine the server binding. This is used for client username
***************
*** 112,123 ****
* address or name.
*/
! len = sizeof(server);
! if (getsockname(fd, (struct sockaddr *) & server, &len) < 0) {
tcpd_warn("getsockname: %m");
return;
}
! request->server->sin = &server;
}
/* sock_hostaddr - map endpoint address to printable form */
--- 113,126 ----
* address or name.
*/
! server.sg_len = sizeof(server.sg_addr);
! if (getsockname(fd, (struct sockaddr *) ADDRP(server),
! &server.sg_len) < 0) {
tcpd_warn("getsockname: %m");
return;
}
! sockgen_simplify(&server);
! request->server->sag = &server;
}
/* sock_hostaddr - map endpoint address to printable form */
***************
*** 125,134 ****
void sock_hostaddr(host)
struct host_info *host;
{
! struct sockaddr_in *sin = host->sin;
! if (sin != 0)
! STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr));
}
/* sock_hostname - map endpoint address to host name */
--- 128,142 ----
void sock_hostaddr(host)
struct host_info *host;
{
! struct sockaddr_gen *sag = host->sag;
! if (sag != 0)
! #ifdef HAVE_IPV6
!
! (void) inet_ntop(FAMILY(*sag), FADDRP(*sag), host->addr, sizeof(host->addr));
! #else
! STRN_CPY(host->addr, inet_ntoa(sag->sg_sin.sin_addr), sizeof(host->addr));
! #endif
}
/* sock_hostname - map endpoint address to host name */
***************
*** 136,142 ****
void sock_hostname(host)
struct host_info *host;
{
! struct sockaddr_in *sin = host->sin;
struct hostent *hp;
int i;
--- 144,150 ----
void sock_hostname(host)
struct host_info *host;
{
! struct sockaddr_gen *sag = host->sag;
struct hostent *hp;
int i;
***************
*** 146,155 ****
* not work the other way around: gethostbyname("INADDR_ANY") fails. We
* have to special-case 0.0.0.0, in order to avoid false alerts from the
* host name/address checking code below.
*/
! if (sin != 0 && sin->sin_addr.s_addr != 0
! && (hp = gethostbyaddr((char *) &(sin->sin_addr),
! sizeof(sin->sin_addr), AF_INET)) != 0) {
STRN_CPY(host->name, hp->h_name, sizeof(host->name));
--- 154,165 ----
* not work the other way around: gethostbyname("INADDR_ANY") fails. We
* have to special-case 0.0.0.0, in order to avoid false alerts from the
* host name/address checking code below.
+ *
+ * We assume this works correctly in the INET6 case.
*/
! if (sag != 0
! && (FAMILY(*sag) != AF_INET || sag->sg_sin.sin_addr.s_addr != 0)
! && (hp = gethostbyaddr(FADDRP(*sag), FSIZE(*sag), FAMILY(*sag))) != 0) {
STRN_CPY(host->name, hp->h_name, sizeof(host->name));
***************
*** 166,172 ****
* we're in big trouble anyway.
*/
! if ((hp = gethostbyname(host->name)) == 0) {
/*
* Unable to verify that the host name matches the address. This
--- 176,188 ----
* we're in big trouble anyway.
*/
! #ifdef HAVE_IPV6
! if (FAMILY(*sag) != AF_INET)
! hp = getipnodebyname(host->name, FAMILY(*sag), AI_DEFAULT, 0);
! else
! #endif
! hp = gethostbyname(host->name);
! if (hp == 0) {
/*
* Unable to verify that the host name matches the address. This
***************
*** 189,194 ****
--- 205,213 ----
host->name, STRING_LENGTH, hp->h_name);
} else {
+ #ifdef HAVE_IPV6
+ char buf[INET6_ADDRSTRLEN];
+ #endif
/*
* The address should be a member of the address list returned by
***************
*** 199,207 ****
for (i = 0; hp->h_addr_list[i]; i++) {
if (memcmp(hp->h_addr_list[i],
! (char *) &sin->sin_addr,
! sizeof(sin->sin_addr)) == 0)
return; /* name is good, keep it */
}
/*
--- 218,231 ----
for (i = 0; hp->h_addr_list[i]; i++) {
if (memcmp(hp->h_addr_list[i],
! (char *) FADDRP(*sag),
! FSIZE(*sag)) == 0) {
! #ifdef HAVE_IPV6
! if (hp != 0 && FAMILY(*sag) != AF_INET)
! freehostent(hp);
! #endif
return; /* name is good, keep it */
+ }
}
/*
***************
*** 209,218 ****
* someone has messed up. Perhaps someone compromised a name
* server.
*/
-
tcpd_warn("host name/address mismatch: %s != %.*s",
! inet_ntoa(sin->sin_addr), STRING_LENGTH, hp->h_name);
}
strcpy(host->name, paranoid); /* name is bad, clobber it */
}
}
--- 233,250 ----
* someone has messed up. Perhaps someone compromised a name
* server.
*/
tcpd_warn("host name/address mismatch: %s != %.*s",
! #ifdef HAVE_IPV6
! inet_ntop(FAMILY(*sag), FADDRP(*sag), buf, sizeof(buf)),
! #else
! inet_ntoa(sag->sg_sin.sin_addr),
! #endif
! STRING_LENGTH, hp->h_name);
}
+ #ifdef HAVE_IPV6
+ if (hp != 0 && FAMILY(*sag) != AF_INET)
+ freehostent(hp);
+ #endif
strcpy(host->name, paranoid); /* name is bad, clobber it */
}
}
***************
*** 232,235 ****
--- 264,290 ----
*/
(void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *) & sin, &size);
+ }
+
+ void sockgen_simplify(sg)
+ sockaddr_gen *sg;
+ {
+ #ifdef HAVE_IPV6
+ if (sg->sg_family == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&sg->sg_sin6.sin6_addr)) {
+ struct sockaddr_in v4_addr;
+
+ #ifdef IN6_V4MAPPED_TO_INADDR
+ IN6_V4MAPPED_TO_INADDR(&sg->sg_sin6.sin6_addr, &v4_addr.sin_addr);
+ #else
+ IN6_MAPPED_TO_V4(&sg->sg_sin6.sin6_addr, &v4_addr.sin_addr);
+ #endif
+ v4_addr.sin_port = sg->sg_sin6.sin6_port;
+ v4_addr.sin_family = AF_INET;
+ memcpy(&sg->sg_sin,&v4_addr, sizeof(v4_addr));
+ sg->sg_len = sizeof(struct in_addr);
+ }
+ #else
+ return;
+ #endif
}