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.

1521 lines
40 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. ifmgr.c
  5. Abstract:
  6. This module contains the interface management functions
  7. Author:
  8. Stefan Solomon 03/06/1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. //*** Interface Manager Globals ***
  15. //
  16. // Counter of existing interfaces
  17. ULONG InterfaceCount = 0;
  18. //
  19. //*** Interface Manager APIs ***
  20. //
  21. typedef struct _IF_TYPE_TRANSLATION {
  22. ROUTER_INTERFACE_TYPE DIMInterfaceType;
  23. ULONG MIBInterfaceType;
  24. } IF_TYPE_TRANSLATION, *PIF_TYPE_TRANSLATION;
  25. IF_TYPE_TRANSLATION IfTypeTranslation[] = {
  26. { ROUTER_IF_TYPE_FULL_ROUTER, IF_TYPE_WAN_ROUTER },
  27. { ROUTER_IF_TYPE_HOME_ROUTER, IF_TYPE_PERSONAL_WAN_ROUTER },
  28. { ROUTER_IF_TYPE_DEDICATED, IF_TYPE_LAN },
  29. { ROUTER_IF_TYPE_CLIENT, IF_TYPE_WAN_WORKSTATION },
  30. { ROUTER_IF_TYPE_INTERNAL, IF_TYPE_INTERNAL }
  31. };
  32. #define MAX_IF_TRANSLATION_TYPES sizeof(IfTypeTranslation)/sizeof(IF_TYPE_TRANSLATION)
  33. /*++
  34. Function: AddInterface
  35. Descr: Creates the interface control block and adds the specific
  36. structures of the interface info to the corresponding modules.
  37. Arguments:
  38. InterfaceNamep :
  39. Pointer to a WCHAR string representing the interface name.
  40. InterfaceInfop :
  41. Pointer to an IPX_INFO_BLOCK_HEADER structure containing the
  42. IPX, RIP and SAP interface information, static routes and static services.
  43. Pointer to an IPX_INFO_BLOCK_HEADER structure containing the
  44. traffic filters.
  45. InterfaceType:
  46. REMARK: In order for the router to be able to start, the internal interface
  47. has to be added.
  48. --*/
  49. DWORD
  50. AddInterface(
  51. IN LPWSTR InterfaceNamep,
  52. IN LPVOID InterfaceInfop,
  53. // IN LPVOID InFilterInfop,
  54. // IN LPVOID OutFilterInfop,
  55. IN ROUTER_INTERFACE_TYPE DIMInterfaceType,
  56. IN HANDLE hDIMInterface,
  57. IN OUT PHANDLE phInterface)
  58. {
  59. PICB icbp;
  60. ULONG InterfaceNameLen; // if name length in bytes including wchar NULL
  61. PIPX_IF_INFO IpxIfInfop;
  62. PIPX_STATIC_ROUTE_INFO StaticRtInfop;
  63. PIPX_STATIC_SERVICE_INFO StaticSvInfop;
  64. PIPXWAN_IF_INFO IpxwanIfInfop;
  65. PIPX_TRAFFIC_FILTER_GLOBAL_INFO InFltGlInfo, OutFltGlInfo;
  66. // PUCHAR TrafficFilterInfop;
  67. PIPX_INFO_BLOCK_HEADER IfInfop = (PIPX_INFO_BLOCK_HEADER)InterfaceInfop;
  68. PACB acbp;
  69. ULONG AdapterNameLen = 0; // length of adapter name
  70. // for ROUTER_IF_TYPE_DEDICATED interface type.
  71. PIPX_TOC_ENTRY tocep;
  72. UINT i;
  73. PIPX_ADAPTER_INFO AdapterInfop;
  74. ULONG tmp;
  75. FW_IF_INFO FwIfInfo;
  76. PIF_TYPE_TRANSLATION ittp;
  77. ULONG InterfaceIndex;
  78. PIPX_STATIC_NETBIOS_NAME_INFO StaticNbInfop;
  79. Trace(INTERFACE_TRACE, "AddInterface: Entered for interface %S", InterfaceNamep);
  80. if(InterfaceInfop == NULL) {
  81. IF_LOG (EVENTLOG_ERROR_TYPE) {
  82. RouterLogErrorDataW (RMEventLogHdl,
  83. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  84. 1, &InterfaceNamep, 0, NULL);
  85. }
  86. Trace(INTERFACE_TRACE, "AddInterface: Missing interface info for interface %ls\n", InterfaceNamep);
  87. return ERROR_CAN_NOT_COMPLETE;
  88. }
  89. // interface name length including the unicode null
  90. InterfaceNameLen = (wcslen(InterfaceNamep) + 1) * sizeof(WCHAR);
  91. // If the interface type if ROUTER_IF_TYPE_DEDICATED (LAN Adapter) we parse the
  92. // interface name to extract the adapter name and the packet type.
  93. // The packet type will be then converted to an integer and the two will
  94. // be used to identify a corresponding adapter.
  95. if(DIMInterfaceType == ROUTER_IF_TYPE_DEDICATED) {
  96. PWCHAR pszStart, pszEnd;
  97. DWORD dwGuidLength = 37;
  98. // get the lan adapter specific info from the interface
  99. if((AdapterInfop = (PIPX_ADAPTER_INFO)GetInfoEntry(InterfaceInfop,
  100. IPX_ADAPTER_INFO_TYPE)) == NULL)
  101. {
  102. IF_LOG (EVENTLOG_ERROR_TYPE) {
  103. RouterLogErrorDataW (RMEventLogHdl,
  104. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  105. 1, &InterfaceNamep, 0, NULL);
  106. }
  107. Trace(INTERFACE_TRACE, "AddInterface: Dedicated interface %ls missing adapter info\n", InterfaceNamep);
  108. return ERROR_INVALID_PARAMETER;
  109. }
  110. // If the supplied adater is a reference to a guid, then use the name
  111. // of the guid supplied in the interface name. This is because load/save
  112. // config's can cause these two to get out of sync.
  113. pszStart = wcsstr (InterfaceNamep, L"{");
  114. pszEnd = wcsstr (InterfaceNamep, L"}");
  115. if ( (pszStart) &&
  116. (pszEnd) &&
  117. (pszStart == InterfaceNamep) &&
  118. ((DWORD)(pszEnd - pszStart) == dwGuidLength) )
  119. {
  120. wcsncpy (AdapterInfop->AdapterName, InterfaceNamep, dwGuidLength);
  121. }
  122. AdapterNameLen = (wcslen(AdapterInfop->AdapterName) + 1) * sizeof(WCHAR);
  123. }
  124. ACQUIRE_DATABASE_LOCK;
  125. if(RouterOperState != OPER_STATE_UP) {
  126. RELEASE_DATABASE_LOCK;
  127. return ERROR_CAN_NOT_COMPLETE;
  128. }
  129. // Check if this is the internal interface. If it is and if we
  130. // already have the internal interface, we return an error
  131. if((DIMInterfaceType == ROUTER_IF_TYPE_INTERNAL) &&
  132. (InternalInterfacep)) {
  133. RELEASE_DATABASE_LOCK;
  134. // internal interface already exists
  135. Trace(INTERFACE_TRACE, "AddInterface: INTERNAL interface already exists\n");
  136. return ERROR_INVALID_PARAMETER;
  137. }
  138. // Allocate a new ICB and initialize it
  139. // we allocate the interface and adapter name buffers at the end of the
  140. // ICB struct.
  141. if((icbp = (PICB)GlobalAlloc(GPTR,
  142. sizeof(ICB) +
  143. InterfaceNameLen +
  144. AdapterNameLen)) == NULL) {
  145. RELEASE_DATABASE_LOCK;
  146. // can't alloc memory
  147. SS_ASSERT(FALSE);
  148. return ERROR_OUT_OF_STRUCTURES;
  149. }
  150. // signature
  151. memcpy(&icbp->Signature, InterfaceSignature, 4);
  152. // get a new index and increment the global interface index counter
  153. // if this is not the internal interface. For the internal interface we
  154. // have reserved index 0
  155. if(DIMInterfaceType == ROUTER_IF_TYPE_INTERNAL) {
  156. icbp->InterfaceIndex = 0;
  157. }
  158. else
  159. {
  160. icbp->InterfaceIndex = GetNextInterfaceIndex();
  161. if(icbp->InterfaceIndex == MAX_INTERFACE_INDEX) {
  162. GlobalFree(icbp);
  163. RELEASE_DATABASE_LOCK;
  164. return ERROR_CAN_NOT_COMPLETE;
  165. }
  166. }
  167. InterfaceIndex = icbp->InterfaceIndex;
  168. // copy the interface name
  169. icbp->InterfaceNamep = (PWSTR)((PUCHAR)icbp + sizeof(ICB));
  170. memcpy(icbp->InterfaceNamep, InterfaceNamep, InterfaceNameLen);
  171. // copy the adapter name and packet type if dedicated interface
  172. if(DIMInterfaceType == ROUTER_IF_TYPE_DEDICATED) {
  173. icbp->AdapterNamep = (PWSTR)((PUCHAR)icbp + sizeof(ICB) + InterfaceNameLen);
  174. wcscpy(icbp->AdapterNamep, AdapterInfop->AdapterName);
  175. icbp->PacketType = AdapterInfop->PacketType;
  176. }
  177. else
  178. {
  179. icbp->AdapterNamep = NULL;
  180. icbp->PacketType = 0;
  181. }
  182. // insert the if in the index hash table
  183. AddIfToDB(icbp);
  184. // get the if handle used when calling DIM entry points
  185. icbp->hDIMInterface = hDIMInterface;
  186. // reset the update status fields
  187. ResetUpdateRequest(icbp);
  188. // mark connection not requested yet
  189. icbp->ConnectionRequestPending = FALSE;
  190. // get to the interface entries in the interface info block
  191. if(((IpxIfInfop = (PIPX_IF_INFO)GetInfoEntry(InterfaceInfop, IPX_INTERFACE_INFO_TYPE)) == NULL) ||
  192. ((IpxwanIfInfop = (PIPXWAN_IF_INFO)GetInfoEntry(InterfaceInfop, IPXWAN_INTERFACE_INFO_TYPE)) == NULL)) {
  193. RemoveIfFromDB(icbp);
  194. GlobalFree(icbp);
  195. RELEASE_DATABASE_LOCK;
  196. // don't have all ipx or ipxwan interfaces info
  197. IF_LOG (EVENTLOG_ERROR_TYPE) {
  198. RouterLogErrorDataW (RMEventLogHdl,
  199. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  200. 1, &InterfaceNamep, 0, NULL);
  201. }
  202. Trace(INTERFACE_TRACE, "AddInterface: missing ipx or ipxwan interface info\n");
  203. return ERROR_INVALID_PARAMETER;
  204. }
  205. // Initialize the Admin State and the Oper State of this interface.
  206. // Oper State may be changed will be changed later to OPER_STATE_SLEEPING
  207. // if this is a WAN interface.
  208. icbp->OperState = OPER_STATE_DOWN;
  209. // set the DIM interface type of this ICB
  210. icbp->DIMInterfaceType = DIMInterfaceType;
  211. // set the MIB interface type of this ICB
  212. icbp->MIBInterfaceType = IF_TYPE_OTHER;
  213. for(i=0, ittp=IfTypeTranslation; i<MAX_IF_TRANSLATION_TYPES; i++, ittp++) {
  214. if(icbp->DIMInterfaceType == ittp->DIMInterfaceType) {
  215. icbp->MIBInterfaceType = ittp->MIBInterfaceType;
  216. break;
  217. }
  218. }
  219. // create the routing protocols (rip/sap or nlsp) interface info
  220. // If the routing protocols interface info is missing this will fail
  221. if(CreateRoutingProtocolsInterfaces(InterfaceInfop, icbp) != NO_ERROR) {
  222. RELEASE_DATABASE_LOCK;
  223. // don't have all rip and sap interfaces info
  224. Trace(INTERFACE_TRACE, "AddInterface: Bad routing protocols interface config info\n");
  225. goto ErrorExit;
  226. }
  227. // create the Forwarder interface
  228. FwIfInfo.NetbiosAccept = IpxIfInfop->NetbiosAccept;
  229. FwIfInfo.NetbiosDeliver = IpxIfInfop->NetbiosDeliver;
  230. FwCreateInterface(icbp->InterfaceIndex,
  231. MapIpxToNetInterfaceType(icbp),
  232. &FwIfInfo);
  233. // Seed the traffic filters
  234. if ((tocep = GetTocEntry(InterfaceInfop, IPX_IN_TRAFFIC_FILTER_INFO_TYPE))!=NULL) {
  235. if ((InFltGlInfo = GetInfoEntry(InterfaceInfop, IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE)) == NULL) {
  236. RELEASE_DATABASE_LOCK;
  237. IF_LOG (EVENTLOG_ERROR_TYPE) {
  238. RouterLogErrorDataW (RMEventLogHdl,
  239. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  240. 1, &InterfaceNamep, 0, NULL);
  241. }
  242. Trace(INTERFACE_TRACE, "AddInterface: Bad input filters config info");
  243. goto ErrorExit;
  244. }
  245. if (SetFilters(icbp->InterfaceIndex,
  246. IPX_TRAFFIC_FILTER_INBOUND,
  247. InFltGlInfo->FilterAction, // pass or don't pass
  248. tocep->InfoSize, // filter size
  249. (LPBYTE)InterfaceInfop+tocep->Offset,
  250. tocep->InfoSize*tocep->Count) != NO_ERROR) {
  251. RELEASE_DATABASE_LOCK;
  252. IF_LOG (EVENTLOG_ERROR_TYPE) {
  253. RouterLogErrorDataW (RMEventLogHdl,
  254. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  255. 1, &InterfaceNamep, 0, NULL);
  256. }
  257. Trace(INTERFACE_TRACE, "AddInterface: Bad input filters config info");
  258. goto ErrorExit;
  259. }
  260. }
  261. else { // No Filters -> delete all
  262. if (SetFilters(icbp->InterfaceIndex,
  263. IPX_TRAFFIC_FILTER_INBOUND, // in or outbound,
  264. 0, // pass or don't pass
  265. 0, // filter size
  266. NULL,
  267. 0)!=NO_ERROR) {
  268. RELEASE_DATABASE_LOCK;
  269. Trace(INTERFACE_TRACE, "AddInterface: Could not delete input filters");
  270. goto ErrorExit;
  271. }
  272. }
  273. if ((tocep = GetTocEntry(InterfaceInfop, IPX_OUT_TRAFFIC_FILTER_INFO_TYPE))!=NULL) {
  274. if ((OutFltGlInfo = GetInfoEntry(InterfaceInfop, IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE)) == NULL) {
  275. RELEASE_DATABASE_LOCK;
  276. Trace(INTERFACE_TRACE, "AddInterface: Bad output filters config info");
  277. goto ErrorExit;
  278. }
  279. if (SetFilters(icbp->InterfaceIndex,
  280. IPX_TRAFFIC_FILTER_OUTBOUND,
  281. OutFltGlInfo->FilterAction, // pass or don't pass
  282. tocep->InfoSize, // filter size
  283. (LPBYTE)InterfaceInfop+tocep->Offset,
  284. tocep->InfoSize*tocep->Count) != NO_ERROR) {
  285. RELEASE_DATABASE_LOCK;
  286. IF_LOG (EVENTLOG_ERROR_TYPE) {
  287. RouterLogErrorDataW (RMEventLogHdl,
  288. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  289. 1, &InterfaceNamep, 0, NULL);
  290. }
  291. Trace(INTERFACE_TRACE, "AddInterface: Bad output filters config info");
  292. goto ErrorExit;
  293. }
  294. }
  295. else { // No Filters -> delete all
  296. if (SetFilters(icbp->InterfaceIndex,
  297. IPX_TRAFFIC_FILTER_OUTBOUND, // in or outbound,
  298. 0, // pass or don't pass
  299. 0, // filter size
  300. NULL,
  301. 0)!=NO_ERROR) {
  302. RELEASE_DATABASE_LOCK;
  303. Trace(INTERFACE_TRACE, "AddInterface: Could not delete output filters");
  304. goto ErrorExit;
  305. }
  306. }
  307. // mark the interface reachable
  308. icbp->InterfaceReachable = TRUE;
  309. // set the admin state
  310. if(IpxIfInfop->AdminState == ADMIN_STATE_ENABLED) {
  311. AdminEnable(icbp);
  312. }
  313. else
  314. {
  315. AdminDisable(icbp);
  316. }
  317. // seed the static routes
  318. if(DIMInterfaceType!=ROUTER_IF_TYPE_CLIENT) {
  319. if (tocep = GetTocEntry(InterfaceInfop, IPX_STATIC_ROUTE_INFO_TYPE)) {
  320. StaticRtInfop = (PIPX_STATIC_ROUTE_INFO)GetInfoEntry(InterfaceInfop,
  321. IPX_STATIC_ROUTE_INFO_TYPE);
  322. for(i=0; i<tocep->Count; i++, StaticRtInfop++) {
  323. CreateStaticRoute(icbp, StaticRtInfop);
  324. }
  325. }
  326. // seed the static services
  327. if(tocep = GetTocEntry(InterfaceInfop, IPX_STATIC_SERVICE_INFO_TYPE)) {
  328. StaticSvInfop = (PIPX_STATIC_SERVICE_INFO)GetInfoEntry(InterfaceInfop,
  329. IPX_STATIC_SERVICE_INFO_TYPE);
  330. for(i=0; i<tocep->Count; i++, StaticSvInfop++) {
  331. CreateStaticService(icbp, StaticSvInfop);
  332. }
  333. }
  334. // seed the static netbios names
  335. if(tocep = GetTocEntry(InterfaceInfop, IPX_STATIC_NETBIOS_NAME_INFO_TYPE)) {
  336. StaticNbInfop = (PIPX_STATIC_NETBIOS_NAME_INFO)GetInfoEntry(InterfaceInfop,
  337. IPX_STATIC_NETBIOS_NAME_INFO_TYPE);
  338. FwSetStaticNetbiosNames(icbp->InterfaceIndex,
  339. tocep->Count,
  340. StaticNbInfop);
  341. }
  342. }
  343. // set the IPXWAN interface info
  344. icbp->EnableIpxWanNegotiation = IpxwanIfInfop->AdminState;
  345. // mark the interface as unbound to an adapter (default)
  346. icbp->acbp = NULL;
  347. // check if we can bind it now to an adapter. We can do this only for a
  348. // a dedicated (LAN) interface or for an internal interface.
  349. switch(icbp->DIMInterfaceType) {
  350. case ROUTER_IF_TYPE_DEDICATED:
  351. // Only bind interface if internal interface is already
  352. // created and bound
  353. if (InternalInterfacep && InternalInterfacep->acbp) {
  354. // check if we have an adapter with a corresponding name and
  355. // packet type
  356. if((acbp = GetAdapterByNameAndPktType (icbp->AdapterNamep,
  357. icbp->PacketType)) != NULL) {
  358. BindInterfaceToAdapter(icbp, acbp);
  359. }
  360. }
  361. break;
  362. case ROUTER_IF_TYPE_INTERNAL:
  363. // get the pointer to the internal interface
  364. InternalInterfacep = icbp;
  365. // check that we have the adapter with adapter index 0 which
  366. // represents the internal adapter
  367. if(InternalAdapterp) {
  368. PLIST_ENTRY lep;
  369. acbp = InternalAdapterp;
  370. BindInterfaceToAdapter(icbp, acbp);
  371. lep = IndexIfList.Flink;
  372. // Bind all previously added dedicated interfaces that were
  373. // not bound awaiting for internal interface to be added
  374. while(lep != &IndexIfList) {
  375. PACB acbp2;
  376. PICB icbp2 = CONTAINING_RECORD(lep, ICB, IndexListLinkage);
  377. lep = lep->Flink;
  378. switch(icbp2->DIMInterfaceType) {
  379. case ROUTER_IF_TYPE_DEDICATED:
  380. // check if we have an adapter with a corresponding name and
  381. // packet type
  382. if ((icbp2->acbp==NULL)
  383. &&((acbp2 = GetAdapterByNameAndPktType (icbp2->AdapterNamep,
  384. icbp2->PacketType)) != NULL)) {
  385. BindInterfaceToAdapter(icbp2, acbp2);
  386. }
  387. }
  388. }
  389. }
  390. break;
  391. default:
  392. if (icbp->AdminState==ADMIN_STATE_ENABLED)
  393. // this is a WAN interface. As long as it isn't connected, and
  394. // enabled the oper state will be sleeping on this interface
  395. icbp->OperState = OPER_STATE_SLEEPING;
  396. break;
  397. }
  398. // increment the interface counter
  399. InterfaceCount++;
  400. switch(icbp->DIMInterfaceType)
  401. {
  402. case ROUTER_IF_TYPE_DEDICATED:
  403. if(icbp->acbp) {
  404. Trace(INTERFACE_TRACE, "AddInterface: created LAN interface: # %d name %ls bound to adapter # %d name %ls\n",
  405. icbp->InterfaceIndex,
  406. icbp->InterfaceNamep,
  407. icbp->acbp->AdapterIndex,
  408. icbp->AdapterNamep);
  409. }
  410. else
  411. {
  412. Trace(INTERFACE_TRACE, "AddInterface: created LAN interface: # %d name %ls unbound to any adapter\n",
  413. icbp->InterfaceIndex,
  414. icbp->InterfaceNamep);
  415. }
  416. break;
  417. case ROUTER_IF_TYPE_INTERNAL:
  418. if(icbp->acbp) {
  419. Trace(INTERFACE_TRACE, "AddInterface: created INTERNAL interface: # %d name %ls bound to internal adapter\n",
  420. icbp->InterfaceIndex,
  421. icbp->InterfaceNamep);
  422. }
  423. else
  424. {
  425. Trace(INTERFACE_TRACE, "AddInterface: created INTERNAL interface: # %d name %ls unbound to any adapter\n",
  426. icbp->InterfaceIndex,
  427. icbp->InterfaceNamep);
  428. }
  429. break;
  430. default:
  431. Trace(INTERFACE_TRACE, "AddInterface: created WAN interface: # %d name %ls\n",
  432. icbp->InterfaceIndex,
  433. icbp->InterfaceNamep);
  434. break;
  435. }
  436. RELEASE_DATABASE_LOCK;
  437. // return the allocated if index
  438. *phInterface = (HANDLE)UlongToPtr(icbp->InterfaceIndex);
  439. return NO_ERROR;
  440. ErrorExit:
  441. InterfaceCount++;
  442. DeleteInterface((HANDLE)UlongToPtr(InterfaceIndex));
  443. return ERROR_CAN_NOT_COMPLETE;
  444. }
  445. /*++
  446. Function: DeleteInterface
  447. Descr:
  448. --*/
  449. DWORD
  450. DeleteInterface(HANDLE InterfaceIndex)
  451. {
  452. PICB icbp;
  453. Trace(INTERFACE_TRACE, "DeleteInterface: Entered for interface # %d\n",
  454. InterfaceIndex);
  455. ACQUIRE_DATABASE_LOCK;
  456. if(RouterOperState != OPER_STATE_UP) {
  457. RELEASE_DATABASE_LOCK;
  458. return ERROR_CAN_NOT_COMPLETE;
  459. }
  460. icbp = GetInterfaceByIndex(PtrToUlong(InterfaceIndex));
  461. if(icbp == NULL) {
  462. RELEASE_DATABASE_LOCK;
  463. return ERROR_INVALID_PARAMETER;
  464. }
  465. if(memcmp(&icbp->Signature, InterfaceSignature, 4)) {
  466. // not a valid if pointer
  467. SS_ASSERT(FALSE);
  468. RELEASE_DATABASE_LOCK;
  469. return ERROR_INVALID_PARAMETER;
  470. }
  471. // if bound to an adapter -> unbind
  472. if(icbp->acbp) {
  473. UnbindInterfaceFromAdapter(icbp);
  474. }
  475. // delete the routing protocols interfaces
  476. DeleteRoutingProtocolsInterfaces(icbp->InterfaceIndex);
  477. // delete all static routes from RTM
  478. DeleteAllStaticRoutes(icbp->InterfaceIndex);
  479. DeleteAllStaticServices(icbp->InterfaceIndex);
  480. // delete the Fw interface. This will delete all associated filters
  481. FwDeleteInterface(icbp->InterfaceIndex);
  482. // remove the if from the data base
  483. RemoveIfFromDB(icbp);
  484. // done
  485. GlobalFree(icbp);
  486. // decrement the interface counter
  487. InterfaceCount--;
  488. RELEASE_DATABASE_LOCK;
  489. Trace(INTERFACE_TRACE, "DeleteInterface: Deleted interface %d\n", InterfaceIndex);
  490. return NO_ERROR;
  491. }
  492. /*++
  493. Function: GetInterfaceInfo
  494. Descr:
  495. --*/
  496. DWORD
  497. GetInterfaceInfo(
  498. IN HANDLE InterfaceIndex,
  499. OUT LPVOID InterfaceInfop,
  500. IN OUT DWORD *InterfaceInfoSize
  501. // OUT LPVOID InFilterInfo,
  502. // IN OUT DWORD *InFilterInfoSize,
  503. // OUT LPVOID OutFilterInfo,
  504. // IN OUT DWORD *OutFilterInfoSize
  505. )
  506. {
  507. PICB icbp;
  508. PIPX_INFO_BLOCK_HEADER ibhp, fbhp;
  509. PIPX_TOC_ENTRY tocep;
  510. PIPX_IF_INFO IpxIfInfop;
  511. PIPX_STATIC_ROUTE_INFO StaticRtInfop;
  512. PIPX_STATIC_SERVICE_INFO StaticSvInfop;
  513. PIPXWAN_IF_INFO IpxwanIfInfop;
  514. PIPX_ADAPTER_INFO IpxAdapterInfop;
  515. PIPX_TRAFFIC_FILTER_GLOBAL_INFO InFltGlInfo, OutFltGlInfo;
  516. ULONG InFltAction, OutFltAction;
  517. ULONG InFltSize, OutFltSize;
  518. ULONG InFltInfoSize=0, OutFltInfoSize=0;
  519. FW_IF_STATS FwIfStats;
  520. ULONG iftoccount = 0;
  521. ULONG ifinfolen = 0;
  522. ULONG NextInfoOffset;
  523. ULONG IpxIfOffset = 0;
  524. ULONG StaticRtOffset = 0;
  525. ULONG StaticSvOffset = 0;
  526. IPX_STATIC_ROUTE_INFO StaticRoute;
  527. UINT i;
  528. HANDLE EnumHandle;
  529. FW_IF_INFO FwIfInfo;
  530. ULONG StaticRoutesCount, StaticServicesCount, TrafficFiltersCount;
  531. DWORD rc;
  532. PIPX_STATIC_NETBIOS_NAME_INFO NetbiosNamesInfop;
  533. ULONG NetbiosNamesCount = 0;
  534. Trace(INTERFACE_TRACE, "GetInterfaceInfo: Entered for interface # %d\n", InterfaceIndex);
  535. ACQUIRE_DATABASE_LOCK;
  536. if(RouterOperState != OPER_STATE_UP) {
  537. RELEASE_DATABASE_LOCK;
  538. return ERROR_CAN_NOT_COMPLETE;
  539. }
  540. if((icbp = GetInterfaceByIndex(PtrToUlong(InterfaceIndex))) == NULL) {
  541. RELEASE_DATABASE_LOCK;
  542. Trace(INTERFACE_TRACE, "GetInterfaceInfo: Nonexistent interface with # %d\n", InterfaceIndex);
  543. return ERROR_INVALID_HANDLE;
  544. }
  545. SS_ASSERT(!memcmp(&icbp->Signature, InterfaceSignature, 4));
  546. // calculate the minimum number of toc entries we should have:
  547. // ipx toc entry
  548. // routing protocols toc entries
  549. // ipxwan toc entry
  550. iftoccount = 2 + RoutingProtocolsTocCount();
  551. // if this is a lan adapter, it should also have adapter info
  552. if(icbp->DIMInterfaceType == ROUTER_IF_TYPE_DEDICATED) {
  553. iftoccount++;
  554. }
  555. // calculate the minimun length of the interface info block
  556. ifinfolen = sizeof(IPX_INFO_BLOCK_HEADER) +
  557. (iftoccount - 1) * sizeof(IPX_TOC_ENTRY) +
  558. sizeof(IPX_IF_INFO) +
  559. SizeOfRoutingProtocolsIfsInfo(PtrToUlong(InterfaceIndex)) +
  560. sizeof(IPXWAN_IF_INFO);
  561. // if this is a lan adapter, add the size of the adapter info
  562. if(icbp->DIMInterfaceType == ROUTER_IF_TYPE_DEDICATED) {
  563. ifinfolen += sizeof(IPX_ADAPTER_INFO);
  564. }
  565. if(StaticRoutesCount = GetStaticRoutesCount(icbp->InterfaceIndex)) {
  566. ifinfolen += sizeof(IPX_TOC_ENTRY) +
  567. StaticRoutesCount * sizeof(IPX_STATIC_ROUTE_INFO);
  568. iftoccount++;
  569. }
  570. if(StaticServicesCount = GetStaticServicesCount(icbp->InterfaceIndex)) {
  571. ifinfolen += sizeof(IPX_TOC_ENTRY) +
  572. StaticServicesCount * sizeof(IPX_STATIC_SERVICE_INFO);
  573. iftoccount++;
  574. }
  575. FwGetStaticNetbiosNames(icbp->InterfaceIndex,
  576. &NetbiosNamesCount,
  577. NULL);
  578. if(NetbiosNamesCount) {
  579. ifinfolen += sizeof(IPX_TOC_ENTRY) +
  580. NetbiosNamesCount * sizeof(IPX_STATIC_NETBIOS_NAME_INFO);
  581. iftoccount++;
  582. }
  583. // get the length of the filters info
  584. rc = GetFilters(icbp->InterfaceIndex,
  585. IPX_TRAFFIC_FILTER_INBOUND,
  586. &InFltAction,
  587. &InFltSize,
  588. NULL,
  589. &InFltInfoSize);
  590. if((rc != NO_ERROR) && (rc != ERROR_INSUFFICIENT_BUFFER)) {
  591. RELEASE_DATABASE_LOCK;
  592. return rc;
  593. }
  594. if (InFltInfoSize>0) {
  595. ifinfolen += sizeof (IPX_TOC_ENTRY)*2 + InFltInfoSize
  596. + sizeof (IPX_TRAFFIC_FILTER_GLOBAL_INFO);
  597. iftoccount += 2;
  598. }
  599. rc = GetFilters(icbp->InterfaceIndex,
  600. IPX_TRAFFIC_FILTER_OUTBOUND,
  601. &OutFltAction,
  602. &OutFltSize,
  603. NULL,
  604. &OutFltInfoSize);
  605. if((rc != NO_ERROR) && (rc != ERROR_INSUFFICIENT_BUFFER)) {
  606. RELEASE_DATABASE_LOCK;
  607. return rc;
  608. }
  609. if (OutFltInfoSize>0) {
  610. ifinfolen += sizeof (IPX_TOC_ENTRY)*2 + OutFltInfoSize
  611. + sizeof (IPX_TRAFFIC_FILTER_GLOBAL_INFO);
  612. iftoccount += 2;
  613. }
  614. // check if we have valid and sufficient buffers
  615. if((InterfaceInfop == NULL) ||
  616. (ifinfolen > *InterfaceInfoSize)) {
  617. *InterfaceInfoSize = ifinfolen;
  618. RELEASE_DATABASE_LOCK;
  619. return ERROR_INSUFFICIENT_BUFFER;
  620. }
  621. *InterfaceInfoSize = ifinfolen;
  622. //
  623. // Start filling in the interface info block
  624. //
  625. // start of the info block
  626. ibhp = (PIPX_INFO_BLOCK_HEADER)InterfaceInfop;
  627. // offset of the first INFO entry
  628. NextInfoOffset = sizeof(IPX_INFO_BLOCK_HEADER) +
  629. (iftoccount -1) * sizeof(IPX_TOC_ENTRY);
  630. ibhp->Version = IPX_ROUTER_VERSION_1;
  631. ibhp->Size = ifinfolen;
  632. ibhp->TocEntriesCount = iftoccount;
  633. tocep = ibhp->TocEntry;
  634. // ipx if toc entry
  635. tocep->InfoType = IPX_INTERFACE_INFO_TYPE;
  636. tocep->InfoSize = sizeof(IPX_IF_INFO);
  637. tocep->Count = 1;
  638. tocep->Offset = NextInfoOffset;
  639. NextInfoOffset += tocep->Count * tocep->InfoSize;
  640. // ipx if info entry
  641. IpxIfInfop = (PIPX_IF_INFO)((PUCHAR)ibhp + tocep->Offset);
  642. IpxIfInfop->AdminState = icbp->AdminState;
  643. FwGetInterface(icbp->InterfaceIndex,
  644. &FwIfInfo,
  645. &FwIfStats);
  646. IpxIfInfop->NetbiosAccept = FwIfInfo.NetbiosAccept;
  647. IpxIfInfop->NetbiosDeliver = FwIfInfo.NetbiosDeliver;
  648. // create the toc and info entries for the routing protocols in the
  649. // ouput buffer; this function will update the current TOC entry pointer
  650. // value (tocep) and the current next entry info offset value (nextInfoOffset)
  651. if((rc = CreateRoutingProtocolsTocAndInfoEntries(ibhp,
  652. icbp->InterfaceIndex,
  653. &tocep,
  654. &NextInfoOffset)) != NO_ERROR) {
  655. RELEASE_DATABASE_LOCK;
  656. return rc;
  657. }
  658. // ipxwan if toc entry
  659. tocep++;
  660. tocep->InfoType = IPXWAN_INTERFACE_INFO_TYPE;
  661. tocep->InfoSize = sizeof(IPXWAN_IF_INFO);
  662. tocep->Count = 1;
  663. tocep->Offset = NextInfoOffset;
  664. NextInfoOffset += tocep->Count * tocep->InfoSize;
  665. // ipxwan if info entry
  666. IpxwanIfInfop = (PIPXWAN_IF_INFO)((PUCHAR)ibhp + tocep->Offset);
  667. IpxwanIfInfop->AdminState = icbp->EnableIpxWanNegotiation;
  668. // if this is a lan interface, fill in the adapter info
  669. if(icbp->DIMInterfaceType == ROUTER_IF_TYPE_DEDICATED) {
  670. // ipx adapter toc entry
  671. tocep++;
  672. tocep->InfoType = IPX_ADAPTER_INFO_TYPE;
  673. tocep->InfoSize = sizeof(IPX_ADAPTER_INFO);
  674. tocep->Count = 1;
  675. tocep->Offset = NextInfoOffset;
  676. NextInfoOffset += tocep->Count * tocep->InfoSize;
  677. // ipx adapter info entry
  678. IpxAdapterInfop = (PIPX_ADAPTER_INFO)((PUCHAR)ibhp + tocep->Offset);
  679. IpxAdapterInfop->PacketType = icbp->PacketType;
  680. wcscpy(IpxAdapterInfop->AdapterName, icbp->AdapterNamep);
  681. }
  682. // static routes toc + info entries
  683. if(StaticRoutesCount) {
  684. // static routes toc entry
  685. tocep++;
  686. tocep->InfoType = IPX_STATIC_ROUTE_INFO_TYPE;
  687. tocep->InfoSize = sizeof(IPX_STATIC_ROUTE_INFO);
  688. tocep->Count = StaticRoutesCount;
  689. tocep->Offset = NextInfoOffset;
  690. NextInfoOffset += tocep->Count * tocep->InfoSize;
  691. // Create static routes enumeration handle for this interface
  692. EnumHandle = CreateStaticRoutesEnumHandle(icbp->InterfaceIndex);
  693. for(i=0, StaticRtInfop = (PIPX_STATIC_ROUTE_INFO)((PUCHAR)ibhp + tocep->Offset);
  694. i<StaticRoutesCount;
  695. i++, StaticRtInfop++) {
  696. GetNextStaticRoute(EnumHandle, StaticRtInfop);
  697. }
  698. // Close the enumeration handle
  699. CloseStaticRoutesEnumHandle(EnumHandle);
  700. }
  701. // static services toc + info entries
  702. if(StaticServicesCount) {
  703. // static services toc entry
  704. tocep++;
  705. tocep->InfoType = IPX_STATIC_SERVICE_INFO_TYPE;
  706. tocep->InfoSize = sizeof(IPX_STATIC_SERVICE_INFO);
  707. tocep->Count = StaticServicesCount;
  708. tocep->Offset = NextInfoOffset;
  709. NextInfoOffset += tocep->Count * tocep->InfoSize;
  710. // Create static services enumeration handle for this interface
  711. EnumHandle = CreateStaticServicesEnumHandle(icbp->InterfaceIndex);
  712. for(i=0, StaticSvInfop = (PIPX_STATIC_SERVICE_INFO)((PUCHAR)ibhp + tocep->Offset);
  713. i<StaticServicesCount;
  714. i++, StaticSvInfop++) {
  715. GetNextStaticService(EnumHandle, StaticSvInfop);
  716. }
  717. // Close the enumeration handle
  718. CloseStaticServicesEnumHandle(EnumHandle);
  719. }
  720. // static netbios names toc + info entries
  721. if(NetbiosNamesCount) {
  722. // static netbios names toc entry
  723. tocep++;
  724. tocep->InfoType = IPX_STATIC_NETBIOS_NAME_INFO_TYPE;
  725. tocep->InfoSize = sizeof(IPX_STATIC_NETBIOS_NAME_INFO);
  726. tocep->Count = NetbiosNamesCount;
  727. tocep->Offset = NextInfoOffset;
  728. NextInfoOffset += tocep->Count * tocep->InfoSize;
  729. NetbiosNamesInfop = (PIPX_STATIC_NETBIOS_NAME_INFO)((PUCHAR)ibhp + tocep->Offset);
  730. rc = FwGetStaticNetbiosNames(icbp->InterfaceIndex,
  731. &NetbiosNamesCount,
  732. NetbiosNamesInfop);
  733. if(rc != NO_ERROR) {
  734. RELEASE_DATABASE_LOCK;
  735. return rc;
  736. }
  737. }
  738. if(InFltInfoSize) {
  739. // traffic filter input global info
  740. tocep++;
  741. tocep->InfoType = IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE;
  742. tocep->InfoSize = sizeof(IPX_TRAFFIC_FILTER_GLOBAL_INFO);
  743. tocep->Count = 1;
  744. tocep->Offset = NextInfoOffset;
  745. NextInfoOffset += tocep->Count * tocep->InfoSize;
  746. InFltGlInfo = (PIPX_TRAFFIC_FILTER_GLOBAL_INFO)((PUCHAR)ibhp + tocep->Offset);
  747. rc = GetFilters(icbp->InterfaceIndex,
  748. IPX_TRAFFIC_FILTER_INBOUND,
  749. &InFltAction,
  750. &InFltSize,
  751. (LPBYTE)InterfaceInfop+NextInfoOffset,
  752. &InFltInfoSize);
  753. if(rc != NO_ERROR) {
  754. RELEASE_DATABASE_LOCK;
  755. return rc;
  756. }
  757. InFltGlInfo->FilterAction = InFltAction;
  758. // traffic filter input global info
  759. tocep++;
  760. tocep->InfoType = IPX_IN_TRAFFIC_FILTER_INFO_TYPE;
  761. tocep->InfoSize = InFltSize;
  762. tocep->Count = InFltInfoSize/InFltSize;
  763. tocep->Offset = NextInfoOffset;
  764. NextInfoOffset += tocep->Count * tocep->InfoSize;
  765. }
  766. if(OutFltInfoSize) {
  767. // traffic filter input global info
  768. tocep++;
  769. tocep->InfoType = IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE;
  770. tocep->InfoSize = sizeof(IPX_TRAFFIC_FILTER_GLOBAL_INFO);
  771. tocep->Count = 1;
  772. tocep->Offset = NextInfoOffset;
  773. NextInfoOffset += tocep->Count * tocep->InfoSize;
  774. OutFltGlInfo = (PIPX_TRAFFIC_FILTER_GLOBAL_INFO)((PUCHAR)ibhp + tocep->Offset);
  775. rc = GetFilters(icbp->InterfaceIndex,
  776. IPX_TRAFFIC_FILTER_OUTBOUND,
  777. &OutFltAction,
  778. &OutFltSize,
  779. (LPBYTE)InterfaceInfop+NextInfoOffset,
  780. &OutFltInfoSize);
  781. if(rc != NO_ERROR) {
  782. RELEASE_DATABASE_LOCK;
  783. return rc;
  784. }
  785. OutFltGlInfo->FilterAction = OutFltAction;
  786. // traffic filter input global info
  787. tocep++;
  788. tocep->InfoType = IPX_OUT_TRAFFIC_FILTER_INFO_TYPE;
  789. tocep->InfoSize = OutFltSize;
  790. tocep->Count = OutFltInfoSize/OutFltSize;
  791. tocep->Offset = NextInfoOffset;
  792. NextInfoOffset += tocep->Count * tocep->InfoSize;
  793. }
  794. RELEASE_DATABASE_LOCK;
  795. return NO_ERROR;
  796. }
  797. /*++
  798. Function: SetInterfaceInfo
  799. Descr:
  800. --*/
  801. DWORD
  802. SetInterfaceInfo(
  803. IN HANDLE InterfaceIndex,
  804. IN LPVOID InterfaceInfop)
  805. {
  806. PICB icbp;
  807. PIPX_IF_INFO IpxIfInfop;
  808. PIPXWAN_IF_INFO IpxwanIfInfop;
  809. PIPX_STATIC_ROUTE_INFO NewStaticRtInfop;
  810. PIPX_STATIC_SERVICE_INFO NewStaticSvInfop;
  811. PIPX_INFO_BLOCK_HEADER IfInfop = (PIPX_INFO_BLOCK_HEADER)InterfaceInfop;
  812. PIPX_TOC_ENTRY tocep;
  813. DWORD rc = NO_ERROR;
  814. HANDLE EnumHandle;
  815. FW_IF_INFO FwIfInfo;
  816. PIPX_STATIC_NETBIOS_NAME_INFO StaticNbInfop;
  817. PIPX_TRAFFIC_FILTER_GLOBAL_INFO InFltGlInfo, OutFltGlInfo;
  818. ACQUIRE_DATABASE_LOCK;
  819. if(RouterOperState != OPER_STATE_UP) {
  820. RELEASE_DATABASE_LOCK;
  821. return ERROR_CAN_NOT_COMPLETE;
  822. }
  823. if((icbp = GetInterfaceByIndex(PtrToUlong(InterfaceIndex))) == NULL) {
  824. RELEASE_DATABASE_LOCK;
  825. return ERROR_INVALID_HANDLE;
  826. }
  827. SS_ASSERT(!memcmp(&icbp->Signature, InterfaceSignature, 4));
  828. // check if there was a change in the interface info block
  829. if(IfInfop == NULL) {
  830. RELEASE_DATABASE_LOCK;
  831. return NO_ERROR;
  832. }
  833. // check that we have all the mandatory info blocks
  834. if(((IpxIfInfop = (PIPX_IF_INFO)GetInfoEntry(InterfaceInfop, IPX_INTERFACE_INFO_TYPE)) == NULL) ||
  835. ((IpxwanIfInfop = (PIPXWAN_IF_INFO)GetInfoEntry(InterfaceInfop, IPXWAN_INTERFACE_INFO_TYPE)) == NULL)) {
  836. RELEASE_DATABASE_LOCK;
  837. // invalid info
  838. return ERROR_INVALID_PARAMETER;
  839. }
  840. if(SetRoutingProtocolsInterfaces(InterfaceInfop,
  841. icbp->InterfaceIndex) != NO_ERROR) {
  842. RELEASE_DATABASE_LOCK;
  843. // invalid info
  844. return ERROR_INVALID_PARAMETER;
  845. }
  846. // set ipx if info changes
  847. if(icbp->AdminState != IpxIfInfop->AdminState) {
  848. if(IpxIfInfop->AdminState == ADMIN_STATE_ENABLED) {
  849. AdminEnable(icbp);
  850. }
  851. else
  852. {
  853. AdminDisable(icbp);
  854. }
  855. }
  856. FwIfInfo.NetbiosAccept = IpxIfInfop->NetbiosAccept;
  857. FwIfInfo.NetbiosDeliver = IpxIfInfop->NetbiosDeliver;
  858. FwSetInterface(icbp->InterfaceIndex, &FwIfInfo);
  859. // set IPXWAN info changes
  860. icbp->EnableIpxWanNegotiation = IpxwanIfInfop->AdminState;
  861. // set static routes
  862. if((tocep = GetTocEntry(InterfaceInfop, IPX_STATIC_ROUTE_INFO_TYPE)) == NULL) {
  863. // no static routes
  864. // delete them if we've got them
  865. if(GetStaticRoutesCount(icbp->InterfaceIndex)) {
  866. DeleteAllStaticRoutes(icbp->InterfaceIndex);
  867. }
  868. }
  869. else
  870. {
  871. // delete non-present ones and add new ones
  872. NewStaticRtInfop = (PIPX_STATIC_ROUTE_INFO)GetInfoEntry(InterfaceInfop, IPX_STATIC_ROUTE_INFO_TYPE);
  873. // Create static routes enumeration handle for this interface
  874. EnumHandle = CreateStaticRoutesEnumHandle(icbp->InterfaceIndex);
  875. if(UpdateStaticIfEntries(icbp,
  876. EnumHandle,
  877. sizeof(IPX_STATIC_ROUTE_INFO),
  878. tocep->Count, // number of routes in the new info
  879. NewStaticRtInfop,
  880. GetNextStaticRoute,
  881. DeleteStaticRoute,
  882. CreateStaticRoute)) {
  883. // Close the enumeration handle
  884. CloseStaticRoutesEnumHandle(EnumHandle);
  885. rc = ERROR_GEN_FAILURE;
  886. goto UpdateFailure;
  887. }
  888. // Close the enumeration handle
  889. CloseStaticRoutesEnumHandle(EnumHandle);
  890. }
  891. // set static services
  892. if((tocep = GetTocEntry(InterfaceInfop, IPX_STATIC_SERVICE_INFO_TYPE)) == NULL) {
  893. // no static services
  894. // delete them if we've got them
  895. if(GetStaticServicesCount(icbp->InterfaceIndex)) {
  896. DeleteAllStaticServices(icbp->InterfaceIndex);
  897. }
  898. }
  899. else
  900. {
  901. // delete non-present ones and add new ones
  902. NewStaticSvInfop = (PIPX_STATIC_SERVICE_INFO)GetInfoEntry(InterfaceInfop, IPX_STATIC_SERVICE_INFO_TYPE);
  903. // Create static services enumeration handle for this interface
  904. EnumHandle = CreateStaticServicesEnumHandle(icbp->InterfaceIndex);
  905. if(UpdateStaticIfEntries(icbp,
  906. EnumHandle,
  907. sizeof(IPX_STATIC_SERVICE_INFO),
  908. tocep->Count, // number of services in the new info
  909. NewStaticSvInfop,
  910. GetNextStaticService,
  911. DeleteStaticService,
  912. CreateStaticService)) {
  913. // Close the enumeration handle
  914. CloseStaticServicesEnumHandle(EnumHandle);
  915. rc = ERROR_GEN_FAILURE;
  916. goto UpdateFailure;
  917. }
  918. // Close the enumeration handle
  919. CloseStaticServicesEnumHandle(EnumHandle);
  920. }
  921. // set static netbios names
  922. if((tocep = GetTocEntry(InterfaceInfop, IPX_STATIC_NETBIOS_NAME_INFO_TYPE)) == NULL) {
  923. // no static netbios names
  924. FwSetStaticNetbiosNames(icbp->InterfaceIndex,
  925. 0,
  926. NULL);
  927. }
  928. else
  929. {
  930. // set the new ones
  931. StaticNbInfop = (PIPX_STATIC_NETBIOS_NAME_INFO)GetInfoEntry(InterfaceInfop,
  932. IPX_STATIC_NETBIOS_NAME_INFO_TYPE);
  933. FwSetStaticNetbiosNames(icbp->InterfaceIndex,
  934. tocep->Count,
  935. StaticNbInfop);
  936. }
  937. // Seed the traffic filters
  938. if ((tocep = GetTocEntry(InterfaceInfop, IPX_IN_TRAFFIC_FILTER_INFO_TYPE))!=NULL) {
  939. if ((InFltGlInfo = GetInfoEntry(InterfaceInfop, IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE)) == NULL) {
  940. IF_LOG (EVENTLOG_ERROR_TYPE) {
  941. RouterLogErrorDataW (RMEventLogHdl,
  942. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  943. 1, &icbp->InterfaceNamep, 0, NULL);
  944. }
  945. Trace(INTERFACE_TRACE, "SetInterface: Bad input filters config info");
  946. goto UpdateFailure;
  947. }
  948. if (SetFilters(icbp->InterfaceIndex,
  949. IPX_TRAFFIC_FILTER_INBOUND,
  950. InFltGlInfo->FilterAction, // pass or don't pass
  951. tocep->InfoSize, // filter size
  952. (LPBYTE)InterfaceInfop+tocep->Offset,
  953. tocep->InfoSize*tocep->Count) != NO_ERROR) {
  954. IF_LOG (EVENTLOG_ERROR_TYPE) {
  955. RouterLogErrorDataW (RMEventLogHdl,
  956. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  957. 1, &icbp->InterfaceNamep, 0, NULL);
  958. }
  959. Trace(INTERFACE_TRACE, "SetInterface: Bad input filters config info");
  960. goto UpdateFailure;
  961. }
  962. }
  963. else { // No Filters -> delete all
  964. if (SetFilters(icbp->InterfaceIndex,
  965. IPX_TRAFFIC_FILTER_INBOUND, // in or outbound,
  966. 0, // pass or don't pass
  967. 0, // filter size
  968. NULL,
  969. 0)!=NO_ERROR) {
  970. Trace(INTERFACE_TRACE, "SetInterface: Could not delete input filters");
  971. goto UpdateFailure;
  972. }
  973. }
  974. if ((tocep = GetTocEntry(InterfaceInfop, IPX_OUT_TRAFFIC_FILTER_INFO_TYPE))!=NULL) {
  975. if ((OutFltGlInfo = GetInfoEntry(InterfaceInfop, IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE)) == NULL) {
  976. IF_LOG (EVENTLOG_ERROR_TYPE) {
  977. RouterLogErrorDataW (RMEventLogHdl,
  978. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  979. 1, &icbp->InterfaceNamep, 0, NULL);
  980. }
  981. Trace(INTERFACE_TRACE, "SetInterface: Bad output filters config info");
  982. goto UpdateFailure;
  983. }
  984. if (SetFilters(icbp->InterfaceIndex,
  985. IPX_TRAFFIC_FILTER_OUTBOUND,
  986. OutFltGlInfo->FilterAction, // pass or don't pass
  987. tocep->InfoSize, // filter size
  988. (LPBYTE)InterfaceInfop+tocep->Offset,
  989. tocep->InfoSize*tocep->Count) != NO_ERROR) {
  990. IF_LOG (EVENTLOG_ERROR_TYPE) {
  991. RouterLogErrorDataW (RMEventLogHdl,
  992. ROUTERLOG_IPX_BAD_INTERFACE_CONFIG,
  993. 1, &icbp->InterfaceNamep, 0, NULL);
  994. }
  995. Trace(INTERFACE_TRACE, "SetInterface: Bad output filters config info");
  996. goto UpdateFailure;
  997. }
  998. }
  999. else { // No Filters -> delete all
  1000. if (SetFilters(icbp->InterfaceIndex,
  1001. IPX_TRAFFIC_FILTER_OUTBOUND, // in or outbound,
  1002. 0, // pass or don't pass
  1003. 0, // filter size
  1004. NULL,
  1005. 0)!=NO_ERROR) {
  1006. Trace(INTERFACE_TRACE, "SetInterface: Could not delete output filters");
  1007. goto UpdateFailure;
  1008. }
  1009. }
  1010. RELEASE_DATABASE_LOCK;
  1011. return NO_ERROR;
  1012. UpdateFailure:
  1013. RELEASE_DATABASE_LOCK;
  1014. return rc;
  1015. }
  1016. /*++
  1017. Function: InterfaceNotReachable
  1018. Descr: Called in the following cases:
  1019. 1. Following a ConnectInterface request from the Router Manager,
  1020. to indicate that the connection atempt has failed.
  1021. 2. When DIM realizes it won't be able to execute any further
  1022. ConnectInterface requests because of out of resources.
  1023. --*/
  1024. DWORD
  1025. InterfaceNotReachable(
  1026. IN HANDLE InterfaceIndex,
  1027. IN UNREACHABILITY_REASON Reason)
  1028. {
  1029. PICB icbp;
  1030. Trace(INTERFACE_TRACE, "IpxRM: InterfaceNotReachable: Entered for if # %d\n",
  1031. InterfaceIndex);
  1032. ACQUIRE_DATABASE_LOCK;
  1033. if(RouterOperState != OPER_STATE_UP) {
  1034. RELEASE_DATABASE_LOCK;
  1035. return ERROR_CAN_NOT_COMPLETE;
  1036. }
  1037. if((icbp = GetInterfaceByIndex(PtrToUlong(InterfaceIndex))) == NULL) {
  1038. // interface has been removed
  1039. RELEASE_DATABASE_LOCK;
  1040. return ERROR_INVALID_PARAMETER;
  1041. }
  1042. if(icbp->ConnectionRequestPending) {
  1043. icbp->ConnectionRequestPending = FALSE;
  1044. // notify the forwarder of the connection failure
  1045. FwConnectionRequestFailed(icbp->InterfaceIndex);
  1046. }
  1047. // if there is reason to stop advertising routes/services on this if
  1048. // because it can't be reached in the future, do it!
  1049. if(icbp->InterfaceReachable)
  1050. {
  1051. icbp->InterfaceReachable = FALSE;
  1052. // stop advertising static routes on this interface
  1053. DisableStaticRoutes(icbp->InterfaceIndex);
  1054. // disable the interface for all routing prot and fw
  1055. // this will stop advertising any static services
  1056. ExternalDisableInterface(icbp->InterfaceIndex);
  1057. }
  1058. RELEASE_DATABASE_LOCK;
  1059. return NO_ERROR;
  1060. }
  1061. /*++
  1062. Function: InterfaceReachable
  1063. Descr: Called by DIM following a previous InterfaceNotReachable to
  1064. indicate that conditions are met to do connections on this if.
  1065. --*/
  1066. DWORD
  1067. InterfaceReachable(
  1068. IN HANDLE InterfaceIndex)
  1069. {
  1070. PICB icbp;
  1071. Trace(INTERFACE_TRACE, "IpxRM: InterfaceReachable: Entered for if # %d\n",
  1072. InterfaceIndex);
  1073. ACQUIRE_DATABASE_LOCK;
  1074. if(RouterOperState != OPER_STATE_UP) {
  1075. return ERROR_CAN_NOT_COMPLETE;
  1076. }
  1077. if((icbp = GetInterfaceByIndex(PtrToUlong(InterfaceIndex))) == NULL) {
  1078. // interface has been removed
  1079. RELEASE_DATABASE_LOCK;
  1080. return ERROR_INVALID_PARAMETER;
  1081. }
  1082. if(!icbp->InterfaceReachable) {
  1083. icbp->InterfaceReachable = TRUE;
  1084. if(icbp->AdminState == ADMIN_STATE_ENABLED) {
  1085. // enable all static routes for this interface
  1086. EnableStaticRoutes(icbp->InterfaceIndex);
  1087. // enable external interfaces. Implicitly, this will enable static services
  1088. // bound to this interface to be advertised
  1089. ExternalEnableInterface(icbp->InterfaceIndex);
  1090. }
  1091. }
  1092. RELEASE_DATABASE_LOCK;
  1093. return NO_ERROR;
  1094. }
  1095. DWORD APIENTRY
  1096. InterfaceConnected (
  1097. IN HANDLE hInterface,
  1098. IN PVOID pFilter,
  1099. IN PVOID pPppProjectionResult
  1100. ) {
  1101. return NO_ERROR;
  1102. }
  1103. VOID
  1104. DestroyAllInterfaces(VOID)
  1105. {
  1106. PICB icbp;
  1107. while(!IsListEmpty(&IndexIfList)) {
  1108. icbp = CONTAINING_RECORD(IndexIfList.Flink, ICB, IndexListLinkage);
  1109. // remove the if from the data base
  1110. RemoveIfFromDB(icbp);
  1111. Trace(INTERFACE_TRACE, "DestroyAllInterfaces: destroyed interface %d\n", icbp->InterfaceIndex);
  1112. GlobalFree(icbp);
  1113. // decrement the interface counter
  1114. InterfaceCount--;
  1115. }
  1116. }