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.

328 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. ntos\tdi\isn\fwd\lineind.c
  5. Abstract:
  6. Processing line indication (bind/unbind)
  7. Author:
  8. Vadim Eydelman
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. /*++
  13. *******************************************************************
  14. B i n d I n t e r f a c e
  15. Routine Description:
  16. Binds interface to physical adapter and exchanges contexts
  17. with IPX stack
  18. Arguments:
  19. ifCB - interface to bind
  20. NicId - id of an adapter
  21. MaxPacketSize - max size of packet allowed
  22. Network - adapter network address
  23. LocalNode - adapter local node address
  24. RemoteNode - peer node address (for clients on global
  25. net)
  26. Return Value:
  27. STATUS_SUCCESS - interface was bound OK
  28. error status returned by IPX stack driver
  29. *******************************************************************
  30. --*/
  31. NTSTATUS
  32. BindInterface (
  33. IN PINTERFACE_CB ifCB,
  34. IN USHORT NicId,
  35. IN ULONG MaxPacketSize,
  36. IN ULONG Network,
  37. IN PUCHAR LocalNode,
  38. IN PUCHAR RemoteNode
  39. ) {
  40. KIRQL oldIRQL;
  41. NTSTATUS status;
  42. NIC_HANDLE NicHandle={0};
  43. KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL);
  44. if (ifCB->ICB_Stats.OperationalState!=FWD_OPER_STATE_UP) {
  45. switch (ifCB->ICB_InterfaceType) {
  46. case FWD_IF_PERMANENT:
  47. if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX)
  48. status = RegisterPacketConsumer (MaxPacketSize,
  49. &ifCB->ICB_PacketListId);
  50. else
  51. status = STATUS_SUCCESS;
  52. break;
  53. case FWD_IF_DEMAND_DIAL:
  54. case FWD_IF_LOCAL_WORKSTATION:
  55. case FWD_IF_REMOTE_WORKSTATION:
  56. if (IS_IF_CONNECTING (ifCB)) {
  57. SET_IF_NOT_CONNECTING (ifCB);
  58. DequeueConnectionRequest (ifCB);
  59. }
  60. status = STATUS_SUCCESS;
  61. break;
  62. default:
  63. status = STATUS_INVALID_PARAMETER;
  64. ASSERTMSG ("Invalid interface type ", FALSE);
  65. break;
  66. }
  67. if (NT_SUCCESS (status)) {
  68. if (Network==GlobalNetwork) {
  69. ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX);
  70. IPX_NODE_CPY (ifCB->ICB_RemoteNode, RemoteNode);
  71. status = AddGlobalNetClient (ifCB);
  72. ASSERT (status==STATUS_SUCCESS);
  73. }
  74. KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL);
  75. if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) {
  76. NIC_HANDLE_FROM_NIC(NicHandle, NicId);
  77. status = IPXOpenAdapterProc (NicHandle, (ULONG_PTR)ifCB,
  78. &ifCB->ICB_AdapterContext);
  79. }
  80. if (NT_SUCCESS (status)) {
  81. ifCB->ICB_Network = Network;
  82. IPX_NODE_CPY (ifCB->ICB_RemoteNode, RemoteNode);
  83. IPX_NODE_CPY (ifCB->ICB_LocalNode, LocalNode);
  84. if (ifCB->ICB_InterfaceType==FWD_IF_PERMANENT)
  85. ifCB->ICB_Stats.MaxPacketSize = MaxPacketSize;
  86. else
  87. ifCB->ICB_Stats.MaxPacketSize = WAN_PACKET_SIZE;
  88. ifCB->ICB_NicId = NicId;
  89. ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_UP;
  90. AcquireInterfaceReference (ifCB);
  91. IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION,
  92. ("IpxFwd: Bound interface %ld (icb: %08lx):"
  93. " Nic-%d, Net-%08lx,"
  94. " LocalNode-%02x%02x%02x%02x%02x%02x,"
  95. " RemoteNode-%02x%02x%02x%02x%02x%02x.\n",
  96. ifCB->ICB_Index, ifCB, NicId, Network,
  97. LocalNode[0], LocalNode[1], LocalNode[2],
  98. LocalNode[3], LocalNode[4], LocalNode[5],
  99. RemoteNode[0], RemoteNode[1], RemoteNode[2],
  100. RemoteNode[3], RemoteNode[4], RemoteNode[5]));
  101. if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) {
  102. ProcessInternalQueue (ifCB);
  103. ProcessExternalQueue (ifCB);
  104. }
  105. return STATUS_SUCCESS;
  106. }
  107. IpxFwdDbgPrint (DBG_LINEIND, DBG_ERROR,
  108. ("IpxFwd: Could not open adapter %d to bind"
  109. " interface %ld (icb: %08lx)!\n",
  110. NicId, ifCB->ICB_Index, ifCB));
  111. KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL);
  112. if (Network==GlobalNetwork) {
  113. DeleteGlobalNetClient (ifCB);
  114. }
  115. switch (ifCB->ICB_InterfaceType) {
  116. case FWD_IF_PERMANENT:
  117. DeregisterPacketConsumer (ifCB->ICB_PacketListId);
  118. break;
  119. case FWD_IF_DEMAND_DIAL:
  120. case FWD_IF_LOCAL_WORKSTATION:
  121. case FWD_IF_REMOTE_WORKSTATION:
  122. break;
  123. }
  124. }
  125. ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN;
  126. KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL);
  127. ProcessInternalQueue (ifCB);
  128. ProcessExternalQueue (ifCB);
  129. }
  130. else {
  131. ASSERT (Network==ifCB->ICB_Network);
  132. ASSERT (NicId==(USHORT)ifCB->ICB_AdapterContext.NicId);
  133. KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL);
  134. status = STATUS_SUCCESS; // Report success if already
  135. // connected
  136. IpxFwdDbgPrint (DBG_LINEIND, DBG_WARNING,
  137. ("IpxFwd: Interface %ld (icb: %08lx) is already bound to Nic %d.\n",
  138. ifCB->ICB_Index, ifCB, NicId));
  139. }
  140. return status;
  141. }
  142. /*++
  143. *******************************************************************
  144. U n b i n d I n t e r f a c e
  145. Routine Description:
  146. Unbinds interface from physical adapter and breaks connection
  147. with IPX stack
  148. Arguments:
  149. ifCB - interface to unbind
  150. Return Value:
  151. None
  152. *******************************************************************
  153. --*/
  154. VOID
  155. UnbindInterface (
  156. PINTERFACE_CB ifCB
  157. ) {
  158. KIRQL oldIRQL;
  159. KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL);
  160. if (ifCB->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) {
  161. switch (ifCB->ICB_InterfaceType) {
  162. case FWD_IF_PERMANENT:
  163. ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN;
  164. if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX)
  165. DeregisterPacketConsumer (ifCB->ICB_PacketListId);
  166. break;
  167. case FWD_IF_DEMAND_DIAL:
  168. case FWD_IF_LOCAL_WORKSTATION:
  169. case FWD_IF_REMOTE_WORKSTATION:
  170. ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_SLEEPING;
  171. KeQuerySystemTime ((PLARGE_INTEGER)&ifCB->ICB_DisconnectTime);
  172. break;
  173. default:
  174. ASSERTMSG ("Invalid interface type ", FALSE);
  175. break;
  176. }
  177. if (ifCB->ICB_CashedInterface!=NULL)
  178. ReleaseInterfaceReference (ifCB->ICB_CashedInterface);
  179. ifCB->ICB_CashedInterface = NULL;
  180. if (ifCB->ICB_CashedRoute!=NULL)
  181. ReleaseRouteReference (ifCB->ICB_CashedRoute);
  182. ifCB->ICB_CashedRoute = NULL;
  183. if (ifCB->ICB_Network==GlobalNetwork)
  184. DeleteGlobalNetClient (ifCB);
  185. KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL);
  186. IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION,
  187. ("IpxFwd: Unbinding interface %ld (icb: %08lx) from Nic %ld.\n",
  188. ifCB->ICB_Index, ifCB, ifCB->ICB_AdapterContext));
  189. if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) {
  190. // [pmay]. Because of pnp, this interface may not need to have an
  191. // adapter closed any more. This is because nic id's get renumbered.
  192. if (ifCB->ICB_NicId != INVALID_NIC_ID)
  193. IPXCloseAdapterProc (ifCB->ICB_AdapterContext);
  194. ProcessInternalQueue (ifCB);
  195. ProcessExternalQueue (ifCB);
  196. }
  197. ReleaseInterfaceReference (ifCB);
  198. }
  199. else {
  200. KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL);
  201. IpxFwdDbgPrint (DBG_LINEIND, DBG_WARNING,
  202. ("IpxFwd: Interface %ld (icb: %08lx) is already unbound.\n",
  203. ifCB->ICB_Index, ifCB));
  204. }
  205. }
  206. /*++
  207. *******************************************************************
  208. F w L i n e U p
  209. Routine Description:
  210. Process line up indication delivered by IPX stack
  211. Arguments:
  212. NicId - adapter ID on which connection was established
  213. LineInfo - NDIS/IPX line information
  214. DeviceType - medium specs
  215. ConfigurationData - IPX CP configuration data
  216. Return Value:
  217. None
  218. *******************************************************************
  219. --*/
  220. VOID
  221. IpxFwdLineUp (
  222. IN USHORT NicId,
  223. IN PIPX_LINE_INFO LineInfo,
  224. IN NDIS_MEDIUM DeviceType,
  225. IN PVOID ConfigurationData
  226. ) {
  227. PINTERFACE_CB ifCB;
  228. if (ConfigurationData==NULL) // This is just an update for multilink
  229. // connections
  230. return;
  231. if (!EnterForwarder()) {
  232. return;
  233. }
  234. IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, ("IpxFwd: FwdLineUp.\n"));
  235. ifCB = GetInterfaceReference (
  236. ((PIPXCP_CONFIGURATION)ConfigurationData)->InterfaceIndex);
  237. if (ifCB!=NULL) {
  238. LONG Net = GETULONG (((PIPXCP_CONFIGURATION)ConfigurationData)->Network);
  239. ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX);
  240. ASSERT (ifCB->ICB_InterfaceType!=FWD_IF_PERMANENT);
  241. BindInterface (ifCB,
  242. NicId,
  243. LineInfo->MaximumPacketSize,
  244. Net,
  245. ((PIPXCP_CONFIGURATION)ConfigurationData)->LocalNode,
  246. ((PIPXCP_CONFIGURATION)ConfigurationData)->RemoteNode
  247. );
  248. ReleaseInterfaceReference (ifCB);
  249. }
  250. LeaveForwarder ();
  251. }
  252. /*++
  253. *******************************************************************
  254. F w L i n e D o w n
  255. Routine Description:
  256. Process line down indication delivered by IPX stack
  257. Arguments:
  258. NicId - disconnected adapter ID
  259. Return Value:
  260. None
  261. *******************************************************************
  262. --*/
  263. VOID
  264. IpxFwdLineDown (
  265. IN USHORT NicId,
  266. IN ULONG_PTR Context
  267. ) {
  268. PINTERFACE_CB ifCB;
  269. if (!EnterForwarder()) {
  270. return;
  271. }
  272. IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, ("IpxFwd: FwdLineDown.\n"));
  273. ifCB = InterfaceContextToReference ((PVOID)Context, NicId);
  274. if (ifCB!=NULL) {
  275. ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX);
  276. ASSERT (ifCB->ICB_InterfaceType!=FWD_IF_PERMANENT);
  277. UnbindInterface (ifCB);
  278. ReleaseInterfaceReference (ifCB);
  279. }
  280. LeaveForwarder ();
  281. }
  282.