passt/inany.c
David Gibson 0cf6b2d89d inany: Provide more conveniently typed constants for special addresses
Our inany_addr type is used in some places to represent either IPv4 or
IPv6 addresses, and we plan to use it more widely.  We don't yet
provide constants of this type for special addresses (loopback and
"any").  Add some of these, both the IPv4 and IPv6 variants of those
addresses, but typed as union inany_addr.

To avoid actually adding more things to .data we can use some macros and
casting to overlay the IPv6 versions of these with the standard library's
in6addr_loopback and in6addr_any.  For the IPv4 versions we need to create
new constant globals.

For complicated historical reasons, the standard library doesn't
provide constants for IPv4 loopback and any addresses as struct
in_addr.  It just has macros of type in_addr_t == uint32_t, which has
some gotchas w.r.t. endianness.  We can use some more macros to
address this lack, using macros to effectively create these IPv4
constants as pieces of the inany constants above.

We use this last to avoid some awkward temporary variables just used
to get an address of an IPv4 loopback address.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2024-02-29 09:47:28 +01:00

51 lines
1.2 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright Red Hat
* Author: David Gibson <david@gibson.dropbear.id.au>
*
* inany.c - Types and helpers for handling addresses which could be
* IPv6 or IPv4 (encoded as IPv4-mapped IPv6 addresses)
*/
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "util.h"
#include "siphash.h"
#include "inany.h"
const union inany_addr inany_loopback4 = {
.v4mapped = {
.zero = { 0 },
.one = { 0xff, 0xff, },
.a4 = IN4ADDR_LOOPBACK_INIT,
},
};
const union inany_addr inany_any4 = {
.v4mapped = {
.zero = { 0 },
.one = { 0xff, 0xff, },
.a4 = IN4ADDR_ANY_INIT,
},
};
/** inany_ntop - Convert an IPv[46] address to text format
* @src: IPv[46] address
* @dst: output buffer, minimum INANY_ADDRSTRLEN bytes
* @size: size of buffer at @dst
*
* Return: On success, a non-null pointer to @dst, NULL on failure
*/
/* cppcheck-suppress unusedFunction */
const char *inany_ntop(const union inany_addr *src, char *dst, socklen_t size)
{
const struct in_addr *v4 = inany_v4(src);
if (v4)
return inet_ntop(AF_INET, v4, dst, size);
return inet_ntop(AF_INET6, &src->a6, dst, size);
}