Re: [libmicrohttpd] How to get the client IP as IPv4 in dual stack mode?

2019-11-28 Thread Christian Grothoff
Hi silvioprog,

Have you considered simply using

IN6_IS_ADDR_V4MAPPED

on the v6 address, and if it matches, extracting the mapped v4 address?

Happy hacking!

Christian

On 11/28/19 4:35 AM, silvioprog wrote:
> Hi.
> 
> I have a function which checks if the sa_family is AF_INET or AF_INET6
> and formats the client address as IPv4 (e.g. 127.0.0.1) or IPv6 (e.g.
> ::1) into a string. However, when I enable the dual stack in MHD, it
> always returns AF_INET6 in sa_family even when passing -4 as parameter
> in curl.
> 
> I'm using MHD_get_connection_info(...,
> MHD_CONNECTION_INFO_CLIENT_ADDRESS)->client_addr to get the client
> address and the formatting function is in attachment below.
> 
> Is there any flag to force MHD to return AF_INET when the client
> connects explicitly as IPv4?
> 
> Thank you!
> 
> // Attachment: function to format the client address as IPv4 or IPv6
> int get_ip(const void *socket, char *buf, size_t size) {
>   const struct sockaddr *sa;
>   if (!socket || !buf || (ssize_t) size < 0)
>     return EINVAL;
>   sa = socket;
>   switch (sa->sa_family) {
>     case AF_INET:
>       if (!inet_ntop(AF_INET, &(((struct sockaddr_in *) sa)->sin_addr), buf,
>                      size))
>         return errno;
>       break;
>     case AF_INET6:
>       if (!inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)
> sa)->sin6_addr), buf,
>                      size))
>         return errno;
>       break;
>     default:
>       return EINVAL;
>   }
>   return 0;
> }
> 
> --
> Silvio Clécio



signature.asc
Description: OpenPGP digital signature


Re: [libmicrohttpd] How to get the client IP as IPv4 in dual stack mode?

2019-11-28 Thread silvioprog
Hi Christian.

It solved the problem. Thank you so much! :-)

This is the updated version of the function, if someone need it:

int get_ip(const void *socket, char *buf, size_t size) {
  const struct sockaddr *sa;
  const void *addr6;
  size_t len;
  if (!socket || !buf || (ssize_t) size < 0)
return EINVAL;
  sa = socket;
  if (sa->sa_family == AF_INET6) {
addr6 = &(((struct sockaddr_in6 *) sa)->sin6_addr);
if (!inet_ntop(AF_INET6, addr6, buf, size))
  return errno;
len = strlen(":::");
if (IN6_IS_ADDR_V4MAPPED(addr6) && (size > len))
  memcpy(buf, buf + len, strlen(buf + len) + 1);
return 0;
  }
  if (!inet_ntop(AF_INET, &(((struct sockaddr_in *) sa)->sin_addr), buf,
size))
return errno;
  return 0;
}

Thank you!

On Thu, Nov 28, 2019 at 5:02 PM Christian Grothoff 
wrote:

> Hi silvioprog,
>
> Have you considered simply using
>
> IN6_IS_ADDR_V4MAPPED
>
> on the v6 address, and if it matches, extracting the mapped v4 address?
>
> Happy hacking!
>
> Christian


-- 
Silvio Clécio