268 lines
5.2 KiB
C
268 lines
5.2 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
rasadmon.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
RAS Advertisement monitoring module
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
dthaler
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include <winsock2.h>
|
||
|
#include <ws2tcpip.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#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;
|
||
|
}
|