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.

416 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. routing\netsh\if\ifmon.c
  5. Abstract:
  6. If Command dispatcher.
  7. Revision History:
  8. AmritanR
  9. --*/
  10. #include "precomp.h"
  11. #define IFMON_GUID \
  12. { 0x705eca1, 0x7aac, 0x11d2, { 0x89, 0xdc, 0x0, 0x60, 0x8, 0xb0, 0xe5, 0xb9 } }
  13. GUID g_IfGuid = IFMON_GUID;
  14. static const GUID g_NetshGuid = NETSH_ROOT_GUID;
  15. #define IF_HELPER_VERSION 1
  16. //
  17. // The monitor's commands are broken into 2 sets
  18. // - The top level commands are those which deal with the monitor
  19. // itself (meta commands) and others which take 0 arguments
  20. // - The rest of the commands are split into "command groups"
  21. // i.e, commands grouped by the VERB where the VERB is ADD, DELETE,
  22. // GET or SET. This is not for any technical reason - only for
  23. // staying with the semantics used in other monitors and helpers
  24. //
  25. // A command is described using a CMD_ENTRY structure. It requires the
  26. // command token, the handler, a short help message token and an extended
  27. // help message token. To make it easier to create we use the
  28. // CREATE_CMD_ENTRY macro. This, however puts restrictions on how the tokens
  29. // are named.
  30. //
  31. // The command groups are simply arrays of the CMD_ENTRY structure. The
  32. // top level commands are also grouped in a similar array.
  33. //
  34. // The info about a complete command group is put in a CMD_GROUP_ENTRY
  35. // structure, all of which are put in an array.
  36. //
  37. //
  38. // NOTE: Since we have only one entry per group, currently, we really didnt
  39. // need command groups. This is done for later extensibility.
  40. // To add a command entry to a group, simply add the command to the appropriate
  41. // array
  42. // To add a command group - create and array and add its info to the
  43. // command group array
  44. //
  45. CMD_ENTRY g_IfAddCmdTable[] =
  46. {
  47. CREATE_CMD_ENTRY(IF_ADD_IF, HandleIfAddIf),
  48. };
  49. CMD_ENTRY g_IfDelCmdTable[] =
  50. {
  51. CREATE_CMD_ENTRY(IF_DEL_IF, HandleIfDelIf),
  52. };
  53. CMD_ENTRY g_IfSetCmdTable[] =
  54. {
  55. CREATE_CMD_ENTRY(IF_SET_INTERFACE, HandleIfSet),
  56. CREATE_CMD_ENTRY(IF_SET_CREDENTIALS, HandleIfSetCredentials),
  57. };
  58. CMD_ENTRY g_IfShowCmdTable[] =
  59. {
  60. CREATE_CMD_ENTRY(IF_SHOW_IF, HandleIfShowIf),
  61. CREATE_CMD_ENTRY(IF_SHOW_CREDENTIALS, HandleIfShowCredentials),
  62. };
  63. CMD_ENTRY g_IfResetCmdTable[] =
  64. {
  65. CREATE_CMD_ENTRY(IF_RESET_ALL, HandleIfResetAll),
  66. };
  67. CMD_GROUP_ENTRY g_IfCmdGroups[] =
  68. {
  69. CREATE_CMD_GROUP_ENTRY(GROUP_ADD, g_IfAddCmdTable),
  70. CREATE_CMD_GROUP_ENTRY(GROUP_DELETE, g_IfDelCmdTable),
  71. CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_IfShowCmdTable),
  72. CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_IfSetCmdTable),
  73. CREATE_CMD_GROUP_ENTRY(GROUP_RESET, g_IfResetCmdTable),
  74. };
  75. ULONG g_ulNumGroups = sizeof(g_IfCmdGroups)/sizeof(CMD_GROUP_ENTRY);
  76. HANDLE g_hModule;
  77. HANDLE g_hMprConfig = NULL;
  78. HANDLE g_hMprAdmin = NULL;
  79. HANDLE g_hMIBServer = NULL;
  80. BOOL g_bCommit;
  81. PWCHAR g_pwszRouter = NULL;
  82. DWORD ParentVersion;
  83. BOOL g_bIfDirty = FALSE;
  84. ULONG g_ulInitCount;
  85. NS_CONTEXT_CONNECT_FN IfConnect;
  86. DWORD
  87. WINAPI
  88. IfCommit(
  89. IN DWORD dwAction
  90. )
  91. {
  92. BOOL bCommit, bFlush = FALSE;
  93. switch(dwAction)
  94. {
  95. case NETSH_COMMIT:
  96. {
  97. if(g_bCommit)
  98. {
  99. return NO_ERROR;
  100. }
  101. g_bCommit = TRUE;
  102. break;
  103. }
  104. case NETSH_UNCOMMIT:
  105. {
  106. g_bCommit = FALSE;
  107. return NO_ERROR;
  108. }
  109. case NETSH_SAVE:
  110. {
  111. if(g_bCommit)
  112. {
  113. return NO_ERROR;
  114. }
  115. break;
  116. }
  117. case NETSH_FLUSH:
  118. {
  119. //
  120. // Action is a flush. If current state is commit, then
  121. // nothing to be done.
  122. //
  123. if(g_bCommit)
  124. {
  125. return NO_ERROR;
  126. }
  127. bFlush = TRUE;
  128. break;
  129. }
  130. default:
  131. {
  132. return NO_ERROR;
  133. }
  134. }
  135. //
  136. // Switched to commit mode. So set all valid info in the
  137. // strutures. Free memory and invalidate the info.
  138. //
  139. return NO_ERROR;
  140. }
  141. BOOL
  142. WINAPI
  143. IfDllEntry(
  144. HINSTANCE hInstDll,
  145. DWORD fdwReason,
  146. LPVOID pReserved
  147. )
  148. {
  149. switch (fdwReason)
  150. {
  151. case DLL_PROCESS_ATTACH:
  152. {
  153. g_hModule = hInstDll;
  154. DisableThreadLibraryCalls(hInstDll);
  155. break;
  156. }
  157. case DLL_PROCESS_DETACH:
  158. {
  159. break;
  160. }
  161. default:
  162. {
  163. break;
  164. }
  165. }
  166. return TRUE;
  167. }
  168. DWORD
  169. WINAPI
  170. IfStartHelper(
  171. IN CONST GUID *pguidParent,
  172. IN DWORD dwVersion
  173. )
  174. {
  175. DWORD dwErr;
  176. NS_CONTEXT_ATTRIBUTES attMyAttributes;
  177. ParentVersion = dwVersion;
  178. ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
  179. attMyAttributes.pwszContext = L"interface";
  180. attMyAttributes.guidHelper = g_IfGuid;
  181. attMyAttributes.dwVersion = 1;
  182. attMyAttributes.dwFlags = CMD_FLAG_PRIORITY;
  183. attMyAttributes.ulPriority = 10; // very low so gets dumped first
  184. attMyAttributes.ulNumTopCmds = 0;
  185. attMyAttributes.pTopCmds = NULL;
  186. attMyAttributes.ulNumGroups = g_ulNumGroups;
  187. attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])&g_IfCmdGroups;
  188. attMyAttributes.pfnCommitFn = IfCommit;
  189. attMyAttributes.pfnDumpFn = IfDump;
  190. attMyAttributes.pfnConnectFn= IfConnect;
  191. dwErr = RegisterContext( &attMyAttributes );
  192. return dwErr;
  193. }
  194. DWORD WINAPI
  195. IfConnect(
  196. IN LPCWSTR pwszRouter
  197. )
  198. {
  199. // If context info is dirty, reregister it
  200. if (g_bIfDirty)
  201. {
  202. IfStartHelper(NULL, ParentVersion);
  203. }
  204. return ConnectToRouter(pwszRouter);
  205. }
  206. DWORD WINAPI
  207. InitHelperDll(
  208. IN DWORD dwNetshVersion,
  209. OUT PVOID pReserved
  210. )
  211. {
  212. DWORD dwErr;
  213. NS_HELPER_ATTRIBUTES attMyAttributes;
  214. WSADATA wsa;
  215. //
  216. // See if this is the first time we are being called
  217. //
  218. if(InterlockedIncrement(&g_ulInitCount) != 1)
  219. {
  220. return NO_ERROR;
  221. }
  222. dwErr = WSAStartup(MAKEWORD(2,0), &wsa);
  223. g_bCommit = TRUE;
  224. // Register helpers
  225. ZeroMemory( &attMyAttributes, sizeof(attMyAttributes) );
  226. attMyAttributes.guidHelper = g_IfGuid;
  227. attMyAttributes.dwVersion = IF_HELPER_VERSION;
  228. attMyAttributes.pfnStart = IfStartHelper;
  229. attMyAttributes.pfnStop = NULL;
  230. RegisterHelper( &g_NetshGuid, &attMyAttributes );
  231. //
  232. // Register any sub contexts implemented in this dll
  233. //
  234. dwErr = IfContextInstallSubContexts();
  235. if (dwErr isnot NO_ERROR)
  236. {
  237. IfUnInit(0);
  238. return dwErr;
  239. }
  240. return NO_ERROR;
  241. }
  242. DWORD
  243. ConnectToRouter(
  244. IN LPCWSTR pwszRouter
  245. )
  246. {
  247. DWORD dwErr = NO_ERROR;
  248. do
  249. {
  250. // Change the router name if needed
  251. //
  252. if ((g_pwszRouter != pwszRouter) &&
  253. (!g_pwszRouter || !pwszRouter || lstrcmpi(g_pwszRouter,pwszRouter)))
  254. {
  255. if (g_hMprConfig)
  256. {
  257. MprConfigServerDisconnect(g_hMprConfig);
  258. g_hMprConfig = NULL;
  259. }
  260. if (g_hMprAdmin)
  261. {
  262. MprAdminServerDisconnect(g_hMprAdmin);
  263. g_hMprAdmin = NULL;
  264. }
  265. if (g_hMIBServer)
  266. {
  267. MprAdminMIBServerDisconnect(g_hMIBServer);
  268. g_hMIBServer = NULL;
  269. }
  270. }
  271. // Cleanup the old router name
  272. //
  273. if (g_pwszRouter)
  274. {
  275. IfutlFree(g_pwszRouter);
  276. }
  277. // Copy the new router name in
  278. //
  279. if (pwszRouter)
  280. {
  281. g_pwszRouter = IfutlStrDup(pwszRouter);
  282. if (g_pwszRouter == NULL)
  283. {
  284. dwErr = ERROR_CONNECT_REMOTE_CONFIG;
  285. break;
  286. }
  287. }
  288. else
  289. {
  290. g_pwszRouter = NULL;
  291. }
  292. if (!g_hMprConfig)
  293. {
  294. //
  295. // first time connecting to router config
  296. //
  297. dwErr = MprConfigServerConnect((LPWSTR)pwszRouter, &g_hMprConfig);
  298. if (dwErr isnot NO_ERROR)
  299. {
  300. //
  301. // cannot connect to router config.
  302. //
  303. break;
  304. }
  305. }
  306. //
  307. // Check to see if router is running. If so, get the handles
  308. //
  309. if (MprAdminIsServiceRunning((LPWSTR)pwszRouter))
  310. {
  311. if(MprAdminServerConnect((LPWSTR)pwszRouter, &g_hMprAdmin) != NO_ERROR)
  312. {
  313. g_hMprAdmin = NULL;
  314. }
  315. }
  316. } while (FALSE);
  317. return dwErr;
  318. }
  319. DWORD
  320. WINAPI
  321. IfUnInit(
  322. IN DWORD dwReserved
  323. )
  324. {
  325. if(InterlockedDecrement(&g_ulInitCount) isnot 0)
  326. {
  327. return NO_ERROR;
  328. }
  329. return NO_ERROR;
  330. }