diff options
| author | Jan Wolff <janw@mailbox.org> | 2021-07-08 20:31:34 +0200 |
|---|---|---|
| committer | Jan Wolff <janw@mailbox.org> | 2021-07-08 20:31:34 +0200 |
| commit | 16399fab9e592cf1e12f1fd56c11f12ae9bc575f (patch) | |
| tree | e428891a59451187c8ce1866332701973fc0cf3a /wakeup.c | |
initial commit
Diffstat (limited to 'wakeup.c')
| -rw-r--r-- | wakeup.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/wakeup.c b/wakeup.c new file mode 100644 index 0000000..01ae3af --- /dev/null +++ b/wakeup.c @@ -0,0 +1,83 @@ +#include <arpa/inet.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void printUsage() +{ + puts("usage: wakeup <MAC> <BROADCAST> [PORT]"); + puts(" MAC: interface address to wakeup (e.g. ff:ff:ff:ff:ff:ff)"); + puts(" BROADCAST: broadcast address of subnet (e.g. 192.168.2.255)"); + puts(" PORT: port to send UDP packet on (default: 7)"); +} + +/* +Use the UDP broadcast method to send the magic wakeup packet. +*/ +int bcast_wakeup(const char* macAddr, const char* broadcast, in_port_t port) +{ + int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 1) { + perror("could not open socket"); + exit(EXIT_FAILURE); + } + + int opt_broadcast = 1; + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt_broadcast, + sizeof(opt_broadcast)); + + struct in_addr ip; + if (!inet_aton(broadcast, &ip)) { + fputs("could not parse broadcast IP address", stderr); + exit(EXIT_FAILURE); + } + + struct sockaddr_in socket_addr; + memset(&socket_addr, 0, sizeof(socket_addr)); + socket_addr.sin_port = port; + socket_addr.sin_family = AF_INET; + socket_addr.sin_addr.s_addr = ip.s_addr; + + uint8_t macValues[6]; + if (sscanf(macAddr, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &macValues[0], + &macValues[1], &macValues[2], &macValues[3], &macValues[4], + &macValues[5]) != 6) { + fputs("could not parse MAC address", stderr); + exit(EXIT_FAILURE); + } + + uint8_t data[6 + 16 * 6]; + memset(&data, 0xFF, 6); // sync stream for magic packet + for (size_t i = 0; i < 16; + i++) { // followed by 16 repititions of mac address + memcpy(data + 6 + 6 * i, &macValues, 6); + } + + if (sendto(sock, data, sizeof(data), 0, (struct sockaddr*)&socket_addr, + sizeof(socket_addr)) < 0) { + fputs("packet sending failed", stderr); + perror("Error Code:"); + exit(EXIT_FAILURE); + } + return 1; +} + +int main(int argc, char* argv[]) +{ + const char* mac; + const char* ip; + in_port_t port = 7; + if (argc < 3) { + printUsage(); + exit(0); + } else { + mac = argv[1]; + ip = argv[2]; + } + if (argc > 3) { + port = atoi(argv[3]); + } + bcast_wakeup(mac, ip, port); + return 0; +} |
