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.

406 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Some router initialization functions
  7. Author:
  8. Stefan Solomon 05/10/1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //*******************************************************************
  14. //* *
  15. //* IPXCP Interface Functions *
  16. //* *
  17. //*******************************************************************
  18. #define IPXCP_INITIALIZE_ENTRY_POINT "IpxCpInit"
  19. #define IPXCP_CLEANUP_ENTRY_POINT IPXCP_INITIALIZE_ENTRY_POINT
  20. typedef DWORD (* IpxcpInitFunPtr)(BOOL);
  21. typedef DWORD (* IpxcpCleanupFunPtr)(BOOL);
  22. // Initializes IpxCp so that it can be used. Assumes the IpxCp
  23. DWORD InitializeIpxCp (HINSTANCE hInstDll) {
  24. IpxcpInitFunPtr pfnInit;
  25. DWORD dwErr;
  26. pfnInit = (IpxcpInitFunPtr)GetProcAddress(hInstDll, IPXCP_INITIALIZE_ENTRY_POINT);
  27. if (!pfnInit)
  28. return ERROR_CAN_NOT_COMPLETE;
  29. if ((dwErr = (*pfnInit)(TRUE)) != NO_ERROR)
  30. return dwErr;
  31. return NO_ERROR;
  32. }
  33. // Cleansup the initialization of ipxcp that occurred when the
  34. // program loaded.
  35. DWORD CleanupIpxCp (HINSTANCE hInstDll) {
  36. IpxcpCleanupFunPtr pfnCleanup;
  37. DWORD dwErr;
  38. pfnCleanup = (IpxcpCleanupFunPtr)GetProcAddress(hInstDll, IPXCP_CLEANUP_ENTRY_POINT);
  39. if (!pfnCleanup)
  40. return ERROR_CAN_NOT_COMPLETE;
  41. if ((dwErr = (*pfnCleanup)(FALSE)) != NO_ERROR)
  42. return dwErr;
  43. return NO_ERROR;
  44. }
  45. /*++
  46. Function: RmCreateGlobalRoute
  47. Descr: called by ipxcp to create the global wan net if so configured
  48. --*/
  49. DWORD
  50. RmCreateGlobalRoute(PUCHAR Network)
  51. {
  52. DWORD rc;
  53. Trace(IPXCPIF_TRACE, "RmCreateGlobalRoute: Entered for 0x%x%x%x%x%x%x (%x)",
  54. Network[0], Network[1], Network[2], Network[3], Network[4], Network[5],
  55. WanNetDatabaseInitialized);
  56. ACQUIRE_DATABASE_LOCK;
  57. if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
  58. RELEASE_DATABASE_LOCK;
  59. return ERROR_CAN_NOT_COMPLETE;
  60. }
  61. // In NT5 we allow changing the global route on the
  62. // fly although it will only happen when there are
  63. // no WAN connections active.
  64. //
  65. // SS_ASSERT(WanNetDatabaseInitialized == FALSE);
  66. //
  67. if (WanNetDatabaseInitialized == TRUE) {
  68. DeleteGlobalRoute(GlobalWanNet);
  69. }
  70. WanNetDatabaseInitialized = TRUE;
  71. if((rc = CreateGlobalRoute(Network)) != NO_ERROR) {
  72. RELEASE_DATABASE_LOCK;
  73. return rc;
  74. }
  75. EnableGlobalWanNet = TRUE;
  76. memcpy(GlobalWanNet, Network, 4);
  77. RELEASE_DATABASE_LOCK;
  78. return NO_ERROR;
  79. }
  80. /*++
  81. Function: AllLocalWkstaDialoutInterface
  82. Descr: called by ipxcp to add an interface for the case when the
  83. host dials out. This interface type is not handled by DIM
  84. --*/
  85. DWORD
  86. RmAddLocalWkstaDialoutInterface(
  87. IN LPWSTR InterfaceNamep,
  88. IN LPVOID InterfaceInfop,
  89. IN OUT PULONG InterfaceIndexp)
  90. {
  91. PICB icbp;
  92. ULONG InterfaceNameLen; // if name length in bytes including wchar NULL
  93. PIPX_IF_INFO IpxIfInfop;
  94. PIPXWAN_IF_INFO IpxwanIfInfop;
  95. PIPX_INFO_BLOCK_HEADER IfInfop = (PIPX_INFO_BLOCK_HEADER)InterfaceInfop;
  96. PACB acbp;
  97. PIPX_TOC_ENTRY tocep;
  98. UINT i;
  99. ULONG tmp;
  100. FW_IF_INFO FwIfInfo;
  101. Trace(IPXCPIF_TRACE, "AddLocalWkstaDialoutInterface: Entered for interface %S\n", InterfaceNamep);
  102. // interface name length including the unicode null
  103. InterfaceNameLen = (wcslen(InterfaceNamep) + 1) * sizeof(WCHAR);
  104. ACQUIRE_DATABASE_LOCK;
  105. if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
  106. RELEASE_DATABASE_LOCK;
  107. return ERROR_CAN_NOT_COMPLETE;
  108. }
  109. // Allocate a new ICB and initialize it
  110. // we allocate the interface and adapter name buffers at the end of the
  111. // ICB struct.
  112. if((icbp = (PICB)GlobalAlloc(GPTR,
  113. sizeof(ICB) +
  114. InterfaceNameLen)) == NULL) {
  115. RELEASE_DATABASE_LOCK;
  116. // can't alloc memory
  117. SS_ASSERT(FALSE);
  118. return ERROR_NOT_ENOUGH_MEMORY;
  119. }
  120. // signature
  121. memcpy(&icbp->Signature, InterfaceSignature, 4);
  122. icbp->InterfaceIndex = GetNextInterfaceIndex();
  123. // copy the interface name
  124. icbp->InterfaceNamep = (PWSTR)((PUCHAR)icbp + sizeof(ICB));
  125. memcpy(icbp->InterfaceNamep, InterfaceNamep, InterfaceNameLen);
  126. icbp->AdapterNamep = NULL;
  127. icbp->PacketType = 0;
  128. // set the DIM interface type of this ICB
  129. icbp->DIMInterfaceType = 0xFFFFFFFF;
  130. // set the MIB interface type of this ICB
  131. icbp->MIBInterfaceType = IF_TYPE_ROUTER_WORKSTATION_DIALOUT;
  132. // mark the interface as unbound to an adapter (default)
  133. icbp->acbp = NULL;
  134. // get the if handle used when calling DIM entry points
  135. icbp->hDIMInterface = INVALID_HANDLE_VALUE;
  136. // reset the update status fields
  137. ResetUpdateRequest(icbp);
  138. // mark connection not requested yet
  139. icbp->ConnectionRequestPending = FALSE;
  140. // get to the interface entries in the interface info block
  141. if(((IpxIfInfop = (PIPX_IF_INFO)GetInfoEntry(InterfaceInfop, IPX_INTERFACE_INFO_TYPE)) == NULL) ||
  142. ((IpxwanIfInfop = (PIPXWAN_IF_INFO)GetInfoEntry(InterfaceInfop, IPXWAN_INTERFACE_INFO_TYPE)) == NULL)) {
  143. GlobalFree(icbp);
  144. RELEASE_DATABASE_LOCK;
  145. IF_LOG (EVENTLOG_ERROR_TYPE) {
  146. RouterLogErrorDataW (RMEventLogHdl,
  147. ROUTERLOG_IPX_BAD_CLIENT_INTERFACE_CONFIG,
  148. 0, NULL, 0, NULL);
  149. }
  150. // don't have all ipx or ipxwan interfaces info
  151. Trace(IPXCPIF_TRACE, "AddInterface: missing ipx or ipxwan interface info\n");
  152. SS_ASSERT(FALSE);
  153. return ERROR_INVALID_PARAMETER;
  154. }
  155. // set the IPXWAN interface info
  156. icbp->EnableIpxWanNegotiation = IpxwanIfInfop->AdminState;
  157. // Initialize the Oper State of this interface.
  158. icbp->OperState = OPER_STATE_DOWN;
  159. // this is a WAN interface. As long as it isn't connected, and enabled the
  160. // oper state will be sleeping on this interface
  161. if(IpxIfInfop->AdminState == ADMIN_STATE_ENABLED)
  162. icbp->OperState = OPER_STATE_SLEEPING;
  163. // create the routing protocols (rip/sap or nlsp) interface info
  164. // insert the if in the index hash table
  165. AddIfToDB(icbp);
  166. // If the routing protocols interface info is missing this will fail
  167. if(CreateRoutingProtocolsInterfaces(InterfaceInfop, icbp) != NO_ERROR) {
  168. RemoveIfFromDB(icbp);
  169. GlobalFree(icbp);
  170. RELEASE_DATABASE_LOCK;
  171. IF_LOG (EVENTLOG_ERROR_TYPE) {
  172. RouterLogErrorDataW (RMEventLogHdl,
  173. ROUTERLOG_IPX_BAD_CLIENT_INTERFACE_CONFIG,
  174. 0, NULL, 0, NULL);
  175. }
  176. // don't have all rip and sap interfaces info
  177. Trace(IPXCPIF_TRACE, "AddInterface: missing routing protocols interface info\n");
  178. SS_ASSERT(FALSE);
  179. return ERROR_INVALID_PARAMETER;
  180. }
  181. // create the Forwarder interface
  182. FwIfInfo.NetbiosAccept = IpxIfInfop->NetbiosAccept;
  183. FwIfInfo.NetbiosDeliver = IpxIfInfop->NetbiosDeliver;
  184. FwCreateInterface(icbp->InterfaceIndex,
  185. LOCAL_WORKSTATION_DIAL,
  186. &FwIfInfo);
  187. // mark the interface reachable
  188. icbp->InterfaceReachable = TRUE;
  189. // set the admin state
  190. if(IpxIfInfop->AdminState == ADMIN_STATE_ENABLED) {
  191. AdminEnable(icbp);
  192. }
  193. else
  194. {
  195. AdminDisable(icbp);
  196. }
  197. // increment the interface counter
  198. InterfaceCount++;
  199. *InterfaceIndexp = icbp->InterfaceIndex;
  200. RELEASE_DATABASE_LOCK;
  201. return NO_ERROR;
  202. }
  203. DWORD
  204. RmDeleteLocalWkstaDialoutInterface(ULONG InterfaceIndex)
  205. {
  206. return(DeleteInterface((HANDLE)UlongToPtr(InterfaceIndex)));
  207. }
  208. DWORD
  209. RmGetIpxwanInterfaceConfig(ULONG InterfaceIndex,
  210. PULONG IpxwanConfigRequired)
  211. {
  212. PICB icbp;
  213. ACQUIRE_DATABASE_LOCK;
  214. if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
  215. RELEASE_DATABASE_LOCK;
  216. return ERROR_CAN_NOT_COMPLETE;
  217. }
  218. if((icbp = GetInterfaceByIndex(InterfaceIndex)) == NULL) {
  219. RELEASE_DATABASE_LOCK;
  220. return ERROR_CAN_NOT_COMPLETE;
  221. }
  222. if(icbp->EnableIpxWanNegotiation == ADMIN_STATE_ENABLED) {
  223. *IpxwanConfigRequired = 1;
  224. }
  225. else
  226. {
  227. *IpxwanConfigRequired = 0;
  228. }
  229. RELEASE_DATABASE_LOCK;
  230. return NO_ERROR;
  231. }
  232. BOOL
  233. RmIsRoute(PUCHAR Network)
  234. {
  235. BOOL rc;
  236. ACQUIRE_DATABASE_LOCK;
  237. if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
  238. RELEASE_DATABASE_LOCK;
  239. return FALSE;
  240. }
  241. rc = IsRoute(Network);
  242. RELEASE_DATABASE_LOCK;
  243. return rc;
  244. }
  245. DWORD
  246. RmGetInternalNetNumber(PUCHAR Network)
  247. {
  248. PACB acbp;
  249. ACQUIRE_DATABASE_LOCK;
  250. if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
  251. RELEASE_DATABASE_LOCK;
  252. return ERROR_CAN_NOT_COMPLETE;
  253. }
  254. if(InternalInterfacep) {
  255. if(acbp = InternalInterfacep->acbp) {
  256. memcpy(Network, acbp->AdapterInfo.Network, 4);
  257. RELEASE_DATABASE_LOCK;
  258. return NO_ERROR;
  259. }
  260. }
  261. RELEASE_DATABASE_LOCK;
  262. return ERROR_CAN_NOT_COMPLETE;
  263. }
  264. //
  265. // This is a function added for pnp reasons so that the
  266. // ipx-related ras server settings could be updated.
  267. //
  268. DWORD RmUpdateIpxcpConfig (PIPXCP_ROUTER_CONFIG_PARAMS pParams) {
  269. DWORD dwErr;
  270. // Validate parameters
  271. if (! pParams)
  272. return ERROR_INVALID_PARAMETER;
  273. // Trace out the new settings
  274. Trace(IPXCPIF_TRACE, "RmUpdateIpxcpConfig: entered: %x %x %x %x",
  275. pParams->ThisMachineOnly, pParams->WanNetDatabaseInitialized,
  276. pParams->EnableGlobalWanNet, *((DWORD*)pParams->GlobalWanNet));
  277. // Update the forwarder's ThisMachineOnly setting
  278. if ((dwErr = FwUpdateConfig(pParams->ThisMachineOnly)) != NO_ERROR)
  279. return dwErr;
  280. return NO_ERROR;
  281. }