home *** CD-ROM | disk | FTP | other *** search
/ PC World 2004 November / PCWorld_2004-11_cd.bin / software / temacd / poweroff / pwroff30.exe / src / wol.c < prev   
C/C++ Source or Header  |  2002-02-16  |  3KB  |  110 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <winsock2.h>
  5. #include "poweroff.h"
  6.  
  7. #define REPEAT_ADDRESS     20
  8. #define MAC_ADDRESS_LENGTH  6
  9. #define HEADER_LENGTH       6
  10.  
  11. unsigned char atox(char s)
  12. {
  13.     if (s >= 'a'){
  14.         s -= 0x20;
  15.     }
  16.     if (s >= 'A'){
  17.         s -= 'A';
  18.         s += 10;
  19.     } else if ('1' <= s && s <= '9') {
  20.         s -= '1';
  21.         s += 1;
  22.     } else {
  23.         s = 0;
  24.     }
  25.     return((unsigned char)s);
  26. }
  27.  
  28. int get_broadcast_addr(char *broadcast,char *subnet,char *mask)
  29. {
  30.   long sn, ba, ma;
  31.   struct in_addr ia;
  32.  
  33.   Log("get_broadcast_addr start");
  34.   sn = ntohl(inet_addr(subnet));
  35.   ma = ntohl(inet_addr(mask));
  36.   ba = sn & ma;
  37.   ba |= ~ma;
  38.   ia.s_addr = htonl(ba);
  39.   strcpy(broadcast, (char *)inet_ntoa(ia));
  40.   Log("get_broadcast_addr end, addr=%s",broadcast);
  41.   return(0);
  42. }
  43.  
  44. int WakeOnLan(PowerSettings *ps,char *ip_address,char *mask,char *mac_address)
  45. {
  46.   int sd; /* Socket descriptor */
  47.   unsigned char dest_mac_address[10];
  48.   unsigned char sync[10] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  49.   unsigned char buf[REPEAT_ADDRESS*MAC_ADDRESS_LENGTH+HEADER_LENGTH];
  50.   int n; /* The number of octet sent to destination */
  51.   struct sockaddr_in hostaddr;  /* holds socket address */
  52.   char broadcastaddr[50];
  53.   BOOL t=TRUE;
  54.   
  55.   Log("WakeOnLan start, ip=%s, mask=%s, mac=%s",ip_address,mask,mac_address);
  56.   get_broadcast_addr(broadcastaddr, ip_address, mask);
  57.   dest_mac_address[0] = atox(mac_address[0])*0x10 + atox(mac_address[1]);
  58.   dest_mac_address[1] = atox(mac_address[2])*0x10 + atox(mac_address[3]);
  59.   dest_mac_address[2] = atox(mac_address[4])*0x10 + atox(mac_address[5]);
  60.   dest_mac_address[3] = atox(mac_address[6])*0x10 + atox(mac_address[7]);
  61.   dest_mac_address[4] = atox(mac_address[8])*0x10 + atox(mac_address[9]);
  62.   dest_mac_address[5] = atox(mac_address[10])*0x10 + atox(mac_address[11]);
  63.   
  64.   memcpy(buf, sync, HEADER_LENGTH);
  65.   for (n = 0; n < REPEAT_ADDRESS; n++)
  66.   {
  67.     memcpy(&buf[HEADER_LENGTH+n*MAC_ADDRESS_LENGTH], dest_mac_address, MAC_ADDRESS_LENGTH);
  68.   }
  69.     
  70.   /* Set Destination Address */
  71.   hostaddr.sin_family = AF_INET;
  72.   hostaddr.sin_addr.s_addr = inet_addr(broadcastaddr);
  73.   
  74.   /* Set Destination Port */
  75.   hostaddr.sin_port = htons(7);
  76.     
  77.   /* Open an UDP socket */
  78.   if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  79.   {
  80.     ShowSocketError(ps,"socket");
  81.     return -5;
  82.   }
  83.  
  84.   /* Enable to broadcast */
  85.   if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, (char *)&t, sizeof(t)) == SOCKET_ERROR)
  86.   {
  87.     ShowSocketError(ps,"setsockopt");
  88.     closesocket(sd);
  89.     return -6;
  90.   }
  91.   
  92.   Log("Sending magic packet");
  93.   /* Send *Magic data* to destination node */
  94.   if ((n = sendto(sd, buf, REPEAT_ADDRESS*MAC_ADDRESS_LENGTH+HEADER_LENGTH, 0, (LPSOCKADDR)&hostaddr, sizeof(hostaddr))) == SOCKET_ERROR)
  95.   {
  96.     ShowSocketError(ps,"sendto");
  97.     closesocket(sd);
  98.     return -7;
  99.   }
  100.  
  101.   /* Close the UDP socket */
  102.   if (sd >= 0)
  103.   {
  104.     closesocket(sd);
  105.   }
  106.  
  107.   Log("WakeOnLan end");
  108.   return 0;
  109. }
  110.