From a37668e9f545d9763cae53778aa04852ca395e9e Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Mon, 28 Dec 2020 12:42:54 -0500 Subject: [PATCH] GUACAMOLE-1245: Add support for specifying Wake-on-LAN port. --- src/libguac/guacamole/wol.h | 6 +++++- src/libguac/wol.c | 13 +++++++++---- src/protocols/rdp/rdp.c | 3 ++- src/protocols/rdp/settings.c | 12 ++++++++++++ src/protocols/rdp/settings.h | 5 +++++ src/protocols/ssh/settings.c | 10 ++++++++++ src/protocols/ssh/settings.h | 5 +++++ src/protocols/ssh/ssh.c | 3 ++- src/protocols/telnet/settings.c | 15 +++++++++++++++ src/protocols/telnet/settings.h | 5 +++++ src/protocols/telnet/telnet.c | 3 ++- src/protocols/vnc/settings.c | 15 +++++++++++++++ src/protocols/vnc/settings.h | 5 +++++ src/protocols/vnc/vnc.c | 3 ++- 14 files changed, 94 insertions(+), 9 deletions(-) diff --git a/src/libguac/guacamole/wol.h b/src/libguac/guacamole/wol.h index cdbb7391..9af1a8d0 100644 --- a/src/libguac/guacamole/wol.h +++ b/src/libguac/guacamole/wol.h @@ -42,11 +42,15 @@ * @param broadcast_addr * The broadcast address to which to send the magic Wake-on-LAN packet. * + * @param udp_port + * The UDP port to use when sending the WoL packet. + * * @return * Zero if the packet is successfully sent to the destination; non-zero * if the packet cannot be sent. */ -int guac_wol_wake(const char* mac_addr, const char* broadcast_addr); +int guac_wol_wake(const char* mac_addr, const char* broadcast_addr, + const unsigned short udp_port); #endif /* GUAC_WOL_H */ diff --git a/src/libguac/wol.c b/src/libguac/wol.c index dcbd07cd..9d69306c 100644 --- a/src/libguac/wol.c +++ b/src/libguac/wol.c @@ -69,6 +69,9 @@ static void __guac_wol_create_magic_packet(unsigned char packet[], * @param broadcast_addr * The broadcast address to which to send the magic WoL packet. * + * @param udp_port + * The UDP port to use when sending the WoL packet. + * * @param packet * The magic WoL packet to send. * @@ -76,13 +79,13 @@ static void __guac_wol_create_magic_packet(unsigned char packet[], * The number of bytes sent, or zero if nothing could be sent. */ static ssize_t __guac_wol_send_packet(const char* broadcast_addr, - unsigned char packet[]) { + const unsigned short udp_port, unsigned char packet[]) { struct sockaddr_in wol_dest; int wol_socket; /* Determine the IP version, starting with IPv4. */ - wol_dest.sin_port = htons(GUAC_WOL_PORT); + wol_dest.sin_port = htons(udp_port); wol_dest.sin_family = AF_INET; int retval = inet_pton(wol_dest.sin_family, broadcast_addr, &(wol_dest.sin_addr)); @@ -165,7 +168,8 @@ static ssize_t __guac_wol_send_packet(const char* broadcast_addr, } -int guac_wol_wake(const char* mac_addr, const char* broadcast_addr) { +int guac_wol_wake(const char* mac_addr, const char* broadcast_addr, + const unsigned short udp_port) { unsigned char wol_packet[GUAC_WOL_PACKET_SIZE]; unsigned int dest_mac[6]; @@ -183,7 +187,8 @@ int guac_wol_wake(const char* mac_addr, const char* broadcast_addr) { __guac_wol_create_magic_packet(wol_packet, dest_mac); /* Send the packet and record bytes sent. */ - int bytes_sent = __guac_wol_send_packet(broadcast_addr, wol_packet); + int bytes_sent = __guac_wol_send_packet(broadcast_addr, udp_port, + wol_packet); /* Return 0 if bytes were sent, otherwise return an error. */ if (bytes_sent) diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index d7b75892..ce6a2796 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -615,7 +615,8 @@ void* guac_rdp_client_thread(void* data) { "and pausing for %d seconds.", settings->wol_wait_time); /* Send the Wake-on-LAN request. */ - if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr)) + if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr, + settings->wol_udp_port)) return NULL; /* If wait time is specified, sleep for that amount of time. */ diff --git a/src/protocols/rdp/settings.c b/src/protocols/rdp/settings.c index 57760d93..dd8a96fb 100644 --- a/src/protocols/rdp/settings.c +++ b/src/protocols/rdp/settings.c @@ -124,6 +124,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = { "wol-send-packet", "wol-mac-addr", "wol-broadcast-addr", + "wol-udp-port", "wol-wait-time", NULL }; @@ -609,6 +610,11 @@ enum RDP_ARGS_IDX { */ IDX_WOL_BROADCAST_ADDR, + /** + * The UDP port to use in the magic WoL packet. + */ + IDX_WOL_UDP_PORT, + /** * The amount of time, in seconds, to wait after sending the WoL packet * before attempting to connect to the host. This should be a reasonable @@ -1133,6 +1139,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST); + /* Parse the WoL broadcast port. */ + settings->wol_udp_port = (unsigned short) + guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_WOL_UDP_PORT, GUAC_WOL_PORT); + /* Parse the WoL wait time. */ settings->wol_wait_time = guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, @@ -1202,6 +1213,7 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) { /* Free load balancer information string */ free(settings->load_balance_info); + /* Free Wake-on-LAN strings */ free(settings->wol_mac_addr); free(settings->wol_broadcast_addr); diff --git a/src/protocols/rdp/settings.h b/src/protocols/rdp/settings.h index d8092216..323ba5d3 100644 --- a/src/protocols/rdp/settings.h +++ b/src/protocols/rdp/settings.h @@ -583,6 +583,11 @@ typedef struct guac_rdp_settings { */ char* wol_broadcast_addr; + /** + * The UDP port to use when sending the magic WoL packet. + */ + unsigned short wol_udp_port; + /** * The amount of time to wait after sending the magic WoL packet before * continuing the connection. diff --git a/src/protocols/ssh/settings.c b/src/protocols/ssh/settings.c index 242e1d29..b286555a 100644 --- a/src/protocols/ssh/settings.c +++ b/src/protocols/ssh/settings.c @@ -72,6 +72,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = { "wol-send-packet", "wol-mac-addr", "wol-broadcast-addr", + "wol-udp-port", "wol-wait-time", NULL }; @@ -317,6 +318,11 @@ enum SSH_ARGS_IDX { */ IDX_WOL_BROADCAST_ADDR, + /** + * The UDP port to use when sending the WoL packet. + */ + IDX_WOL_UDP_PORT, + /** * The amount of time to wait after sending the magic WoL packet prior to * continuing the connection attempt. The default is no wait time @@ -533,6 +539,10 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv, IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST); + settings->wol_udp_port = (unsigned short) + guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv, + IDX_WOL_UDP_PORT, GUAC_WOL_PORT); + settings->wol_wait_time = guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv, IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME); diff --git a/src/protocols/ssh/settings.h b/src/protocols/ssh/settings.h index d106b0a7..64691de6 100644 --- a/src/protocols/ssh/settings.h +++ b/src/protocols/ssh/settings.h @@ -302,6 +302,11 @@ typedef struct guac_ssh_settings { */ char* wol_broadcast_addr; + /** + * The UDP port to use when sending the magic WoL packet. + */ + unsigned short wol_udp_port; + /** * The amount of time to wait for the system to wake after sending the packet. */ diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c index 03f5b0b6..aaa5a8eb 100644 --- a/src/protocols/ssh/ssh.c +++ b/src/protocols/ssh/ssh.c @@ -208,7 +208,8 @@ void* ssh_client_thread(void* data) { "and pausing for %d seconds.", settings->wol_wait_time); /* Send the Wake-on-LAN request. */ - if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr)) + if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr, + settings->wol_udp_port)) return NULL; /* If wait time is specified, sleep for that amount of time. */ diff --git a/src/protocols/telnet/settings.c b/src/protocols/telnet/settings.c index 91b9e11c..464f9363 100644 --- a/src/protocols/telnet/settings.c +++ b/src/protocols/telnet/settings.c @@ -63,6 +63,7 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = { "wol-send-packet", "wol-mac-addr", "wol-broadcast-addr", + "wol-udp-port", "wol-wait-time", NULL }; @@ -258,6 +259,11 @@ enum TELNET_ARGS_IDX { */ IDX_WOL_BROADCAST_ADDR, + /** + * The UDP port to use when sending the WoL packet. + */ + IDX_WOL_UDP_PORT, + /** * The amount of time, in seconds, to wait after the magic WoL packet is * sent before continuing the connection attempt. The default is not to @@ -511,6 +517,11 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv, IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST); + /* Parse the WoL broadcast port. */ + settings->wol_udp_port = (unsigned short) + guac_user_parse_args_int(user, GUAC_TELNET_CLIENT_ARGS, argv, + IDX_WOL_UDP_PORT, GUAC_WOL_PORT); + /* Parse the WoL wait time. */ settings->wol_wait_time = guac_user_parse_args_int(user, GUAC_TELNET_CLIENT_ARGS, argv, @@ -553,6 +564,10 @@ void guac_telnet_settings_free(guac_telnet_settings* settings) { /* Free terminal emulator type. */ free(settings->terminal_type); + + /* Free WoL settings. */ + free(settings->wol_mac_addr); + free(settings->wol_broadcast_addr); /* Free overall structure */ free(settings); diff --git a/src/protocols/telnet/settings.h b/src/protocols/telnet/settings.h index dfaaa97b..c55dc522 100644 --- a/src/protocols/telnet/settings.h +++ b/src/protocols/telnet/settings.h @@ -275,6 +275,11 @@ typedef struct guac_telnet_settings { */ char* wol_broadcast_addr; + /** + * The UDP port to use when sending the WoL packet. + */ + unsigned short wol_udp_port; + /** * The number of seconds to wait after sending the magic WoL packet before * continuing the connection. diff --git a/src/protocols/telnet/telnet.c b/src/protocols/telnet/telnet.c index 8d8d4398..b2b3106e 100644 --- a/src/protocols/telnet/telnet.c +++ b/src/protocols/telnet/telnet.c @@ -564,7 +564,8 @@ void* guac_telnet_client_thread(void* data) { "and pausing for %d seconds.", settings->wol_wait_time); /* Send the Wake-on-LAN request. */ - if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr)) + if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr, + settings->wol_udp_port)) return NULL; /* If wait time is specified, sleep for that amount of time. */ diff --git a/src/protocols/vnc/settings.c b/src/protocols/vnc/settings.c index c6f36464..691e7083 100644 --- a/src/protocols/vnc/settings.c +++ b/src/protocols/vnc/settings.c @@ -89,6 +89,7 @@ const char* GUAC_VNC_CLIENT_ARGS[] = { "wol-send-packet", "wol-mac-addr", "wol-broadcast-addr", + "wol-udp-port", "wol-wait-time", NULL }; @@ -360,6 +361,11 @@ enum VNC_ARGS_IDX { */ IDX_WOL_BROADCAST_ADDR, + /** + * The UDP port to use when sending the WoL packet. + */ + IDX_WOL_UDP_PORT, + /** * The number of seconds to wait after sending the magic WoL packet before * attempting to connect to the remote host. The default is not to wait @@ -608,6 +614,11 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv, IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST); + /* Parse the WoL broadcast port. */ + settings->wol_udp_port = (unsigned short) + guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv, + IDX_WOL_UDP_PORT, GUAC_WOL_PORT); + /* Parse the WoL wait time. */ settings->wol_wait_time = guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv, @@ -652,6 +663,10 @@ void guac_vnc_settings_free(guac_vnc_settings* settings) { /* Free PulseAudio settings */ free(settings->pa_servername); #endif + + /* Free Wake-on-LAN strings */ + free(settings->wol_mac_addr); + free(settings->wol_broadcast_addr); /* Free settings structure */ free(settings); diff --git a/src/protocols/vnc/settings.h b/src/protocols/vnc/settings.h index 8d5659ef..6d1c6575 100644 --- a/src/protocols/vnc/settings.h +++ b/src/protocols/vnc/settings.h @@ -289,6 +289,11 @@ typedef struct guac_vnc_settings { */ char* wol_broadcast_addr; + /** + * The UDP port to use when sending the WoL packet. + */ + unsigned short wol_udp_port; + /** * The number of seconds after sending the magic WoL packet to wait before * attempting to connect to the remote host. diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c index a310e515..cd09951a 100644 --- a/src/protocols/vnc/vnc.c +++ b/src/protocols/vnc/vnc.c @@ -247,7 +247,8 @@ void* guac_vnc_client_thread(void* data) { "and pausing for %d seconds.", settings->wol_wait_time); /* Send the Wake-on-LAN request. */ - if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr)) + if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr, + settings->wol_udp_port)) return NULL; /* If wait time is specified, sleep for that amount of time. */