Source code of Windows XP (NT5)
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.

267 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. rasadmon.c
  5. Abstract:
  6. RAS Advertisement monitoring module
  7. Revision History:
  8. dthaler
  9. --*/
  10. #include "precomp.h"
  11. #include <winsock2.h>
  12. #include <ws2tcpip.h>
  13. #include <time.h>
  14. #define RASADV_PORT 9753
  15. #define RASADV_GROUP "239.255.2.2"
  16. typedef DWORD IPV4_ADDRESS;
  17. #undef CATCH_CTRL
  18. #ifdef CATCH_CTRL
  19. BOOL
  20. HandlerRoutine(
  21. DWORD dwCtrlType // control signal type
  22. )
  23. {
  24. HANDLE hMib;
  25. if (dwCtrlType == CTRL_C_EVENT)
  26. {
  27. hMib = OpenEvent(EVENT_ALL_ACCESS, FALSE, MIB_REFRESH_EVENT);
  28. SetEvent(hMib);
  29. }
  30. return TRUE;
  31. };
  32. #endif
  33. char * // OUT: string version of IP address
  34. AddrToString(
  35. u_long addr, // IN : address to convert
  36. char *ptr // OUT: buffer, or NULL
  37. )
  38. {
  39. char *str;
  40. struct in_addr in;
  41. in.s_addr = addr;
  42. str = inet_ntoa(in);
  43. if (ptr && str) {
  44. strcpy(ptr, str);
  45. return ptr;
  46. }
  47. return str;
  48. }
  49. //
  50. // Convert an address to a name
  51. //
  52. char *
  53. AddrToHostname(
  54. long addr,
  55. BOOL bNumeric_flag
  56. )
  57. {
  58. if (!addr)
  59. return "local";
  60. if (!bNumeric_flag) {
  61. struct hostent * host_ptr = NULL;
  62. host_ptr = gethostbyaddr ((char *) &addr, sizeof(addr), AF_INET);
  63. if (host_ptr)
  64. return host_ptr->h_name;
  65. }
  66. return AddrToString(addr, NULL);
  67. }
  68. DWORD
  69. HandleRasShowServers(
  70. IN LPCWSTR pwszMachine,
  71. IN OUT LPWSTR *ppwcArguments,
  72. IN DWORD dwCurrentIndex,
  73. IN DWORD dwArgCount,
  74. IN DWORD dwFlags,
  75. IN LPCVOID pvData,
  76. OUT BOOL *pbDone
  77. )
  78. /*++
  79. Routine Description:
  80. Monitors RAS Server advertisements.
  81. Arguments:
  82. None
  83. Return Value:
  84. None
  85. --*/
  86. {
  87. DWORD dwErr,
  88. dwFromLen,
  89. dwBytesRcvd;
  90. WSADATA wsaData;
  91. SOCKET s;
  92. BOOL bOption,
  93. bNumeric_flag = FALSE;
  94. SOCKADDR_IN sinAddr,
  95. sinFrom;
  96. IPV4_ADDRESS ipIface = INADDR_ANY,
  97. ipGroup = inet_addr(RASADV_GROUP);
  98. WORD wPort = RASADV_PORT;
  99. BYTE buff[256];
  100. CHAR szTimeStamp[30];
  101. struct ip_mreq imOption;
  102. time_t t;
  103. char *p, *q;
  104. // Start up
  105. dwErr = WSAStartup( MAKEWORD(2,0), &wsaData );
  106. if ( dwErr isnot NO_ERROR )
  107. {
  108. return dwErr;
  109. }
  110. // Open socket to listen on
  111. s = socket( AF_INET, SOCK_DGRAM, 0 );
  112. if (s is INVALID_SOCKET)
  113. {
  114. return WSAGetLastError();
  115. }
  116. bOption = TRUE;
  117. setsockopt( s,
  118. SOL_SOCKET,
  119. SO_REUSEADDR,
  120. (const char FAR*)&bOption,
  121. sizeof(BOOL));
  122. // Bind to the specified port
  123. sinAddr.sin_family = AF_INET;
  124. sinAddr.sin_port = htons(wPort);
  125. sinAddr.sin_addr.s_addr = ipIface;
  126. dwErr = bind( s, (struct sockaddr *)&sinAddr, sizeof(sinAddr) );
  127. if (dwErr isnot NO_ERROR)
  128. {
  129. return dwErr;
  130. }
  131. #if 0
  132. printf("Listening to %s ", AddrToString(ipGroup, NULL));
  133. printf("on interface %s\n\n", AddrToString(ipIface, NULL));
  134. #endif
  135. // Join group
  136. imOption.imr_multiaddr.s_addr = ipGroup;
  137. imOption.imr_interface.s_addr = ipIface;
  138. if ( setsockopt( s,
  139. IPPROTO_IP,
  140. IP_ADD_MEMBERSHIP,
  141. (PBYTE)&imOption,
  142. sizeof(imOption) ) != NO_ERROR)
  143. {
  144. return GetLastError();
  145. }
  146. DisplayMessage( g_hModule, MSG_RAS_SHOW_SERVERS_HEADER );
  147. #ifdef CATCH_CTRL
  148. // Intercept CTRL-C
  149. SetConsoleCtrlHandler(HandlerRoutine, TRUE);
  150. #endif
  151. // Loop indefinitely, listening for senders
  152. for (;;)
  153. {
  154. dwFromLen = sizeof(sinFrom);
  155. dwBytesRcvd = recvfrom( s,
  156. buff,
  157. sizeof(buff),
  158. 0,
  159. (struct sockaddr *)&sinFrom,
  160. &dwFromLen );
  161. if ( dwBytesRcvd is SOCKET_ERROR
  162. && GetLastError() == WSAEMSGSIZE )
  163. {
  164. dwBytesRcvd = sizeof(buff);
  165. }
  166. if ( dwBytesRcvd is SOCKET_ERROR )
  167. {
  168. return GetLastError();
  169. }
  170. // Get timestamp
  171. time(&t);
  172. strcpy( szTimeStamp, ctime(&t) );
  173. szTimeStamp[24] = '\0';
  174. // Print info on sender
  175. if (bNumeric_flag)
  176. {
  177. printf( "%s %s\n",
  178. szTimeStamp,
  179. AddrToString(sinFrom.sin_addr.s_addr, NULL) );
  180. }
  181. else
  182. {
  183. printf( "%s %s (%s)\n",
  184. szTimeStamp,
  185. AddrToString(sinFrom.sin_addr.s_addr, NULL),
  186. AddrToHostname(sinFrom.sin_addr.s_addr, bNumeric_flag) );
  187. }
  188. buff[dwBytesRcvd] = '\0';
  189. for (p=buff; p && *p; p=q)
  190. {
  191. q = strchr(p, '\n');
  192. if (q)
  193. {
  194. *q++ = 0;
  195. }
  196. printf(" %s\n", p);
  197. }
  198. }
  199. #ifdef CATCH_CTRL
  200. // Stop intercepting CTRL-C
  201. SetConsoleCtrlHandler(HandlerRoutine, FALSE);
  202. #endif
  203. return NO_ERROR;
  204. }