Author Topic: Win 7 changes network "wake from sleep" protocal...  (Read 4225 times)


  • Guest
Win 7 changes network "wake from sleep" protocal...
« on: September 06, 2010, 03:14:32 pm »
In Win7 Microsoft has changed the wake from sleep protocals for their LAN networking.  Simply pinging a machine will no longer wake it.  You must either connect to it with TCP or send it a Magic Packet before using UDP... In fact the only guaranteed wakeup is the magic packet.

The details are here...

Ok so ... what the @#$@# is a Magic Packet?

Basically it's a 128 byte packet where the first 6 bytes are set to 0xFF, followed by at least 16 repetitions of the target machine's MAC address (the physical network ID of the NIC chip).  To get the MAC address you use the Windows SendARP function.  

Below is an example of how to get the MAC address and send a Magic Packet from an open UDP port using Winsock2.... Basically you hand it a SOCKADDR structure with the target IP address, the number of retires for the ARP request and the delay between retries (in seconds).

Code: [Select]
// Send Magic Packet

// build and send magic packet
BOOL WakeHost(PSOCKADDR Host, BYTE Tries, BYTE Delay)
  { SOCKADDR  ha;                 // host ip and port
    BYTE      mac[6];             // host mac address
    ULONG     smac = 6;           // size of mac address
    BYTE      magic[128] = {0};   // magic packet  
    FD_SET    st;                 // socket to be tested
    TIMEVAL   tv;                 // delay time for test
    BYTE      rt = 0;              // retry counter
    // make a copy of the sockaddr
    // switch port
    ((PSOCKADDR_IN) &ha)->sin_port = htons(9);
    // get mac address
    while (SendARP(((PSOCKADDR_IN)&ha)->sin_addr.S_un.S_addr,0,(PULONG)&mac,&smac))
      { if (++ rt > Tries)
          return 0;
        Sleep(Delay * 1000); }
    // build magic packet
    for ( int x = 6; x < 102 ; x++)
      magic[x] = mac[x % 6];
    // wait then send
    st.fd_count    = 1;
    st.fd_array[0] = hSocket;
    tv.tv_sec      = 5;
    tv.tv_usec     = 0;
    if (select(1,NULL,&st,NULL,&tv) > 0)
    return 1; }

« Last Edit: September 06, 2010, 06:48:34 pm by CommonTater »