Re: bug in addrlist_match (with IPv6 addresses)
Christof Meerwald <[email protected]> Wed, 6 Aug 2003 23:20:19 +0200
| Newsgroups | gmane.network.xinetd |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Jun 19, 2003 at 06:54:30PM -0700, Steve G wrote:
> - uint32_t *tmp_addr = (unsigned *)&addr->sa_data[3];
> + uint32_t *tmp_addr =
> &SAIN6(addr)->sin6_addr.s6_addr32[3];
>
> This should be applied, the rest doesn't need to be.
This one isn't included in xinetd 2.3.12 (you reverted the change a few days
later).
But your code isn't correct. Have a look at the sockaddr and sockaddr_in6
definitions (from glibc 2.2.x, Debian woody):
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
struct sockaddr_in6
{
__SOCKADDR_COMMON (sin6_);
in_port_t sin6_port; /* Transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* IPv6 scope-id */
};
So, "(unsigned *)&addr->sa_data[3]" definitely won't contain the mapped IPv4
address, instead it will contain 24 bits of the sin6_flowinfo field and 8
bits of sin6_addr (and will probably segfault on some RISC architectures
because of a misaligned memory access).
Hmm, in case my fix just wasn't portable enough, this one might be better
(untested):
uint32_t *tmp_addr = (uint32_t *) &SAIN6(addr)->sin6_addr.s6_addr[12];
(see
http://www.opengroup.org/onlinepubs/007904975/basedefs/netinet/in.h.html:
"The <netinet/in.h> header shall define the in6_addr structure that contains
at least the following member: uint8_t s6_addr[16]")
bye, Christof
--
http://cmeerw.org JID: [email protected]
mailto cmeerw at web.de