1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * Wake on LAN
 * v0.2
 */

// Example
// ./wakeonlan 00:11:22:33:44:55 192.168.1.10

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

// Create WakeUpPacket
void createWakeUpPacket(unsigned char packet[], unsigned int macAddress[]){
    int i;
    // Mac Address Variable
    unsigned char mac[6];

    // 6 x 0xFF on start of packet
    for(i = 0; i < 6; i++){
        packet[i] = 0xFF;
        mac[i] = macAddress[i];
    }
    // Rest of the packet is MAC address of the pc
    for(i = 1; i <= 16; i++){
        memcpy(&packet[i*6], &mac, 6*sizeof(unsigned char));
    }
}

// Main Program
int main(int argc, const char* argv[]){
    // Broadcast address
    char broadcastAddress[16] = "192.168.1.255";
    // Packet Variable
    unsigned char packet[102];
    // Mac Address Variable
    unsigned int mac[6];
    // Help variable
    int i = 0;
    // Socket
    int udpSocket;
    // Set broadcast
    int broadcast = 1;
    // Socket address
    struct sockaddr_in udpClient;
    struct sockaddr_in udpServer;
    
    // Check if mac address was given
    if(argc < 2){
        printf("Usage:\n./wakeonlan <mac address> (<broadcast address>)\n");
        exit(1);
    }
    // Parse Mac Address
    i = sscanf(argv[1],"%x:%x:%x:%x:%x:%x", &(mac[0]), &(mac[1]), &(mac[2]), &(mac[3]), &(mac[4]), &(mac[5]));
    if(i != 6){
        printf("Invalid mac address was given.\n");
        exit(1);
    }

    // Print address
    printf("Packet will be sent to %02hhx:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    // Check if broadcast address was given
    if(argc > 2){
        // Parse Broadcast Address
        i = sscanf(argv[2],"%d.%d.%d.%d", &i, &i, &i, &i);
        if(i == 4){
            strcpy(broadcastAddress, argv[2]);
        }
    }
    printf("Broadcast address %s will be used.\n", broadcastAddress);

    // Create Packet
    createWakeUpPacket(packet, mac);

    // Setup broadcast socket
    udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if(setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1){
        printf("Failed to setup broadcast socket.\n");
        exit(1);
    }
    // Set parameters
    udpClient.sin_family = AF_INET;
    udpClient.sin_addr.s_addr = INADDR_ANY;
    udpClient.sin_port = 0;
    // Bind socket
    bind(udpSocket, (struct sockaddr*)&udpClient, sizeof(udpClient));

    // Set server end point (the broadcast addres)
    udpServer.sin_family = AF_INET;
    udpServer.sin_addr.s_addr = inet_addr(broadcastAddress);
    udpServer.sin_port = htons(9);

    // Send the packet
    sendto(udpSocket, &packet, sizeof(unsigned char)*102, 0, (struct sockaddr*)&udpServer, sizeof(udpServer));

    // Done
    printf("Wake up packet was sent.\n");
    exit(0);
}