necouchman commented on code in PR #591:
URL: https://github.com/apache/guacamole-server/pull/591#discussion_r2105242800


##########
src/libguac/wol.c:
##########
@@ -63,6 +63,173 @@ static void __guac_wol_create_magic_packet(unsigned char 
packet[],
     
 }
 
+/**
+ * Converts the given IPv4 address and UDP port number into its binary
+ * representation (struct sockaddr_in). The size of the structure used will be
+ * stored in wol_dest_size.
+ *
+ * @param addr
+ *     The IPv4 address to convert.
+ *
+ * @param udp_port
+ *     The UDP port number to convert and include in the resulting sockaddr_in
+ *     structure.
+ *
+ * @param wol_dest
+ *     Storage that is sufficiently large and correctly aligned such that it
+ *     may be typecast as a sockaddr_in without issue (this is guaranteed by
+ *     the definition of the sockaddr_storage structure).
+ *
+ * @param wol_dest_size
+ *     Pointer to a socklen_t that should receive the size of the sockaddr_in
+ *     structure. This value is assigned only if this call succeeds.
+ *
+ * @return
+ *     A positive value if conversion succeeded, zero if conversion failed, and
+ *     a negative value if IPv4 is unsupported by this system.
+ */
+static int __guac_wol_convert_addr_ipv4(const char* addr, const unsigned short 
udp_port,
+        struct sockaddr_storage* wol_dest, socklen_t* wol_dest_size) {
+
+    struct sockaddr_in* wol_dest_ipv4 = (struct sockaddr_in*) wol_dest;
+    *wol_dest_size = sizeof(struct sockaddr_in);
+
+    /* Init address structure for IPv4 details */
+    memset(wol_dest, 0, *wol_dest_size);
+    wol_dest_ipv4->sin_port = htons(udp_port);
+    wol_dest_ipv4->sin_family = AF_INET;
+
+    return inet_pton(wol_dest_ipv4->sin_family, addr, 
&(wol_dest_ipv4->sin_addr));
+
+}
+
+/**
+ * Converts the given IPv6 address and UDP port number into its binary
+ * representation (struct sockaddr_in6). The size of the structure used will be
+ * stored in wol_dest_size.
+ *
+ * @param addr
+ *     The IPv6 address to convert.
+ *
+ * @param udp_port
+ *     The UDP port number to convert and include in the resulting sockaddr_in6
+ *     structure.
+ *
+ * @param wol_dest
+ *     Storage that is sufficiently large and correctly aligned such that it
+ *     may be typecast as a sockaddr_in6 without issue (this is guaranteed by
+ *     the definition of the sockaddr_storage structure).
+ *
+ * @param wol_dest_size
+ *     Pointer to a socklen_t that should receive the size of the sockaddr_in6
+ *     structure. This value is assigned only if this call succeeds.
+ *
+ * @return
+ *     A positive value if conversion succeeded, zero if conversion failed, and
+ *     a negative value if IPv6 is unsupported by this system.
+ */
+static int __guac_wol_convert_addr_ipv6(const char* addr, const unsigned short 
udp_port,
+         struct sockaddr_storage* wol_dest, socklen_t* wol_dest_size) {
+
+    struct sockaddr_in6* wol_dest_ipv6 = (struct sockaddr_in6*) wol_dest;
+    *wol_dest_size = sizeof(struct sockaddr_in6);
+
+    /* Init address structure for IPv6 details */
+    memset(wol_dest, 0, *wol_dest_size);
+    wol_dest_ipv6->sin6_family = AF_INET6;
+    wol_dest_ipv6->sin6_port = htons(udp_port);
+
+    return inet_pton(wol_dest_ipv6->sin6_family, addr, 
&(wol_dest_ipv6->sin6_addr));
+
+}
+
+/**
+ * Converts the given IPv4 or IPv6 address and UDP port number into its binary
+ * representation (either a struct sockaddr_in or struct sockaddr_in6). The
+ * size of the structure used will be stored in wol_dest_size. If conversion
+ * fails, guac_error and guac_error_message are set appropriately.
+ *
+ * @param addr
+ *     The address to convert.
+ *
+ * @param udp_port
+ *     The UDP port number to convert and include in the resulting structure.
+ *
+ * @param wol_dest
+ *     Storage that is sufficiently large and correctly aligned such that it
+ *     may be typecast as a sockaddr_in OR sockaddr_in6 without issue (this is
+ *     guaranteed by the definition of the sockaddr_storage structure).
+ *
+ * @param wol_dest_size
+ *     Pointer to a socklen_t that should receive the size of the structure
+ *     ultimately used. This value is assigned only if this call succeeds.
+ *
+ * @return
+ *     Non-zero if conversion succeeded, zero otherwise.
+ */
+static int __guac_wol_convert_addr(const char* addr, const unsigned short 
udp_port,
+          struct sockaddr_storage* wol_dest, socklen_t* wol_dest_size) {
+
+    /* Attempt to resolve as an IPv4 address first */
+    int ipv4_retval = __guac_wol_convert_addr_ipv4(addr, udp_port, wol_dest, 
wol_dest_size);
+    if (ipv4_retval > 0)
+        return 1;
+
+    /* Failing that, reattempt as IPv6 */
+    int ipv6_retval = __guac_wol_convert_addr_ipv6(addr, udp_port, wol_dest, 
wol_dest_size);
+    if (ipv6_retval > 0)
+        return 1;
+
+    /*
+     * Translate all possible IPv4 / IPv6 failure combinations into a single,
+     * human-readable message.
+     */
+
+    /* The provided address is not valid IPv4 ... */
+    if (ipv4_retval == 0) {
+
+        /* ... and also not valid IPv6. */
+        if (ipv6_retval == 0) {
+            guac_error = GUAC_STATUS_INVALID_ARGUMENT;
+            guac_error_message = "The broadcast or multicast address "
+                "specified for Wake-on-LAN is not a valid IPv4 or IPv6 "
+                "address";
+        }
+
+        /* ... but we can't try IPv6 because this system doesn't support it. */
+        else {
+            guac_error = GUAC_STATUS_INVALID_ARGUMENT;
+            guac_error_message = "IPv6 is not supported by this system and "
+                "the broadcast/multicast address specified for Wake-on-LAN is "
+                "not a valid IPv4 address";

Review Comment:
   `IPv4` -> `IPv6`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to