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.

951 lines
22 KiB

  1. /*++
  2. Copyright (c) 1997 FORE Systems, Inc.
  3. Copyright (c) 1997 Microsoft Corporation
  4. Module Name:
  5. atmlane.c
  6. Abstract:
  7. ATM LAN Emulation Client Admin Utility.
  8. Usage:
  9. atmlane
  10. Revision History:
  11. Who When What
  12. -------- -------- ---------------------------------------------
  13. v-lcleet 02-03-98 Created
  14. Notes:
  15. Modelled after atmadm utility from the UNI 3.1 Call Manager
  16. --*/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <memory.h>
  21. #include <ctype.h>
  22. #include <malloc.h>
  23. #include <time.h>
  24. #include <nt.h>
  25. #include <ntrtl.h>
  26. #include <nturtl.h>
  27. #include <winerror.h>
  28. #include <winsock.h>
  29. #ifndef NDIS_STATUS
  30. #define NDIS_STATUS ULONG
  31. #endif
  32. #include "laneinfo.h"
  33. #include "atmmsg.h"
  34. //
  35. // Private types
  36. //
  37. typedef struct {
  38. DWORD Message;
  39. LPSTR String;
  40. } MESSAGE_STRING, *PMESSAGE_STRING;
  41. #define MSG_NO_MESSAGE 0
  42. #define MAX_ATMLANE_ADAPTERS 64
  43. #define MAX_ATMLANE_ELANS 64
  44. #define MAX_ATMLANE_NAME_LEN 256
  45. #define MAX_ATMLANE_ARP_ENTRIES 4096
  46. #define MAX_ATMLANE_CONNECTIONS 4096
  47. //
  48. // Globals
  49. //
  50. CHAR DefaultDeviceName[] = "\\\\.\\AtmLane";
  51. CHAR *pDeviceName = DefaultDeviceName;
  52. //
  53. // Data structures to store list of adapters:
  54. //
  55. #define ADAPTER_LIST_BUFFER_SIZE (sizeof(ATMLANE_ADAPTER_LIST) + \
  56. (MAX_ATMLANE_ADAPTERS * \
  57. (sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR)))))
  58. UCHAR AdapterListBuffer[ADAPTER_LIST_BUFFER_SIZE];
  59. PATMLANE_ADAPTER_LIST pAdapterList = (PATMLANE_ADAPTER_LIST)AdapterListBuffer;
  60. //
  61. // Data structures to store list of ELANS on an adapter:
  62. //
  63. #define ELAN_LIST_BUFFER_SIZE (sizeof(ATMLANE_ELAN_LIST) + \
  64. (MAX_ATMLANE_ELANS * \
  65. (sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR)))))
  66. UCHAR ElanListBuffer[ELAN_LIST_BUFFER_SIZE];
  67. PATMLANE_ELAN_LIST pElanList = (PATMLANE_ELAN_LIST)ElanListBuffer;
  68. //
  69. // Data structure to hold ELAN information
  70. //
  71. #define ELAN_INFO_BUFFER_SIZE (sizeof(ATMLANE_ELANINFO) + \
  72. ((sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR))) * 2))
  73. UCHAR ElanInfoBuffer[ELAN_INFO_BUFFER_SIZE];
  74. PATMLANE_ELANINFO pElanInfo = (PATMLANE_ELANINFO)ElanInfoBuffer;
  75. //
  76. // Data structure to hold an ELAN's ARP table
  77. //
  78. #define ARP_TABLE_BUFFER_SIZE (sizeof(ATMLANE_ARPTABLE) + \
  79. ((sizeof(ATMLANE_ARPENTRY) * MAX_ATMLANE_ARP_ENTRIES)))
  80. UCHAR ArpTableBuffer[ARP_TABLE_BUFFER_SIZE];
  81. PATMLANE_ARPTABLE pArpTable = (PATMLANE_ARPTABLE)ArpTableBuffer;
  82. //
  83. // Data structure to hold an ELAN's connection table
  84. //
  85. #define CONN_TABLE_BUFFER_SIZE (sizeof(ATMLANE_CONNECTTABLE) + \
  86. ((sizeof(ATMLANE_CONNECTENTRY) * MAX_ATMLANE_CONNECTIONS)))
  87. UCHAR ConnTableBuffer[CONN_TABLE_BUFFER_SIZE];
  88. PATMLANE_CONNECTTABLE pConnTable = (PATMLANE_CONNECTTABLE)ConnTableBuffer;
  89. //
  90. // Internationalizable message strings loaded by this module. If we fail
  91. // to load, default to English language strings.
  92. //
  93. MESSAGE_STRING ElanState[] = {
  94. MSG_ELAN_STATE_UNKNOWN, TEXT(" ? "),
  95. MSG_ELAN_STATE_INIT, TEXT("INITIAL"),
  96. MSG_ELAN_STATE_LECS_CONNECT_ILMI, TEXT("LECS CONNECT ILMI"),
  97. MSG_ELAN_STATE_LECS_CONNECT_WKA, TEXT("LECS CONNECT WKA"),
  98. MSG_ELAN_STATE_LECS_CONNECT_PVC, TEXT("LECS CONNECT PVC"),
  99. MSG_ELAN_STATE_LECS_CONNECT_CFG, TEXT("LECS CONNECT CFG"),
  100. MSG_ELAN_STATE_CONFIGURE, TEXT("CONFIGURE"),
  101. MSG_ELAN_STATE_LES_CONNECT, TEXT("LES CONNECT"),
  102. MSG_ELAN_STATE_JOIN, TEXT("JOIN"),
  103. MSG_ELAN_STATE_BUS_CONNECT, TEXT("BUS CONNECT"),
  104. MSG_ELAN_STATE_OPERATIONAL, TEXT("OPERATIONAL"),
  105. MSG_ELAN_STATE_SHUTDOWN, TEXT("SHUTDOWN")
  106. };
  107. #define NUMBER_OF_ELAN_STATES (sizeof(ElanState)/sizeof(ElanState[0]))
  108. MESSAGE_STRING LanType[] = {
  109. MSG_LANTYPE_UNKNOWN, TEXT(" ? "),
  110. MSG_LANTYPE_UNSPECIFIED, TEXT("Unspecified"),
  111. MSG_LANTYPE_ETHERNET, TEXT("Ethernet/802.3"),
  112. MSG_LANTYPE_TOKENRING, TEXT("Token Ring/802.5")
  113. };
  114. #define NUMBER_OF_LAN_TYPES (sizeof(LanType)/sizeof(LanType[0]))
  115. MESSAGE_STRING VcType[] = {
  116. MSG_VCTYPE_UNKNOWN, TEXT(" ? "),
  117. MSG_VCTYPE_DATA_DIRECT, TEXT("DataDirect"),
  118. MSG_VCTYPE_CONFIG_DIRECT, TEXT("ConfigDirect"),
  119. MSG_VCTYPE_CONTROL_DIRECT, TEXT("CtrlDirect"),
  120. MSG_VCTYPE_CONTROL_DISTRIBUTE, TEXT("+ CtrlDistr"),
  121. MSG_VCTYPE_MULTI_SEND, TEXT("McastSend"),
  122. MSG_VCTYPE_MULTI_FORWARD, TEXT("+ McastFwd")
  123. };
  124. #define NUMBER_OF_VC_TYPES (sizeof(VcType)/sizeof(VcType[0]))
  125. MESSAGE_STRING McastSendVcType[] = {
  126. MSG_MCAST_VCTYPE_UNKNOWN, TEXT(" ? "),
  127. MSG_MCAST_VCTYPE_BESTEFFORT, TEXT("Best Effort"),
  128. MSG_MCAST_VCTYPE_VARIABLE, TEXT("Variable"),
  129. MSG_MCAST_VCTYPE_VARIABLE, TEXT("Constant"),
  130. };
  131. #define NUMBER_OF_MCAST_VC_TYPES (sizeof(McastSendVcType)/sizeof(McastSendVcType[0]))
  132. MESSAGE_STRING Misc[] = {
  133. MSG_NONE, TEXT("None"),
  134. MSG_OFF, TEXT("Off"),
  135. MSG_ON, TEXT("On"),
  136. MSG_UNSPECIFIED, TEXT("Unspecified"),
  137. MSG_NOCONNECT, TEXT("<no connection>")
  138. };
  139. #define NUMBER_OF_MISC (sizeof(Misc)/sizeof(Misc[0]))
  140. MESSAGE_STRING ConnType[] = {
  141. MSG_CONNTYPE_PEER, TEXT("PEER"),
  142. MSG_CONNTYPE_LECS, TEXT("LECS"),
  143. MSG_CONNTYPE_LES, TEXT("LES "),
  144. MSG_CONNTYPE_BUS, TEXT("BUS ")
  145. };
  146. #define NUMBER_OF_CONN_TYPES (sizeof(ConnType)/sizeof(ConnType[0]))
  147. //
  148. // LoadMessageTable
  149. //
  150. // Loads internationalizable strings into a table, replacing the default for
  151. // each. If an error occurs, the English language default is left in place.
  152. //
  153. //
  154. VOID
  155. LoadMessageTable(
  156. PMESSAGE_STRING Table,
  157. UINT MessageCount
  158. )
  159. {
  160. LPTSTR string;
  161. DWORD count;
  162. //
  163. // for all messages in a MESSAGE_STRING table, load the string from this
  164. // module, replacing the default string in the table (only there in case
  165. // we get an error while loading the string, so we at least have English
  166. // to fall back on)
  167. //
  168. while (MessageCount--) {
  169. if (Table->Message != MSG_NO_MESSAGE) {
  170. //
  171. // we really want LoadString here, but LoadString doesn't indicate
  172. // how big the string is, so it doesn't give us an opportunity to
  173. // allocate exactly the right buffer size. FormatMessage does the
  174. // right thing
  175. //
  176. count = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
  177. | FORMAT_MESSAGE_FROM_HMODULE,
  178. NULL, // use default hModule
  179. Table->Message,
  180. 0, // use default language
  181. (LPTSTR)&string,
  182. 0, // minimum size to allocate
  183. NULL // no arguments for inclusion in strings
  184. );
  185. if (count) {
  186. //
  187. // Format message returned the string: replace the English
  188. // language default
  189. //
  190. Table->String = string;
  191. } else {
  192. //
  193. // this is ok if there is no string (e.g. just %0) in the .mc
  194. // file
  195. //
  196. Table->String = TEXT("");
  197. }
  198. }
  199. ++Table;
  200. }
  201. }
  202. //
  203. // LoadMessages - courtesy IPCONFIG
  204. //
  205. // Loads all internationalizable messages into the various tables
  206. //
  207. VOID
  208. LoadMessages(
  209. )
  210. {
  211. LoadMessageTable(ElanState, NUMBER_OF_ELAN_STATES);
  212. LoadMessageTable(LanType, NUMBER_OF_LAN_TYPES);
  213. LoadMessageTable(VcType, NUMBER_OF_VC_TYPES);
  214. LoadMessageTable(McastSendVcType, NUMBER_OF_MCAST_VC_TYPES);
  215. LoadMessageTable(Misc, NUMBER_OF_MISC);
  216. LoadMessageTable(ConnType, NUMBER_OF_CONN_TYPES);
  217. }
  218. VOID
  219. DisplayMessage(
  220. IN BOOLEAN Tabbed,
  221. IN DWORD MessageId,
  222. ...
  223. )
  224. {
  225. va_list pArg;
  226. CHAR MessageBuffer[2048];
  227. INT Count;
  228. va_start(pArg, MessageId);
  229. Count = FormatMessage(
  230. FORMAT_MESSAGE_FROM_HMODULE,
  231. NULL, // default hModule
  232. MessageId,
  233. 0, // default language
  234. MessageBuffer,
  235. sizeof(MessageBuffer),
  236. &pArg
  237. );
  238. va_end(pArg);
  239. if (Tabbed)
  240. {
  241. putchar('\t');
  242. }
  243. printf(MessageBuffer);
  244. }
  245. HANDLE
  246. OpenDevice(
  247. CHAR *pDeviceName
  248. )
  249. {
  250. DWORD DesiredAccess;
  251. DWORD ShareMode;
  252. LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
  253. DWORD CreationDistribution;
  254. DWORD FlagsAndAttributes;
  255. HANDLE TemplateFile;
  256. HANDLE Handle;
  257. DesiredAccess = GENERIC_READ|GENERIC_WRITE;
  258. ShareMode = 0;
  259. CreationDistribution = OPEN_EXISTING;
  260. FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
  261. TemplateFile = (HANDLE)INVALID_HANDLE_VALUE;
  262. Handle = CreateFile(
  263. pDeviceName,
  264. DesiredAccess,
  265. ShareMode,
  266. lpSecurityAttributes,
  267. CreationDistribution,
  268. FlagsAndAttributes,
  269. TemplateFile
  270. );
  271. return (Handle);
  272. }
  273. VOID
  274. CloseDevice(
  275. HANDLE DeviceHandle
  276. )
  277. {
  278. CloseHandle(DeviceHandle);
  279. }
  280. BOOLEAN
  281. CheckVersion(
  282. HANDLE DeviceHandle
  283. )
  284. {
  285. ULONG Version;
  286. ULONG BytesReturned;
  287. if (!DeviceIoControl(
  288. DeviceHandle,
  289. ATMLANE_IOCTL_GET_INFO_VERSION,
  290. (PVOID)&Version,
  291. sizeof(Version),
  292. (PVOID)&Version,
  293. sizeof(Version),
  294. &BytesReturned,
  295. 0))
  296. {
  297. DisplayMessage(FALSE, MSG_ERROR_GETTING_VERSION_INFO);
  298. return FALSE;
  299. }
  300. if (Version != ATMLANE_INFO_VERSION)
  301. {
  302. DisplayMessage(FALSE, MSG_ERROR_INVALID_INFO_VERSION);
  303. return FALSE;
  304. }
  305. return TRUE;
  306. }
  307. BOOLEAN
  308. GetAdapterList(
  309. HANDLE DeviceHandle
  310. )
  311. {
  312. ULONG BytesReturned;
  313. BOOLEAN Result = FALSE;
  314. if (DeviceIoControl(
  315. DeviceHandle,
  316. ATMLANE_IOCTL_ENUM_ADAPTERS,
  317. (PVOID)pAdapterList,
  318. ADAPTER_LIST_BUFFER_SIZE,
  319. (PVOID)pAdapterList,
  320. ADAPTER_LIST_BUFFER_SIZE,
  321. &BytesReturned,
  322. 0))
  323. {
  324. Result = TRUE;
  325. }
  326. else
  327. {
  328. DisplayMessage(FALSE, MSG_ERROR_GETTING_ADAPTER_LIST);
  329. }
  330. return Result;
  331. }
  332. BOOLEAN
  333. GetElanList(
  334. HANDLE DeviceHandle,
  335. PUNICODE_STRING pAdapterName
  336. )
  337. {
  338. ULONG BytesReturned;
  339. BOOLEAN Result = FALSE;
  340. //
  341. // Copy adapter name in to buffer as input
  342. //
  343. memcpy(pElanList, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
  344. if (DeviceIoControl(
  345. DeviceHandle,
  346. ATMLANE_IOCTL_ENUM_ELANS,
  347. (PVOID)pElanList,
  348. sizeof(UNICODE_STRING)+pAdapterName->Length,
  349. (PVOID)pElanList,
  350. ELAN_LIST_BUFFER_SIZE,
  351. &BytesReturned,
  352. 0))
  353. {
  354. Result = TRUE;
  355. }
  356. else
  357. {
  358. DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_LIST);
  359. }
  360. return Result;
  361. }
  362. BOOLEAN
  363. GetElanInfo(
  364. HANDLE DeviceHandle,
  365. PUNICODE_STRING pAdapterName,
  366. PUNICODE_STRING pElanName
  367. )
  368. {
  369. ULONG BytesReturned;
  370. BOOLEAN Result = FALSE;
  371. //
  372. // copy adapter name into buffer as input
  373. //
  374. memcpy(ElanInfoBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
  375. //
  376. // copy elan name in to buffer as input
  377. //
  378. memcpy(ElanInfoBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName,
  379. sizeof(UNICODE_STRING)+pElanName->Length);
  380. if (DeviceIoControl(
  381. DeviceHandle,
  382. ATMLANE_IOCTL_GET_ELAN_INFO,
  383. (PVOID)pElanInfo,
  384. sizeof(UNICODE_STRING)+pAdapterName->Length +
  385. sizeof(UNICODE_STRING)+pElanName->Length,
  386. (PVOID)pElanInfo,
  387. ELAN_INFO_BUFFER_SIZE,
  388. &BytesReturned,
  389. 0))
  390. {
  391. Result = TRUE;
  392. }
  393. else
  394. {
  395. DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_INFO);
  396. }
  397. return Result;
  398. }
  399. BOOLEAN
  400. GetElanArpTable(
  401. HANDLE DeviceHandle,
  402. PUNICODE_STRING pAdapterName,
  403. PUNICODE_STRING pElanName
  404. )
  405. {
  406. ULONG BytesReturned;
  407. BOOLEAN Result = FALSE;
  408. //
  409. // copy adapter name into buffer as input
  410. //
  411. memcpy(ArpTableBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
  412. //
  413. // copy elan name in to buffer as input
  414. //
  415. memcpy(ArpTableBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName,
  416. sizeof(UNICODE_STRING)+pElanName->Length);
  417. if (DeviceIoControl(
  418. DeviceHandle,
  419. ATMLANE_IOCTL_GET_ELAN_ARP_TABLE,
  420. (PVOID)pArpTable,
  421. sizeof(UNICODE_STRING)+pAdapterName->Length +
  422. sizeof(UNICODE_STRING)+pElanName->Length,
  423. (PVOID)pArpTable,
  424. ARP_TABLE_BUFFER_SIZE,
  425. &BytesReturned,
  426. 0))
  427. {
  428. Result = TRUE;
  429. }
  430. else
  431. {
  432. DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_ARP_TABLE);
  433. }
  434. return Result;
  435. }
  436. BOOLEAN
  437. GetElanConnTable(
  438. HANDLE DeviceHandle,
  439. PUNICODE_STRING pAdapterName,
  440. PUNICODE_STRING pElanName
  441. )
  442. {
  443. ULONG BytesReturned;
  444. BOOLEAN Result = FALSE;
  445. //
  446. // copy adapter name into buffer as input
  447. //
  448. memcpy(ConnTableBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
  449. //
  450. // copy elan name in to buffer as input
  451. //
  452. memcpy(ConnTableBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName,
  453. sizeof(UNICODE_STRING)+pElanName->Length);
  454. if (DeviceIoControl(
  455. DeviceHandle,
  456. ATMLANE_IOCTL_GET_ELAN_CONNECT_TABLE,
  457. (PVOID)pConnTable,
  458. sizeof(UNICODE_STRING)+pAdapterName->Length +
  459. sizeof(UNICODE_STRING)+pElanName->Length,
  460. (PVOID)pConnTable,
  461. CONN_TABLE_BUFFER_SIZE,
  462. &BytesReturned,
  463. 0))
  464. {
  465. Result = TRUE;
  466. }
  467. else
  468. {
  469. DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_CONN_TABLE);
  470. }
  471. return Result;
  472. }
  473. LPSTR
  474. ElanStateToString(ULONG In)
  475. {
  476. switch(In)
  477. {
  478. case 1:
  479. case 2:
  480. case 3:
  481. case 4:
  482. case 5:
  483. case 6:
  484. case 7:
  485. case 8:
  486. case 9:
  487. case 10:
  488. case 11:
  489. return (ElanState[In].String);
  490. default:
  491. return (ElanState[0].String);
  492. }
  493. }
  494. LPSTR
  495. ElanLanTypeToString(ULONG In)
  496. {
  497. switch(In)
  498. {
  499. case 0:
  500. return LanType[1].String;
  501. case 1:
  502. return LanType[2].String;
  503. case 2:
  504. return LanType[3].String;
  505. default:
  506. return LanType[0].String;
  507. }
  508. }
  509. LPSTR
  510. ElanMaxFrameSizeToString(ULONG In)
  511. {
  512. switch(In)
  513. {
  514. case 0:
  515. return Misc[3].String;
  516. case 1:
  517. return "1516";
  518. case 2:
  519. return "4544";
  520. case 3:
  521. return "9234";
  522. case 4:
  523. return "18190";
  524. default:
  525. return " ? ";
  526. }
  527. }
  528. LPSTR
  529. McastVcTypeToString(ULONG In)
  530. {
  531. switch(In)
  532. {
  533. case 0:
  534. return McastSendVcType[1].String;
  535. case 1:
  536. return McastSendVcType[2].String;
  537. case 2:
  538. return McastSendVcType[3].String;
  539. default:
  540. return McastSendVcType[0].String;
  541. }
  542. }
  543. PUCHAR
  544. MacAddrToString(PVOID In)
  545. {
  546. static UCHAR String[20];
  547. static PUCHAR HexChars = "0123456789abcdef";
  548. PUCHAR EthAddr = (PUCHAR) In;
  549. UINT i;
  550. PUCHAR s;
  551. for (i = 0, s = String; i < 6; i++, EthAddr++)
  552. {
  553. *s++ = HexChars[(*EthAddr)>>4];
  554. *s++ = HexChars[(*EthAddr)&0xf];
  555. *s++ = '.';
  556. }
  557. *(--s) = '\0';
  558. return String;
  559. }
  560. PUCHAR
  561. AtmAddrToString(PVOID In)
  562. {
  563. static UCHAR String[80];
  564. static PUCHAR HexChars = "0123456789abcdef";
  565. PUCHAR AtmAddr = (PUCHAR) In;
  566. UINT i;
  567. PUCHAR s = String;
  568. *s++ = HexChars[(*AtmAddr)>>4];
  569. *s++ = HexChars[(*AtmAddr++)&0xf]; // 1
  570. *s++ = '.';
  571. *s++ = HexChars[(*AtmAddr)>>4];
  572. *s++ = HexChars[(*AtmAddr++)&0xf]; // 2
  573. *s++ = HexChars[(*AtmAddr)>>4];
  574. *s++ = HexChars[(*AtmAddr++)&0xf]; // 3
  575. *s++ = '.';
  576. *s++ = HexChars[(*AtmAddr)>>4];
  577. *s++ = HexChars[(*AtmAddr++)&0xf]; // 4
  578. *s++ = '.';
  579. *s++ = HexChars[(*AtmAddr)>>4];
  580. *s++ = HexChars[(*AtmAddr++)&0xf]; // 5
  581. *s++ = HexChars[(*AtmAddr)>>4];
  582. *s++ = HexChars[(*AtmAddr++)&0xf]; // 6
  583. *s++ = HexChars[(*AtmAddr)>>4];
  584. *s++ = HexChars[(*AtmAddr++)&0xf]; // 7
  585. *s++ = '.';
  586. *s++ = HexChars[(*AtmAddr)>>4];
  587. *s++ = HexChars[(*AtmAddr++)&0xf]; // 8
  588. *s++ = HexChars[(*AtmAddr)>>4];
  589. *s++ = HexChars[(*AtmAddr++)&0xf]; // 9
  590. *s++ = '.';
  591. *s++ = HexChars[(*AtmAddr)>>4];
  592. *s++ = HexChars[(*AtmAddr++)&0xf]; // 10
  593. *s++ = HexChars[(*AtmAddr)>>4];
  594. *s++ = HexChars[(*AtmAddr++)&0xf]; // 11
  595. *s++ = '.';
  596. *s++ = HexChars[(*AtmAddr)>>4];
  597. *s++ = HexChars[(*AtmAddr++)&0xf]; // 12
  598. *s++ = HexChars[(*AtmAddr)>>4];
  599. *s++ = HexChars[(*AtmAddr++)&0xf]; // 13
  600. *s++ = '.';
  601. *s++ = HexChars[(*AtmAddr)>>4];
  602. *s++ = HexChars[(*AtmAddr++)&0xf]; // 14
  603. *s++ = HexChars[(*AtmAddr)>>4];
  604. *s++ = HexChars[(*AtmAddr++)&0xf]; // 15
  605. *s++ = HexChars[(*AtmAddr)>>4];
  606. *s++ = HexChars[(*AtmAddr++)&0xf]; // 16
  607. *s++ = HexChars[(*AtmAddr)>>4];
  608. *s++ = HexChars[(*AtmAddr++)&0xf]; // 17
  609. *s++ = HexChars[(*AtmAddr)>>4];
  610. *s++ = HexChars[(*AtmAddr++)&0xf]; // 18
  611. *s++ = HexChars[(*AtmAddr)>>4];
  612. *s++ = HexChars[(*AtmAddr++)&0xf]; // 19
  613. *s++ = '.';
  614. *s++ = HexChars[(*AtmAddr)>>4];
  615. *s++ = HexChars[(*AtmAddr++)&0xf]; // 20
  616. *s = '\0';
  617. return String;
  618. }
  619. VOID
  620. DisplayElanInfo(
  621. VOID
  622. )
  623. {
  624. DisplayMessage(FALSE, MSG_ELAN_NUMBER, pElanInfo->ElanNumber);
  625. DisplayMessage(FALSE, MSG_ELAN_STATE, ElanStateToString(pElanInfo->ElanState));
  626. DisplayMessage(FALSE, MSG_C1, AtmAddrToString(&pElanInfo->AtmAddress));
  627. DisplayMessage(FALSE, MSG_C2, ElanLanTypeToString(pElanInfo->LanType));
  628. DisplayMessage(FALSE, MSG_C3, ElanMaxFrameSizeToString(pElanInfo->MaxFrameSizeCode));
  629. DisplayMessage(FALSE, MSG_C4, Misc[1].String); // always off
  630. if (pElanInfo->ElanName[0] == '\0')
  631. {
  632. DisplayMessage(FALSE, MSG_C5, Misc[3].String); // unspecified
  633. }
  634. else
  635. {
  636. DisplayMessage(FALSE, MSG_C5, pElanInfo->ElanName);
  637. }
  638. DisplayMessage(FALSE, MSG_C6, MacAddrToString(&pElanInfo->MacAddress));
  639. DisplayMessage(FALSE, MSG_C7, pElanInfo->ControlTimeout);
  640. DisplayMessage(FALSE, MSG_C8, Misc[0].String);
  641. DisplayMessage(FALSE, MSG_LECS_ADDR, AtmAddrToString(&pElanInfo->LecsAddress));
  642. DisplayMessage(FALSE, MSG_C9, AtmAddrToString(&pElanInfo->LesAddress));
  643. DisplayMessage(FALSE, MSG_BUS_ADDR, AtmAddrToString(&pElanInfo->BusAddress));
  644. DisplayMessage(FALSE, MSG_C10, pElanInfo->MaxUnkFrameCount);
  645. DisplayMessage(FALSE, MSG_C11, pElanInfo->MaxUnkFrameTime);
  646. DisplayMessage(FALSE, MSG_C12, pElanInfo->VccTimeout);
  647. DisplayMessage(FALSE, MSG_C13, pElanInfo->MaxRetryCount);
  648. DisplayMessage(FALSE, MSG_C14, pElanInfo->LecId);
  649. DisplayMessage(FALSE, MSG_C15);
  650. DisplayMessage(FALSE, MSG_C16);
  651. DisplayMessage(FALSE, MSG_C17, pElanInfo->AgingTime);
  652. DisplayMessage(FALSE, MSG_C18, pElanInfo->ForwardDelayTime);
  653. DisplayMessage(FALSE, MSG_C19, pElanInfo->TopologyChange==0?Misc[1].String:Misc[2].String);
  654. DisplayMessage(FALSE, MSG_C20, pElanInfo->ArpResponseTime);
  655. DisplayMessage(FALSE, MSG_C21, pElanInfo->FlushTimeout);
  656. DisplayMessage(FALSE, MSG_C22, pElanInfo->PathSwitchingDelay);
  657. DisplayMessage(FALSE, MSG_C23, pElanInfo->LocalSegmentId);
  658. DisplayMessage(FALSE, MSG_C24, McastVcTypeToString(pElanInfo->McastSendVcType));
  659. DisplayMessage(FALSE, MSG_C25, pElanInfo->McastSendVcAvgRate);
  660. DisplayMessage(FALSE, MSG_C26, pElanInfo->McastSendVcPeakRate);
  661. DisplayMessage(FALSE, MSG_C27, Misc[0].String);
  662. DisplayMessage(FALSE, MSG_C28, pElanInfo->ConnComplTimer);
  663. }
  664. VOID
  665. DisplayElanArpTable(
  666. VOID
  667. )
  668. {
  669. PATMLANE_ARPENTRY pArpEntry;
  670. ULONG i;
  671. DisplayMessage(FALSE, MSG_C16_LE_ARP_CACHE);
  672. pArpEntry = (PATMLANE_ARPENTRY) (ArpTableBuffer + sizeof(ATMLANE_ARPTABLE));
  673. for (i = 0; i < pArpTable->ArpEntriesReturned; i++)
  674. {
  675. DisplayMessage(FALSE, MSG_ARP_ENTRY,
  676. MacAddrToString(pArpEntry->MacAddress),
  677. AtmAddrToString(pArpEntry->AtmAddress));
  678. pArpEntry++;
  679. }
  680. }
  681. VOID
  682. DisplayElanConnTable(
  683. VOID
  684. )
  685. {
  686. PATMLANE_CONNECTENTRY pConnEntry;
  687. ULONG i;
  688. DisplayMessage(FALSE, MSG_CONN_CACHE);
  689. pConnEntry = (PATMLANE_CONNECTENTRY) (ConnTableBuffer + sizeof(ATMLANE_CONNECTTABLE));
  690. for (i = 0; i < pConnTable->ConnectEntriesReturned; i++)
  691. {
  692. switch (pConnEntry->Type)
  693. {
  694. default:
  695. case 0: // peer
  696. DisplayMessage(FALSE, MSG_CONN_ENTRY,
  697. ConnType[0].String,
  698. AtmAddrToString(pConnEntry->AtmAddress),
  699. pConnEntry->Vc?VcType[1].String:Misc[4].String,
  700. TEXT(""));
  701. break;
  702. case 1: // lecs
  703. DisplayMessage(FALSE, MSG_CONN_ENTRY,
  704. ConnType[1].String,
  705. AtmAddrToString(pConnEntry->AtmAddress),
  706. pConnEntry->Vc?VcType[2].String:Misc[4].String,
  707. TEXT(""));
  708. break;
  709. case 2: // les
  710. DisplayMessage(FALSE, MSG_CONN_ENTRY,
  711. ConnType[2].String,
  712. AtmAddrToString(pConnEntry->AtmAddress),
  713. pConnEntry->Vc?VcType[3].String:Misc[4].String,
  714. pConnEntry->VcIncoming?VcType[4].String:TEXT(""));
  715. break;
  716. case 3: // bus
  717. DisplayMessage(FALSE, MSG_CONN_ENTRY,
  718. ConnType[3].String,
  719. AtmAddrToString(pConnEntry->AtmAddress),
  720. pConnEntry->Vc?VcType[5].String:Misc[4].String,
  721. pConnEntry->VcIncoming?VcType[6].String:TEXT(""));
  722. break;
  723. }
  724. pConnEntry++;
  725. }
  726. }
  727. VOID __cdecl
  728. main(
  729. INT argc,
  730. CHAR *argv[]
  731. )
  732. {
  733. HANDLE DeviceHandle;
  734. PUNICODE_STRING pAdapterName;
  735. PUNICODE_STRING pElanName;
  736. ULONG i, j;
  737. BOOLEAN Result;
  738. DisplayMessage(FALSE, MSG_ATMLANE_BANNER);
  739. DeviceHandle = OpenDevice(pDeviceName);
  740. if (DeviceHandle == INVALID_HANDLE_VALUE)
  741. {
  742. DisplayMessage(FALSE, MSG_ERROR_OPENING_DEVICE);
  743. return;
  744. }
  745. //
  746. // First check the version
  747. //
  748. if (!CheckVersion(DeviceHandle))
  749. {
  750. CloseDevice(DeviceHandle);
  751. return;
  752. }
  753. //
  754. // First get the list of available adapters
  755. //
  756. if (!GetAdapterList(DeviceHandle))
  757. {
  758. CloseDevice(DeviceHandle);
  759. return;
  760. }
  761. //
  762. // Loop thru the adapters getting each adapter's elan list
  763. //
  764. pAdapterName = &pAdapterList->AdapterList;
  765. for (i = 0; i < pAdapterList->AdapterCountReturned; i++)
  766. {
  767. DisplayMessage(FALSE, MSG_ADAPTER,
  768. (PWSTR)((PUCHAR)pAdapterName + sizeof(UNICODE_STRING)));
  769. if (GetElanList(DeviceHandle, pAdapterName))
  770. {
  771. //
  772. // Loop thru the elan list getting ELAN info
  773. //
  774. pElanName = &pElanList->ElanList;
  775. for (j = 0; j < pElanList->ElanCountReturned; j++)
  776. {
  777. DisplayMessage(FALSE, MSG_ELAN,
  778. (PWSTR)((PUCHAR)pElanName + sizeof(UNICODE_STRING)));
  779. if (GetElanInfo(DeviceHandle, pAdapterName, pElanName))
  780. {
  781. DisplayElanInfo();
  782. }
  783. if (GetElanArpTable(DeviceHandle, pAdapterName, pElanName))
  784. {
  785. DisplayElanArpTable();
  786. }
  787. if (GetElanConnTable(DeviceHandle, pAdapterName, pElanName))
  788. {
  789. DisplayElanConnTable();
  790. }
  791. //
  792. // next elan
  793. //
  794. pElanName = (PUNICODE_STRING)((PUCHAR)pElanName +
  795. sizeof(UNICODE_STRING) + pElanName->Length);
  796. }
  797. }
  798. //
  799. // next adapter
  800. //
  801. pAdapterName = (PUNICODE_STRING)((PUCHAR)pAdapterName +
  802. sizeof(UNICODE_STRING) + pAdapterName->Length);
  803. }
  804. CloseDevice(DeviceHandle);
  805. return;
  806. }