Win 7 changes network "wake from sleep" protocal...

Started by CommonTater, September 06, 2010, 03:14:32 PM

Previous topic - Next topic

CommonTater

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... http://technet.microsoft.com/en-us/library/ee617165(WS.10).aspx

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).



/////////////////////////////////////////////////////////////////////////////////////////
// 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
   memcpy(&ha,Host,sizeof(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
   memset(&magic,255,6);
   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)
     sendto(hSocket,(PCHAR)&magic,128,0,&ha,sizeof(SOCKADDR));
   return 1; }