none
Wake on LAN through VB.NET

    Question

  • Hi All

     

    I am looking to create a program that utilises the Wake on LAN function that most machines support now. I know you need the remote machine's MAC address before you can send anything to it while it is turned off but lets forget about finding the MAC address for now, I can do that in other ways than VB.

    I know that there is a "magic" packet that has to be sent to the ethernet card of the remote PC and I believe this has to contain a certain number of repititions of the MAC address itself but I dont have a clue where to start when it comes to sending this to the card via VB.NET. I read somewhere it has something to do with Winsock? Can anyone offer any suggestions where to begin or if someone has done this before I'd really appreciate some help.

    Cheers

     

     

    P.S is this the correct forum for this sort of thing?

    Monday, June 11, 2007 10:45 PM

Answers

  • Chris, what you are looking for is really WOW, or wake on wan.

     

    You say remote sites, so that means its not on the local lan that this signal is sent, but to a WAN public IP that would then have to be filtered down to the LAN via the router.

     

    I am not sure that all routers support this type of packet forwarding, but I know mine does (I have a dlink gaming router) and I have successfuly done what you are talking about.

     

    Here is the code I have used. However like I said, I remember having to configure my router a bit to get this to work from a WAN location. Also this isn't production code, just something I did to mess around, so it isn't fully error handled.

     

    Code Snippet

    Private Function GetIP(ByVal DNSName As String) As String

    Try

    Return Net.Dns.GetHostEntry(DNSName).AddressList.GetLowerBound(0).ToString

    Catch ex As Exception

    Return String.Empty

    End Try

    End Function

     

    Private Sub SendMagicPacket()

    'SET THESE VARIABLES TO REAL VALUES

    Dim MacAddress As String = String.Empty

    Dim WANIPAddr As String = String.Empty

    Dim LanSubnet As String = String.Empty

     

    Dim Port As Integer = 9

    Dim udpClient As New System.Net.Sockets.UdpClient

    Dim buf(101) As Char

    Dim sendBytes As [Byte]() = System.Text.Encoding.ASCII.GetBytes(buf)

    For x As Integer = 0 To 5

    sendBytes(x) = CByte("&HFF")

    Next

    MacAddress = MacAddress.Replace("-", "").Replace(":", "")

    Dim i As Integer = 6

    For x As Integer = 1 To 16

    sendBytes(i) = CByte("&H" + MacAddress.Substring(0, 2))

    sendBytes(i + 1) = CByte("&H" + MacAddress.Substring(2, 2))

    sendBytes(i + 2) = CByte("&H" + MacAddress.Substring(4, 2))

    sendBytes(i + 3) = CByte("&H" + MacAddress.Substring(6, 2))

    sendBytes(i + 4) = CByte("&H" + MacAddress.Substring(8, 2))

    sendBytes(i + 5) = CByte("&H" + MacAddress.Substring(10, 2))

    i += 6

    Next

    Dim myAddress As String

    Try

    myAddress = Net.IPAddress.Parse(WANIPAddr).ToString

    Catch ex As Exception

    myAddress = GetIP(WANIPAddr)

    End Try

    If myAddress = String.Empty Then

    MessageBox.Show("Invalid IP address/Host Name given")

    Return

    End If

    Dim mySubnetArray() As String

    Dim sm1, sm2, sm3, sm4 As Int64

    mySubnetArray = LanSubnet.Split("."c)

    For i = 0 To mySubnetArray.GetUpperBound(0)

    Select Case i

    Case Is = 0

    sm1 = Convert.ToInt64(mySubnetArray(i))

    Case Is = 1

    sm2 = Convert.ToInt64(mySubnetArray(i))

    Case Is = 2

    sm3 = Convert.ToInt64(mySubnetArray(i))

    Case Is = 3

    sm4 = Convert.ToInt64(mySubnetArray(i))

    End Select

    Next

    myAddress = WANIPAddr

    udpClient.Send(sendBytes, sendBytes.Length, myAddress, Port)

    End Sub

     

    Thursday, June 14, 2007 5:58 PM
  • the code I posted is for doing it over a wan, which is why you specify an IP. The IP is the IP of the WAN, but the machine itself on the LAN is identified by the MAC address, not the IP.

     

    So you should be able to rework the code to omit the WAN IP, since you are doing this inside the LAN, and only use the MAC address as the destination for the magic packet.

     

    If you cant get it to work, I will try to alter the code to be LAN specific instead of WAN.

    Friday, June 15, 2007 10:43 PM

All replies

  • Chris128,

     

    I hope the following thread on Wake on LAN can provide you some help on your application:

     

    Power management and network applications

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1141753&SiteId=1

     

    This will largely depend on your application design.  For sleep transitions (S3/hybrid sleep/S4) the network stack does not tear down network connections explicitly.  If wake-on-LAN is configured, the network adapter will be put into WoL mode and remain powered.  If WoL is not enabled, the network adapter will (in most cases) be powered off to conserve power.  So for certain applications, the transition to and from sleep can be seamless.  However, there are a few gotchas:

     

    First, if there is network traffic sent to the sleeping machine it will not be processed as the OS is not running.  The NIC and associated firmware does nothing to respond to this traffic (except in the case of wake on LAN, more on that below).  So since the traffic is not received the sending host may detect this and close the connection from that side.  This is especially true of TCP connections because the acknowledgements will not be sent.

     

    Second, the host’s network address may change when the machine resumes from sleep.  For mobiles, this is very common (e.g. sleep the machine at work, go home, wake machine…) however, it can (and does) occur on desktop machine as well.  There are ways to register for notifications through the networking APIs for when this occurs.  You should note that it usually takes a few seconds to detect the network change, it does not happen immediately on resume.  So your applications needs to be aware of this as well.

     

    Third, if the host is configured to wake in response to a network request (WoL), the packet that woke the machine may not be processed by the host.  In many cases that packet will be send and processed on the network stack normally, but it is not guaranteed by the specification.  Also, the sending machine must be able to handle delay incurred as the machine resumes.  Most machines will wake quickly (usually less than 2 second) but that does not guarantee that your application will be able to process the request immediately.  There may be other activity or applications performing work on resume.

     

    Thursday, June 14, 2007 6:04 AM
  • thanks for the reply but im afraid that doesnt really help. They are just talking about how applications will respond when awakening from a shutdown state  where as I want to know how to go about programming an application that actually sends the "waking up" packet to the network card. Im not talking about an application running on the target machine that I want to start up, I mean simply sending the WOL wake up "command" to the network card so that when PCs are shutdown at remote sites we can turn them back on. I realise there are products out there that do this, and I wanted to know how you would go about creating one.

     

    Thanks

    Chris

    Thursday, June 14, 2007 5:39 PM
  • Chris, what you are looking for is really WOW, or wake on wan.

     

    You say remote sites, so that means its not on the local lan that this signal is sent, but to a WAN public IP that would then have to be filtered down to the LAN via the router.

     

    I am not sure that all routers support this type of packet forwarding, but I know mine does (I have a dlink gaming router) and I have successfuly done what you are talking about.

     

    Here is the code I have used. However like I said, I remember having to configure my router a bit to get this to work from a WAN location. Also this isn't production code, just something I did to mess around, so it isn't fully error handled.

     

    Code Snippet

    Private Function GetIP(ByVal DNSName As String) As String

    Try

    Return Net.Dns.GetHostEntry(DNSName).AddressList.GetLowerBound(0).ToString

    Catch ex As Exception

    Return String.Empty

    End Try

    End Function

     

    Private Sub SendMagicPacket()

    'SET THESE VARIABLES TO REAL VALUES

    Dim MacAddress As String = String.Empty

    Dim WANIPAddr As String = String.Empty

    Dim LanSubnet As String = String.Empty

     

    Dim Port As Integer = 9

    Dim udpClient As New System.Net.Sockets.UdpClient

    Dim buf(101) As Char

    Dim sendBytes As [Byte]() = System.Text.Encoding.ASCII.GetBytes(buf)

    For x As Integer = 0 To 5

    sendBytes(x) = CByte("&HFF")

    Next

    MacAddress = MacAddress.Replace("-", "").Replace(":", "")

    Dim i As Integer = 6

    For x As Integer = 1 To 16

    sendBytes(i) = CByte("&H" + MacAddress.Substring(0, 2))

    sendBytes(i + 1) = CByte("&H" + MacAddress.Substring(2, 2))

    sendBytes(i + 2) = CByte("&H" + MacAddress.Substring(4, 2))

    sendBytes(i + 3) = CByte("&H" + MacAddress.Substring(6, 2))

    sendBytes(i + 4) = CByte("&H" + MacAddress.Substring(8, 2))

    sendBytes(i + 5) = CByte("&H" + MacAddress.Substring(10, 2))

    i += 6

    Next

    Dim myAddress As String

    Try

    myAddress = Net.IPAddress.Parse(WANIPAddr).ToString

    Catch ex As Exception

    myAddress = GetIP(WANIPAddr)

    End Try

    If myAddress = String.Empty Then

    MessageBox.Show("Invalid IP address/Host Name given")

    Return

    End If

    Dim mySubnetArray() As String

    Dim sm1, sm2, sm3, sm4 As Int64

    mySubnetArray = LanSubnet.Split("."c)

    For i = 0 To mySubnetArray.GetUpperBound(0)

    Select Case i

    Case Is = 0

    sm1 = Convert.ToInt64(mySubnetArray(i))

    Case Is = 1

    sm2 = Convert.ToInt64(mySubnetArray(i))

    Case Is = 2

    sm3 = Convert.ToInt64(mySubnetArray(i))

    Case Is = 3

    sm4 = Convert.ToInt64(mySubnetArray(i))

    End Select

    Next

    myAddress = WANIPAddr

    udpClient.Send(sendBytes, sendBytes.Length, myAddress, Port)

    End Sub

     

    Thursday, June 14, 2007 5:58 PM
  • Hi,

     

    Im not talking about Wake on Wan. We have site to site VPNs configured on our routers so we basically are on the same LAN as the target machines. I'll see if I can adapt your code to work on the LAN rather than WAN (if theres even anything that needs changing) and give it a go. Thanks for the code example.

     

    Cheers

    Chris

    Friday, June 15, 2007 6:32 PM
  • Hi again,

     

    I tried the code and it doesnt seem to work, heres what I am using (I have a windows form with 1 button on it named button1)

     

    Code Snippet

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim MacAddress As String = "0011432c4032"

    Dim udpClient As New System.Net.Sockets.UdpClient

    Dim buf(101) As Char

    Dim sendBytes As [Byte]() = System.Text.Encoding.ASCII.GetBytes(buf)

    For x As Integer = 0 To 5

    sendBytes(x) = CByte("&HFF")

    Next

    Dim i As Integer = 6

    For x As Integer = 1 To 16

    sendBytes(i) = CByte("&H" + MacAddress.Substring(0, 2))

    sendBytes(i + 1) = CByte("&H" + MacAddress.Substring(2, 2))

    sendBytes(i + 2) = CByte("&H" + MacAddress.Substring(4, 2))

    sendBytes(i + 3) = CByte("&H" + MacAddress.Substring(6, 2))

    sendBytes(i + 4) = CByte("&H" + MacAddress.Substring(8, 2))

    sendBytes(i + 5) = CByte("&H" + MacAddress.Substring(10, 2))

    i += 6

    Next

    udpClient.Send(sendBytes, sendBytes.Length, "citddsk1", 9)

    End Sub

     

    Is this udpclient.send going to work properly over the LAN? Cos im thinking how is it going to work sending the "magic packet" to an IP address on the LAN because when the machine is turned off it doesnt have an IP address. Is there a different method I can use to send the packet to a MAC address?

     

    Thanks

    Chris

    Friday, June 15, 2007 6:49 PM
  • the code I posted is for doing it over a wan, which is why you specify an IP. The IP is the IP of the WAN, but the machine itself on the LAN is identified by the MAC address, not the IP.

     

    So you should be able to rework the code to omit the WAN IP, since you are doing this inside the LAN, and only use the MAC address as the destination for the magic packet.

     

    If you cant get it to work, I will try to alter the code to be LAN specific instead of WAN.

    Friday, June 15, 2007 10:43 PM
  • I REALLY NEED HELP im tryin 2 do that wake on lan thing...

    ive enabled WOL on the bios, network cars and practically ne thing i cud find lol, but its just to coplicated especially because i'm going from a new intel computer trhough a router then to a wireless computer and i know the subnets, IP's, n MAC addresses but i dont no how 2 put them all together 2 send a magic packet, i also need a decent program that sends packets n that has alot more options

     Sad  Sad  Sad  pllzzzzz sum 1 reply

     

    NOTE: this aint a reply i just couldnt find the post button 

    Monday, June 18, 2007 7:50 AM
  • You guy's solved this one ?

     

    Below is some code that I've lifted from a program that I've just finished to carry out a Wake-On-LAN in my building.  I've removed any extraneous bits but it should still work pretty much out of the tin.

     

    Sorry about the extra lines, the indenting on this thing is adding them.

     

    Before class definition add :

    Imports System.management

    Imports System.Net.Sockets

     

    Top of class definition add :

    Dim udpClt As New UdpClient

     

    And then add these three code snippets :

    Private Function generatePacket(ByVal MAC As String, ByRef packet As Byte()) As Boolean

    generatePacket = True

     

    Dim byteLength As Integer

    Select Case MAC.Length

    Case 12

    byteLength = 2

    Case 17

    byteLength = 3

    Case Else

    generatePacket = False

    Exit Function

    End Select

     

    Dim i, j As Integer

    Dim block As [Byte]()

    ReDim block(5)

     

    Try

    For i = 0 To 5

    block(i) = Convert.ToByte(MAC.Substring(byteLength * i, 2), 16)

    Next

    Catch

    generatePacket = False

    Exit Function

    End Try

     

    For i = 0 To 5

    packet(i) = &HFF

    Next

    For i = 6 To 97 Step 6

    For j = 0 To 5

    packet(i + j) = block(j)

    Next

    Next

    End Function

     

    Private Sub executeWOL(ByVal MAC as String)

    Dim packet As [Byte]()

    ReDim packet(101)

    Dim localBCast As New IPEndPoint(IPAddress.Parse(lBcast.Text), CInt(udpPort.Text))

    generatePacket(MAC, packet)

    udpClt.Send(packet, 102, localBCast)

    localBCast = Nothing

    End Sub

     

    Private Function getIpInfo() As Boolean

    'How to calculate the subnet-directed broadcast address

    '1) Convert machine address to binary e.g. 10.208.20.1 = 00001010.11010000.00010100.00000001

    '2) Convert the Subnet Mask to Binary e.g. 255.255.240.0 = 11111111.11111111.11110000.00000000

    '3) Invert the Binary Subnet Mask e.g. 11111111.11111111.11110000.00000000 becomes 00000000.00000000.00001111.11111111

    '4) Or the machine address and the inverted subnet mask e.g. 00001010.11010000.00010100.00000001 Or 00000000.00000000.00001111.11111111 = 00001010.11010000.00011111.11111111 = 10.208.31.255

    getIpInfo = True

    Try

    Dim objMC As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")

    Dim objMOC As ManagementObjectCollection = objMC.GetInstances()

    Dim objMO As ManagementObject

     

    Dim data As String()

    Dim IP As String

    Dim Mask as String

     

    'You will need to do some checking in this loop if you have more than one NIC (or bluetooth adapter installed, etc)

    For Each objMO In objMOC

    data = CType(objMO("IPAddress"), String())

    If data IsNot Nothing Then

    IP = data(0)

    End If

    data = CType(objMO("IPSubnet"), String())

    If data IsNot Nothing Then

    Mask = data(0)

    End If

    Next

     

    objMO.Dispose()

    objMOC.Dispose()

    objMC.Dispose()

     

    Dim i(), m(), b(3) As String

     

    i = Split(IP.Text, ".")

    m = Split(Mask.Text, ".")

     

    Dim c As Integer

    For c = 0 To 3

    b(c) = (Convert.ToByte(i(c), 10) Or (Not Convert.ToByte(m(c), 10))).ToString

    Next

     

    lBcast.Text = Join(b, ".")

    Catch

    getIpInfo = False

    End Try

    End Function

     

    Call the GetIpInfo before the executeWOL.

     

    The MAC Address can be in the format 001122334455 or 00:11:22:33:44:55 (in fact any character can be between the bytes).

     

    udpPort.Text is a TextBox containing the port number to use (I use 7)

     

    lBcast.text is the Local Broadcast IP Address

     

    I'd been googling around trying to find how to this for a bit and in the end gave up and did it from scratch (with a bucket full of help from various sources, none of which I can remember and thank).  Now I've done it I decided to spread the love :-)

     

    Gunney

    Monday, June 25, 2007 3:51 PM
  • Hi!

     

    Use this:

     

     http://www.lucamauri.com/snippet/snip.aspx?id=6

     

    That's what you are looking for.

    • Proposed as answer by Steve Bobosky Monday, October 05, 2009 10:14 PM
    Sunday, July 08, 2007 12:30 PM
  • Hi Kleinma


    Can you please post the working code for WAN ? I tried your code with out IP address and subnet mask, its working fine for LAN but I need the same for WAN

    also could not understand what the use of mySubnetArray variable and sm1,2, ..please explain

    would be great if you send some url/documents

    Thanks
    MSK.
    Friday, October 10, 2008 11:44 AM
  • Welle's answer was the most helpful for me. Copy and paste the class into vb.net. works great.
    Steve Bobosky - ConfigMgr MVP - www.systemcentertools.com - systemcentertools.blogspot.com
    Monday, October 05, 2009 10:15 PM