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.

498 lines
8.4 KiB

  1. /*******************************************************************/
  2. /* Copyright(c) 1993 Microsoft Corporation */
  3. /*******************************************************************/
  4. //***
  5. //
  6. // Filename: misc.c
  7. //
  8. // Description: misc & aux routines
  9. //
  10. //
  11. // Author: Stefan Solomon (stefans) October 27, 1995
  12. //
  13. // Revision History:
  14. //
  15. //***
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. // Hash Table for the case where we have to accept the remote client node number and
  19. // we have a global wan net. The table is used to detect if the same node number
  20. // is not allocated twice
  21. #define NODE_HASH_TABLE_SIZE 31
  22. LIST_ENTRY NodeHT[NODE_HASH_TABLE_SIZE];
  23. // Coonection Id Hash Table
  24. #define CONN_HASH_TABLE_SIZE 31
  25. LIST_ENTRY ConnHT[CONN_HASH_TABLE_SIZE];
  26. #define connhash(ConnectionId) (ConnectionId) % CONN_HASH_TABLE_SIZE;
  27. //***
  28. //
  29. // Function: IpxCpGetNegotiatedInfo
  30. //
  31. // Descr: returns the client IPX address
  32. //
  33. //***
  34. DWORD
  35. IpxCpGetNegotiatedInfo(IN VOID *pWorkBuffer,
  36. OUT VOID * pIpxCpResultBuf
  37. )
  38. {
  39. PIPXCP_CONTEXT contextp = (PIPXCP_CONTEXT)pWorkBuffer;
  40. PPP_IPXCP_RESULT * pIpxCpResult = (PPP_IPXCP_RESULT *)pIpxCpResultBuf;
  41. memcpy( pIpxCpResult->bLocalAddress, contextp->Config.Network, 4 );
  42. memcpy( pIpxCpResult->bLocalAddress+4, contextp->Config.LocalNode, 6 );
  43. memcpy( pIpxCpResult->bRemoteAddress, contextp->Config.Network, 4 );
  44. memcpy( pIpxCpResult->bRemoteAddress+4, contextp->Config.RemoteNode, 6 );
  45. return NO_ERROR;
  46. }
  47. /*++
  48. Function: GetInterfaceType
  49. Dscr:
  50. --*/
  51. ULONG
  52. GetInterfaceType(PPPPCP_INIT initp)
  53. {
  54. ULONG InterfaceType;
  55. InterfaceType = IF_TYPE_OTHER;
  56. if(initp->hInterface == INVALID_HANDLE_VALUE) {
  57. // The handle has invalid value. This happens in 2 cases:
  58. // 1. Dialed out as a standalone workstation
  59. // 2. Dialed out from a router but using the client UI. This will
  60. // result later in an interface added to the router.
  61. if(!initp->fServer) {
  62. // Workstation dialing out
  63. if(IsRouterStarted()) {
  64. InterfaceType = IF_TYPE_ROUTER_WORKSTATION_DIALOUT;
  65. }
  66. else
  67. {
  68. InterfaceType = IF_TYPE_STANDALONE_WORKSTATION_DIALOUT;
  69. }
  70. }
  71. else
  72. {
  73. // Somebody dialed in but it doesn't have an interface handle !!!
  74. SS_ASSERT(FALSE);
  75. }
  76. }
  77. else
  78. {
  79. // The handle has a valid value
  80. if(!initp->fServer) {
  81. // Dialout - this can be only a WAN router interface
  82. if(IsRouterStarted()) {
  83. // double check with the PPP router type
  84. switch(initp->IfType) {
  85. case ROUTER_IF_TYPE_FULL_ROUTER:
  86. InterfaceType = IF_TYPE_WAN_ROUTER;
  87. break;
  88. case ROUTER_IF_TYPE_HOME_ROUTER:
  89. InterfaceType = IF_TYPE_PERSONAL_WAN_ROUTER;
  90. break;
  91. default:
  92. // Doesn't match the PPP Interface Type
  93. SS_ASSERT(FALSE);
  94. break;
  95. }
  96. }
  97. else
  98. {
  99. // Router not started but we got a valid handle !!!
  100. SS_ASSERT(FALSE);
  101. }
  102. }
  103. else
  104. {
  105. // Dialin - this can be:
  106. // 1. Remote router dialing in
  107. // 2. Remote client dialing in
  108. if(IsRouterStarted()) {
  109. switch(initp->IfType) {
  110. case ROUTER_IF_TYPE_FULL_ROUTER:
  111. InterfaceType = IF_TYPE_WAN_ROUTER;
  112. break;
  113. case ROUTER_IF_TYPE_HOME_ROUTER:
  114. InterfaceType = IF_TYPE_PERSONAL_WAN_ROUTER;
  115. break;
  116. case ROUTER_IF_TYPE_CLIENT:
  117. InterfaceType = IF_TYPE_WAN_WORKSTATION;
  118. break;
  119. default:
  120. // Doesn't match the PPP Interface Type
  121. SS_ASSERT(FALSE);
  122. break;
  123. }
  124. }
  125. else
  126. {
  127. // Router not started but we got a valid handle !!!
  128. SS_ASSERT(FALSE);
  129. }
  130. }
  131. }
  132. return InterfaceType;
  133. }
  134. VOID
  135. NetToAscii(PUCHAR ascp,
  136. PUCHAR net)
  137. {
  138. PUCHAR hexdigit = "0123456789ABCDEF";
  139. int i;
  140. for(i=0; i<4; i++) {
  141. *ascp++ = hexdigit[net[i] / 16];
  142. *ascp++ = hexdigit[net[i] % 16];
  143. }
  144. }
  145. //*** Routines for handling the hash table of node numbers ***
  146. //***
  147. //
  148. // Function: InitializeNodeHT
  149. //
  150. // Descr:
  151. //
  152. //***
  153. VOID
  154. InitializeNodeHT(VOID)
  155. {
  156. int i;
  157. PLIST_ENTRY NodeHTBucketp;
  158. NodeHTBucketp = NodeHT;
  159. for(i=0; i<NODE_HASH_TABLE_SIZE; i++, NodeHTBucketp++) {
  160. InitializeListHead(NodeHTBucketp);
  161. }
  162. }
  163. //***
  164. //
  165. // Function: ndhash
  166. //
  167. // Descr: compute the hash index for this node
  168. //
  169. //***
  170. int
  171. ndhash(PUCHAR nodep)
  172. {
  173. USHORT ndindex = 6;
  174. int hv = 0; // hash value
  175. while(ndindex--) {
  176. hv += nodep[ndindex] & 0xff;
  177. }
  178. return hv % NODE_HASH_TABLE_SIZE;
  179. }
  180. //***
  181. //
  182. // Function: NodeIsUnique
  183. //
  184. // Descr: returns TRUE if the node is not in the Node Table
  185. //
  186. //***
  187. BOOL
  188. NodeIsUnique(PUCHAR nodep)
  189. {
  190. int hv;
  191. PLIST_ENTRY nextp;
  192. PIPXCP_CONTEXT contextp;
  193. hv = ndhash(nodep);
  194. // walk the niccbs list until we get to the node
  195. nextp = NodeHT[hv].Flink;
  196. while(nextp != &NodeHT[hv]) {
  197. contextp = CONTAINING_RECORD(nextp, IPXCP_CONTEXT, NodeHtLinkage);
  198. if(!memcmp(contextp->Config.RemoteNode, nodep, 6)) {
  199. return FALSE;
  200. }
  201. nextp = contextp->NodeHtLinkage.Flink;
  202. }
  203. return TRUE;
  204. }
  205. //***
  206. //
  207. // Function: AddToNodeHT
  208. //
  209. // Descr: Inserts a new context buffer in the Node Hash Table
  210. //
  211. //***
  212. VOID
  213. AddToNodeHT(PIPXCP_CONTEXT contextp)
  214. {
  215. int hv;
  216. hv = ndhash(contextp->Config.RemoteNode);
  217. InsertTailList(&NodeHT[hv], &contextp->NodeHtLinkage);
  218. }
  219. //***
  220. //
  221. // Function: RemoveFromNodeHT
  222. //
  223. // Descr: Removes a context buffer from the Node Hash Table
  224. //
  225. //***
  226. VOID
  227. RemoveFromNodeHT(PIPXCP_CONTEXT contextp)
  228. {
  229. RemoveEntryList(&contextp->NodeHtLinkage);
  230. }
  231. /*++
  232. Function: GetUniqueHigherNetNumber
  233. Descr: Try to generate a network number which is higher then oldnet
  234. and is unique for this router's routing table
  235. --*/
  236. DWORD
  237. GetUniqueHigherNetNumber(PUCHAR newnet,
  238. PUCHAR oldnet,
  239. PIPXCP_CONTEXT contextp)
  240. {
  241. ULONG ulnewnet, uloldnet, i;
  242. GETLONG2ULONG(&ulnewnet, oldnet);
  243. // if this connection is a remote client and global wan is set, we can't
  244. // change the network number
  245. if((contextp->InterfaceType == IF_TYPE_WAN_WORKSTATION) &&
  246. (GlobalConfig.RParams.EnableGlobalWanNet)) {
  247. // we cannot change the client's net number
  248. return ERROR_CAN_NOT_COMPLETE;
  249. }
  250. // if the router is not started, anything will do
  251. if(contextp->InterfaceType == IF_TYPE_STANDALONE_WORKSTATION_DIALOUT) {
  252. ulnewnet++;
  253. PUTULONG2LONG(newnet, ulnewnet);
  254. return NO_ERROR;
  255. }
  256. for(i=0, ulnewnet++; i<100000; i++, ulnewnet++) {
  257. if(ulnewnet > 0xFFFFFFFE) {
  258. return ERROR_CAN_NOT_COMPLETE;
  259. }
  260. PUTULONG2LONG(newnet, ulnewnet);
  261. if(!IsRoute(newnet)) {
  262. return NO_ERROR;
  263. }
  264. }
  265. return ERROR_CAN_NOT_COMPLETE;
  266. }
  267. BOOL
  268. IsWorkstationDialoutActive(VOID)
  269. {
  270. BOOL rc = FALSE;;
  271. ACQUIRE_DATABASE_LOCK;
  272. if(WorkstationDialoutActive) {
  273. rc = TRUE;
  274. }
  275. RELEASE_DATABASE_LOCK;
  276. return rc;
  277. }
  278. BOOL
  279. IsRouterStarted(VOID)
  280. {
  281. BOOL rc = FALSE;;
  282. ACQUIRE_DATABASE_LOCK;
  283. if(RouterStarted) {
  284. rc = TRUE;
  285. }
  286. RELEASE_DATABASE_LOCK;
  287. return rc;
  288. }
  289. //*** Routines for handling the hash table of connection ids ***
  290. //***
  291. //
  292. // Function: InitializeConnHT
  293. //
  294. // Descr:
  295. //
  296. //***
  297. VOID
  298. InitializeConnHT(VOID)
  299. {
  300. int i;
  301. PLIST_ENTRY ConnHTBucketp;
  302. ConnHTBucketp = ConnHT;
  303. for(i=0; i<CONN_HASH_TABLE_SIZE; i++, ConnHTBucketp++) {
  304. InitializeListHead(ConnHTBucketp);
  305. }
  306. }
  307. //***
  308. //
  309. // Function: AddToConnHT
  310. //
  311. // Descr: Inserts a new context buffer in the Connection Hash Table
  312. //
  313. // Remark: >> Called with database lock held <<
  314. //
  315. //***
  316. VOID
  317. AddToConnHT(PIPXCP_CONTEXT contextp)
  318. {
  319. ULONG hv;
  320. hv = connhash(contextp->Config.ConnectionId);
  321. InsertTailList(&ConnHT[hv], &contextp->ConnHtLinkage);
  322. }
  323. //***
  324. //
  325. // Function: RemoveFromConnHT
  326. //
  327. // Descr: Removes a context buffer from the Node Hash Table
  328. //
  329. // Remark: >> Called with database lock held <<
  330. //
  331. //***
  332. VOID
  333. RemoveFromConnHT(PIPXCP_CONTEXT contextp)
  334. {
  335. RemoveEntryList(&contextp->ConnHtLinkage);
  336. }
  337. /*++
  338. Function: GetContextBuffer
  339. Descr: gets a ptr to the context buffer based on the connection id
  340. Remark: >> Called with database lock held <<
  341. --*/
  342. PIPXCP_CONTEXT
  343. GetContextBuffer(ULONG_PTR ConnectionId)
  344. {
  345. ULONG hv;
  346. PLIST_ENTRY nextp;
  347. PIPXCP_CONTEXT contextp;
  348. hv = (ULONG)connhash(ConnectionId);
  349. nextp = ConnHT[hv].Flink;
  350. while(nextp != &ConnHT[hv]) {
  351. contextp = CONTAINING_RECORD(nextp, IPXCP_CONTEXT, ConnHtLinkage);
  352. if(contextp->Config.ConnectionId == ConnectionId) {
  353. return contextp;
  354. }
  355. nextp = contextp->ConnHtLinkage.Flink;
  356. }
  357. return NULL;
  358. }