Click here to Skip to main content
Click here to Skip to main content

Wake-On-Lan Class

By , 27 Oct 2003
 

Sample Image - wolclass.gif

Introduction

This class provides the functionality to wake up a machine over a local area network. There is not yet any functionality to use directed broadcasts, if your router supports it. The VS.NET project contains the class itself and a little command line app class which makes use of it.

Background

The basic Idea was to provide a web based interface to wake up other machines from an always running server. Why want that? Because I usually forget some actual working files on my desktop client at home or work, but I don't want them to be running all the time. And having a ASP.NET enabled always running web server at hand makes me wanting a pure .NET based solution, getting rid of the old Com-Objects or even worse command line tools. Here you will not find any ASP.NET code, but it should be no big deal for you to make use of the class in an ASP.NET environment, cause there are only two lines of code to add.
I named the class Magic Packet after AMD's registered trademark how developed this technology and provide some good background information.

Using the code

First you need to instantiate a MagicPacket object by presenting a MAC-Address to the class constructor. This Object represents now the ability to start this particular computer within the LAN. Next step is just to call the objects WakeUp() method. There is also a read only property called macAddress to read out the objects MAC address.

if (macOK==true) 
{
    //create MagicPacket
    MagicPacket wakeUpPacket = NetTools.MagicPacket(macAdress);
    //Wake Up call
    byteSend = wakeUpPacket.WakeUp();
    Console.WriteLine("{0} Byte Send to {1}", byteSend, 
        wakeUpPacket.macAdress);
}

MagicPacket Class

The MagicPacket class itself is more or less self describing. I'm using System.Text.RegularExpressions just to make my life easy getting rid of all unwanted characters in the provided MAC-Address sting. Otherwise I would have to write a lot more code for string checking and I usually prefer to ignore things I don't like rather than handling those exceptions. What brings us to the class method Mac2Byte, this function has to convert the 12 digit string containing the MAC-Address in hexadecimal format (I think it is just common because nobody really wants to keep a 48 bit long sequence in mind :) to the byte array format.

protected static byte[] Mac2Byte(string strMacAddress) 
{
    string macAddr; byte[] 
    macBytes = new byte[BYTELENGHT]; 
    //remove all non 0-9, A-F, a-f characters 
    macAddr = Regex.Replace(strMacAddress, @"[^0-9A-Fa-f]", ""); 
    //check if it is now a valid mac adress 
    length if (!(macAddr.Length == BYTELENGHT*2)) 
        throw new ArgumentException("Mac Adress must be " + 
             (BYTELENGHT*2).ToString() + 
              "digits of 0-9, A-F, a-f characters in length."); 
    string hex; 
    for (int i=0; i < macBytes.Length;i++)
    {
        hex = new String(new Char[] {macAddr[i*2], macAddr[i*2+1]});
        macBytes[(i)] = byte.Parse(hex, 
             System.Globalization.NumberStyles.HexNumber); 
    }
    return macBytes; 
} 

After converting the MAC-Address to byte format we can now create the payload. Especially here I decided to use class wide constants in the old C coder style to enhance readability and maintainability.

protected static byte[] CreatePayload(byte[] macAddress) 
{
    byte[] payloadData = new byte[HEADER+MAGICPACKETLENGTH*BYTELENGHT];
    for (int i=0; i<HEADER; i++) 
    {
        payloadData[i] = byte.Parse("FF", 
             System.Globalization.NumberStyles.HexNumber);
    }
    for(int i=0; iMAGICPACKETLENGTH; i++)
    {
        for(int j=0;jBYTELENGHT;j++)
        {
            payloadData[((i*BYTELENGHT)+j)+HEADER] = macAddress[j];
        }
    }
    return payloadData;
}

The last thing to do is to get the packet on the network. This is almost as easy as it sounds. Just instantiate a Socket and send the payload in byte array format. As we are using UDP and don't require any answer we can just do it in a send and forget style.

protected static int SendUDP(byte[] Payload, IPEndPoint EndPoint)
{        
    int byteSend;
    //create a new client socket...
    Socket socketClient = new Socket(EndPoint.AddressFamily, 
        SocketType.Dgram, ProtocolType.Udp);
    try
    {
        //open connection...
        socketClient.Connect(EndPoint);
        //send MagicPacket(TM)...
        byteSend = socketClient.Send (Payload, 0, Payload.Length, 
           SocketFlags.None);
    }
    catch (SocketException ex)
    {
        throw ex;
    }
    finally
    {
        socketClient.Close();
    }
    return byteSend;
}

Doing the coding

Using sockets with .NET is absolutely straight forward. So the most thoughts I had to put in as creating the MagicPacket payload with the Ethernet broadcast address "FF FF FF FF FF FF" followed by 16 times of the targets MAC-Address. And the conversion of the MAC-Address from standard hex format to byte format taken by the socket. But the trouble converting the MAC-Address was quite a breeze thanks to neilck and his hex encoding/decoding class, providing me a good example.

Issues

Having this very basic class running now the next step I'm thinking of is to add at least the ability to use directed broadcasts and to solve dns names for a remote target network. You might also think about some RARP functionality to solve IP-Address into MAC-Address, but there for you need to maintain a table for a long time and it might not be the best solution because the machine you are going to wake is not running in the moment, so I already discarded that idea. Also I was thinking about how to check if the machine has started, but I haven't figured out how to do it the smart way.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

mkruppa
Team Leader
Germany Germany
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat is the license of this code? Pinmemberangelo moscati16 Oct '11 - 4:49 
Can I use it in commercial application?
 
Thanks,
Angelo
AnswerRe: What is the license of this code? Pinmembermkruppa16 Oct '11 - 10:47 
QuestionEasy to extend to use across networks PinmemberPer Hejndorf2 Aug '11 - 23:08 
This is still a great article. I just ported the code to .Net 4, and extended it so I can now turn on my work-machine via VPN. Only thing needed was to change the constructor code that relies on:
 
private System.Net.IPAddress wolIPAddr = System.Net.IPAddress.Broadcast;
 
so that it takes an ipAddressMask as a parameter and then sets the mask:
 
wolIPAddr = IPAddress.Parse(ipAddressMask);
 
Now I can call the MagicPacket class with these parameters :
 
MagicPacket wakeUpPacket = new MagicPacket(macAdress,"10.1.8.255");
 
to access my work machine. It's really exhilerating to have a ping /t command running and seeing it waking up miles away Smile | :)
 
I hope that I can now enable/inspire my coworkers to save energy by not leaving their work computers always on, just in case they need it. Next step for me is to set up a task to have the work computer switch off every night an on again in the morning automatically...
Questioncan be improved using .Net's built-in PhysicalAddress PinmemberMember 40957453 Sep '09 - 1:50 
There is no need to need to loop in Mac2Byte/Mac2String methods... .NET has a built-in class for MAC addresses called PhysicalAddress( in System.Net.NetworkInformation).
 

using System.Net.NetworkInformation;
 
public byte[] Mac2Byte(string strMacAddress)
{
string macAddr = Regex.Replace(strMacAddress.ToUpperInvariant()), @"[^0-9A-Fa-f]", "");
return PhysicalAddress.Parse(macAddr).GetAddressBytes();
}

 

public string Mac2String(byte[] macAddrBytes)
{
 
PhysicalAddress physAddr = new PhysicalAddress(macAddrBytes);
return physAddr.ToString();
}
 

see...no loops! Smile | :)
Generalhi Pinmemberrojasrojas13 Sep '08 - 13:48 
IS this using broadcasting or is it sending only to a particular ip.. can u explain it clearly..
 

Thanks a lot for the code
GeneralBroadcast was Re: hi Pinmembermkruppa13 Sep '08 - 23:55 
GeneralRe: Broadcast was Re: hi Pinmemberrojasrojas14 Sep '08 - 6:11 
GeneralRe: Broadcast was Re: hi Pinmembermkruppa14 Sep '08 - 9:57 
GeneralRe: Broadcast was Re: hi Pinmemberrojasrojas14 Sep '08 - 10:24 
GeneralRe: Broadcast was Re: hi Pinmembermkruppa15 Sep '08 - 3:19 
GeneralRe: Broadcast was Re: hi Pinmemberrojasrojas16 Sep '08 - 20:57 
GeneralRe: Broadcast was Re: hi Pinmembermkruppa16 Sep '08 - 23:43 
GeneralRe: Broadcast was Re: hi Pinmemberrojasrojas16 Sep '08 - 23:50 
GeneralRe: Broadcast was Re: hi Pinmembermkruppa17 Sep '08 - 1:44 
GeneralRe: Broadcast was Re: hi Pinmemberrojasrojas17 Sep '08 - 3:11 
GeneralRe: Broadcast was Re: hi Pinmembermkruppa17 Sep '08 - 5:59 
Yes, that should be OK if you can execute your wake-on-lan program on a machine in a give subnet or vlan. If you use fixed ip addresses and the cache time of the arp tables within your routers or layer-3-ip-switches is sufficed you might try a direct ip-magic-packet to that particular machine, but that might not work in any case.
GeneralRe: Broadcast was Re: hi Pinmemberrojasrojas25 Sep '08 - 2:20 
GeneralWonderful work Pinmemberedmundo_gz@hotmail.com3 Aug '05 - 14:07 
it´s a simple code and it does its function perfectly
Generalwol Pinmemberramazoti7 Nov '03 - 10:51 
Hello
 
i search a source code for Wake on lan in C++.Confused | :confused:
 
Can someone tell me where I can find it.
 

Thanks
 

 

GeneralRe: wol Pinmembermkruppa7 Nov '03 - 21:51 
GeneralRe: wol Pinmemberramazoti19 Nov '03 - 5:52 
GeneralRe: wol Pinmemberthe-unforgiven19 Jul '05 - 10:01 
GeneralRe: wol Pinmembertsurutsuru22 Sep '04 - 6:11 
Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 28 Oct 2003
Article Copyright 2003 by mkruppa
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid