source: ogServer-Git/src/wol.c @ 927d42b

Last change on this file since 927d42b was 1f13855, checked in by OpenGnSys Support Team <soporte-og@…>, 3 years ago

#1043 add WOL_SENT state

WOL_SENT tells that WakeOnLan? was sent to computer, after 60 seconds,
if computer does not boot, this state is released.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/*
2 * Copyright (C) 2020 Soleta Networks <info@soleta.eu>
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Affero General Public License as published by the
6 * Free Software Foundation, version 3.
7 */
8#include <sys/types.h>
9#include <ifaddrs.h>
10#include <string.h>
11#include <netinet/in.h>
12#include <sys/socket.h>
13#include <syslog.h>
14#include <stddef.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <sys/types.h>
18#include <sys/socket.h>
19#include <fcntl.h>
20#include "wol.h"
21#include "rest.h"
22#include "cfg.h"
23#include "ogAdmServer.h"
24
25int wol_socket_open(void)
26{
27        unsigned int on = 1;
28        int ret, s;
29
30        s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
31        if (s < 0) {
32                syslog(LOG_ERR, "cannot create socket for magic packet\n");
33                return -1;
34        }
35        ret = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (unsigned int *) &on,
36                         sizeof(on));
37        if (ret < 0) {
38                syslog(LOG_ERR, "cannot set broadcast socket\n");
39                return -1;
40        }
41
42        return s;
43}
44
45bool wake_up_send(int sd, struct sockaddr_in *client,
46                  const struct wol_msg *msg, const struct in_addr *addr)
47{
48        int ret;
49
50        client->sin_addr.s_addr = addr->s_addr;
51
52        ret = sendto(sd, msg, sizeof(*msg), 0,
53                     (struct sockaddr *)client, sizeof(*client));
54        if (ret < 0) {
55                syslog(LOG_ERR, "failed to send wol\n");
56                return false;
57        }
58
59        return true;
60}
61
62bool wake_up_broadcast(int sd, struct sockaddr_in *client,
63                       const struct wol_msg *msg)
64{
65        struct sockaddr_in *broadcast_addr, addr = {};
66        struct ifaddrs *ifaddr, *ifa;
67
68        if (getifaddrs(&ifaddr) < 0) {
69                syslog(LOG_ERR, "cannot get list of addresses\n");
70                return false;
71        }
72
73        addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
74
75        for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
76                if (ifa->ifa_addr == NULL ||
77                    ifa->ifa_addr->sa_family != AF_INET ||
78                    strcmp(ifa->ifa_name, ogconfig.wol.interface) != 0)
79                        continue;
80
81                broadcast_addr =
82                        (struct sockaddr_in *)ifa->ifa_ifu.ifu_broadaddr;
83                addr.sin_addr.s_addr = broadcast_addr->sin_addr.s_addr;
84                break;
85        }
86        freeifaddrs(ifaddr);
87
88        return wake_up_send(sd, client, msg, &addr.sin_addr);
89}
90
91#define OG_WOL_CLIENT_TIMEOUT   60
92
93static void og_client_wol_timer_cb(struct ev_loop *loop, ev_timer *timer,
94                                   int events)
95{
96        struct og_client_wol *cli_wol;
97
98        cli_wol = container_of(timer, struct og_client_wol, timer);
99
100        syslog(LOG_ERR, "timeout WakeOnLAN request for client %s\n",
101               inet_ntoa(cli_wol->addr));
102        list_del(&cli_wol->list);
103        free(cli_wol);
104}
105
106struct og_client_wol *og_client_wol_create(const struct in_addr *addr)
107{
108        struct og_client_wol *cli_wol;
109
110        cli_wol = calloc(1, sizeof(struct og_client_wol));
111        if (!cli_wol)
112                return NULL;
113
114        cli_wol->addr = *addr;
115
116        ev_timer_init(&cli_wol->timer, og_client_wol_timer_cb,
117                      OG_WOL_CLIENT_TIMEOUT, 0.);
118        ev_timer_start(og_loop, &cli_wol->timer);
119
120        return cli_wol;
121}
122
123void og_client_wol_refresh(struct og_client_wol *cli_wol)
124{
125        ev_timer_again(og_loop, &cli_wol->timer);
126}
127
128void og_client_wol_destroy(struct og_client_wol *cli_wol)
129{
130        ev_timer_stop(og_loop, &cli_wol->timer);
131        list_del(&cli_wol->list);
132        free(cli_wol);
133}
134
135const char *og_client_wol_status(const struct og_client_wol *wol)
136{
137        return "WOL_SENT";
138}
Note: See TracBrowser for help on using the repository browser.