Skip to content

Instantly share code, notes, and snippets.

@lionello
Created September 8, 2013 02:48
Show Gist options
  • Save lionello/6481448 to your computer and use it in GitHub Desktop.
Save lionello/6481448 to your computer and use it in GitHub Desktop.
Wake-On-LAN
// Portable Wake-On-Lan by Lionello Lunesu, placed in the public domain
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#ifdef _MSC_VER
#pragma comment(lib, "ws2_32.lib")
#endif
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
typedef unsigned char BYTE;
typedef char TCHAR;
typedef int BOOL;
typedef int SOCKET;
#endif
#include <stdio.h>
#define MACLEN (6)
#define PACKLEN (17*MACLEN)
int H2I(TCHAR m) {
return m <= '9' ? m - '0' : (m | 32) - 'a' + 10;
}
BOOL ValidHex(TCHAR t) {
return (t >= '0' && t <= '9') || (t >= 'a' && t <= 'f') || (t >= 'A' && t <= 'F');
}
int main(int argc, char* argv[])
{
#ifdef _WIN32
WSADATA wsaData;
#endif
const char* pMac = (argc >= 2 ? argv[1] : NULL);
const char* pIp = (argc == 3 ? argv[2] : NULL);
struct sockaddr_in addr;
int t = 0, i;
SOCKET sock;
TCHAR nibble1, nibble2;
BOOL BroadCast = 1;
char pack[PACKLEN];
if (pMac == NULL) {
printf("Usage: wol <MAC> [IP]\n");
return -3;
}
// FFFFFFFFFFFF
while (t < MACLEN)
pack[t++] = 0xFF;
// first MAC
for (i=0; t < MACLEN+MACLEN; ++i) {
nibble1 = pMac[i];
if (nibble1 == 0)
break;
if (!ValidHex(nibble1))
continue;
nibble2 = pMac[++i];
if (!ValidHex(nibble2))
break;
pack[t++] = (H2I(nibble1) << 4) | H2I(nibble2);
}
if (t < MACLEN+MACLEN)
{
printf("Could not parse MAC address\n");
return -2;
}
// repeat 15 more times
for (;t < PACKLEN; ++t)
pack[t] = pack[t - MACLEN];
addr.sin_addr.s_addr = ~0;
#ifdef _WIN32
// Initialize Winsock
i = WSAStartup(MAKEWORD(2,2), &wsaData);
if (i != 0) {
printf("WSAStartup failed: %d\n", i);
return i;
}
if (pIp && InetPton(AF_INET, pIp, &addr) <= 0)
{
printf("Could not parse IP address\n");
return WSAGetLastError();
}
#else
if (pIp && inet_pton(AF_INET, pIp, &addr) <= 0)
{
printf("Could not parse IP address\n");
return errno;
}
#endif
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
#ifdef _WIN32
if (sock == INVALID_SOCKET) {
i = WSAGetLastError();
}
#else
if (sock < 0) {
i = errno;
}
#endif
else {
i = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&BroadCast, sizeof(BroadCast));
addr.sin_family = AF_INET;
addr.sin_port = htons(9); // network byte order
t = sendto(sock, pack, PACKLEN, 0, (struct sockaddr*)&addr, sizeof(addr));
#ifdef _WIN32
if (t != PACKLEN)
i = WSAGetLastError();
closesocket(sock);
#else
if (t != PACKLEN)
i = errno;
close(sock);
#endif
}
#ifdef _WIN32
WSACleanup();
#endif
return i;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment