windows-nt/Source/XPSP1/NT/net/rras/netsh/ras/rasadmon.c
2020-09-26 16:20:57 +08:00

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;
}