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.

1854 lines
46 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\rtm\rtmdlg.c
  5. Abstract:
  6. Interactive test code for RTM dll
  7. Author:
  8. Vadim Eydelman
  9. Revision History:
  10. --*/
  11. #ifndef NT_INCLUDED
  12. #include <nt.h>
  13. #endif
  14. #ifndef _NTRTL_
  15. #include <ntrtl.h>
  16. #endif
  17. #ifndef _NTURTL_
  18. #include <nturtl.h>
  19. #endif
  20. #include <windows.h>
  21. #ifndef _WINSOCKAPI_
  22. #include <winsock.h>
  23. #endif
  24. #ifndef _WSIPX_
  25. #include <wsipx.h>
  26. #endif
  27. #ifndef _WSNWLINK_
  28. #include <wsnwlink.h>
  29. #endif
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #ifndef _ROUTING_RTM_
  33. #include "RTM.h"
  34. #endif
  35. #ifndef _ROUTING_RMRTM_
  36. #include "RMRTM.h"
  37. #endif
  38. #include "cldlg.h"
  39. #include "enumdlg.h"
  40. #if DBG
  41. #define ASSERTERR(exp) \
  42. if (!(exp)) { \
  43. DbgPrint("Get last error= %d\n", GetLastError ()); \
  44. RtlAssert( #exp, __FILE__, __LINE__, NULL ); \
  45. }
  46. #define ASSERTERRMSG(msg,exp) \
  47. if (!(exp)) { \
  48. DbgPrint("Get last error= %d\n", GetLastError ()); \
  49. RtlAssert( #exp, __FILE__, __LINE__, msg ); \
  50. }
  51. #else
  52. #define ASSERTERR(exp)
  53. #define ASSERTERRMSG(msg,exp)
  54. #endif
  55. // Basic route info, present in routes of all types
  56. typedef struct {
  57. ROUTE_HEADER;
  58. } RTM_XX_ROUTE, *PRTM_XX_ROUTE;
  59. typedef union _RTM_ROUTE {
  60. RTM_XX_ROUTE XX;
  61. RTM_IP_ROUTE IP;
  62. RTM_IPX_ROUTE IPX;
  63. } RTM_ROUTE, *PRTM_ROUTE;
  64. #define XX_INTERFACE XX.RR_InterfaceID
  65. #define XX_PROTOCOL XX.RR_RoutingProtocol
  66. #define XX_TIMESTAMP XX.RR_TimeStamp
  67. #define IP_PROTOCOL IP.RR_RoutingProtocol
  68. #define IP_INTERFACE IP.RR_InterfaceID
  69. #define IP_METRIC IP.RR_FamilySpecificData.FSD_Metric1
  70. #define IP_TIMESTAMP IP.RR_TimeStamp
  71. #define IP_NET_NUM IP.RR_Network.N_NetNumber
  72. #define IP_NET_MSK IP.RR_Network.N_NetMask
  73. #define IP_NEXT_HOP_NUM IP.RR_NextHopAddress.N_NetNumber
  74. #define IP_NEXT_HOP_MSK IP.RR_NextHopAddress.N_NetMask
  75. #define IP_ADPTER_INDEX IP.RR_FamilySpecificData.FSD_AdapterIndex
  76. #define IP_PROTOCOL_METRIC IP.RR_FamilySpecificData.FSD_ProtocolMetric
  77. #define IP_PSD IP.RR_ProtocolSpecificData
  78. #define IPX_PROTOCOL IPX.RR_RoutingProtocol
  79. #define IPX_INTERFACE IPX.RR_InterfaceID
  80. #define IPX_METRIC IPX.RR_FamilySpecificData.FSD_Ticks
  81. #define IPX_TIMESTAMP IPX.RR_TimeStamp
  82. #define IPX_NET_NUM IPX.RR_Network.N_NetNumber
  83. #define IPX_NEXT_HOP_MAC IPX.RR_NextHopAddress.NHA_Mac
  84. #define IPX_HOP_COUNT IPX.RR_FamilySpecificData.FSD_HopCount
  85. #define IPX_PSD IPX.RR_ProtocolSpecificData
  86. typedef struct _ENABLE_DLG_GROUP_PARAM {
  87. HWND hCtlFirst;
  88. BOOLEAN foundFirst;
  89. BOOLEAN enableFlag;
  90. } ENABLE_DLG_GROUP_PARAM, *PENABLE_DLG_GROUP_PARAM;
  91. HANDLE *Clients;
  92. HANDLE *Events;
  93. HANDLE hDLLInstance;
  94. HANDLE *InteractiveThreads;
  95. HANDLE *IPXRIPThreads;
  96. SOCKET *Sockets;
  97. HANDLE *Enums;
  98. DWORD WINAPI
  99. ClientThread (
  100. LPVOID param
  101. );
  102. BOOL CALLBACK
  103. ClientDlgProc (
  104. HWND hDlg,
  105. UINT uMsg,
  106. WPARAM wParam,
  107. LPARAM lParam
  108. );
  109. BOOL CALLBACK
  110. DoEnable (
  111. HWND hwnd, // handle of child window
  112. LPARAM lParam // application-defined value
  113. );
  114. VOID
  115. EnableDlgGroup (
  116. HWND hDlg,
  117. HWND hCtlFirst,
  118. BOOLEAN enable
  119. );
  120. VOID
  121. DoRegister (
  122. HWND hDlg,
  123. LONG idx
  124. );
  125. VOID
  126. DoDeregister (
  127. HWND hDlg,
  128. LONG idx
  129. );
  130. VOID
  131. SetupAdd (
  132. HWND hDlg
  133. );
  134. VOID
  135. SetupDelete (
  136. HWND hDlg
  137. );
  138. VOID
  139. SetupDequeue (
  140. HWND hDlg
  141. );
  142. VOID
  143. SetupSetEnable (
  144. HWND hDlg
  145. );
  146. VOID
  147. SetupConvert (
  148. HWND hDlg
  149. );
  150. VOID
  151. DoOperation (
  152. HWND hDlg,
  153. LONG idx
  154. );
  155. DWORD WINAPI
  156. IPXRIPListenThread (
  157. LPVOID param
  158. );
  159. DWORD WINAPI
  160. EnumThread (
  161. LPVOID param
  162. );
  163. BOOL CALLBACK
  164. EnumDlgProc (
  165. HWND hDlg,
  166. UINT uMsg,
  167. WPARAM wParam,
  168. LPARAM lParam
  169. );
  170. VOID
  171. GetCriteria (
  172. HWND hDlg,
  173. DWORD *ProtocolFamily,
  174. DWORD *flags,
  175. PRTM_ROUTE Route
  176. );
  177. VOID
  178. GetLastRoute (
  179. HWND hDlg,
  180. DWORD ProtocolFamily,
  181. PRTM_ROUTE Route
  182. );
  183. VOID
  184. DisplayRoute (
  185. HWND hDlg,
  186. DWORD ProtocolFamily,
  187. PRTM_ROUTE Route
  188. );
  189. INT
  190. IPNetCmp (
  191. PVOID Net1,
  192. PVOID Net2
  193. ) {
  194. #define IPNet1 ((PIP_NETWORK)Net1)
  195. #define IPNet2 ((PIP_NETWORK)Net2)
  196. if (IPNet1->N_NetNumber>IPNet2->N_NetNumber)
  197. return 1;
  198. else if (IPNet1->N_NetNumber<IPNet2->N_NetNumber)
  199. return -1;
  200. else if (IPNet1->N_NetMask==IPNet2->N_NetMask)
  201. return 0;
  202. else if (IPNet1->N_NetMask>IPNet2->N_NetMask)
  203. return 1;
  204. else /*if (IPNet1->N_NetMask<IPNet2->N_NetMask)*/
  205. return -1;
  206. #undef IPNet2
  207. #undef IPNet1
  208. }
  209. INT
  210. IPNhaCmp (
  211. PVOID Route1,
  212. PVOID Route2
  213. ) {
  214. #define IPRoute1 ((PRTM_ROUTE)Route1)
  215. #define IPRoute2 ((PRTM_ROUTE)Route2)
  216. if (IPRoute1->IP_NET_NUM>IPRoute2->IP_NET_NUM)
  217. return 1;
  218. else if (IPRoute1->IP_NET_NUM<IPRoute2->IP_NET_NUM)
  219. return -1;
  220. else if (IPRoute1->IP_NET_MSK==IPRoute2->IP_NET_MSK)
  221. return 0;
  222. else if (IPRoute1->IP_NET_MSK>IPRoute2->IP_NET_MSK)
  223. return 1;
  224. else /*if (IPNet1->IP_NET_MSK<IPNet2->IP_NET_MSK)*/
  225. return -1;
  226. #undef IPRoute2
  227. #undef IPRoute1
  228. }
  229. INT
  230. IPMetricCmp (
  231. PVOID Route1,
  232. PVOID Route2
  233. ) {
  234. #define IPRoute1 ((PRTM_ROUTE)Route1)
  235. #define IPRoute2 ((PRTM_ROUTE)Route2)
  236. if (IPRoute1->IP_METRIC>IPRoute2->IP_METRIC)
  237. return 1;
  238. else if (IPRoute1->IP_METRIC<IPRoute2->IP_METRIC)
  239. return -1;
  240. else
  241. return 0;
  242. #undef IPRoute2
  243. #undef IPRoute1
  244. }
  245. BOOL
  246. IPFsdCmp (
  247. PVOID Route1,
  248. PVOID Route2
  249. ) {
  250. #define IPRoute1 ((PRTM_ROUTE)Route1)
  251. #define IPRoute2 ((PRTM_ROUTE)Route2)
  252. return memcmp (&IPRoute1->IP.RR_FamilySpecificData,
  253. &IPRoute2->IP.RR_FamilySpecificData,
  254. sizeof (IPRoute1->IP.RR_FamilySpecificData))==0;
  255. #undef IPRoute2
  256. #undef IPRoute1
  257. }
  258. INT
  259. IPHash (
  260. PVOID Net
  261. ) {
  262. return (*((PULONG)Net))%257;
  263. }
  264. VOID
  265. IPChange (
  266. DWORD Flags,
  267. PVOID CurBestRoute,
  268. PVOID PrevBestRoute
  269. ) {
  270. fprintf (stderr, "IPRouteChange: Flags=%d, CurBest: %08x, PrevBest: %08x\n",
  271. Flags, CurBestRoute, PrevBestRoute);
  272. }
  273. INT
  274. IPXNetCmp (
  275. PVOID Net1,
  276. PVOID Net2
  277. ) {
  278. #define IPXNet1 ((PIPX_NETWORK)Net1)
  279. #define IPXNet2 ((PIPX_NETWORK)Net2)
  280. if (IPXNet1->N_NetNumber>IPXNet2->N_NetNumber)
  281. return 1;
  282. else if (IPXNet1->N_NetNumber<IPXNet2->N_NetNumber)
  283. return -1;
  284. else
  285. return 0;
  286. #undef IPXNet2
  287. #undef IPXNet1
  288. }
  289. INT
  290. IPXNhaCmp (
  291. PVOID Route1,
  292. PVOID Route2
  293. ) {
  294. #define IPXRoute1 ((PRTM_ROUTE)Route1)
  295. #define IPXRoute2 ((PRTM_ROUTE)Route2)
  296. return memcmp (IPXRoute1->IPX_NEXT_HOP_MAC,
  297. IPXRoute2->IPX_NEXT_HOP_MAC,
  298. sizeof (IPXRoute1->IPX_NEXT_HOP_MAC));
  299. #undef IPXRoute2
  300. #undef IPXRoute1
  301. }
  302. INT
  303. IPXMetricCmp (
  304. PVOID Route1,
  305. PVOID Route2
  306. ) {
  307. #define IPXRoute1 ((PRTM_ROUTE)Route1)
  308. #define IPXRoute2 ((PRTM_ROUTE)Route2)
  309. if (IPXRoute1->IPX_METRIC>IPXRoute2->IPX_METRIC)
  310. return 1;
  311. else if (IPXRoute1->IPX_METRIC<IPXRoute2->IPX_METRIC)
  312. return -1;
  313. else
  314. return 0;
  315. #undef IPXRoute2
  316. #undef IPXRoute1
  317. }
  318. BOOL
  319. IPXFsdCmp (
  320. PVOID Route1,
  321. PVOID Route2
  322. ) {
  323. #define IPXRoute1 ((PRTM_ROUTE)Route1)
  324. #define IPXRoute2 ((PRTM_ROUTE)Route2)
  325. return IPXRoute1->IPX_HOP_COUNT==IPXRoute1->IPX_HOP_COUNT;
  326. #undef IPXRoute2
  327. #undef IPXRoute1
  328. }
  329. INT
  330. IPXHash (
  331. PVOID Net
  332. ) {
  333. return (*((PULONG)Net))%257;
  334. }
  335. VOID
  336. IPXChange (
  337. DWORD Flags,
  338. PVOID CurBestRoute,
  339. PVOID PrevBestRoute
  340. ) {
  341. fprintf (stderr, "IPXRouteChange: Flags=%d, CurBest: %08x, PrevBest: %08x\n",
  342. Flags, CurBestRoute, PrevBestRoute);
  343. }
  344. DWORD
  345. Validate (
  346. PVOID Route
  347. ) {
  348. return NO_ERROR;
  349. }
  350. int _cdecl
  351. main (
  352. int argc,
  353. char **argv
  354. ) {
  355. INT i, n, m, p;
  356. INT id;
  357. DWORD status;
  358. static RTM_PROTOCOL_FAMILY_CONFIG IPXConfig = {
  359. 8*1024*1024,
  360. 257,
  361. sizeof (RTM_IPX_ROUTE),
  362. IPXNetCmp,
  363. IPXNhaCmp,
  364. IPXMetricCmp,
  365. IPXFsdCmp,
  366. IPHash,
  367. Validate,
  368. IPXChange };
  369. static RTM_PROTOCOL_FAMILY_CONFIG IPConfig = {
  370. 8*1024*1024,
  371. 257,
  372. sizeof (RTM_IP_ROUTE),
  373. IPNetCmp,
  374. IPNhaCmp,
  375. IPXMetricCmp,
  376. IPFsdCmp,
  377. IPHash,
  378. Validate,
  379. IPChange };
  380. status = RtmCreateRouteTable (RTM_PROTOCOL_FAMILY_IPX,
  381. &IPXConfig);
  382. ASSERTMSG ("Could not create IPX Route Table ", status == NO_ERROR);
  383. status = RtmCreateRouteTable (RTM_PROTOCOL_FAMILY_IP,
  384. &IPConfig);
  385. ASSERTMSG ("Could not create IPX Route Table ", status == NO_ERROR);
  386. if (argc>=4) {
  387. n = atoi (argv[1]);
  388. p = atoi (argv[2]);
  389. m = atoi (argv[3]);
  390. Clients = (HANDLE *)GlobalAlloc (GMEM_FIXED, n*sizeof (HANDLE));
  391. ASSERTERR (Clients!=NULL);
  392. Events = (HANDLE *)GlobalAlloc (GMEM_FIXED, n*sizeof (HANDLE));
  393. ASSERTERR (Events!=NULL);
  394. Enums = (HANDLE *)GlobalAlloc (GMEM_FIXED, p*sizeof (HANDLE));
  395. ASSERTERR (Events!=NULL);
  396. InteractiveThreads = (HANDLE *)GlobalAlloc (GMEM_FIXED, (n+p)*sizeof (HANDLE));
  397. ASSERTERR (InteractiveThreads!=NULL);
  398. hDLLInstance = LoadLibrary ("rtm.dll");
  399. ASSERTERR (hDLLInstance!=NULL);
  400. if (m>0) {
  401. INT m1;
  402. WORD wVersionRequested;
  403. WSADATA wsaData;
  404. INT err, length;
  405. SOCKADDR_IPX addr;
  406. SOCKET s;
  407. IPX_ADDRESS_DATA adptData;
  408. BOOL flag;
  409. wVersionRequested = MAKEWORD( 1, 1 );
  410. err = WSAStartup( wVersionRequested, &wsaData );
  411. ASSERT (err==NO_ERROR);
  412. s = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
  413. ASSERTERR (s!=INVALID_SOCKET);
  414. memset (&addr, 0, sizeof (addr));
  415. addr.sa_family = AF_IPX;
  416. status = bind (s, (PSOCKADDR)&addr, sizeof (addr));
  417. ASSERTERRMSG ("Can't bind to default address.\n", status==0);
  418. // Get number of available adapters
  419. length = sizeof (INT);
  420. status = getsockopt (s,
  421. NSPROTO_IPX,
  422. IPX_MAX_ADAPTER_NUM,
  423. (PUCHAR)&m1,
  424. &length);
  425. ASSERTERRMSG ("Can't get number of adapters.", status==0);
  426. ASSERTMSG ("No adapters available", m1>0);
  427. if (m>m1)
  428. m = m1;
  429. IPXRIPThreads = (HANDLE *)GlobalAlloc (GMEM_FIXED, m*sizeof(HANDLE));
  430. ASSERTERR (IPXRIPThreads!=NULL);
  431. Sockets = (SOCKET *)GlobalAlloc (GMEM_FIXED, m*sizeof (SOCKET));
  432. ASSERTERR (Sockets!=NULL);
  433. for (i=0; i<m; i++) {
  434. Sockets[i] = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
  435. ASSERTERR (Sockets[i]!=INVALID_SOCKET);
  436. flag = TRUE;
  437. status = setsockopt (Sockets[i],
  438. SOL_SOCKET,
  439. SO_BROADCAST,
  440. (PCHAR)&flag,
  441. sizeof (BOOL));
  442. ASSERTERRMSG ("Can't set socket broadcast option.", status==0);
  443. flag = TRUE;
  444. status = setsockopt (Sockets[i],
  445. NSPROTO_IPX,
  446. IPX_RECEIVE_BROADCAST,
  447. (PCHAR)&flag,
  448. sizeof (BOOL));
  449. ASSERTERRMSG ("Can't set IPX broadcast option.", status==0);
  450. flag = TRUE;
  451. status = setsockopt (Sockets[i],
  452. NSPROTO_IPX,
  453. IPX_RECVHDR,
  454. (PCHAR)&flag,
  455. sizeof (BOOL));
  456. ASSERTERRMSG ("Can't set receive header option.", status==0);
  457. length = sizeof (adptData);
  458. adptData.adapternum = i;
  459. status = getsockopt (s,
  460. NSPROTO_IPX,
  461. IPX_ADDRESS,
  462. (PCHAR)&adptData,
  463. &length);
  464. ASSERTERRMSG ("Can't get adapter parameters.", status==0);
  465. memcpy (&addr.sa_netnum, &adptData.netnum, sizeof (addr.sa_netnum));
  466. fprintf (stderr,
  467. "IPX RIP Listener # %d: Net=%02x%02x%02x%02x\n",
  468. i, (UCHAR)addr.sa_netnum[0],
  469. (UCHAR)addr.sa_netnum[1],
  470. (UCHAR)addr.sa_netnum[2],
  471. (UCHAR)addr.sa_netnum[3]);
  472. memcpy (&addr.sa_nodenum, &adptData.nodenum, sizeof (addr.sa_nodenum));
  473. fprintf (stderr,
  474. "IPX RIP Listener # %d: Node=%02x%02x%02x%02x%02x%02x\n",
  475. i, (UCHAR)addr.sa_nodenum[0],
  476. (UCHAR)addr.sa_nodenum[1],
  477. (UCHAR)addr.sa_nodenum[2],
  478. (UCHAR)addr.sa_nodenum[3],
  479. (UCHAR)addr.sa_nodenum[4],
  480. (UCHAR)addr.sa_nodenum[5]);
  481. addr.sa_family = AF_IPX;
  482. addr.sa_socket = htons (0x452);
  483. status = bind (Sockets[i], (PSOCKADDR)&addr, sizeof(addr));
  484. ASSERTERRMSG ("Can't bind to adapter's address.", status==0);
  485. IPXRIPThreads[i] = CreateThread (NULL,
  486. 0,
  487. &IPXRIPListenThread,
  488. (LPVOID)i,
  489. 0,
  490. &id);
  491. ASSERTERR (IPXRIPThreads[i]!=NULL);
  492. }
  493. closesocket (s);
  494. }
  495. for (i=0; i<n; i++) {
  496. InteractiveThreads[i] = CreateThread (NULL,
  497. 0,
  498. &ClientThread,
  499. (LPVOID)i,
  500. 0,
  501. &id);
  502. ASSERTERR (InteractiveThreads[i]!=NULL);
  503. }
  504. for (i=0; i<p ; i++) {
  505. InteractiveThreads[n+i] = CreateThread (NULL,
  506. 0,
  507. &EnumThread,
  508. (LPVOID)i,
  509. 0,
  510. &id);
  511. ASSERTERR (InteractiveThreads[n+i]!=NULL);
  512. }
  513. WaitForMultipleObjects (n+p, InteractiveThreads, TRUE, INFINITE);
  514. if (m>0) {
  515. for (i=0; i<m; i++)
  516. closesocket (Sockets[i]);
  517. status = WaitForMultipleObjects (m, IPXRIPThreads, TRUE, 5*1000);
  518. if (status==WAIT_TIMEOUT) {
  519. for (i=0; i<m; i++)
  520. TerminateThread (IPXRIPThreads[i], 0);
  521. }
  522. for (i=0; i<m; i++)
  523. CloseHandle (IPXRIPThreads[i]);
  524. }
  525. for (i=0; i<=n; i++)
  526. CloseHandle (InteractiveThreads[i]);
  527. FreeLibrary (hDLLInstance);
  528. WSACleanup ();
  529. }
  530. else
  531. fprintf (stderr,
  532. "Usage: %s <n_of_clients> <n_of_enumerators> <max_rip_listeners>\n",
  533. argv[0]);
  534. RtmDeleteRouteTable (RTM_PROTOCOL_FAMILY_IP);
  535. RtmDeleteRouteTable (RTM_PROTOCOL_FAMILY_IPX);
  536. return 0;
  537. }
  538. #define idx ((LONG)param)
  539. DWORD WINAPI
  540. ClientThread (
  541. LPVOID param
  542. ) {
  543. MSG msg;
  544. DWORD status;
  545. HWND ClientDlg;
  546. char buf[16];
  547. BOOLEAN done = FALSE;
  548. Clients[idx] = NULL;
  549. Events[idx] = CreateEvent (NULL, FALSE, FALSE, NULL);
  550. ASSERTERR (Events[idx]!=NULL);
  551. // Create dialog window
  552. ClientDlg = CreateDialogParam (hDLLInstance,
  553. MAKEINTRESOURCE(IDD_RTM_CLIENT),
  554. NULL,
  555. &ClientDlgProc,
  556. (LPARAM)idx);
  557. ASSERTERR (ClientDlg!=NULL);
  558. sprintf (buf, "Client # %d", idx+1);
  559. SetWindowText (ClientDlg, buf);
  560. while (!done) {
  561. status = MsgWaitForMultipleObjects (
  562. 1,
  563. &Events[idx],
  564. FALSE,
  565. 1000,
  566. QS_ALLINPUT
  567. );
  568. ASSERTERR (status!=0xFFFFFFFF);
  569. if (status==WAIT_OBJECT_0) {
  570. if (IsWindow (ClientDlg) && (Clients[idx]!=NULL))
  571. EnableWindow (GetDlgItem (ClientDlg, IDR_DEQUEUE_C), TRUE);
  572. else
  573. ASSERTMSG ("Event signalled to dead client or closed window ", FALSE);
  574. }
  575. while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  576. if (msg.message!=WM_QUIT) {
  577. if (!IsWindow(ClientDlg)
  578. || !IsDialogMessage(ClientDlg, &msg)) {
  579. TranslateMessage (&msg);
  580. DispatchMessage (&msg);
  581. }
  582. }
  583. else
  584. done = TRUE;
  585. }
  586. }
  587. if (IsWindow (ClientDlg)) {
  588. DestroyWindow (ClientDlg);
  589. ClientDlg = NULL;
  590. }
  591. CloseHandle (Events[idx]);
  592. return msg.wParam;
  593. }
  594. #undef idx
  595. BOOL CALLBACK
  596. ClientDlgProc (
  597. HWND hDlg,
  598. UINT uMsg,
  599. WPARAM wParam,
  600. LPARAM lParam
  601. ) {
  602. BOOL res = FALSE;
  603. LONG idx;
  604. idx = GetWindowLong (hDlg, DWL_USER)-1;
  605. switch (uMsg) {
  606. case WM_INITDIALOG: // Dialog is being created
  607. idx = lParam+1;
  608. SetWindowLong (hDlg, DWL_USER, idx);
  609. ASSERTERR (GetLastError ()==NO_ERROR);
  610. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), FALSE);
  611. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_REQUEST_C), FALSE);
  612. SendDlgItemMessage (hDlg,
  613. IDC_PROTOCOL_FAMILY_C,
  614. CB_INSERTSTRING,
  615. RTM_PROTOCOL_FAMILY_IPX,
  616. (LPARAM)"IPX"
  617. );
  618. SendDlgItemMessage (hDlg,
  619. IDC_PROTOCOL_FAMILY_C,
  620. CB_INSERTSTRING,
  621. RTM_PROTOCOL_FAMILY_IP,
  622. (LPARAM)"IP"
  623. );
  624. SendDlgItemMessage (hDlg,
  625. IDC_PROTOCOL_FAMILY_C,
  626. CB_SETCURSEL,
  627. 0,
  628. 0
  629. );
  630. SetDlgItemText (hDlg, IDB_REGISTER_OP_C, "Register");
  631. res = TRUE;
  632. break;
  633. case WM_COMMAND: // Process child window messages only
  634. switch (LOWORD(wParam)) {
  635. case IDCANCEL:
  636. PostQuitMessage (0);
  637. res = TRUE;
  638. break;
  639. case IDB_REGISTER_OP_C:
  640. if (Clients[idx]==NULL)
  641. DoRegister (hDlg, idx);
  642. else
  643. DoDeregister (hDlg, idx);
  644. res = TRUE;
  645. break;
  646. case IDR_ADD_C:
  647. SetupAdd (hDlg);
  648. res = TRUE;
  649. break;
  650. case IDR_DELETE_C:
  651. SetupDelete (hDlg);
  652. res = TRUE;
  653. break;
  654. case IDR_DEQUEUE_C:
  655. if (GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C,
  656. NULL, FALSE)!=0)
  657. SetupDequeue (hDlg);
  658. else
  659. SetupConvert (hDlg);
  660. res = TRUE;
  661. break;
  662. case IDR_DISABLE_C:
  663. case IDR_ENABLE_C:
  664. SetupSetEnable (hDlg);
  665. res = TRUE;
  666. break;
  667. case IDB_DO_IT_C:
  668. DoOperation (hDlg, idx);
  669. res = TRUE;
  670. break;
  671. }
  672. break;
  673. case WM_DESTROY:
  674. if (Clients[idx]!=NULL) {
  675. if (RtmDeregisterClient (Clients[idx])!=NO_ERROR)
  676. MessageBox (hDlg, "Deregister failed!", NULL, MB_OK|MB_ICONSTOP);
  677. Clients[idx] = NULL;
  678. }
  679. break;
  680. }
  681. return res;
  682. }
  683. VOID
  684. DoRegister (
  685. HWND hDlg,
  686. LONG idx
  687. ) {
  688. DWORD ProtocolFamily;
  689. DWORD RoutingProtocol;
  690. ProtocolFamily = SendDlgItemMessage (hDlg, IDC_PROTOCOL_FAMILY_C,
  691. CB_GETCURSEL, 0, 0);
  692. RoutingProtocol = GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
  693. SetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, RoutingProtocol, FALSE);
  694. Clients[idx] = RtmRegisterClient (ProtocolFamily,
  695. RoutingProtocol,
  696. (RoutingProtocol!=0)
  697. ? Events[idx]
  698. : NULL,
  699. (RoutingProtocol!=0)
  700. ? 0
  701. : RTM_PROTOCOL_SINGLE_ROUTE);
  702. if (Clients[idx]!=NULL) {
  703. RECT rectScr, rectDlg;
  704. EnableWindow (GetDlgItem (hDlg, IDC_PROTOCOL_FAMILY_C), FALSE);
  705. EnableWindow (GetDlgItem (hDlg, IDE_ROUTING_PROTOCOL_C), FALSE);
  706. SetDlgItemText (hDlg, IDB_REGISTER_OP_C, "Deregister");
  707. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_REQUEST_C), TRUE);
  708. if (RoutingProtocol!=0) {
  709. SetDlgItemText (hDlg, IDR_DEQUEUE_C, "Dequeue");
  710. EnableWindow (GetDlgItem (hDlg, IDR_DEQUEUE_C), FALSE);
  711. }
  712. else
  713. SetDlgItemText (hDlg, IDR_DEQUEUE_C, "Convert");
  714. GetWindowRect (GetDlgItem (hDlg, IDE_NET_NUMBER_C), &rectScr);
  715. MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
  716. rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
  717. switch (ProtocolFamily) {
  718. case RTM_PROTOCOL_FAMILY_IPX:
  719. rectDlg.right = 8*4+5;
  720. break;
  721. case RTM_PROTOCOL_FAMILY_IP:
  722. rectDlg.right = 16*4+5;
  723. break;
  724. }
  725. MapDialogRect (hDlg, &rectDlg);
  726. MoveWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C),
  727. rectScr.left,
  728. rectScr.top,
  729. rectDlg.right,
  730. rectScr.bottom-rectScr.top,
  731. TRUE);
  732. GetWindowRect (GetDlgItem (hDlg, IDE_NEXT_HOP_C), &rectScr);
  733. MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
  734. rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
  735. switch (ProtocolFamily) {
  736. case RTM_PROTOCOL_FAMILY_IPX:
  737. rectDlg.right = 12*4+5;
  738. break;
  739. case RTM_PROTOCOL_FAMILY_IP:
  740. rectDlg.right = 16*4+5;
  741. break;
  742. }
  743. MapDialogRect (hDlg, &rectDlg);
  744. MoveWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C),
  745. rectScr.left,
  746. rectScr.top,
  747. rectDlg.right,
  748. rectScr.bottom-rectScr.top,
  749. TRUE);
  750. SendDlgItemMessage (hDlg, IDR_ADD_C, BM_SETCHECK, (WPARAM)1, 0);
  751. SetupAdd (hDlg);
  752. }
  753. else
  754. MessageBox (hDlg, "Registration failed!", NULL, MB_OK|MB_ICONSTOP);
  755. }
  756. VOID
  757. DoDeregister (
  758. HWND hDlg,
  759. LONG idx
  760. ) {
  761. if (RtmDeregisterClient (Clients[idx])!=NO_ERROR)
  762. MessageBox (hDlg, "Deregister failed!", NULL, MB_OK|MB_ICONSTOP);
  763. Clients[idx] = NULL;
  764. ResetEvent (Events[idx]);
  765. EnableWindow (GetDlgItem (hDlg, IDC_PROTOCOL_FAMILY_C), TRUE);
  766. EnableWindow (GetDlgItem (hDlg, IDE_ROUTING_PROTOCOL_C), TRUE);
  767. SetDlgItemText (hDlg, IDB_REGISTER_OP_C, "Register");
  768. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), FALSE);
  769. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_REQUEST_C), FALSE);
  770. }
  771. VOID
  772. SetupAdd (
  773. HWND hDlg
  774. ) {
  775. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
  776. EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
  777. }
  778. VOID
  779. SetupDelete (
  780. HWND hDlg
  781. ) {
  782. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
  783. EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
  784. EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
  785. EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
  786. }
  787. VOID
  788. SetupDequeue (
  789. HWND hDlg
  790. ) {
  791. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
  792. EnableWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C), FALSE);
  793. EnableWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C), FALSE);
  794. EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_C), FALSE);
  795. EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
  796. EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
  797. EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
  798. }
  799. VOID
  800. SetupSetEnable (
  801. HWND hDlg
  802. ) {
  803. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
  804. EnableWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C), FALSE);
  805. EnableWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C), FALSE);
  806. EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_C), TRUE);
  807. EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
  808. EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
  809. EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
  810. }
  811. VOID
  812. SetupConvert (
  813. HWND hDlg
  814. ) {
  815. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
  816. EnableWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C), FALSE);
  817. EnableWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C), FALSE);
  818. EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_C), TRUE);
  819. EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
  820. EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
  821. EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
  822. }
  823. VOID
  824. DoOperation (
  825. HWND hDlg,
  826. LONG idx
  827. ) {
  828. char buf[32];
  829. LONG TimeToLive;
  830. RTM_ROUTE Route;
  831. DWORD status;
  832. DWORD ProtocolFamily;
  833. INT i,n,val;
  834. DWORD Flags;
  835. char *p;
  836. memset (&Route, 0 , sizeof (RTM_ROUTE));
  837. ProtocolFamily = SendDlgItemMessage (hDlg, IDC_PROTOCOL_FAMILY_C,
  838. CB_GETCURSEL, 0, 0);
  839. if (IsDlgButtonChecked (hDlg, IDR_ADD_C)
  840. || IsDlgButtonChecked (hDlg, IDR_DELETE_C)) {
  841. Route.XX_PROTOCOL
  842. = GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
  843. GetDlgItemText (hDlg, IDE_NET_NUMBER_C, buf, sizeof (buf)-1);
  844. p = buf;
  845. switch (ProtocolFamily) {
  846. case RTM_PROTOCOL_FAMILY_IPX:
  847. if (sscanf (p, "%8X%n", &val, &n)==1)
  848. Route.IPX_NET_NUM = val;
  849. else
  850. Route.IPX_NET_NUM = 0;
  851. p += n;
  852. break;
  853. case RTM_PROTOCOL_FAMILY_IP:
  854. if (sscanf (p, "%8X%n", &val, &n)==1)
  855. Route.IP_NET_NUM = val;
  856. else
  857. Route.IP_NET_NUM = 0;
  858. p += n;
  859. if (sscanf (p, "%8X%n", &val, &n)==1)
  860. Route.IP_NET_MSK = val;
  861. else
  862. Route.IP_NET_MSK = 0;
  863. p += n;
  864. break;
  865. }
  866. GetDlgItemText (hDlg, IDE_NEXT_HOP_C, buf, sizeof (buf)-1);
  867. p = buf;
  868. switch (ProtocolFamily) {
  869. case RTM_PROTOCOL_FAMILY_IPX:
  870. for (i=0; i<sizeof(Route.IPX_NEXT_HOP_MAC); i++, p+=n) {
  871. if (sscanf (p, "%2X%n", &val, &n)==1)
  872. Route.IPX_NEXT_HOP_MAC[i] = (BYTE)val;
  873. else
  874. Route.IPX_NEXT_HOP_MAC[i] = 0;
  875. }
  876. break;
  877. case RTM_PROTOCOL_FAMILY_IP:
  878. if (sscanf (p, "%8X%n", &val, &n)==1)
  879. Route.IP_NEXT_HOP_NUM = val;
  880. else
  881. Route.IP_NEXT_HOP_NUM = 0;
  882. p += n;
  883. if (sscanf (p, "%8X%n", &val, &n)==1)
  884. Route.IP_NEXT_HOP_MSK = val;
  885. else
  886. Route.IP_NEXT_HOP_MSK = 0;
  887. p += n;
  888. break;
  889. }
  890. Route.XX_INTERFACE
  891. = GetDlgItemInt (hDlg, IDE_INTERFACE_C, NULL, FALSE);
  892. if (IsDlgButtonChecked (hDlg, IDR_ADD_C)) {
  893. switch (ProtocolFamily) {
  894. case RTM_PROTOCOL_FAMILY_IPX:
  895. Route.IPX_METRIC = (USHORT)GetDlgItemInt
  896. (hDlg, IDE_METRIC_C, NULL, FALSE);
  897. break;
  898. case RTM_PROTOCOL_FAMILY_IP:
  899. Route.IP_METRIC = (USHORT)GetDlgItemInt
  900. (hDlg, IDE_METRIC_C, NULL, FALSE);
  901. break;
  902. }
  903. TimeToLive = GetDlgItemInt (hDlg, IDE_TIMEOUT_C, NULL, FALSE);
  904. SetDlgItemInt (hDlg, IDE_TIMEOUT_C, TimeToLive, FALSE);
  905. GetDlgItemText (hDlg, IDR_ADD_C, buf, sizeof (buf)-1);
  906. status = RtmAddRoute (Clients[idx], &Route,
  907. TimeToLive,
  908. &Flags, NULL, NULL);
  909. }
  910. else {
  911. status = RtmDeleteRoute (Clients[idx], &Route,
  912. &Flags, NULL);
  913. SetDlgItemText (hDlg, IDE_TIMEOUT_C, "");
  914. }
  915. if (status!=NO_ERROR) {
  916. sprintf (buf, "Rtm returned error: %ld", status);
  917. MessageBox (hDlg, buf, "Error", MB_OK|MB_ICONEXCLAMATION);
  918. }
  919. SetDlgItemText (hDlg, IDL_ROUTING_PROTOCOL_C, "");
  920. }
  921. else if (IsDlgButtonChecked (hDlg, IDR_DEQUEUE_C)) {
  922. RTM_ROUTE Route1;
  923. Route.XX_PROTOCOL
  924. = GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
  925. if (Route.XX_PROTOCOL!=0) {
  926. status = RtmDequeueRouteChangeMessage (Clients[idx],
  927. &Flags,
  928. &Route,
  929. &Route1);
  930. if (status==NO_ERROR) {
  931. SendDlgItemMessage (hDlg, IDR_DEQUEUE_C, BM_SETCHECK, (WPARAM)0, 0);
  932. EnableWindow (GetDlgItem (hDlg, IDR_DEQUEUE_C), FALSE);
  933. EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), FALSE);
  934. }
  935. else if (status!=ERROR_MORE_MESSAGES) {
  936. sprintf (buf, "Rtm returned error: %ld", status);
  937. MessageBox (hDlg, buf, "Error", MB_OK|MB_ICONEXCLAMATION);
  938. }
  939. if (!(Flags & RTM_CURRENT_BEST_ROUTE))
  940. memcpy (&Route, &Route1, sizeof (Route));
  941. SetDlgItemInt (hDlg, IDL_ROUTING_PROTOCOL_C, (UINT)Route.XX_PROTOCOL, FALSE);
  942. SetDlgItemText (hDlg, IDE_TIMEOUT_C, "");
  943. }
  944. else {
  945. Route.XX_INTERFACE
  946. = GetDlgItemInt (hDlg, IDE_INTERFACE_C, NULL, FALSE);
  947. status = RtmBlockConvertRoutesToStatic (
  948. Clients[idx],
  949. RTM_ONLY_THIS_INTERFACE,
  950. &Route);
  951. goto OpDone;
  952. }
  953. }
  954. else if (IsDlgButtonChecked (hDlg, IDR_DISABLE_C)
  955. || IsDlgButtonChecked (hDlg, IDR_ENABLE_C)) {
  956. Route.XX_PROTOCOL
  957. = GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
  958. Route.XX_INTERFACE
  959. = GetDlgItemInt (hDlg, IDE_INTERFACE_C, NULL, FALSE);
  960. status = RtmBlockSetRouteEnable (Clients[idx],
  961. RTM_ONLY_THIS_INTERFACE,
  962. &Route,
  963. IsDlgButtonChecked (hDlg, IDR_ENABLE_C));
  964. goto OpDone;
  965. }
  966. SetDlgItemInt (hDlg, IDL_MESSAGE_FLAGS_C, (UINT)Flags, FALSE);
  967. SetDlgItemInt (hDlg, IDE_INTERFACE_C, (UINT)Route.XX_INTERFACE, FALSE);
  968. switch (ProtocolFamily) {
  969. case RTM_PROTOCOL_FAMILY_IPX:
  970. sprintf (buf,
  971. "%08X",
  972. Route.IPX_NET_NUM);
  973. SetDlgItemInt (hDlg, IDE_METRIC_C, (UINT)Route.IPX_METRIC, FALSE);
  974. break;
  975. case RTM_PROTOCOL_FAMILY_IP:
  976. sprintf (buf,
  977. "%08X%08X",
  978. Route.IP_NET_NUM,
  979. Route.IP_NET_MSK);
  980. SetDlgItemInt (hDlg, IDE_METRIC_C, (UINT)Route.IP_METRIC, FALSE);
  981. break;
  982. }
  983. SetDlgItemText (hDlg, IDE_NET_NUMBER_C, buf);
  984. switch (ProtocolFamily) {
  985. case RTM_PROTOCOL_FAMILY_IPX:
  986. sprintf (buf,
  987. "%02X%02X%02X%02X%02X%02X",
  988. Route.IPX_NEXT_HOP_MAC[0],
  989. Route.IPX_NEXT_HOP_MAC[1],
  990. Route.IPX_NEXT_HOP_MAC[2],
  991. Route.IPX_NEXT_HOP_MAC[3],
  992. Route.IPX_NEXT_HOP_MAC[4],
  993. Route.IPX_NEXT_HOP_MAC[5]);
  994. break;
  995. case RTM_PROTOCOL_FAMILY_IP:
  996. sprintf (buf,
  997. "%08X%08X",
  998. Route.IP_NEXT_HOP_NUM,
  999. Route.IP_NEXT_HOP_MSK);
  1000. break;
  1001. }
  1002. SetDlgItemText (hDlg, IDE_NEXT_HOP_C, buf);
  1003. OpDone:
  1004. ;
  1005. }
  1006. #define pParam ((PENABLE_DLG_GROUP_PARAM)lParam)
  1007. BOOL CALLBACK
  1008. DoEnable (
  1009. HWND hwnd, // handle of child window
  1010. LPARAM lParam // application-defined value
  1011. ) {
  1012. if (!pParam->foundFirst) {
  1013. if (pParam->hCtlFirst != hwnd)
  1014. return TRUE;
  1015. else
  1016. pParam->foundFirst = TRUE;
  1017. }
  1018. else if (GetWindowLong (hwnd, GWL_STYLE) & WS_GROUP)
  1019. return FALSE;
  1020. EnableWindow (hwnd, pParam->enableFlag);
  1021. return TRUE;
  1022. }
  1023. #undef pParam
  1024. VOID
  1025. EnableDlgGroup (
  1026. HWND hDlg,
  1027. HWND hCtlFirst,
  1028. BOOLEAN enable
  1029. ) {
  1030. ENABLE_DLG_GROUP_PARAM param;
  1031. param.hCtlFirst = hCtlFirst;
  1032. param.foundFirst = FALSE;
  1033. param.enableFlag = enable;
  1034. EnumChildWindows (hDlg, DoEnable, (LPARAM)&param);
  1035. }
  1036. typedef USHORT IPX_SOCKETNUM, *PIPX_SOCKETNUM;
  1037. typedef UCHAR IPX_NETNUM[4], *PIPX_NETNUM;
  1038. typedef UCHAR IPX_NODENUM[6], *PIPX_NODENUM;
  1039. typedef struct _IPX_ADDRESS_BLOCK {
  1040. IPX_NETNUM net;
  1041. IPX_NODENUM node;
  1042. IPX_SOCKETNUM socket;
  1043. } IPX_ADDRESS_BLOCK, *PIPX_ADDRESS_BLOCK;
  1044. // IPX Net Number copy macro
  1045. #define IPX_NETNUM_CPY(dst,src) memcpy(dst,src,sizeof(IPX_NETNUM))
  1046. // IPX Net Number comparison
  1047. #define IPX_NETNUM_CMP(addr1,addr2) memcmp(net1,net2,sizeof(IPX_NETNUM))
  1048. // IPX Node Number copy macro
  1049. #define IPX_NODENUM_CPY(dst,src) memcpy(dst,src,sizeof(IPX_NODENUM))
  1050. // IPX Node Number comparison
  1051. #define IPX_NODENUM_CMP(node1,node2) memcmp(node1,node2,sizeof(IPX_NODENUM))
  1052. // IPX Address copy macro
  1053. #define IPX_ADDR_CPY(dst,src) memcpy(dst,src,sizeof(IPX_ADDRESS_BLOCK))
  1054. // IPX Address comparison
  1055. #define IPX_ADDR_CMP(addr1,addr2) memcmp(addr1,addr2,sizeof(IPX_ADDRESS_BLOCK))
  1056. // Header of IPX packet
  1057. typedef struct _IPX_HEADER {
  1058. USHORT checksum;
  1059. USHORT length;
  1060. UCHAR transportctl;
  1061. UCHAR pkttype;
  1062. IPX_ADDRESS_BLOCK dst;
  1063. IPX_ADDRESS_BLOCK src;
  1064. } IPX_HEADER, *PIPX_HEADER;
  1065. typedef struct _IPX_SAP_PACKET {
  1066. IPX_HEADER hdr;
  1067. USHORT operation;
  1068. struct {
  1069. USHORT type;
  1070. UCHAR name[48];
  1071. IPX_ADDRESS_BLOCK addr;
  1072. USHORT hops;
  1073. } entry[7];
  1074. } IPX_SAP_PACKET, *PIPX_SAP_PACKET;
  1075. DWORD WINAPI
  1076. IPXRIPListenThread (
  1077. LPVOID param
  1078. ) {
  1079. #define adptIdx ((INT)param)
  1080. INT status;
  1081. IPX_SAP_PACKET packet;
  1082. HANDLE hClient;
  1083. RTM_IPX_ROUTE Route;
  1084. DWORD flags;
  1085. IPX_NETNUM_DATA netData;
  1086. INT length;
  1087. fprintf (stderr, "IXP RIP Listener # %d: Started.\n", adptIdx);
  1088. hClient = RtmRegisterClient (RTM_PROTOCOL_FAMILY_IPX, 1000+adptIdx, NULL, 0);
  1089. ASSERT (hClient!=NULL);
  1090. while (((status=recvfrom (Sockets[adptIdx],
  1091. (PCHAR)&packet,
  1092. sizeof (packet),
  1093. 0, NULL, NULL)) != 0)
  1094. && (status!=SOCKET_ERROR)) {
  1095. // fprintf (stderr, "IXP RIP Listener # %d: Packet received.\n", adptIdx);
  1096. if (status>=sizeof (IPX_HEADER)) {
  1097. packet.hdr.length = (USHORT)ntohs (packet.hdr.length);
  1098. if (packet.hdr.length>status)
  1099. packet.hdr.length = (USHORT)status;
  1100. if (packet.hdr.length>=FIELD_OFFSET (IPX_SAP_PACKET, entry[0])) {
  1101. if ((packet.hdr.pkttype==4)
  1102. && (ntohs(packet.operation)==2)) {
  1103. if (FIELD_OFFSET(IPX_SAP_PACKET,entry[1])
  1104. <= packet.hdr.length) {
  1105. IPX_NETNUM_CPY (&netData.netnum, &packet.entry[0].addr.net);
  1106. length = sizeof (netData);
  1107. status = getsockopt (Sockets[adptIdx],
  1108. NSPROTO_IPX,
  1109. IPX_GETNETINFO,
  1110. (PCHAR)&netData,
  1111. &length);
  1112. if (status==0) {
  1113. Route.RR_InterfaceID = (1000+adptIdx);
  1114. Route.RR_RoutingProtocol = 0;
  1115. Route.RR_FamilySpecificData.FSD_Ticks =
  1116. (USHORT)netData.netdelay;
  1117. RtlRetrieveUlong (&Route.RR_Network.N_NetNumber,
  1118. netData.netnum);
  1119. Route.RR_Network.N_NetNumber =
  1120. ntohl (Route.RR_Network.N_NetNumber);
  1121. IPX_NODENUM_CPY (&Route.RR_NextHopAddress.NHA_Mac,
  1122. &netData.router);
  1123. Route.RR_FamilySpecificData.FSD_HopCount = netData.hopcount;
  1124. if (Route.RR_FamilySpecificData.FSD_HopCount<16)
  1125. status = RtmAddRoute (hClient, &Route, 200, &flags, NULL, NULL);
  1126. else
  1127. status = RtmDeleteRoute (hClient, &Route, &flags, NULL);
  1128. if (status!=0) {
  1129. fprintf (stderr,
  1130. "IPX RIP Listener # %d: %s failed with status %d\n",
  1131. adptIdx,
  1132. Route.RR_FamilySpecificData.FSD_HopCount<16 ? "AddRoute" : "DeleteRoute",
  1133. status);
  1134. }
  1135. }
  1136. else
  1137. fprintf (stderr,
  1138. "IPX RIP Listener # %d:"
  1139. " Can't get info about net # %02x%02x%02x%02x\n",
  1140. adptIdx,
  1141. netData.netnum[0],
  1142. netData.netnum[1],
  1143. netData.netnum[2],
  1144. netData.netnum[3]);
  1145. }
  1146. else
  1147. fprintf (stderr,
  1148. "IPX RIP Listener # %d:"
  1149. " Invalid packet length %d.\n",
  1150. adptIdx,
  1151. packet.hdr.length);
  1152. }
  1153. // else
  1154. // fprintf (stderr,
  1155. // "IPX RIP Listener # %d:"
  1156. // " Packet type %d, operation %d ignored.\n",
  1157. // adptIdx,
  1158. // packet.hdr.pkttype,
  1159. // ntohs (packet.operation));
  1160. }
  1161. else
  1162. fprintf (stderr, "IPX RIP Listener # %d: Short packet: %d\n",
  1163. adptIdx,
  1164. packet.hdr.length);
  1165. }
  1166. else
  1167. fprintf (stderr, "IPX RIP Listener # %d: Invalid packet: %d\n",
  1168. adptIdx,
  1169. status);
  1170. // Sleep (5*1000);
  1171. }
  1172. fprintf (stderr,
  1173. "IPX RIP Listener # %d: Terminating loop. Status: %d, err: %d\n",
  1174. adptIdx, status, GetLastError ());
  1175. if (RtmDeregisterClient (hClient)!=NO_ERROR)
  1176. fprintf (stderr, "Deregister client failed.\n");
  1177. fprintf (stderr, "IXP RIP Listener # %d exited.\n", adptIdx);
  1178. return 0;
  1179. #undef adptIdx
  1180. }
  1181. #define idx ((LONG)param)
  1182. DWORD WINAPI
  1183. EnumThread (
  1184. LPVOID param
  1185. ) {
  1186. MSG msg;
  1187. HWND EnumDlg;
  1188. char buf[16];
  1189. Enums[idx] = NULL;
  1190. // Create dialog window
  1191. EnumDlg = CreateDialogParam (hDLLInstance,
  1192. MAKEINTRESOURCE(IDD_ENUMERATION),
  1193. NULL,
  1194. &EnumDlgProc,
  1195. (LPARAM)idx);
  1196. ASSERTERR (EnumDlg!=NULL);
  1197. sprintf (buf, "Enumerator # %d", idx+1);
  1198. SetWindowText (EnumDlg, buf);
  1199. while (GetMessage (&msg, NULL, 0, 0)) {
  1200. if (!IsWindow(EnumDlg)
  1201. || !IsDialogMessage(EnumDlg, &msg)) {
  1202. TranslateMessage (&msg);
  1203. DispatchMessage (&msg);
  1204. }
  1205. }
  1206. if (IsWindow (EnumDlg)) {
  1207. DestroyWindow (EnumDlg);
  1208. EnumDlg = NULL;
  1209. }
  1210. if (Enums[idx]!=NULL) {
  1211. if (Enums[idx]!=INVALID_HANDLE_VALUE) {
  1212. if (RtmCloseEnumerationHandle (Enums[idx])!=NO_ERROR)
  1213. MessageBox (NULL, "Close handle failed!", NULL, MB_OK|MB_ICONSTOP);
  1214. }
  1215. Enums[idx] = NULL;
  1216. }
  1217. return msg.wParam;
  1218. }
  1219. #undef idx
  1220. BOOL CALLBACK
  1221. EnumDlgProc (
  1222. HWND hDlg,
  1223. UINT uMsg,
  1224. WPARAM wParam,
  1225. LPARAM lParam
  1226. ) {
  1227. BOOL res = FALSE;
  1228. LONG idx;
  1229. RTM_ROUTE Route;
  1230. DWORD ProtocolFamily;
  1231. DWORD flags;
  1232. DWORD status;
  1233. RECT rectDlg, rectScr;
  1234. idx = GetWindowLong (hDlg, DWL_USER)-1;
  1235. switch (uMsg) {
  1236. case WM_INITDIALOG: // Dialog is being created
  1237. idx = lParam+1;
  1238. SetWindowLong (hDlg, DWL_USER, idx);
  1239. ASSERTERR (GetLastError ()==NO_ERROR);
  1240. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CRITERIA_E), TRUE);
  1241. EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_BUTTONS_E), TRUE);
  1242. EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E), FALSE);
  1243. SendDlgItemMessage (hDlg,
  1244. IDC_PROTOCOL_FAMILY_E,
  1245. CB_INSERTSTRING,
  1246. RTM_PROTOCOL_FAMILY_IPX,
  1247. (LPARAM)"IPX"
  1248. );
  1249. SendDlgItemMessage (hDlg,
  1250. IDC_PROTOCOL_FAMILY_E,
  1251. CB_INSERTSTRING,
  1252. RTM_PROTOCOL_FAMILY_IP,
  1253. (LPARAM)"IP"
  1254. );
  1255. SendDlgItemMessage (hDlg,
  1256. IDC_PROTOCOL_FAMILY_E,
  1257. CB_SETCURSEL,
  1258. 0,
  1259. 0
  1260. );
  1261. GetWindowRect (GetDlgItem (hDlg, IDE_NETWORK_E), &rectScr);
  1262. MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
  1263. rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
  1264. rectDlg.right = 8*4+5;
  1265. MapDialogRect (hDlg, &rectDlg);
  1266. EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E), TRUE);
  1267. MoveWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
  1268. rectScr.left,
  1269. rectScr.top,
  1270. rectDlg.right,
  1271. rectScr.bottom-rectScr.top,
  1272. TRUE);
  1273. EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_E),
  1274. IsDlgButtonChecked (hDlg, IDC_INTERFACE_E));
  1275. EnableWindow (GetDlgItem (hDlg, IDE_PROTOCOL_E),
  1276. IsDlgButtonChecked (hDlg, IDC_PROTOCOL_E));
  1277. EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
  1278. IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
  1279. EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E),
  1280. IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
  1281. SetDlgItemText (hDlg, IDB_CREATEDELETE_E, "Create Handle");
  1282. SetDlgItemText (hDlg, IDB_GETFIRST_E, "Get First");
  1283. res = TRUE;
  1284. break;
  1285. case WM_COMMAND: // Process child window messages only
  1286. switch (LOWORD(wParam)) {
  1287. case IDCANCEL:
  1288. PostQuitMessage (0);
  1289. res = TRUE;
  1290. break;
  1291. case IDC_PROTOCOL_FAMILY_E:
  1292. if (HIWORD(wParam)==CBN_SELENDOK) {
  1293. ProtocolFamily = SendMessage (
  1294. (HWND)lParam,
  1295. CB_GETCURSEL,
  1296. 0, 0);
  1297. GetWindowRect (GetDlgItem (hDlg, IDE_NETWORK_E), &rectScr);
  1298. MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
  1299. rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
  1300. switch (ProtocolFamily) {
  1301. case RTM_PROTOCOL_FAMILY_IPX:
  1302. rectDlg.right = 8*4+5;
  1303. break;
  1304. case RTM_PROTOCOL_FAMILY_IP:
  1305. rectDlg.right = 16*4+5;
  1306. break;
  1307. }
  1308. MapDialogRect (hDlg, &rectDlg);
  1309. EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E), TRUE);
  1310. MoveWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
  1311. rectScr.left,
  1312. rectScr.top,
  1313. rectDlg.right,
  1314. rectScr.bottom-rectScr.top,
  1315. TRUE);
  1316. EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
  1317. IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
  1318. }
  1319. break;
  1320. case IDC_NETWORK_E:
  1321. if (HIWORD(wParam)==BN_CLICKED)
  1322. EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E),
  1323. IsDlgButtonChecked (hDlg, LOWORD(wParam)));
  1324. break;
  1325. case IDC_INTERFACE_E:
  1326. case IDC_PROTOCOL_E:
  1327. if (HIWORD(wParam)==BN_CLICKED)
  1328. EnableWindow (GetDlgItem (hDlg, LOWORD(wParam)+1),
  1329. IsDlgButtonChecked (hDlg, LOWORD(wParam)));
  1330. break;
  1331. case IDB_CREATEDELETE_E:
  1332. if (Enums[idx]==NULL) {
  1333. GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
  1334. Enums[idx] = RtmCreateEnumerationHandle (
  1335. ProtocolFamily,
  1336. flags,
  1337. &Route);
  1338. if (Enums[idx]!=NULL) {
  1339. EnableDlgGroup (hDlg,
  1340. GetDlgItem (hDlg, IDG_CRITERIA_E), FALSE);
  1341. EnableWindow (GetDlgItem (hDlg, IDB_GETFIRST_E),
  1342. FALSE);
  1343. SetWindowText ((HWND)lParam, "Close Handle");
  1344. EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E),
  1345. TRUE);
  1346. }
  1347. else
  1348. MessageBox (hDlg, "Create Handle failed!",
  1349. NULL, MB_OK|MB_ICONSTOP);
  1350. }
  1351. else {
  1352. if (RtmCloseEnumerationHandle (Enums[idx])!=NO_ERROR)
  1353. MessageBox (hDlg, "Close handle failed!",
  1354. NULL, MB_OK|MB_ICONSTOP);
  1355. Enums[idx] = NULL;
  1356. EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E), FALSE);
  1357. SetWindowText ((HWND)lParam, "Create Handle");
  1358. EnableWindow (GetDlgItem (hDlg, IDB_GETFIRST_E), TRUE);
  1359. EnableDlgGroup (hDlg,
  1360. GetDlgItem (hDlg, IDG_CRITERIA_E), TRUE);
  1361. }
  1362. res = TRUE;
  1363. break;
  1364. case IDB_GETFIRST_E:
  1365. if (Enums[idx]==NULL) {
  1366. GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
  1367. status = RtmGetFirstRoute (
  1368. ProtocolFamily,
  1369. flags,
  1370. &Route);
  1371. if (status==NO_ERROR) {
  1372. DisplayRoute (hDlg, ProtocolFamily, &Route);
  1373. Enums[idx] = INVALID_HANDLE_VALUE;
  1374. EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E), FALSE);
  1375. EnableDlgGroup (hDlg,
  1376. GetDlgItem (hDlg, IDG_CRITERIA_E), FALSE);
  1377. EnableWindow (GetDlgItem (hDlg, IDB_CREATEDELETE_E),
  1378. FALSE);
  1379. SetWindowText ((HWND)lParam, "Stop Scan");
  1380. EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E),
  1381. TRUE);
  1382. }
  1383. else if (status==ERROR_NO_ROUTES)
  1384. MessageBox (hDlg, "ERROR_NO_ROUTES!",
  1385. NULL, MB_OK|MB_ICONSTOP);
  1386. else
  1387. MessageBox (hDlg, "ERROR!",
  1388. NULL, MB_OK|MB_ICONSTOP);
  1389. }
  1390. else {
  1391. Enums[idx] = NULL;
  1392. EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E), FALSE);
  1393. SetWindowText ((HWND)lParam, "Get First");
  1394. EnableWindow (GetDlgItem (hDlg, IDB_CREATEDELETE_E), TRUE);
  1395. EnableDlgGroup (hDlg,
  1396. GetDlgItem (hDlg, IDG_CRITERIA_E), TRUE);
  1397. EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E),
  1398. IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
  1399. }
  1400. res = TRUE;
  1401. break;
  1402. case IDB_GETNEXT_E:
  1403. if (Enums[idx]==INVALID_HANDLE_VALUE) {
  1404. GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
  1405. GetLastRoute (hDlg, ProtocolFamily, &Route);
  1406. status = RtmGetNextRoute (ProtocolFamily, flags, &Route);
  1407. }
  1408. else {
  1409. status = RtmEnumerateGetNextRoute (Enums[idx], &Route);
  1410. ProtocolFamily = SendDlgItemMessage (hDlg,
  1411. IDC_PROTOCOL_FAMILY_E,
  1412. CB_GETCURSEL, 0, 0);
  1413. }
  1414. if (status==NO_ERROR)
  1415. DisplayRoute (hDlg, ProtocolFamily, &Route);
  1416. else if (status==ERROR_NO_MORE_ROUTES)
  1417. MessageBox (hDlg, "ERROR_NO_MORE_ROUTES!",
  1418. NULL, MB_OK|MB_ICONSTOP);
  1419. else
  1420. MessageBox (hDlg, "ERROR!",
  1421. NULL, MB_OK|MB_ICONSTOP);
  1422. res = TRUE;
  1423. break;
  1424. case IDB_GETBEST_E:
  1425. GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
  1426. res = RtmIsRoute (ProtocolFamily, ((char *)&Route)+sizeof(RTM_XX_ROUTE), &Route);
  1427. if (res)
  1428. DisplayRoute (hDlg, ProtocolFamily, &Route);
  1429. else
  1430. MessageBox (hDlg, "NO_ROUTES!",
  1431. NULL, MB_OK|MB_ICONSTOP);
  1432. res = TRUE;
  1433. break;
  1434. case IDB_GETAGE_E:
  1435. ProtocolFamily = SendDlgItemMessage (hDlg,
  1436. IDC_PROTOCOL_FAMILY_E,
  1437. CB_GETCURSEL, 0, 0);
  1438. GetLastRoute (hDlg, ProtocolFamily, &Route);
  1439. status = RtmGetSpecificRoute (ProtocolFamily, &Route);
  1440. if (status==NO_ERROR) {
  1441. DisplayRoute (hDlg, ProtocolFamily, &Route);
  1442. SetDlgItemInt (hDlg, IDL_AGESEC_E,
  1443. RtmGetRouteAge (&Route), FALSE);
  1444. }
  1445. else
  1446. MessageBox (hDlg, "NO_ROUTES!",
  1447. NULL, MB_OK|MB_ICONSTOP);
  1448. res = TRUE;
  1449. break;
  1450. }
  1451. break;
  1452. case WM_DESTROY:
  1453. if (Enums[idx]!=NULL) {
  1454. if (Enums[idx]!=INVALID_HANDLE_VALUE) {
  1455. if (RtmCloseEnumerationHandle (Enums[idx])!=NO_ERROR)
  1456. MessageBox (hDlg, "Close handle failed!",
  1457. NULL, MB_OK|MB_ICONSTOP);
  1458. }
  1459. Enums[idx] = NULL;
  1460. }
  1461. break;
  1462. }
  1463. return res;
  1464. }
  1465. VOID
  1466. GetCriteria (
  1467. HWND hDlg,
  1468. DWORD *ProtocolFamily,
  1469. DWORD *flags,
  1470. PRTM_ROUTE Route
  1471. ) {
  1472. char buf[32];
  1473. char *p;
  1474. INT val,i,n;
  1475. *ProtocolFamily = SendDlgItemMessage (hDlg, IDC_PROTOCOL_FAMILY_E,
  1476. CB_GETCURSEL, 0, 0);
  1477. if (IsDlgButtonChecked (hDlg, IDC_BESTROUTES_E)) {
  1478. *flags = RTM_ONLY_BEST_ROUTES;
  1479. }
  1480. else
  1481. *flags = 0;
  1482. if (IsDlgButtonChecked (hDlg, IDC_INTERFACE_E)) {
  1483. *flags |= RTM_ONLY_THIS_INTERFACE;
  1484. Route->XX_INTERFACE = GetDlgItemInt (hDlg,
  1485. IDE_INTERFACE_E, NULL, FALSE);
  1486. }
  1487. if (IsDlgButtonChecked (hDlg, IDC_PROTOCOL_E)) {
  1488. *flags |= RTM_ONLY_THIS_PROTOCOL;
  1489. Route->XX.RR_RoutingProtocol = GetDlgItemInt (hDlg,
  1490. IDE_PROTOCOL_E, NULL, FALSE);
  1491. }
  1492. if (IsDlgButtonChecked (hDlg, IDC_NETWORK_E)) {
  1493. *flags |= RTM_ONLY_THIS_NETWORK;
  1494. GetDlgItemText (hDlg, IDE_NETWORK_E, buf, sizeof (buf)-1);
  1495. p = buf;
  1496. switch (*ProtocolFamily) {
  1497. case RTM_PROTOCOL_FAMILY_IPX:
  1498. if (sscanf (p, "%8X%n", &val, &n)==1)
  1499. Route->IPX_NET_NUM = val;
  1500. else
  1501. Route->IPX_NET_NUM = 0;
  1502. p += n;
  1503. sprintf (buf,
  1504. "%08X",
  1505. Route->IPX_NET_NUM);
  1506. break;
  1507. case RTM_PROTOCOL_FAMILY_IP:
  1508. if (sscanf (p, "%8X%n", &val, &n)==1)
  1509. Route->IP_NET_NUM = val;
  1510. else
  1511. Route->IP_NET_NUM = 0;
  1512. p += n;
  1513. if (sscanf (p, "%8X%n", &val, &n)==1)
  1514. Route->IP_NET_MSK = val;
  1515. else
  1516. Route->IP_NET_MSK = 0;
  1517. p += n;
  1518. sprintf (buf,
  1519. "%08X%08X",
  1520. Route->IP_NET_NUM,
  1521. Route->IP_NET_MSK);
  1522. break;
  1523. }
  1524. SetDlgItemText (hDlg, IDE_NETWORK_E, buf);
  1525. }
  1526. }
  1527. VOID
  1528. GetLastRoute (
  1529. HWND hDlg,
  1530. DWORD ProtocolFamily,
  1531. PRTM_ROUTE Route
  1532. ) {
  1533. char buf[128];
  1534. char *p;
  1535. INT i,n,val;
  1536. GetDlgItemText (hDlg, IDL_ROUTE_E, buf, sizeof (buf)-1);
  1537. p = buf;
  1538. switch (ProtocolFamily) {
  1539. case RTM_PROTOCOL_FAMILY_IPX:
  1540. if (sscanf (p, "%8X%n", &val, &n)==1)
  1541. Route->IPX_NET_NUM = val;
  1542. else
  1543. Route->IPX_NET_NUM = 0;
  1544. p += n;
  1545. sscanf (p,
  1546. " %d %d %n",
  1547. &Route->XX_INTERFACE,
  1548. &Route->XX_PROTOCOL,
  1549. &n);
  1550. p += n;
  1551. for (i=0; i<sizeof(Route->IPX_NEXT_HOP_MAC); i++, p+=n) {
  1552. if (sscanf (p, "%2X%n", &val, &n)==1)
  1553. Route->IPX_NEXT_HOP_MAC[i] = (BYTE)val;
  1554. else
  1555. Route->IPX_NEXT_HOP_MAC[i] = 0;
  1556. }
  1557. break;
  1558. case RTM_PROTOCOL_FAMILY_IP:
  1559. if (sscanf (p, "%8X%n", &val, &n)==1)
  1560. Route->IP_NET_NUM = val;
  1561. else
  1562. Route->IP_NET_NUM = 0;
  1563. p += n;
  1564. sscanf (p, "-%n", &n);
  1565. p += n;
  1566. if (sscanf (p, "%8X%n", &val, &n)==1)
  1567. Route->IP_NET_MSK = val;
  1568. else
  1569. Route->IP_NET_MSK = 0;
  1570. p += n;
  1571. sscanf (p,
  1572. " %d %d %n",
  1573. &Route->XX_INTERFACE,
  1574. &Route->XX_PROTOCOL,
  1575. &n);
  1576. p += n;
  1577. if (sscanf (p, "%8X%n", &val, &n)==1)
  1578. Route->IP_NEXT_HOP_NUM = val;
  1579. else
  1580. Route->IP_NEXT_HOP_NUM = 0;
  1581. p += n;
  1582. sscanf (p, "-%n", &n);
  1583. p += n;
  1584. if (sscanf (p, "%8X%n", &val, &n)==1)
  1585. Route->IP_NEXT_HOP_MSK = val;
  1586. else
  1587. Route->IP_NEXT_HOP_MSK = 0;
  1588. p += n;
  1589. break;
  1590. }
  1591. }
  1592. VOID
  1593. DisplayRoute (
  1594. HWND hDlg,
  1595. DWORD ProtocolFamily,
  1596. PRTM_ROUTE Route
  1597. ) {
  1598. char buf[128];
  1599. switch (ProtocolFamily) {
  1600. case RTM_PROTOCOL_FAMILY_IPX:
  1601. sprintf (buf,
  1602. " %08X "
  1603. " %4d %4d"
  1604. " %02X%02X%02X%02X%02X%02X "
  1605. " %4d",
  1606. Route->IPX_NET_NUM,
  1607. Route->XX_INTERFACE,
  1608. Route->XX_PROTOCOL,
  1609. Route->IPX_NEXT_HOP_MAC[0],
  1610. Route->IPX_NEXT_HOP_MAC[1],
  1611. Route->IPX_NEXT_HOP_MAC[2],
  1612. Route->IPX_NEXT_HOP_MAC[3],
  1613. Route->IPX_NEXT_HOP_MAC[4],
  1614. Route->IPX_NEXT_HOP_MAC[5],
  1615. Route->IPX_METRIC);
  1616. break;
  1617. case RTM_PROTOCOL_FAMILY_IP:
  1618. sprintf (buf,
  1619. "%08X-%08X"
  1620. " %4d %4d"
  1621. " %08X-%08X"
  1622. " %4d",
  1623. Route->IP_NET_NUM,
  1624. Route->IP_NET_MSK,
  1625. Route->XX_INTERFACE,
  1626. Route->XX_PROTOCOL,
  1627. Route->IP_NEXT_HOP_NUM,
  1628. Route->IP_NEXT_HOP_MSK,
  1629. Route->IP_METRIC);
  1630. break;
  1631. }
  1632. SetDlgItemText (hDlg, IDL_ROUTE_E, buf);
  1633. sprintf (buf, "%08X", Route->XX_TIMESTAMP.dwHighDateTime);
  1634. SetDlgItemText (hDlg, IDL_TIMEHIGH_E, buf);
  1635. sprintf (buf, "%08X", Route->XX_TIMESTAMP.dwLowDateTime);
  1636. SetDlgItemText (hDlg, IDL_TIMELOW_E, buf);
  1637. }