2021-04-06 02:12:58 +03:00
|
|
|
|
using NetworkResurrector.Server.Abstractions;
|
2020-11-27 01:04:55 +02:00
|
|
|
|
using System.Globalization;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace NetworkResurrector.WakeOnLan.Inhouse
|
|
|
|
|
{
|
|
|
|
|
internal class WolDriver : IWakeOnLanService
|
|
|
|
|
{
|
|
|
|
|
private readonly WolClient _client;
|
|
|
|
|
|
|
|
|
|
public WolDriver(WolClient client)
|
|
|
|
|
{
|
|
|
|
|
_client = client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<(bool success, string message)> Wake(string macAddress)
|
|
|
|
|
{
|
|
|
|
|
//remove all non 0-9, A-F, a-f characters
|
|
|
|
|
macAddress = Regex.Replace(macAddress, @"[^0-9A-Fa-f]", "");
|
|
|
|
|
|
|
|
|
|
//check if mac adress length is valid
|
|
|
|
|
if (macAddress.Length != 12)
|
|
|
|
|
return (false, "Invalid MAC address.");
|
|
|
|
|
else
|
|
|
|
|
return await Wakeup(macAddress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region Wakeup
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Wakes up the machine with the given <paramref name="macAddress"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// <note>
|
|
|
|
|
/// <list type="number">
|
|
|
|
|
/// <item> The motherboard must support Wake On LAN.</item>
|
|
|
|
|
/// <item> The NIC must support Wake On LAN.</item>
|
|
|
|
|
/// <item> There must be a wire connecting the motherboard's WOL port to
|
|
|
|
|
/// the NIC's WOL port. Usually there always is a connection on most of
|
|
|
|
|
/// the PCs.</item>
|
|
|
|
|
/// <item> The Wake On LAN feature must be enabled in the motherboard's
|
|
|
|
|
/// BIOS. Usually this is also enabled by default, but you might like to
|
|
|
|
|
/// check again.</item>
|
|
|
|
|
/// <item> The "Good Connection" light on the back of the NIC must be lit
|
|
|
|
|
/// when the machine is off. (By default always good if you are not
|
|
|
|
|
/// facing any network issues)</item>
|
|
|
|
|
/// <item> Port 12287 (0x2FFF) must be open. (By default it should be
|
|
|
|
|
/// open unless some antivirus or any other such program has changed
|
|
|
|
|
/// settings.)</item>
|
|
|
|
|
/// <item> Packets cannot be broadcast across the Internet. That's why
|
|
|
|
|
/// it's called Wake On Lan, not Wake On Internet.</item>
|
|
|
|
|
/// <item> To find your MAC address, run the MSINFO32.EXE tool that is a
|
|
|
|
|
/// part of Windows and navigate to Components > Network > Adapter
|
|
|
|
|
/// or simply type nbtstat -a <your hostname < at command prompt.
|
|
|
|
|
/// e.g. nbtstat -a mymachinename or nbtstat -A 10.2.100.213.
|
|
|
|
|
/// <param name="macAddress">The MAC address of the host which has to be
|
|
|
|
|
/// woken up.</param>
|
|
|
|
|
///
|
|
|
|
|
private async Task<(bool success, string message)> Wakeup(string macAddress)
|
|
|
|
|
{
|
|
|
|
|
_client.Connect(new IPAddress(0xffffffff) /*255.255.255.255 i.e broadcast*/, 0x2fff /*port = 12287*/);
|
|
|
|
|
|
|
|
|
|
if (!_client.SetClientInBrodcastMode())
|
|
|
|
|
return (false, "Remote client could not be set in broadcast mode!");
|
|
|
|
|
|
|
|
|
|
int byteCount = 0;
|
|
|
|
|
byte[] bytes = new byte[102];
|
|
|
|
|
|
|
|
|
|
for (int trailer = 0; trailer < 6; trailer++)
|
|
|
|
|
{
|
|
|
|
|
bytes[byteCount++] = 0xFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int macPackets = 0; macPackets < 16; macPackets++)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (int macBytes = 0; macBytes < 6; macBytes++)
|
|
|
|
|
{
|
|
|
|
|
bytes[byteCount++] = byte.Parse(macAddress.Substring(i, 2), NumberStyles.HexNumber);
|
|
|
|
|
i += 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int returnValue = await _client.SendAsync(bytes, byteCount);
|
|
|
|
|
|
|
|
|
|
return (true, $"{returnValue} bytes sent to {macAddress}");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|