/*++ Copyright (c) 1999 Microsoft Corporation Module Name: rasadmon.c Abstract: RAS Advertisement monitoring module Revision History: dthaler --*/ #include "precomp.h" #include #include #include #define RASADV_PORT 9753 #define RASADV_GROUP "239.255.2.2" typedef DWORD IPV4_ADDRESS; #undef CATCH_CTRL #ifdef CATCH_CTRL BOOL HandlerRoutine( DWORD dwCtrlType // control signal type ) { HANDLE hMib; if (dwCtrlType == CTRL_C_EVENT) { hMib = OpenEvent(EVENT_ALL_ACCESS, FALSE, MIB_REFRESH_EVENT); SetEvent(hMib); } return TRUE; }; #endif char * // OUT: string version of IP address AddrToString( u_long addr, // IN : address to convert char *ptr // OUT: buffer, or NULL ) { char *str; struct in_addr in; in.s_addr = addr; str = inet_ntoa(in); if (ptr && str) { strcpy(ptr, str); return ptr; } return str; } // // Convert an address to a name // char * AddrToHostname( long addr, BOOL bNumeric_flag ) { if (!addr) return "local"; if (!bNumeric_flag) { struct hostent * host_ptr = NULL; host_ptr = gethostbyaddr ((char *) &addr, sizeof(addr), AF_INET); if (host_ptr) return host_ptr->h_name; } return AddrToString(addr, NULL); } DWORD HandleRasShowServers( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++ Routine Description: Monitors RAS Server advertisements. Arguments: None Return Value: None --*/ { DWORD dwErr, dwFromLen, dwBytesRcvd; WSADATA wsaData; SOCKET s; BOOL bOption, bNumeric_flag = FALSE; SOCKADDR_IN sinAddr, sinFrom; IPV4_ADDRESS ipIface = INADDR_ANY, ipGroup = inet_addr(RASADV_GROUP); WORD wPort = RASADV_PORT; BYTE buff[256]; CHAR szTimeStamp[30]; struct ip_mreq imOption; time_t t; char *p, *q; // Start up dwErr = WSAStartup( MAKEWORD(2,0), &wsaData ); if ( dwErr isnot NO_ERROR ) { return dwErr; } // Open socket to listen on s = socket( AF_INET, SOCK_DGRAM, 0 ); if (s is INVALID_SOCKET) { return WSAGetLastError(); } bOption = TRUE; setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (const char FAR*)&bOption, sizeof(BOOL)); // Bind to the specified port sinAddr.sin_family = AF_INET; sinAddr.sin_port = htons(wPort); sinAddr.sin_addr.s_addr = ipIface; dwErr = bind( s, (struct sockaddr *)&sinAddr, sizeof(sinAddr) ); if (dwErr isnot NO_ERROR) { return dwErr; } #if 0 printf("Listening to %s ", AddrToString(ipGroup, NULL)); printf("on interface %s\n\n", AddrToString(ipIface, NULL)); #endif // Join group imOption.imr_multiaddr.s_addr = ipGroup; imOption.imr_interface.s_addr = ipIface; if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (PBYTE)&imOption, sizeof(imOption) ) != NO_ERROR) { return GetLastError(); } DisplayMessage( g_hModule, MSG_RAS_SHOW_SERVERS_HEADER ); #ifdef CATCH_CTRL // Intercept CTRL-C SetConsoleCtrlHandler(HandlerRoutine, TRUE); #endif // Loop indefinitely, listening for senders for (;;) { dwFromLen = sizeof(sinFrom); dwBytesRcvd = recvfrom( s, buff, sizeof(buff), 0, (struct sockaddr *)&sinFrom, &dwFromLen ); if ( dwBytesRcvd is SOCKET_ERROR && GetLastError() == WSAEMSGSIZE ) { dwBytesRcvd = sizeof(buff); } if ( dwBytesRcvd is SOCKET_ERROR ) { return GetLastError(); } // Get timestamp time(&t); strcpy( szTimeStamp, ctime(&t) ); szTimeStamp[24] = '\0'; // Print info on sender if (bNumeric_flag) { printf( "%s %s\n", szTimeStamp, AddrToString(sinFrom.sin_addr.s_addr, NULL) ); } else { printf( "%s %s (%s)\n", szTimeStamp, AddrToString(sinFrom.sin_addr.s_addr, NULL), AddrToHostname(sinFrom.sin_addr.s_addr, bNumeric_flag) ); } buff[dwBytesRcvd] = '\0'; for (p=buff; p && *p; p=q) { q = strchr(p, '\n'); if (q) { *q++ = 0; } printf(" %s\n", p); } } #ifdef CATCH_CTRL // Stop intercepting CTRL-C SetConsoleCtrlHandler(HandlerRoutine, FALSE); #endif return NO_ERROR; }