]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Introduce virSocketAddrBytes
authorJiri Denemark <jdenemar@redhat.com>
Wed, 31 Jan 2024 10:58:47 +0000 (11:58 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 7 Feb 2024 13:19:42 +0000 (14:19 +0100)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/libvirt_private.syms
src/util/virsocketaddr.c
src/util/virsocketaddr.h

index c336d06fb36221dcb07df2bdea31d40551e268e0..5fe7ebe9d2bc727b52c5d6d21c123d1f713acad0 100644 (file)
@@ -3378,6 +3378,7 @@ virSocketSendMsgWithFDs;
 # util/virsocketaddr.h
 virSocketAddrBroadcast;
 virSocketAddrBroadcastByPrefix;
+virSocketAddrBytes;
 virSocketAddrCheckNetmask;
 virSocketAddrEqual;
 virSocketAddrFormat;
index fbda858cfef25a345bed76c8b4578c982ffb6595..0a1ae1ac5fb556cb385e5beaa800cce5dba75a46 100644 (file)
@@ -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)
 {
index ec265d6e440cf47aa90aa59856b7029430dabe87..47b8effa85e7280c475c036a1874d858cf61f5cd 100644 (file)
@@ -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);