Re: [libmicrohttpd] How to get the client IP as IPv4 in dual stack mode?
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?
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