xref: /haiku/src/bin/network/wakeonlan.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
1 /*
2  * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include <sys/socket.h>
9 #include <netinet/in.h>
10 
11 int
12 main(int argc, char *argv[])
13 {
14 	if (argc < 2) {
15 		printf("usage: %s <MAC address>\n", argv[0]);
16 		return 1;
17 	}
18 
19 	unsigned char mac[6];
20 	if (sscanf(argv[1], "%2x%*c%2x%*c%2x%*c%2x%*c%2x%*c%2x", &mac[0], &mac[1],
21 		&mac[2], &mac[3], &mac[4], &mac[5]) != 6) {
22 		printf("unrecognized MAC format\n");
23 		return 2;
24 	}
25 
26 	char buffer[102];
27 	memset(buffer, 0xff, 6);
28 	for (int i = 1; i <= 16; i++)
29 		memcpy(buffer + i * 6, mac, sizeof(mac));
30 
31 	int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
32 	if (sock < 0) {
33 		printf("failed to create socket: %s\n", strerror(sock));
34 		return 3;
35 	}
36 
37 	int value = 1;
38 	int result = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value,
39 		sizeof(value));
40 	if (result < 0) {
41 		printf("failed to set broadcast socket option: %s\n", strerror(result));
42 		return 4;
43 	}
44 
45 	sockaddr_in address;
46 	address.sin_family = AF_INET;
47 	address.sin_addr.s_addr = 0xffffffff;
48 	address.sin_port = 0;
49 
50 	result = sendto(sock, buffer, sizeof(buffer), 0,
51 		(struct sockaddr *)&address, sizeof(address));
52 	if (result < 0) {
53 		printf("failed to send magic packet: %s\n", strerror(result));
54 		return 5;
55 	}
56 
57 	printf("magic packet sent to %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0],
58 		mac[1], mac[2], mac[3], mac[4], mac[5]);
59 	return 0;
60 }
61