summaryrefslogtreecommitdiff
path: root/lib/wol.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/wol.c')
-rw-r--r--lib/wol.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/wol.c b/lib/wol.c
new file mode 100644
index 0000000..2fb1eca
--- /dev/null
+++ b/lib/wol.c
@@ -0,0 +1,116 @@
+/*
+ * wol.c:
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+
+#include "common.h"
+#include "wol.h"
+
+//***************************************************************************
+// Send WOL
+//***************************************************************************
+
+int sendWol(const char* mac, const char* device)
+{
+ struct sockaddr_in addr;
+ unsigned char packet[sizeWolPacket];
+ int sock;
+ int optval = 1;
+ cWolHeader wolHeader;
+ const char* bcast = "";
+
+ if (isEmpty(device))
+ device = getFirstInterface();
+
+ bcast = bcastAddressOf(getIpOf(device), getMaskOf(device));
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ {
+ tell(0, "Error: Cannot open socket '%s'", strerror(errno));
+ return fail;
+ }
+
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval)) < 0)
+ {
+ tell(0, "Error: Cannot set socket options '%s'", strerror(errno));
+ return fail;
+ }
+
+ sprintf(wolHeader.remoteAddr, "%.*s", sizeAddr, bcast);
+
+ if (packMacAddr(mac, &wolHeader.macAddr) < 0)
+ {
+ tell(0, "Error: MAC Address '%s' ist not valid", mac);
+ return fail;
+ }
+
+ // .....
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(wolPort);
+
+ if (inet_aton(wolHeader.remoteAddr, &addr.sin_addr) == 0)
+ {
+ tell(0, "Error: Invalid remote ip address given '%s'", wolHeader.remoteAddr);
+ return fail;
+ }
+
+ for (int i = 0; i < 6; i++)
+ packet[i] = 0xFF;
+
+ for (int i = 1; i <= 16; i++)
+ for (int j = 0; j < 6; j++)
+ packet[i * 6 + j] = wolHeader.macAddr.macAddr[j];
+
+ if (sendto(sock, packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+ {
+ tell(0, "Error: Cannot send data '%s'", strerror(errno));
+ return fail;
+ }
+
+ tell(0, "Info: Successful sent WOL magic packet to '%s' via bcast '%s'",
+ wolHeader.macAddr.macAddrStr, bcast);
+
+ close(sock);
+
+ return success;
+}
+
+//***************************************************************************
+// Pack MAC Address
+//***************************************************************************
+
+int packMacAddr(const char* mac, cMacAddr* packedMac)
+{
+ char* tmpMac = strdup(mac);
+ char* tok;
+
+ tok = strtok(tmpMac, ":");
+
+ for (int i = 0; i < macAddrTupel; i++)
+ {
+ if (!tok)
+ {
+ free(tmpMac);
+ return fail;
+ }
+
+ packedMac->macAddr[i] = (unsigned char)strtol(tok, 0, 16); // HEX
+ tok = strtok(0, ":");
+ }
+
+ strncpy(packedMac->macAddrStr, mac, sizeMacStr);
+ free(tmpMac);
+
+ return success;
+}