Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

406 lines
9.2 KiB

/*++
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>
#include <mswsock.h>
#define RASADV_PORT 9753
#define RASADV_GROUP "239.255.2.2"
typedef DWORD IPV4_ADDRESS;
HANDLE g_hCtrlC = NULL;
BOOL
HandlerRoutine(
DWORD dwCtrlType // control signal type
)
{
switch (dwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
default:
SetEvent(g_hCtrlC);
}
return TRUE;
};
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
--*/
{
BOOL bCleanWSA = TRUE, bCleanCtrl = TRUE;
DWORD dwErr = NO_ERROR;
SOCKET s = INVALID_SOCKET;
WSABUF wsaBuf;
WSADATA wsaData;
WSAEVENT WaitEvts[2];
SOCKADDR_IN sinFrom;
LPFN_WSARECVMSG WSARecvMsgFuncPtr = NULL;
do
{
ZeroMemory(&wsaBuf, sizeof(WSABUF));
dwErr = WSAStartup( MAKEWORD(2,0), &wsaData );
if (dwErr)
{
bCleanWSA = FALSE;
break;
}
//
// create socket
//
s = WSASocket(
AF_INET, // address family
SOCK_DGRAM, // type
0, // protocol
NULL,
0,
WSA_FLAG_OVERLAPPED);
if(INVALID_SOCKET == s)
{
dwErr = WSAGetLastError();
break;
}
{
BOOL bOption = TRUE;
if (setsockopt(
s,
SOL_SOCKET,
SO_REUSEADDR,
(const char FAR*)&bOption,
sizeof(BOOL))
)
{
dwErr = WSAGetLastError();
break;
}
}
//
// Bind to the specified port
//
{
SOCKADDR_IN sinAddr;
sinAddr.sin_family = AF_INET;
sinAddr.sin_port = htons(RASADV_PORT);
sinAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr*)&sinAddr, sizeof(sinAddr)))
{
dwErr = WSAGetLastError();
break;
}
}
//
// Join group
//
{
struct ip_mreq imOption;
imOption.imr_multiaddr.s_addr = inet_addr(RASADV_GROUP);
imOption.imr_interface.s_addr = INADDR_ANY;
if (setsockopt(
s,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
(PBYTE)&imOption,
sizeof(imOption))
)
{
dwErr = WSAGetLastError();
break;
}
}
//
// Get WSARecvMsg function pointer
//
{
GUID WSARecvGuid = WSAID_WSARECVMSG;
DWORD dwReturned = 0;
if (WSAIoctl(
s,
SIO_GET_EXTENSION_FUNCTION_POINTER,
(void*)&WSARecvGuid,
sizeof(GUID),
(void*)&WSARecvMsgFuncPtr,
sizeof(LPFN_WSARECVMSG),
&dwReturned,
NULL,
NULL)
)
{
dwErr = WSAGetLastError();
break;
}
}
//
// Get a name buffer for the recv socket
//
wsaBuf.buf = RutlAlloc(MAX_PATH + 1, TRUE);
if (!wsaBuf.buf)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
wsaBuf.len = MAX_PATH;
//
// Create wsa wait event for the recv socket
//
WaitEvts[0] = WSACreateEvent();
if (WSA_INVALID_EVENT == WaitEvts[0])
{
dwErr = WSAGetLastError();
break;
}
if (WSAEventSelect(s, WaitEvts[0], FD_READ))
{
dwErr = WSAGetLastError();
break;
}
//
// Create Ctrl-C wait event
//
g_hCtrlC = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!g_hCtrlC)
{
dwErr = GetLastError();
break;
}
//
// Intercept CTRL-C
//
if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
{
dwErr = GetLastError();
bCleanCtrl = FALSE;
break;
}
WaitEvts[1] = g_hCtrlC;
DisplayMessage( g_hModule, MSG_RAS_SHOW_SERVERS_HEADER );
for (;;)
{
CHAR szTimeStamp[30], *p, *q;
DWORD dwBytesRcvd, dwStatus, dwReturn;
WSAMSG wsaMsg;
time_t t;
dwReturn = WSAWaitForMultipleEvents(
2,
WaitEvts,
FALSE,
WSA_INFINITE,
FALSE);
if (WSA_WAIT_EVENT_0 == dwReturn)
{
if (!WSAResetEvent(WaitEvts[0]))
{
dwErr = WSAGetLastError();
break;
}
}
else if (WSA_WAIT_EVENT_0 + 1 == dwReturn)
{
dwErr = NO_ERROR;
break;
}
else
{
dwErr = WSAGetLastError();
break;
}
//
// .Net bug# 510712 Buffer overflow in HandleRasShowServers
//
// Init wsaMsg struct
//
ZeroMemory(&wsaMsg, sizeof(WSAMSG));
wsaMsg.dwBufferCount = 1;
wsaMsg.lpBuffers = &wsaBuf;
wsaMsg.name = (struct sockaddr *)&sinFrom;
wsaMsg.namelen = sizeof(sinFrom);
dwStatus = WSARecvMsgFuncPtr(
s,
&wsaMsg,
&dwBytesRcvd,
NULL,
NULL);
if (SOCKET_ERROR == dwStatus)
{
dwErr = WSAGetLastError();
if (WSAEMSGSIZE == dwErr)
{
dwBytesRcvd = MAX_PATH;
}
else
{
break;
}
}
//
// Only process multicast packets, skip all others
//
else if (!(wsaMsg.dwFlags & MSG_MCAST))
{
continue;
}
//
// Get timestamp
//
time(&t);
strcpy(szTimeStamp, ctime(&t));
szTimeStamp[24] = '\0';
//
// Print info on sender
//
printf( "%s %s (%s)\n",
szTimeStamp,
AddrToString(sinFrom.sin_addr.s_addr, NULL),
AddrToHostname(sinFrom.sin_addr.s_addr, FALSE) );
wsaMsg.lpBuffers->buf[dwBytesRcvd] = '\0';
for (p=wsaMsg.lpBuffers->buf; p && *p; p=q)
{
q = strchr(p, '\n');
if (q)
{
*q++ = 0;
}
printf(" %s\n", p);
}
}
} while (FALSE);
//
// Clean up
//
RutlFree(wsaBuf.buf);
if (g_hCtrlC)
{
CloseHandle(g_hCtrlC);
}
if (WaitEvts[0])
{
WSACloseEvent(WaitEvts[0]);
}
if (INVALID_SOCKET != s)
{
closesocket(s);
}
if (bCleanWSA)
{
WSACleanup();
}
if (bCleanCtrl)
{
SetConsoleCtrlHandler(HandlerRoutine, FALSE);
}
return dwErr;
}