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