summaryrefslogtreecommitdiff
path: root/wakeup.c
diff options
context:
space:
mode:
Diffstat (limited to 'wakeup.c')
-rw-r--r--wakeup.c83
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;
+}