On Thu, Aug 14, 2003 at 10:41:44AM -0700, Justin Erenkrantz wrote:
> --On Thursday, August 14, 2003 6:06 PM +0100 "Colm MacCarthaigh,,,"
> <[EMAIL PROTECTED]> wrote:
>
> >Both these things really need to happen. The first is relatively
> >trivial:
>
> Yup, I agree. I committed a variant of this to the tree. (The patch you
> submitted would only execute if the APR_IPV4_ADDR_ONLY flag or whatever
> would be passed in.)
Good good, silly me :)
> >Until a truly AF agnostic ACL implementation can be used (see
> >http://www.stdlib.net/~colmmacc/nsd/subnet.h and the accomponying
> >subnet.c for a rough idea) the Darwin problem should be solveable
> >by checking the IN6_IS_ADDR_V4MAPPED macro, and if so ignoring
> >the first 96 bytes and passing the last 32 on.
>
> Hmm. Would it be possible to submit a patch for this? I'm not entirely
> clear where this would go.
Patch attached. Since I havnt got a DARWIN machine to test on I
can't confirm it works, but it should. It works on Linux anyway
(not that it needs to).
Darwin might need some slightly different sa.[members] set to make
getnameinfo work but it shouldnt be anything major. If someone
with a darwin box could try it out I'd be much obliged. Turn
HostnameLookups On to get an idea as to whether it's working or
not.
Basically the patch spoofs enough of a valid _in v4 type structure
to make getnameinfo work, and grabs the address itself from the
appropriate place in the mapped one.
--
Colm MacC�rthaigh Public Key: [EMAIL PROTECTED]
[EMAIL PROTECTED] http://www.stdlib.net/
Index: sockaddr.c
===================================================================
RCS file: /home/cvspublic/apr/network_io/unix/sockaddr.c,v
retrieving revision 1.41
diff -u -r1.41 sockaddr.c
--- sockaddr.c 14 Aug 2003 17:36:17 -0000 1.41
+++ sockaddr.c 14 Aug 2003 19:48:38 -0000
@@ -634,9 +634,28 @@
* a numeric address string if it fails to resolve the host name;
* that is *not* what we want here
*/
+#ifdef DARWIN && APR_HAVE_IPV6
+ /* Darwin's getnameinfo does not work for IPv4-mapped-IPv6 addresses,
+ * the workaround is to convert the last 32 bits of the IPv6 address
+ * to a valid sockaddr_in structure. This is extremely hacky, avoid
+ * re-use. */
+ if (sockaddr->family == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr))
+ {
+ struct apr_sockaddr_t tmpsa;
+
+ tmpsa.sa.sin.sin_family = AF_INET;
+ tmpsa.sa.sin.sin_addr.s_addr = ((uint32_t *)sockaddr->ipaddr_ptr)[3];
+
+ rc = getnameinfo((const struct sockaddr *)&tmpsa.sa, sizeof(struct
sockaddr_in),
+ tmphostname, sizeof(tmphostname), NULL, 0,
+ flags != 0 ? flags : NI_NAMEREQD);
+ }
+ else
+#endif
rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
tmphostname, sizeof(tmphostname), NULL, 0,
flags != 0 ? flags : NI_NAMEREQD);
+
if (rc != 0) {
*hostname = NULL;