windows-nt/Source/XPSP1/NT/net/atm/lane/exe/atmlane.c

952 lines
22 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 FORE Systems, Inc.
Copyright (c) 1997 Microsoft Corporation
Module Name:
atmlane.c
Abstract:
ATM LAN Emulation Client Admin Utility.
Usage:
atmlane
Revision History:
Who When What
-------- -------- ---------------------------------------------
v-lcleet 02-03-98 Created
Notes:
Modelled after atmadm utility from the UNI 3.1 Call Manager
--*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
#include <malloc.h>
#include <time.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <winerror.h>
#include <winsock.h>
#ifndef NDIS_STATUS
#define NDIS_STATUS ULONG
#endif
#include "laneinfo.h"
#include "atmmsg.h"
//
// Private types
//
typedef struct {
DWORD Message;
LPSTR String;
} MESSAGE_STRING, *PMESSAGE_STRING;
#define MSG_NO_MESSAGE 0
#define MAX_ATMLANE_ADAPTERS 64
#define MAX_ATMLANE_ELANS 64
#define MAX_ATMLANE_NAME_LEN 256
#define MAX_ATMLANE_ARP_ENTRIES 4096
#define MAX_ATMLANE_CONNECTIONS 4096
//
// Globals
//
CHAR DefaultDeviceName[] = "\\\\.\\AtmLane";
CHAR *pDeviceName = DefaultDeviceName;
//
// Data structures to store list of adapters:
//
#define ADAPTER_LIST_BUFFER_SIZE (sizeof(ATMLANE_ADAPTER_LIST) + \
(MAX_ATMLANE_ADAPTERS * \
(sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR)))))
UCHAR AdapterListBuffer[ADAPTER_LIST_BUFFER_SIZE];
PATMLANE_ADAPTER_LIST pAdapterList = (PATMLANE_ADAPTER_LIST)AdapterListBuffer;
//
// Data structures to store list of ELANS on an adapter:
//
#define ELAN_LIST_BUFFER_SIZE (sizeof(ATMLANE_ELAN_LIST) + \
(MAX_ATMLANE_ELANS * \
(sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR)))))
UCHAR ElanListBuffer[ELAN_LIST_BUFFER_SIZE];
PATMLANE_ELAN_LIST pElanList = (PATMLANE_ELAN_LIST)ElanListBuffer;
//
// Data structure to hold ELAN information
//
#define ELAN_INFO_BUFFER_SIZE (sizeof(ATMLANE_ELANINFO) + \
((sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR))) * 2))
UCHAR ElanInfoBuffer[ELAN_INFO_BUFFER_SIZE];
PATMLANE_ELANINFO pElanInfo = (PATMLANE_ELANINFO)ElanInfoBuffer;
//
// Data structure to hold an ELAN's ARP table
//
#define ARP_TABLE_BUFFER_SIZE (sizeof(ATMLANE_ARPTABLE) + \
((sizeof(ATMLANE_ARPENTRY) * MAX_ATMLANE_ARP_ENTRIES)))
UCHAR ArpTableBuffer[ARP_TABLE_BUFFER_SIZE];
PATMLANE_ARPTABLE pArpTable = (PATMLANE_ARPTABLE)ArpTableBuffer;
//
// Data structure to hold an ELAN's connection table
//
#define CONN_TABLE_BUFFER_SIZE (sizeof(ATMLANE_CONNECTTABLE) + \
((sizeof(ATMLANE_CONNECTENTRY) * MAX_ATMLANE_CONNECTIONS)))
UCHAR ConnTableBuffer[CONN_TABLE_BUFFER_SIZE];
PATMLANE_CONNECTTABLE pConnTable = (PATMLANE_CONNECTTABLE)ConnTableBuffer;
//
// Internationalizable message strings loaded by this module. If we fail
// to load, default to English language strings.
//
MESSAGE_STRING ElanState[] = {
MSG_ELAN_STATE_UNKNOWN, TEXT(" ? "),
MSG_ELAN_STATE_INIT, TEXT("INITIAL"),
MSG_ELAN_STATE_LECS_CONNECT_ILMI, TEXT("LECS CONNECT ILMI"),
MSG_ELAN_STATE_LECS_CONNECT_WKA, TEXT("LECS CONNECT WKA"),
MSG_ELAN_STATE_LECS_CONNECT_PVC, TEXT("LECS CONNECT PVC"),
MSG_ELAN_STATE_LECS_CONNECT_CFG, TEXT("LECS CONNECT CFG"),
MSG_ELAN_STATE_CONFIGURE, TEXT("CONFIGURE"),
MSG_ELAN_STATE_LES_CONNECT, TEXT("LES CONNECT"),
MSG_ELAN_STATE_JOIN, TEXT("JOIN"),
MSG_ELAN_STATE_BUS_CONNECT, TEXT("BUS CONNECT"),
MSG_ELAN_STATE_OPERATIONAL, TEXT("OPERATIONAL"),
MSG_ELAN_STATE_SHUTDOWN, TEXT("SHUTDOWN")
};
#define NUMBER_OF_ELAN_STATES (sizeof(ElanState)/sizeof(ElanState[0]))
MESSAGE_STRING LanType[] = {
MSG_LANTYPE_UNKNOWN, TEXT(" ? "),
MSG_LANTYPE_UNSPECIFIED, TEXT("Unspecified"),
MSG_LANTYPE_ETHERNET, TEXT("Ethernet/802.3"),
MSG_LANTYPE_TOKENRING, TEXT("Token Ring/802.5")
};
#define NUMBER_OF_LAN_TYPES (sizeof(LanType)/sizeof(LanType[0]))
MESSAGE_STRING VcType[] = {
MSG_VCTYPE_UNKNOWN, TEXT(" ? "),
MSG_VCTYPE_DATA_DIRECT, TEXT("DataDirect"),
MSG_VCTYPE_CONFIG_DIRECT, TEXT("ConfigDirect"),
MSG_VCTYPE_CONTROL_DIRECT, TEXT("CtrlDirect"),
MSG_VCTYPE_CONTROL_DISTRIBUTE, TEXT("+ CtrlDistr"),
MSG_VCTYPE_MULTI_SEND, TEXT("McastSend"),
MSG_VCTYPE_MULTI_FORWARD, TEXT("+ McastFwd")
};
#define NUMBER_OF_VC_TYPES (sizeof(VcType)/sizeof(VcType[0]))
MESSAGE_STRING McastSendVcType[] = {
MSG_MCAST_VCTYPE_UNKNOWN, TEXT(" ? "),
MSG_MCAST_VCTYPE_BESTEFFORT, TEXT("Best Effort"),
MSG_MCAST_VCTYPE_VARIABLE, TEXT("Variable"),
MSG_MCAST_VCTYPE_VARIABLE, TEXT("Constant"),
};
#define NUMBER_OF_MCAST_VC_TYPES (sizeof(McastSendVcType)/sizeof(McastSendVcType[0]))
MESSAGE_STRING Misc[] = {
MSG_NONE, TEXT("None"),
MSG_OFF, TEXT("Off"),
MSG_ON, TEXT("On"),
MSG_UNSPECIFIED, TEXT("Unspecified"),
MSG_NOCONNECT, TEXT("<no connection>")
};
#define NUMBER_OF_MISC (sizeof(Misc)/sizeof(Misc[0]))
MESSAGE_STRING ConnType[] = {
MSG_CONNTYPE_PEER, TEXT("PEER"),
MSG_CONNTYPE_LECS, TEXT("LECS"),
MSG_CONNTYPE_LES, TEXT("LES "),
MSG_CONNTYPE_BUS, TEXT("BUS ")
};
#define NUMBER_OF_CONN_TYPES (sizeof(ConnType)/sizeof(ConnType[0]))
//
// LoadMessageTable
//
// Loads internationalizable strings into a table, replacing the default for
// each. If an error occurs, the English language default is left in place.
//
//
VOID
LoadMessageTable(
PMESSAGE_STRING Table,
UINT MessageCount
)
{
LPTSTR string;
DWORD count;
//
// for all messages in a MESSAGE_STRING table, load the string from this
// module, replacing the default string in the table (only there in case
// we get an error while loading the string, so we at least have English
// to fall back on)
//
while (MessageCount--) {
if (Table->Message != MSG_NO_MESSAGE) {
//
// we really want LoadString here, but LoadString doesn't indicate
// how big the string is, so it doesn't give us an opportunity to
// allocate exactly the right buffer size. FormatMessage does the
// right thing
//
count = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE,
NULL, // use default hModule
Table->Message,
0, // use default language
(LPTSTR)&string,
0, // minimum size to allocate
NULL // no arguments for inclusion in strings
);
if (count) {
//
// Format message returned the string: replace the English
// language default
//
Table->String = string;
} else {
//
// this is ok if there is no string (e.g. just %0) in the .mc
// file
//
Table->String = TEXT("");
}
}
++Table;
}
}
//
// LoadMessages - courtesy IPCONFIG
//
// Loads all internationalizable messages into the various tables
//
VOID
LoadMessages(
)
{
LoadMessageTable(ElanState, NUMBER_OF_ELAN_STATES);
LoadMessageTable(LanType, NUMBER_OF_LAN_TYPES);
LoadMessageTable(VcType, NUMBER_OF_VC_TYPES);
LoadMessageTable(McastSendVcType, NUMBER_OF_MCAST_VC_TYPES);
LoadMessageTable(Misc, NUMBER_OF_MISC);
LoadMessageTable(ConnType, NUMBER_OF_CONN_TYPES);
}
VOID
DisplayMessage(
IN BOOLEAN Tabbed,
IN DWORD MessageId,
...
)
{
va_list pArg;
CHAR MessageBuffer[2048];
INT Count;
va_start(pArg, MessageId);
Count = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
NULL, // default hModule
MessageId,
0, // default language
MessageBuffer,
sizeof(MessageBuffer),
&pArg
);
va_end(pArg);
if (Tabbed)
{
putchar('\t');
}
printf(MessageBuffer);
}
HANDLE
OpenDevice(
CHAR *pDeviceName
)
{
DWORD DesiredAccess;
DWORD ShareMode;
LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
DWORD CreationDistribution;
DWORD FlagsAndAttributes;
HANDLE TemplateFile;
HANDLE Handle;
DesiredAccess = GENERIC_READ|GENERIC_WRITE;
ShareMode = 0;
CreationDistribution = OPEN_EXISTING;
FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
TemplateFile = (HANDLE)INVALID_HANDLE_VALUE;
Handle = CreateFile(
pDeviceName,
DesiredAccess,
ShareMode,
lpSecurityAttributes,
CreationDistribution,
FlagsAndAttributes,
TemplateFile
);
return (Handle);
}
VOID
CloseDevice(
HANDLE DeviceHandle
)
{
CloseHandle(DeviceHandle);
}
BOOLEAN
CheckVersion(
HANDLE DeviceHandle
)
{
ULONG Version;
ULONG BytesReturned;
if (!DeviceIoControl(
DeviceHandle,
ATMLANE_IOCTL_GET_INFO_VERSION,
(PVOID)&Version,
sizeof(Version),
(PVOID)&Version,
sizeof(Version),
&BytesReturned,
0))
{
DisplayMessage(FALSE, MSG_ERROR_GETTING_VERSION_INFO);
return FALSE;
}
if (Version != ATMLANE_INFO_VERSION)
{
DisplayMessage(FALSE, MSG_ERROR_INVALID_INFO_VERSION);
return FALSE;
}
return TRUE;
}
BOOLEAN
GetAdapterList(
HANDLE DeviceHandle
)
{
ULONG BytesReturned;
BOOLEAN Result = FALSE;
if (DeviceIoControl(
DeviceHandle,
ATMLANE_IOCTL_ENUM_ADAPTERS,
(PVOID)pAdapterList,
ADAPTER_LIST_BUFFER_SIZE,
(PVOID)pAdapterList,
ADAPTER_LIST_BUFFER_SIZE,
&BytesReturned,
0))
{
Result = TRUE;
}
else
{
DisplayMessage(FALSE, MSG_ERROR_GETTING_ADAPTER_LIST);
}
return Result;
}
BOOLEAN
GetElanList(
HANDLE DeviceHandle,
PUNICODE_STRING pAdapterName
)
{
ULONG BytesReturned;
BOOLEAN Result = FALSE;
//
// Copy adapter name in to buffer as input
//
memcpy(pElanList, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
if (DeviceIoControl(
DeviceHandle,
ATMLANE_IOCTL_ENUM_ELANS,
(PVOID)pElanList,
sizeof(UNICODE_STRING)+pAdapterName->Length,
(PVOID)pElanList,
ELAN_LIST_BUFFER_SIZE,
&BytesReturned,
0))
{
Result = TRUE;
}
else
{
DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_LIST);
}
return Result;
}
BOOLEAN
GetElanInfo(
HANDLE DeviceHandle,
PUNICODE_STRING pAdapterName,
PUNICODE_STRING pElanName
)
{
ULONG BytesReturned;
BOOLEAN Result = FALSE;
//
// copy adapter name into buffer as input
//
memcpy(ElanInfoBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
//
// copy elan name in to buffer as input
//
memcpy(ElanInfoBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName,
sizeof(UNICODE_STRING)+pElanName->Length);
if (DeviceIoControl(
DeviceHandle,
ATMLANE_IOCTL_GET_ELAN_INFO,
(PVOID)pElanInfo,
sizeof(UNICODE_STRING)+pAdapterName->Length +
sizeof(UNICODE_STRING)+pElanName->Length,
(PVOID)pElanInfo,
ELAN_INFO_BUFFER_SIZE,
&BytesReturned,
0))
{
Result = TRUE;
}
else
{
DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_INFO);
}
return Result;
}
BOOLEAN
GetElanArpTable(
HANDLE DeviceHandle,
PUNICODE_STRING pAdapterName,
PUNICODE_STRING pElanName
)
{
ULONG BytesReturned;
BOOLEAN Result = FALSE;
//
// copy adapter name into buffer as input
//
memcpy(ArpTableBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
//
// copy elan name in to buffer as input
//
memcpy(ArpTableBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName,
sizeof(UNICODE_STRING)+pElanName->Length);
if (DeviceIoControl(
DeviceHandle,
ATMLANE_IOCTL_GET_ELAN_ARP_TABLE,
(PVOID)pArpTable,
sizeof(UNICODE_STRING)+pAdapterName->Length +
sizeof(UNICODE_STRING)+pElanName->Length,
(PVOID)pArpTable,
ARP_TABLE_BUFFER_SIZE,
&BytesReturned,
0))
{
Result = TRUE;
}
else
{
DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_ARP_TABLE);
}
return Result;
}
BOOLEAN
GetElanConnTable(
HANDLE DeviceHandle,
PUNICODE_STRING pAdapterName,
PUNICODE_STRING pElanName
)
{
ULONG BytesReturned;
BOOLEAN Result = FALSE;
//
// copy adapter name into buffer as input
//
memcpy(ConnTableBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length);
//
// copy elan name in to buffer as input
//
memcpy(ConnTableBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName,
sizeof(UNICODE_STRING)+pElanName->Length);
if (DeviceIoControl(
DeviceHandle,
ATMLANE_IOCTL_GET_ELAN_CONNECT_TABLE,
(PVOID)pConnTable,
sizeof(UNICODE_STRING)+pAdapterName->Length +
sizeof(UNICODE_STRING)+pElanName->Length,
(PVOID)pConnTable,
CONN_TABLE_BUFFER_SIZE,
&BytesReturned,
0))
{
Result = TRUE;
}
else
{
DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_CONN_TABLE);
}
return Result;
}
LPSTR
ElanStateToString(ULONG In)
{
switch(In)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
return (ElanState[In].String);
default:
return (ElanState[0].String);
}
}
LPSTR
ElanLanTypeToString(ULONG In)
{
switch(In)
{
case 0:
return LanType[1].String;
case 1:
return LanType[2].String;
case 2:
return LanType[3].String;
default:
return LanType[0].String;
}
}
LPSTR
ElanMaxFrameSizeToString(ULONG In)
{
switch(In)
{
case 0:
return Misc[3].String;
case 1:
return "1516";
case 2:
return "4544";
case 3:
return "9234";
case 4:
return "18190";
default:
return " ? ";
}
}
LPSTR
McastVcTypeToString(ULONG In)
{
switch(In)
{
case 0:
return McastSendVcType[1].String;
case 1:
return McastSendVcType[2].String;
case 2:
return McastSendVcType[3].String;
default:
return McastSendVcType[0].String;
}
}
PUCHAR
MacAddrToString(PVOID In)
{
static UCHAR String[20];
static PUCHAR HexChars = "0123456789abcdef";
PUCHAR EthAddr = (PUCHAR) In;
UINT i;
PUCHAR s;
for (i = 0, s = String; i < 6; i++, EthAddr++)
{
*s++ = HexChars[(*EthAddr)>>4];
*s++ = HexChars[(*EthAddr)&0xf];
*s++ = '.';
}
*(--s) = '\0';
return String;
}
PUCHAR
AtmAddrToString(PVOID In)
{
static UCHAR String[80];
static PUCHAR HexChars = "0123456789abcdef";
PUCHAR AtmAddr = (PUCHAR) In;
UINT i;
PUCHAR s = String;
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 1
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 2
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 3
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 4
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 5
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 6
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 7
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 8
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 9
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 10
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 11
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 12
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 13
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 14
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 15
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 16
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 17
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 18
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 19
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 20
*s = '\0';
return String;
}
VOID
DisplayElanInfo(
VOID
)
{
DisplayMessage(FALSE, MSG_ELAN_NUMBER, pElanInfo->ElanNumber);
DisplayMessage(FALSE, MSG_ELAN_STATE, ElanStateToString(pElanInfo->ElanState));
DisplayMessage(FALSE, MSG_C1, AtmAddrToString(&pElanInfo->AtmAddress));
DisplayMessage(FALSE, MSG_C2, ElanLanTypeToString(pElanInfo->LanType));
DisplayMessage(FALSE, MSG_C3, ElanMaxFrameSizeToString(pElanInfo->MaxFrameSizeCode));
DisplayMessage(FALSE, MSG_C4, Misc[1].String); // always off
if (pElanInfo->ElanName[0] == '\0')
{
DisplayMessage(FALSE, MSG_C5, Misc[3].String); // unspecified
}
else
{
DisplayMessage(FALSE, MSG_C5, pElanInfo->ElanName);
}
DisplayMessage(FALSE, MSG_C6, MacAddrToString(&pElanInfo->MacAddress));
DisplayMessage(FALSE, MSG_C7, pElanInfo->ControlTimeout);
DisplayMessage(FALSE, MSG_C8, Misc[0].String);
DisplayMessage(FALSE, MSG_LECS_ADDR, AtmAddrToString(&pElanInfo->LecsAddress));
DisplayMessage(FALSE, MSG_C9, AtmAddrToString(&pElanInfo->LesAddress));
DisplayMessage(FALSE, MSG_BUS_ADDR, AtmAddrToString(&pElanInfo->BusAddress));
DisplayMessage(FALSE, MSG_C10, pElanInfo->MaxUnkFrameCount);
DisplayMessage(FALSE, MSG_C11, pElanInfo->MaxUnkFrameTime);
DisplayMessage(FALSE, MSG_C12, pElanInfo->VccTimeout);
DisplayMessage(FALSE, MSG_C13, pElanInfo->MaxRetryCount);
DisplayMessage(FALSE, MSG_C14, pElanInfo->LecId);
DisplayMessage(FALSE, MSG_C15);
DisplayMessage(FALSE, MSG_C16);
DisplayMessage(FALSE, MSG_C17, pElanInfo->AgingTime);
DisplayMessage(FALSE, MSG_C18, pElanInfo->ForwardDelayTime);
DisplayMessage(FALSE, MSG_C19, pElanInfo->TopologyChange==0?Misc[1].String:Misc[2].String);
DisplayMessage(FALSE, MSG_C20, pElanInfo->ArpResponseTime);
DisplayMessage(FALSE, MSG_C21, pElanInfo->FlushTimeout);
DisplayMessage(FALSE, MSG_C22, pElanInfo->PathSwitchingDelay);
DisplayMessage(FALSE, MSG_C23, pElanInfo->LocalSegmentId);
DisplayMessage(FALSE, MSG_C24, McastVcTypeToString(pElanInfo->McastSendVcType));
DisplayMessage(FALSE, MSG_C25, pElanInfo->McastSendVcAvgRate);
DisplayMessage(FALSE, MSG_C26, pElanInfo->McastSendVcPeakRate);
DisplayMessage(FALSE, MSG_C27, Misc[0].String);
DisplayMessage(FALSE, MSG_C28, pElanInfo->ConnComplTimer);
}
VOID
DisplayElanArpTable(
VOID
)
{
PATMLANE_ARPENTRY pArpEntry;
ULONG i;
DisplayMessage(FALSE, MSG_C16_LE_ARP_CACHE);
pArpEntry = (PATMLANE_ARPENTRY) (ArpTableBuffer + sizeof(ATMLANE_ARPTABLE));
for (i = 0; i < pArpTable->ArpEntriesReturned; i++)
{
DisplayMessage(FALSE, MSG_ARP_ENTRY,
MacAddrToString(pArpEntry->MacAddress),
AtmAddrToString(pArpEntry->AtmAddress));
pArpEntry++;
}
}
VOID
DisplayElanConnTable(
VOID
)
{
PATMLANE_CONNECTENTRY pConnEntry;
ULONG i;
DisplayMessage(FALSE, MSG_CONN_CACHE);
pConnEntry = (PATMLANE_CONNECTENTRY) (ConnTableBuffer + sizeof(ATMLANE_CONNECTTABLE));
for (i = 0; i < pConnTable->ConnectEntriesReturned; i++)
{
switch (pConnEntry->Type)
{
default:
case 0: // peer
DisplayMessage(FALSE, MSG_CONN_ENTRY,
ConnType[0].String,
AtmAddrToString(pConnEntry->AtmAddress),
pConnEntry->Vc?VcType[1].String:Misc[4].String,
TEXT(""));
break;
case 1: // lecs
DisplayMessage(FALSE, MSG_CONN_ENTRY,
ConnType[1].String,
AtmAddrToString(pConnEntry->AtmAddress),
pConnEntry->Vc?VcType[2].String:Misc[4].String,
TEXT(""));
break;
case 2: // les
DisplayMessage(FALSE, MSG_CONN_ENTRY,
ConnType[2].String,
AtmAddrToString(pConnEntry->AtmAddress),
pConnEntry->Vc?VcType[3].String:Misc[4].String,
pConnEntry->VcIncoming?VcType[4].String:TEXT(""));
break;
case 3: // bus
DisplayMessage(FALSE, MSG_CONN_ENTRY,
ConnType[3].String,
AtmAddrToString(pConnEntry->AtmAddress),
pConnEntry->Vc?VcType[5].String:Misc[4].String,
pConnEntry->VcIncoming?VcType[6].String:TEXT(""));
break;
}
pConnEntry++;
}
}
VOID __cdecl
main(
INT argc,
CHAR *argv[]
)
{
HANDLE DeviceHandle;
PUNICODE_STRING pAdapterName;
PUNICODE_STRING pElanName;
ULONG i, j;
BOOLEAN Result;
DisplayMessage(FALSE, MSG_ATMLANE_BANNER);
DeviceHandle = OpenDevice(pDeviceName);
if (DeviceHandle == INVALID_HANDLE_VALUE)
{
DisplayMessage(FALSE, MSG_ERROR_OPENING_DEVICE);
return;
}
//
// First check the version
//
if (!CheckVersion(DeviceHandle))
{
CloseDevice(DeviceHandle);
return;
}
//
// First get the list of available adapters
//
if (!GetAdapterList(DeviceHandle))
{
CloseDevice(DeviceHandle);
return;
}
//
// Loop thru the adapters getting each adapter's elan list
//
pAdapterName = &pAdapterList->AdapterList;
for (i = 0; i < pAdapterList->AdapterCountReturned; i++)
{
DisplayMessage(FALSE, MSG_ADAPTER,
(PWSTR)((PUCHAR)pAdapterName + sizeof(UNICODE_STRING)));
if (GetElanList(DeviceHandle, pAdapterName))
{
//
// Loop thru the elan list getting ELAN info
//
pElanName = &pElanList->ElanList;
for (j = 0; j < pElanList->ElanCountReturned; j++)
{
DisplayMessage(FALSE, MSG_ELAN,
(PWSTR)((PUCHAR)pElanName + sizeof(UNICODE_STRING)));
if (GetElanInfo(DeviceHandle, pAdapterName, pElanName))
{
DisplayElanInfo();
}
if (GetElanArpTable(DeviceHandle, pAdapterName, pElanName))
{
DisplayElanArpTable();
}
if (GetElanConnTable(DeviceHandle, pAdapterName, pElanName))
{
DisplayElanConnTable();
}
//
// next elan
//
pElanName = (PUNICODE_STRING)((PUCHAR)pElanName +
sizeof(UNICODE_STRING) + pElanName->Length);
}
}
//
// next adapter
//
pAdapterName = (PUNICODE_STRING)((PUCHAR)pAdapterName +
sizeof(UNICODE_STRING) + pAdapterName->Length);
}
CloseDevice(DeviceHandle);
return;
}