diff options
author | Javier Sánchez Parra <jsanchez@soleta.eu> | 2020-07-03 12:42:00 +0200 |
---|---|---|
committer | OpenGnSys Support Team <soporte-og@soleta.eu> | 2020-07-03 14:11:35 +0200 |
commit | 06af0c26f4c46088d8a6f97877f865527bcbc409 (patch) | |
tree | f4ba170d0be8a1192a4f23d8c85a5c103e1b2885 | |
parent | d6789f1384eb515f7bbe0d25762ffb82567eec38 (diff) |
#990 Use client broadcast address on WoL
Some universities have computers in a different subnet where the
ogServer is, but ogServer WoL functionality only supported to send
packet to its own subnets. This commit solves this.
Now ogServer sends two WoL packets per client, one with the broadcast
address of the interface indicated in the config file, the other with
the broadcast address calculated with the address and netmask of the
client.
To ensure that the second WoL works correctly you must configure
correctly the IP and netmask of the clients. Also, you have to configure
the network of your organization to route WoL packet to the correct
subnet.
-rw-r--r-- | src/json.h | 1 | ||||
-rw-r--r-- | src/ogAdmServer.c | 28 | ||||
-rw-r--r-- | src/ogAdmServer.h | 4 | ||||
-rw-r--r-- | src/rest.c | 14 |
4 files changed, 35 insertions, 12 deletions
@@ -53,6 +53,7 @@ struct og_sync_params { struct og_msg_params { const char *ips_array[OG_CLIENTS_MAX]; const char *mac_array[OG_CLIENTS_MAX]; + const char *netmask_array[OG_CLIENTS_MAX]; unsigned int ips_array_len; const char *wol_type; char run_cmd[4096]; diff --git a/src/ogAdmServer.c b/src/ogAdmServer.c index b0eb86a..f063eb1 100644 --- a/src/ogAdmServer.c +++ b/src/ogAdmServer.c @@ -447,7 +447,8 @@ int checkDato(struct og_dbi *dbi, char *dato, const char *tabla, // false: En caso de ocurrir algún error // ________________________________________________________________________________________________________ -bool Levanta(char *ptrIP[], char *ptrMacs[], int lon, char *mar) +bool Levanta(char *ptrIP[], char *ptrMacs[], char *ptrNetmasks[], int lon, + char *mar) { unsigned int on = 1; struct sockaddr_in local; @@ -472,7 +473,7 @@ bool Levanta(char *ptrIP[], char *ptrMacs[], int lon, char *mar) local.sin_addr.s_addr = htonl(INADDR_ANY); for (i = 0; i < lon; i++) { - if (!WakeUp(s, ptrIP[i], ptrMacs[i], mar)) { + if (!WakeUp(s, ptrIP[i], ptrMacs[i], ptrNetmasks[i], mar)) { syslog(LOG_ERR, "problem sending magic packet\n"); close(s); return false; @@ -566,16 +567,28 @@ enum wol_delivery_type { // false: En caso de ocurrir algún error //_____________________________________________________________________________________________________________ // -bool WakeUp(int s, char* iph, char *mac, char *mar) +bool WakeUp(int s, char* iph, char *mac, char *netmask, char *mar) { + struct in_addr addr, netmask_addr, broadcast_addr ={}; unsigned int macaddr[OG_WOL_MACADDR_LEN]; char HDaddress_bin[OG_WOL_MACADDR_LEN]; struct sockaddr_in WakeUpCliente; struct wol_msg Trama_WakeUp; - struct in_addr addr; bool ret; int i; + if (inet_aton(iph, &addr) < 0) { + syslog(LOG_ERR, "bad IP address\n"); + return false; + } + + if (inet_aton(netmask, &netmask_addr) < 0) { + syslog(LOG_ERR, "bad netmask address: %s\n", netmask); + return false; + } + + broadcast_addr.s_addr = addr.s_addr | ~netmask_addr.s_addr; + for (i = 0; i < 6; i++) // Primera secuencia de la trama Wake Up (0xFFFFFFFFFFFF) Trama_WakeUp.secuencia_FF[i] = 0xFF; @@ -596,13 +609,10 @@ bool WakeUp(int s, char* iph, char *mac, char *mar) switch (atoi(mar)) { case OG_WOL_BROADCAST: ret = wake_up_broadcast(s, &WakeUpCliente, &Trama_WakeUp); + ret &= wake_up_unicast(s, &WakeUpCliente, &Trama_WakeUp, + &broadcast_addr); break; case OG_WOL_UNICAST: - if (inet_aton(iph, &addr) < 0) { - syslog(LOG_ERR, "bad IP address for unicast wol\n"); - ret = false; - break; - } ret = wake_up_unicast(s, &WakeUpCliente, &Trama_WakeUp, &addr); break; default: diff --git a/src/ogAdmServer.h b/src/ogAdmServer.h index c5b5e26..7e5fcd3 100644 --- a/src/ogAdmServer.h +++ b/src/ogAdmServer.h @@ -45,8 +45,8 @@ struct og_dbi; bool clienteExistente(char *,int *); bool clienteDisponible(char *,int *); bool actualizaConfiguracion(struct og_dbi *,char* ,int); -bool Levanta(char**, char**, int, char*); -bool WakeUp(int,char*,char*,char*); +bool Levanta(char**, char**, char**, int, char*); +bool WakeUp(int,char*,char*,char*,char*); bool actualizaCreacionImagen(struct og_dbi *,char*,char*,char*,char*,char*,char*); bool actualizaRestauracionImagen(struct og_dbi *,char*,char*,char*,char*,char*); bool actualizaHardware(struct og_dbi *dbi, char* ,char*,char*,char*); @@ -109,6 +109,7 @@ static bool og_send_cmd(char *ips_array[], int ips_array_len, #define OG_REST_PARAM_TIME_HOURS (1UL << 37) #define OG_REST_PARAM_TIME_AM_PM (1UL << 38) #define OG_REST_PARAM_TIME_MINUTES (1UL << 39) +#define OG_REST_PARAM_NETMASK (1UL << 40) static LIST_HEAD(client_list); @@ -508,6 +509,14 @@ static int og_json_parse_target(json_t *element, struct og_msg_params *params) json_string_value(value); params->flags |= OG_REST_PARAM_MAC; + } else if (!strcmp(key, "netmask")) { + if (json_typeof(value) != JSON_STRING) + return -1; + + params->netmask_array[params->ips_array_len] = + json_string_value(value); + + params->flags |= OG_REST_PARAM_NETMASK; } } @@ -580,11 +589,13 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params) if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR | OG_REST_PARAM_MAC | + OG_REST_PARAM_NETMASK | OG_REST_PARAM_WOL_TYPE)) return -1; if (!Levanta((char **)params->ips_array, (char **)params->mac_array, - params->ips_array_len, (char *)params->wol_type)) + (char **)params->netmask_array, params->ips_array_len, + (char *)params->wol_type)) return -1; return 0; @@ -2252,6 +2263,7 @@ void og_schedule_run(unsigned int task_id, unsigned int schedule_id, if (Levanta((char **)cmd->params.ips_array, (char **)cmd->params.mac_array, + (char **)cmd->params.netmask_array, cmd->params.ips_array_len, (char *)cmd->params.wol_type)) og_dbi_update_action(cmd->id, true); |