/*
Copyright (C) JAEHYUK CHO
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int s_argc, char **s_argv);
int main(int s_argc, char **s_argv)
{
static const unsigned char s_target_mac[6] = { /* 이 부분을 자신이 깨우고자 하는 PC의 Ethernet MAC address로 채워주면 되겠습니다. */
0x44u, 0x87u, 0xfcu, 0x8fu, 0xbbu, 0xb4u
};
int s_socket;
struct sockaddr_in s_sockaddr_in;
unsigned char s_magic_packet[ 6 + (6 * 16) ];
int s_repeat;
ssize_t s_send_bytes;
int s_value;
/* UDP socket open */
s_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(s_socket == (-1)) {
perror("socket");
return(EXIT_FAILURE);
}
/* bind */
(void)memset((void *)(&s_sockaddr_in), 0, sizeof(s_sockaddr_in));
s_sockaddr_in.sin_family = AF_INET;
s_sockaddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
s_sockaddr_in.sin_port = htons(0);
if(bind(s_socket, (const struct sockaddr *)(&s_sockaddr_in), (socklen_t)sizeof(s_sockaddr_in)) == (-1)) {
perror("bind");
(void)close(s_socket);
return(EXIT_FAILURE);
}
/* broadcast socket option enable (Broadcast를 위해서는 SO_BROADCAST가 설정되어야 합니다.) */
s_value = 1;
(void)setsockopt(s_socket, SOL_SOCKET, SO_BROADCAST, (const void *)(&s_value), (socklen_t)sizeof(s_value));
/* WOL packet build (repeat 6) */
(void)memset((void *)(&s_magic_packet[0]), 0xff, (size_t)6u); /* 첫 6byte는 FFH로 채웁니다. */
for(s_repeat = 0;s_repeat < 16;s_repeat++) { /* 깨우고자 하는 MAC address를 16회 반복하여 채웁니다. */
(void)memcpy((void *)(&s_magic_packet[6 + (s_repeat * 6)]), (const void *)(&s_target_mac[0]), sizeof(s_target_mac));
}
/* broadcast socket address structure set */
(void)memset((void *)(&s_sockaddr_in), 0, sizeof(s_sockaddr_in));
s_sockaddr_in.sin_family = AF_INET;
(void)inet_pton(s_sockaddr_in.sin_family, "255.255.255.255", (void *)(&s_sockaddr_in.sin_addr));
s_sockaddr_in.sin_port = htons(2304); /* any port ... (사실상 port는 아무거나 상관하지 않습니다. 다만 다른 응용프로그램들에게 방해가 되지 않는 포트를 선택하는것 뿐입니다.) */
/* send */
s_send_bytes = sendto(
s_socket,
(const void *)(&s_magic_packet[0]),
sizeof(s_magic_packet),
0,
(const struct sockaddr *)(&s_sockaddr_in),
(socklen_t)sizeof(s_sockaddr_in)
);
if(s_send_bytes == ((ssize_t)(-1))) {
perror("sendto");
(void)close(s_socket);
return(EXIT_FAILURE);
}
(void)fprintf(stdout,
"WOL packet : %ld bytes (Target %02X:%02X:%02X:%02X:%02X:%02X)\n",
(long)s_send_bytes,
(unsigned int)s_target_mac[0], (unsigned int)s_target_mac[1], (unsigned int)s_target_mac[2],
(unsigned int)s_target_mac[3], (unsigned int)s_target_mac[4], (unsigned int)s_target_mac[5]
);
/* socket close */
(void)close(s_socket);
return(EXIT_SUCCESS);
}
/* vim: set expandtab: */
/* End of source */