send a magic ipv4 wake-on-lan packet
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

83 lines
2.3 KiB

#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;
}