Commit 76f5fca9 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(cast_to_sockaddr_in): Removed.

(isc_mkipaddress): Changed struct sockaddr to SOCKADDR_STORAGE.
(isc_getladdress): Ditto.  Cast argument of getsockname from
	SOCKADDR_STORAGE* to struct sockaddr*.
(isc_getraddress): Ditto (but for getpeername instead of getsockname).
(isc_getipnum): Handle IPv6.
(isc_gethostname): Ditto.
(isc_getportnum): Ditto.
(isc_getservice): Use isc_getportnum to simplify code.
parent 4756259a
......@@ -89,23 +89,9 @@ char *inet_ntoa(ad)
#endif
/* cast a struct sockaddr to a struct sockaddr_in. On some systems,
this cast produces a warning:
isc_socket.c:225: warning: cast increases required alignment of target type
The cast should be safe, tough. This function removes the warning
in a safe manner. */
static inline struct sockaddr_in *
cast_to_sockaddr_in(struct sockaddr *in)
{
return (void*)in;
}
IscAddress *
isc_mkipaddress(struct sockaddr *addr)
isc_mkipaddress(SOCKADDR_STORAGE *addr)
{
IscAddress *ia;
......@@ -122,7 +108,7 @@ isc_mkipaddress(struct sockaddr *addr)
IscAddress *
isc_getladdress(IscSession *scb)
{
struct sockaddr addr;
SOCKADDR_STORAGE addr;
socklen_t len;
......@@ -131,7 +117,7 @@ isc_getladdress(IscSession *scb)
return NULL;
len = sizeof(addr);
if (getsockname(scb->fd, &addr, &len) < 0)
if (getsockname(scb->fd, (struct sockaddr *) &addr, &len) < 0)
return NULL;
return isc_mkipaddress(&addr);
......@@ -142,7 +128,7 @@ isc_getladdress(IscSession *scb)
IscAddress *
isc_getraddress(IscSession *scb)
{
struct sockaddr addr;
SOCKADDR_STORAGE addr;
socklen_t len;
......@@ -151,7 +137,7 @@ isc_getraddress(IscSession *scb)
return NULL;
len = sizeof(addr);
if (getpeername(scb->fd, &addr, &len) < 0)
if (getpeername(scb->fd, (struct sockaddr *) &addr, &len) < 0)
return NULL;
return isc_mkipaddress(&addr);
......@@ -178,10 +164,26 @@ isc_copyaddress(IscAddress *addr)
/* isc_getipnum makes a textual representation of the IP address
stored in an IscAddress. When an IPv6 socket is connected to an
IPv4 socket this will be an IPv6-mapped IPv4 address. To hide this
from the user (who might not be used to IPv6), we'll extract the
IPv4 address part and present it as an ordinary IPv4 address.
RFC2553 suggests no pretty way to do this, but says that we can get
the IPv4 address by skipping the first 12 bytes of the in6_addr
structure -- so that's what we'll do...
If you have a weird IPv6 implementation that doesn't have inet_ntop
you simply lose -- RFC2553 requires inet_ntop, and clearly states
that inet_ntoa is specific to IPv4. However, it's still possible to
handle IPv6-mapped IPv4 addresses with inet_ntoa and the same
trickery as above.
*/
char *isc_getipnum(IscAddress *ia, char *buf, int len)
{
static char hostname[256];
struct sockaddr_in *addr;
if (!buf)
......@@ -190,9 +192,32 @@ char *isc_getipnum(IscAddress *ia, char *buf, int len)
len = sizeof(hostname);
}
addr = cast_to_sockaddr_in(&ia->ip.saddr);
strncpy(buf, inet_ntoa(addr->sin_addr), len-1);
#ifdef HAVE_INET_NTOP
CHOOSE_IP4OR6(ia->ip.saddr,
inet_ntop(ia->ip.saddr.sa.sa_family,
(const void *) &ia->ip.saddr.sa_in.sin_addr,
buf,
len),
IN6_IS_ADDR_V4MAPPED(&ia->ip.saddr.sa_in6.sin6_addr)
? inet_ntop(AF_INET,
(const void *)
&ia->ip.saddr.sa_in6.sin6_addr.s6_addr[12],
buf,
len)
: inet_ntop(ia->ip.saddr.sa.sa_family,
(const void *) &ia->ip.saddr.sa_in6.sin6_addr,
buf,
len));
#else
strncopy(buf,
CHOOSE_IP4OR6(ia->ip.saddr,
inet_ntoa(ia->ip.saddr.sa_in.sin_addr),
IN6_IS_ADDR_V4MAPPED(&ia->ip.saddr.sa_in6.sin6_addr)
? inet_ntoa((struct in_addr *)
&ia->ip.saddr.sa_in6.sin6_addr.s6_addr[12])
: ""),
len-1);
#endif
buf[len-1] = '\0';
return buf;
......@@ -203,7 +228,6 @@ char *isc_getipnum(IscAddress *ia, char *buf, int len)
char *isc_gethostname(IscAddress *ia, char *buf, int len)
{
static char hostname[256];
struct sockaddr_in *addr;
struct hostent *hp;
if (ia == NULL)
......@@ -217,9 +241,14 @@ char *isc_gethostname(IscAddress *ia, char *buf, int len)
len = sizeof(hostname)-1;
}
addr = cast_to_sockaddr_in(&ia->ip.saddr);
hp = CHOOSE_IP4OR6(ia->ip.saddr,
gethostbyaddr((char *) &ia->ip.saddr.sa_in.sin_addr,
sizeof(ia->ip.saddr.sa_in.sin_addr),
ia->ip.saddr.sa.sa_family),
gethostbyaddr((char *) &ia->ip.saddr.sa_in6.sin6_addr,
sizeof(ia->ip.saddr.sa_in6.sin6_addr),
ia->ip.saddr.sa.sa_family));
hp = gethostbyaddr((char*)&addr->sin_addr, sizeof(struct in_addr), AF_INET);
if (!hp)
return NULL;
......@@ -233,12 +262,9 @@ char *isc_gethostname(IscAddress *ia, char *buf, int len)
int isc_getportnum(IscAddress *ia)
{
struct sockaddr_in *addr;
addr = cast_to_sockaddr_in(&ia->ip.saddr);
return ntohs(addr->sin_port);
return CHOOSE_IP4OR6(ia->ip.saddr,
ntohs(ia->ip.saddr.sa_in.sin_port),
ntohs(ia->ip.saddr.sa_in6.sin6_port));
}
......@@ -248,7 +274,6 @@ char *isc_getservice(IscAddress *ia,
IscSessionType type)
{
static char servbuf[256];
struct sockaddr_in *addr;
struct servent *sp;
if (!buf)
......@@ -257,16 +282,14 @@ char *isc_getservice(IscAddress *ia,
len = sizeof(servbuf)-1;
}
addr = cast_to_sockaddr_in(&ia->ip.saddr);
switch (type)
{
case ISC_TYPE_TCP:
sp = getservbyport(ntohs(addr->sin_port), "tcp");
sp = getservbyport(isc_getportnum(ia), "tcp");
break;
case ISC_TYPE_UDP:
sp = getservbyport(ntohs(addr->sin_port), "udp");
sp = getservbyport(isc_getportnum(ia), "udp");
break;
default:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment