Wikipedia says:
Wake-on-LAN (WoL) is an Ethernet or Token Ring computer networking standard that allows a computer to be turned on or awakened by a network message.
But, in another section:
Responding to the magic packet ... Most WoL hardware functionally is typically blocked by default and needs to be enabled in using the system BIOS. Further configuration from the OS is required in some cases, for example via the Device Manager network card properties on Windows operating systems.
Why? why do we need to also enable WOL in OS?
The Problem:
My actual problem rise when I implement a WOL program to turn on other PCs in a network(connected by LAN) from a local server. But failed, because it needs some extra configurations in the PCs:
- The configurations are different from OS to OS (and from version to version).
- Some of the configurations are not permanent and need to be done in every OS startup. (for example: in Ubuntu 16.04 I had to run
ethtool -s eno1 wol g
).
Is there any way to bypass the OS configurations and only enable WOL from BIOS settings? Or it's the code problem?
WOL Example:
#include <QByteArray>
#include <QDebug>
#include <QUdpSocket>
#include <thread>
auto sendMagicPacket(QString const& ip, QString const& mac)
{
std::pair<bool, QString> result = {true, ""};
///
/// \note Constants are from
/// https://en.wikipedia.org/wiki/Wake-on-LAN#Magic_packet
///
constexpr auto magicPacketLength = 102;
constexpr auto payloadLength = 6;
constexpr auto payloadValue = static_cast<char>(0xFF);
constexpr auto defaultPort = 9; // Could be 0, 7, 9
char toSend[magicPacketLength];
for (int i = 0; i < payloadLength; ++i)
{
toSend[i] = payloadValue;
}
auto const macSplited = mac.split(':');
auto const macLength = macSplited.size();
for (int j = payloadLength; j < magicPacketLength; j += macLength)
{
for (int i = 0; i < macLength; ++i)
{
toSend[i + j] = static_cast<char>(macSplited[i].toUInt(nullptr, 16));
}
}
QUdpSocket socket;
auto const writtenSize =
socket.writeDatagram(toSend, magicPacketLength, QHostAddress(ip), defaultPort);
if (writtenSize != magicPacketLength)
{
result = {false, "writtenSize(" + QString::number(writtenSize) +
") != magicPacketLength(" +
QString::number(magicPacketLength) +
"): " + socket.errorString()
};
}
return result;
}
int main()
{
for (int i = 0; i < 5; ++i)
{
auto const result = sendMagicPacket("192.168.11.31", "1c:1c:1e:1f:19:15");
if (not result.first)
{
qDebug() << result.second;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}