NAlek
![]() |
Wake-On-Lan – технология удаленного включения компьютера. Идея заключается в том, чтобы по сети отправить удаленному компьютеру, специально сформированный пакет - magic packet. Сам "magic packet" представляет собой последовательность байт, размером 102 байта, где первые 6 - это 0xFF, остальные MAC адрес удаленного компьютера (повторенный 16 раз). Прежде чем отправить пакет, необходимо преобразовать его из шестнадцатеричного представления в двоичное. Этим занимается функция: int hex2bin( void *dest, const char *src, int max ) После того как пакет сформирован – отправляем его с помощью широковещательной рассылки (broadcast). NWOL.cpp // Copyright (C) 2011 NAlek // Wake-on-Lan v1.0 // #include "stdafx.h" #define __WOL_PORT 2304 #define __COPYRIGHT "Copyright (C) 2011 NAlek" #define __DESCRIPTION "NAlek Wake-on-LAN" #define __HELP "Usage: nwol.exe destanation_MAC_address [-b <ip_broadcast_address>]" int hex2bin( void *dest, const char *src, int max ) { int i,j,c; for(i=j=0;src[i];i++) { if(j>=2*max) return max; c=src[i]; if(c>='0' && c<='9') c-='0'; else if(c>='A' && c<='F') c-='A'-10; else if(c>='a' && c<='f') c-='a'-10; else if( c=='.' || c==' ' || c=='-' || c=='t' || c==':' ) continue; else break; if(j&1) ((unsigned char *)dest)[(j-1)>>1]+=c; else ((unsigned char *)dest)[j>>1]=c<<4; j++; } return ((j&~1)>>1); } int BroadcastMagicPacket( TCHAR **szMAC, int iMACCount, TCHAR *szIPBroadcast, unsigned short usPort ) { int iRet =0; // создаюм UDP сокет SOCKET sSock =socket( AF_INET, SOCK_DGRAM, 0 ); if( sSock ==INVALID_SOCKET ) { // ERROR // ошибка создания сокета printf("ERROR: socket()nCode: %dn", WSAGetLastError() ); iRet =1; } else { struct sockaddr_in sSA; sSA.sin_family =AF_INET; sSA.sin_addr.s_addr =INADDR_ANY; sSA.sin_port =htons(usPort); if( bind( sSock, (struct sockaddr*)&sSA, sizeof(sSA) ) ==SOCKET_ERROR ) { // ERROR // ошибка привязки printf("ERROR: bind()nCode: %dn", WSAGetLastError() ); iRet =1; } else { BOOL bBroadcast =TRUE; if( setsockopt( sSock, SOL_SOCKET, SO_BROADCAST, (char *)&bBroadcast, sizeof(BOOL) ) ==SOCKET_ERROR ) { // ERROR // ошибка изменения параметров сокета printf("ERROR: setsockopt()nCode: %dn", WSAGetLastError() ); iRet =1; } else { sSA.sin_addr.s_addr = szIPBroadcast ==NULL ? INADDR_BROADCAST : inet_addr(szIPBroadcast); //printf("Broadcast Address %snn", szIPBroadcast ==NULL ? "255.255.255.255" : szIPBroadcast ); for( int i =0; i <iMACCount; ++i ) { if( szMAC[i] ==NULL || strlen(szMAC[i]) !=12 ) { // ERROR // неправельный MAC адрес printf("Wrong MAC addressn"); iRet =1; } else { // формируем MagicPacket char btMacAddress[6] ={NULL}; hex2bin( btMacAddress, szMAC[i], 6); char btMagicPacket[204] ={NULL}; hex2bin( btMagicPacket, "FFFFFFFFFFFF", 6); for( int iOffset=6; iOffset<=96; iOffset +=6 ) memcpy( btMagicPacket+iOffset, btMacAddress, 6 ); if( sendto( sSock, btMagicPacket, 102, 0, (struct sockaddr*)&sSA, sizeof(sSA) ) ==SOCKET_ERROR ) { // ERROR // ошибка отправки широковещательного сообщения printf("ERROR: sendto()nCode: %dn", WSAGetLastError() ); iRet =1; }// sendto else { printf( "Magic Packet sent for [%s] via broadcast address %sn", szMAC[i], szIPBroadcast ==NULL ? "255.255.255.255" : szIPBroadcast ); } } }// for }// setsockopt }// bind // закрываем созданный сокет closesocket( sSock ); }// socket return iRet; } int _tmain(int argc, _TCHAR* argv[]) { int iRet =0; TCHAR **szMAC =NULL; int iMACCount =0; TCHAR *szIPBroadcast =NULL; WSADATA wsaData; WORD wVersionRequested =MAKEWORD( 2, 2 ); printf("%sn", __DESCRIPTION); printf("%snn", __COPYRIGHT); // 0 - mac address // 1 - broadcas address int iArg =-1; for( int i =1; i <argc; ++i ) { size_t iLen =strlen(argv[i]); if( iArg ==-1 ) { if( !_stricmp( argv[i], "-b" ) && !szIPBroadcast ) { // broadcast address iArg =1; continue; } else if( !szMAC ) iArg =0; else break; } switch(iArg) { // mac case 0: TCHAR szTmp[13]; if( sscanf_s( argv[i], "%[0-9A-Za-z]", &szTmp, 13 ) !=0 ) if( ( szMAC =(TCHAR **)malloc( sizeof(TCHAR *) ) ) ) { if( ( szMAC[iMACCount] =(TCHAR *)calloc(iLen+1, sizeof(TCHAR) ) ) ) memcpy( szMAC[iMACCount], szTmp, iLen ); ++iMACCount; } iArg =-1; break; // broadcast ip case 1: if( ( szIPBroadcast =(TCHAR *)calloc(iLen+1, sizeof(TCHAR)) ) ) memcpy( szIPBroadcast, argv[i], iLen ); iArg =-1; break; } } if( szMAC ==NULL ) { FILE *file; TCHAR szTmp[256]; TCHAR szMACTmp[13]; if( fopen_s(&file, "mac.txt", "r" ) ==0 ) { while( fgets( szTmp, 256, file ) ) { if( sscanf_s( szTmp, "%[0-9A-Za-z]", &szMACTmp, 13 ) ==0 ) continue; if( szMAC ==NULL ) szMAC =(TCHAR **)malloc( sizeof(TCHAR *) ); else szMAC =(TCHAR **)realloc(szMAC, (iMACCount+1)*sizeof(TCHAR *) ); if( szMAC ) { if( ( szMAC[iMACCount] =(TCHAR *)calloc( 13, sizeof(TCHAR) ) ) ) memcpy( szMAC[iMACCount], szMACTmp, 12 ); ++iMACCount; }// if }// while fclose(file); } else { printf("%sn", __HELP); } } // загружаем библиатеку winsock if( WSAStartup( wVersionRequested, &wsaData ) !=0 ) { // ERROR // ошибка приинициализации библиотеки winsock iRet =1; printf("ERROR: Could not load winsocknCode: %dn", WSAGetLastError() ); } else { // проверяем инициализируема версия ту которую мы запрашивали if( LOBYTE( wsaData.wVersion ) !=2 || HIBYTE( wsaData.wVersion ) !=2 ) { // ERROR // загруженая версия winsock отлична от требуемой iRet =1; printf("ERROR: Bad winsock versionn"); } else { BroadcastMagicPacket( szMAC, iMACCount, szIPBroadcast, __WOL_PORT ); } // выгружаем библиотеку WSACleanup(); } // // очищаем выделенную память // for( int i =0; i <iMACCount; ++i ) free(szMAC[i]); free(szMAC); free(szIPBroadcast); return iRet; } ![]() ![]() |