Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> Reviewed-by: Ján Tomko <jtomko@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virsocketaddr.c | 63 ++++++++++++++++++++++++++++++++++++++++ src/util/virsocketaddr.h | 4 +++ 3 files changed, 68 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c336d06fb3..5fe7ebe9d2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3378,6 +3378,7 @@ virSocketSendMsgWithFDs; # util/virsocketaddr.h virSocketAddrBroadcast; virSocketAddrBroadcastByPrefix; +virSocketAddrBytes; virSocketAddrCheckNetmask; virSocketAddrEqual; virSocketAddrFormat; diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c index fbda858cfe..0a1ae1ac5f 100644 --- a/src/util/virsocketaddr.c +++ b/src/util/virsocketaddr.c @@ -30,6 +30,7 @@ */ typedef unsigned char virSocketAddrIPv4[4]; typedef unsigned short virSocketAddrIPv6[8]; +typedef unsigned char virSocketAddrIPv6Bytes[16]; typedef unsigned char virSocketAddrIPv6Nibbles[32]; static int @@ -68,6 +69,23 @@ virSocketAddrGetIPv6Addr(const virSocketAddr *addr, virSocketAddrIPv6 *tab) return 0; } + +static int +virSocketAddrGetIPv6Bytes(const virSocketAddr *addr, + virSocketAddrIPv6Bytes *tab) +{ + size_t i; + + if (!addr || !tab || addr->data.stor.ss_family != AF_INET6) + return -1; + + for (i = 0; i < 16; i++) + (*tab)[i] = addr->data.inet6.sin6_addr.s6_addr[i]; + + return 0; +} + + static int virSocketAddrGetIPv6Nibbles(const virSocketAddr *addr, virSocketAddrIPv6Nibbles *tab) @@ -1331,6 +1349,51 @@ virSocketAddrPTRDomain(const virSocketAddr *addr, return 0; } + +/** + * virSocketAddrBytes: + * @addr: address to convert to byte array + * @bytes: a preallocated array to store the address bytes to + * @maxBytes: the size of @bytes + * + * Extracts individual bytes of an IPv4 or IPv6 address in the provided @bytes + * array, which should be large enough to store 16 bytes (the size of an IPv6 + * address). Bytes are stored in network order. + * + * Returns the number of bytes stored in @bytes on success or 0 when @bytes + * array is not big enough or @addr is not IPv4 or IPv6. + */ +int +virSocketAddrBytes(const virSocketAddr *addr, + unsigned char *bytes, + int maxBytes) +{ + if (VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET6)) { + virSocketAddrIPv6Bytes ip; + + if (maxBytes < sizeof(ip)) + return 0; + + virSocketAddrGetIPv6Bytes(addr, &ip); + memcpy(bytes, ip, sizeof(ip)); + return sizeof(ip); + } + + if (VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET)) { + virSocketAddrIPv4 ip; + + if (maxBytes < sizeof(ip)) + return 0; + + virSocketAddrGetIPv4Addr(addr, &ip); + memcpy(bytes, ip, sizeof(ip)); + return sizeof(ip); + } + + return 0; +} + + void virSocketAddrFree(virSocketAddr *addr) { diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h index ec265d6e44..47b8effa85 100644 --- a/src/util/virsocketaddr.h +++ b/src/util/virsocketaddr.h @@ -143,6 +143,10 @@ int virSocketAddrPTRDomain(const virSocketAddr *addr, char **ptr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); +int virSocketAddrBytes(const virSocketAddr *addr, + unsigned char *bytes, + int maxBytes); + void virSocketAddrFree(virSocketAddr *addr); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSocketAddr, virSocketAddrFree); -- 2.43.0 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx