83 lines
2.3 KiB
C
83 lines
2.3 KiB
C
#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_pton(AF_INET, 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;
|
|
}
|