|
|
|
|
Rawether .NET C# Enumeration Test ApplicationVersion 5.51.18.01, August 12, 2004
using System; using System.IO; using System.Threading; using System.Collections; using System.Net; using PcaUsa.Rawether; using PcaUsa.Rawether.IO; using PcaUsa.Rawether.ProtocolInterface; using PcaUsa.Ndis; using PcaUsa.Ethernet; // Copyright And Configuration Management ---------------------------------- // // Rawether.NET Adapter Enumeration Sample Application - EnumTest.cs // // Rawether.NET for Windows // // Copyright (c) 2003-2004, Printing Communications Associates, Inc. (PCAUSA) // // Thomas F. Divine // 4201 Brunswick Court // Smyrna, Georgia 30080 USA // (770) 432-4580 // tdivine@pcausa.com // // End --------------------------------------------------------------------- namespace PcaUsa.EnumTest
{
/// <summary>
/// Rawether.NET C# adapter enumeration sample application.
/// </summary>
class EnumTest
{
/////////////////////////////////////////////////////////////////////////////
#region DisplayGeneralStatistics Test
/// <summary>
/// Make NDIS queries and display AdapterObject general statistics.
/// </summary>
/// <param name="adapter">Specifies the adapter to be queried.</param>
/// <remarks>These are various queries from the OID_GEN_XYZ family. Here we use the
/// QueryInformation function, which provides a simple interface for fetching
/// non-critical numeric values. The function is called in the "quiet mode" by specifying
/// a default value. This overloaded version of QueryInformation makes the query and
/// catches I/O and NDIS exceptions. If an exception is encountered default value is silently
/// returned.</remarks>
static void DisplayGeneralStatistics( AdapterObject adapter )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Adapter General Statistics" );
// For this simple console sample application make a list of statistics OIDs to
// query and then query each OID OID in the list in a loop. All statistic OID return
// values are fetched as Uint32 - although Uint64 could be used if desired.
//
// The loop displays the OID using ToString, so it is not "pretty" but easy to implement.
// Build list of statistics OIDs To query.
Ndis.Oid[] queryList =
new Ndis.Oid[]{
//
// Mandatory General Statistics Queries
//
Ndis.Oid.OID_GEN_XMIT_OK,
Ndis.Oid.OID_GEN_RCV_OK,
Ndis.Oid.OID_GEN_XMIT_ERROR,
Ndis.Oid.OID_GEN_RCV_ERROR,
Ndis.Oid.OID_GEN_RCV_NO_BUFFER,
//
// Optional General Statistics Queries
//
Ndis.Oid.OID_GEN_DIRECTED_BYTES_XMIT,
Ndis.Oid.OID_GEN_DIRECTED_FRAMES_XMIT,
Ndis.Oid.OID_GEN_MULTICAST_BYTES_XMIT,
Ndis.Oid.OID_GEN_MULTICAST_FRAMES_XMIT,
Ndis.Oid.OID_GEN_BROADCAST_BYTES_XMIT,
Ndis.Oid.OID_GEN_BROADCAST_FRAMES_XMIT,
Ndis.Oid.OID_GEN_DIRECTED_BYTES_RCV,
Ndis.Oid.OID_GEN_DIRECTED_FRAMES_RCV,
Oid.OID_GEN_MULTICAST_BYTES_RCV,
Ndis.Oid.OID_GEN_MULTICAST_FRAMES_RCV,
Ndis.Oid.OID_GEN_BROADCAST_BYTES_RCV,
Ndis.Oid.OID_GEN_BROADCAST_FRAMES_RCV,
Ndis.Oid.OID_GEN_RCV_CRC_ERROR,
Ndis.Oid.OID_GEN_TRANSMIT_QUEUE_LENGTH
};
// Query each OID in the list.
for( int i = 0; i < queryList.GetLength(0); ++i )
{
uint statistic = 0; // Could use ulong (Uint64) if desired...
uint returnValue = adapter.QueryInformation( queryList[i], ref statistic, 0 ); if( returnValue == 0 )
Console.WriteLine( " {0}: {1}", queryList[i].ToString(), statistic );
else
Console.WriteLine( " {0}: Query Failed; Status: {1}", queryList[i].ToString(), (Ndis.Status )returnValue );
}
Console.WriteLine();
}
#endregion /////////////////////////////////////////////////////////////////////////////
#region DisplayEthernetStatistics Test
/// <summary>
/// Make NDIS queries and display AdapterObject Ethernet statistics characteristics.
/// </summary>
/// <param name="adapter">Specifies the adapter to be queried.</param>
/// <remarks>These are various queries from the OID_802_11_XYZ family. Here we use helper
/// functions designed to simplify fetching operational characteristics.</remarks>
static void DisplayEthernetStatistics( AdapterObject adapter )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Adapter Ethernet Statistics" );
// For this simple console sample application make a list of statistics OIDs to
// query and then query each OID OID in the list in a loop. All statistic OID return
// values are fetched as Uint32 - although Uint64 could be used if desired.
//
// The loop displays the OID using ToString, so it is not "pretty" but easy to implement.
// Build list of statistics OIDs To query.
Ndis.Oid[] queryList =
new Ndis.Oid[]{
//
// Mandatory Ethernet Statistics Queries
//
Ndis.Oid.OID_802_3_RCV_ERROR_ALIGNMENT,
Ndis.Oid.OID_802_3_XMIT_ONE_COLLISION,
Ndis.Oid.OID_802_3_XMIT_MORE_COLLISIONS,
//
// Optional Ethernet Statistics Queries
//
Ndis.Oid.OID_802_3_XMIT_DEFERRED,
Ndis.Oid.OID_802_3_XMIT_MAX_COLLISIONS,
Ndis.Oid.OID_802_3_RCV_OVERRUN,
Ndis.Oid.OID_802_3_XMIT_UNDERRUN,
Ndis.Oid.OID_802_3_XMIT_HEARTBEAT_FAILURE,
Ndis.Oid.OID_802_3_XMIT_TIMES_CRS_LOST,
Ndis.Oid.OID_802_3_XMIT_LATE_COLLISIONS
};
// Query each OID in the list.
for( int i = 0; i < queryList.GetLength(0); ++i )
{
uint statistic = 0; // Could use ulong (Uint64) if desired...
uint returnValue = adapter.QueryInformation( queryList[i], ref statistic, 0 ); if( returnValue == 0 )
Console.WriteLine( " {0}: {1}", queryList[i].ToString(), statistic );
else
Console.WriteLine( " {0}: Query Failed; Status: {1}", queryList[i].ToString(), (Ndis.Status )returnValue );
}
Console.WriteLine();
}
#endregion /////////////////////////////////////////////////////////////////////////////
#region DisplayEthernetOperationalCharacteristics Test
/// <summary>
/// Make NDIS queries and display AdapterObject Ethernet operational characteristics.
/// </summary>
/// <param name="adapter">Specifies the adapter to be queried.</param>
/// <remarks>These are various queries from the OID_802_3_XYZ family. Here we use helper
/// functions designed to simplify fetching operational characteristics.</remarks>
static void DisplayEthernetOperationalCharacteristics( AdapterObject adapter )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Adapter Ethernet Operational Characteristics" );
uint returnValue = 0; Ndis.NDIS_802_3_ADDRESS macAddress = new NDIS_802_3_ADDRESS(); // Query for Current MAC Address
returnValue = adapter.QueryInformation( Ndis.Oid.OID_802_3_CURRENT_ADDRESS, macAddress );
Console.WriteLine( " Current Address: {0}", macAddress );
// Query for Permanent MAC Address
returnValue = adapter.QueryInformation( Ndis.Oid.OID_802_3_PERMANENT_ADDRESS, macAddress );
Console.WriteLine( " Permanent Address: {0}", macAddress );
Console.WriteLine(); // Query for Multicast List
Ndis.NDIS_802_3_ADDRESS[] multicastList;
returnValue = adapter.QueryInformation( Ndis.Oid.OID_802_3_MULTICAST_LIST, out multicastList ); if( returnValue == 0 )
{
Console.WriteLine( " Multicast List:" );
if( multicastList.GetLength( 0 ) == 0 )
{
Console.WriteLine( " Empty List" );
}
else
{
for( int i = 0; i < multicastList.GetLength( 0 ); ++i )
{
Console.WriteLine( " Address {0}: {1}", i, multicastList[i] );
}
}
}
else
Console.WriteLine( " Multicast List Query: Failed; Status: {0}", (Ndis.Status )returnValue );
Console.WriteLine(); DisplayWLANInformation( adapter, false );
}
#endregion /////////////////////////////////////////////////////////////////////////////
#region DisplayWLANInformation Test
/// <summary>
/// Make NDIS queries and display AdapterObject wireless LAN (802.11) information.
/// </summary>
/// <param name="adapter">Specifies the adapter to be queried.</param>
/// <param name="testSetInformation">If this parameter is true then the test will exercise
/// illustrative calls to set 802.11 information.</param>
/// <remarks>These are various queries from the OID_802_11_XYZ family. Here we use helper
/// functions designed to simplify fetching operational characteristics.</remarks>
/// <remarks>Some SetInformation code fragments are conditionally excluded from being
/// executed by the testSetInformation parameter. The code that is excluded correctly
/// illustrates the syntax of the SetInformation call. However, the code fragments should
/// not actually be executed in the context of this simple demonstration application. If the
/// SetInformation code fragments were actually executed the behavior would not be
/// sensible.</remarks>
static void DisplayWLANInformation( AdapterObject adapter, bool testSetInformation )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Adapter 802.11 Information" );
// Get 802.11 Adapter Supported Rates
Ndis.NDIS_802_11_SUPPORTED_RATES supportedRates = new Ndis.NDIS_802_11_SUPPORTED_RATES();
uint returnValue;
returnValue = adapter.QueryInformation( supportedRates ); if( returnValue == 0 )
Console.WriteLine( " Supported Rates: {0} Mbps", supportedRates.ToString() );
else
{
Console.WriteLine( " Supported Rates: Query Failed; Status: {0}", (Ndis.Status )returnValue );
return;
}
// Query for SSID
Ndis.NDIS_802_11_SSID ssid = new Ndis.NDIS_802_11_SSID();
returnValue = adapter.QueryInformation( ssid ); if( returnValue == 0 )
Console.WriteLine( " SSID: \x22{0}\x22", ssid );
else
Console.WriteLine( " SSID: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Possibly Illustrate Setting SSID
if( testSetInformation && adapter.CanSetInformation )
{
//Set the SSID
// ssid.Ssid = "pcausa-gee";
ssid.SetBytes( new byte[] { 0x70, 0x63, 0x61, 0x75, 0x73, 0x61, 0x2D, 0x67, 0x65, 0x65 } );
returnValue = adapter.SetInformation( ssid ); if( returnValue == 0 )
Console.WriteLine( " Set SSID: Successful" );
else
Console.WriteLine( " Set SSID: Failed" );
// Query SSID after setting
returnValue = adapter.QueryInformation( ssid );
if( returnValue == 0 )
Console.WriteLine( " SSID After Setting: \x22{0}\x22", ssid );
else
Console.WriteLine( " SSID After Setting: Query Failed" );
}
// Query for BSSID
Ndis.NDIS_802_3_ADDRESS macAddress = new NDIS_802_3_ADDRESS();
returnValue = adapter.QueryInformation( Ndis.Oid.OID_802_11_BSSID, macAddress ); if( returnValue == 0 )
Console.WriteLine( " MacAddress: {0}", macAddress );
else
Console.WriteLine( " MacAddress: Query Failed; Status: {0}", (Ndis.Status )returnValue );
if( adapter.CanSetInformation )
{
// Set BSSID
macAddress.SetAddress( new byte[] {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } );
returnValue = adapter.SetInformation( Ndis.Oid.OID_802_11_BSSID, macAddress ); if( returnValue == 0 )
Console.WriteLine( " Set BSSID: Operation Successful" );
else
Console.WriteLine( " Set BSSID: Operation Failed" );
}
// Query for RSSI
Ndis.NDIS_802_11_RSSI rssi = new NDIS_802_11_RSSI();
returnValue = adapter.QueryInformation( rssi ); if( returnValue == 0 )
{
Console.WriteLine( " RSSI: {0} dBm ({1})", rssi, rssi.SignalStrength );
}
else
Console.WriteLine( " RSSI: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Query for Infrastructure Mode
Ndis.NDIS_802_11_NETWORK_INFRASTRUCTURE infrastructureMode = new NDIS_802_11_NETWORK_INFRASTRUCTURE();
returnValue = adapter.QueryInformation( ref infrastructureMode ); if( returnValue == 0 )
Console.WriteLine( " Infrastructure Mode: {0}", infrastructureMode );
else
Console.WriteLine( " Infrastructure Mode: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Possibly Illustrate Setting Infrastructure Mode
if( ( testSetInformation == true ) && ( adapter.CanSetInformation == true ) )
{
// Set infrastructure mode
infrastructureMode = Ndis.NDIS_802_11_NETWORK_INFRASTRUCTURE.IBSS; // An example...
returnValue = adapter.SetInformation( infrastructureMode ); if( returnValue == 0 )
Console.WriteLine( " Set Infrastructure Mode: Operation Successful" );
else
Console.WriteLine( " Set Infrastructure Mode: Operation Failed" );
}
// Query for Authentication Mode
Ndis.NDIS_802_11_AUTHENTICATION_MODE authenticationMode = new NDIS_802_11_AUTHENTICATION_MODE();
returnValue = adapter.QueryInformation( ref authenticationMode ); if( returnValue == 0 )
Console.WriteLine( " Authentication Mode: {0}", authenticationMode );
else
Console.WriteLine( " Authentication Mode: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Query for Encryption Status
Ndis.NDIS_802_11_ENCRYPTION_STATUS encryptionStatus = new NDIS_802_11_ENCRYPTION_STATUS();
returnValue = adapter.QueryInformation( ref encryptionStatus ); if( returnValue == 0 )
Console.WriteLine( " Encryption Status: {0}", encryptionStatus );
else
Console.WriteLine( " Encryption Status: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Possibly Illustrate Setting Authentication Mode
if( testSetInformation && adapter.CanSetInformation )
{
// Set Authentication Mode
authenticationMode = Ndis.NDIS_802_11_AUTHENTICATION_MODE.Open; // An example
returnValue = adapter.SetInformation( authenticationMode ); if( returnValue == 0 )
Console.WriteLine( " Set Authentication Mode: Operation Successful" );
else
Console.WriteLine( " Set Authentication Mode: Operation Failed" );
}
// Query for network type in use
Ndis.NDIS_802_11_NETWORK_TYPE networkType = new NDIS_802_11_NETWORK_TYPE();
returnValue = adapter.QueryInformation( ref networkType ); if( returnValue == 0 )
Console.WriteLine( " Network Type In Use: {0}", networkType );
else
Console.WriteLine( " Network Type In Use: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Possibly Illustrate Setting Network Type
if( testSetInformation && adapter.CanSetInformation )
{
// Set network type in use
networkType = Ndis.NDIS_802_11_NETWORK_TYPE.DirectSequencing; // An example...
returnValue = adapter.SetInformation( networkType ); if( returnValue == 0 )
Console.WriteLine( " Set Network Type In Use: Operation Successful" );
else
Console.WriteLine( " Set Network Type In Use: Operation Failed" );
}
// Query for 802.11 configuration
NDIS_802_11_CONFIGURATION configutation = new NDIS_802_11_CONFIGURATION();
returnValue = adapter.QueryInformation( ref configutation ); if( returnValue == 0 )
{
Console.WriteLine( " Configuration: Query Successful" );
Console.WriteLine( " Beacon Period: {0} Kusec", configutation.BeaconPeriod );
Console.WriteLine( " ATIM Window: {0} Kusec", configutation.ATIMWindow );
// Calculate and Display Frequency and Channel
uint channel = 0;
if( configutation.DSConfig >= 2412000 )
{
channel = ( (configutation.DSConfig - 2412000)/5000 ) + 1;
}
Console.WriteLine( " DSConfig: {0} MHz (CH {1})", configutation.DSConfig/1000, channel );
if( adapter.CanSetInformation )
{
// Set 802.11 configuration
// ------------------------
// For illustrative purposes, just set the same data queried above. Understand that
// although this is a mandatory OID, some adapters do not seem to accept it.
returnValue = adapter.SetInformation( ref configutation );
if( returnValue == 0 )
Console.WriteLine( " Set Configuration: Successful" );
else
Console.WriteLine( " Set Configuration: Failed; Status: {0}", (Ndis.Status )returnValue );
}
}
else
Console.WriteLine( " 802.11 Configuration: Query Failed; Status: {0}", (Ndis.Status )returnValue );
if( adapter.CanSetInformation )
{
// Make a call to start BSSID list scan
returnValue = adapter.SetInformation( Ndis.Oid.OID_802_11_BSSID_LIST_SCAN ); // No parameter required
}
// Make a call to get a BSSID list
BssidList bssidList = new BssidList();
returnValue = adapter.QueryInformation( bssidList ); if( returnValue == 0 )
{
int i = 0;
Console.WriteLine();
Console.WriteLine( " BSSID List: Query Successful" );
Console.WriteLine( " Number of Items: {0}", bssidList.NumberOfItems );
foreach( BssidListItem bssidItem in bssidList )
{
Console.WriteLine();
Console.WriteLine( " BSSID_LIST Entry {0}", i++ );
// Display The MacAddress Field
Console.WriteLine( " MacAddress: {0}", bssidItem.MacAddress.ToString() );
// Display The Ssid
Console.WriteLine( " SSID: \x22{0}\x22", bssidItem.Ssid );
// Display Rssi
Console.WriteLine( " RSSI: {0} dBm ({1})", bssidItem.Rssi, bssidItem.Rssi.SignalStrength );
// Display Network Type In Use
Console.WriteLine( " Network Type In Use: {0}", bssidItem.NetworkTypeInUse );
// Display Infrastructure Mode
Console.WriteLine( " InfrastructureMode: {0}", bssidItem.InfrastructureMode );
// Display Supported Rates
Console.WriteLine( " Supported Rates: {0} Mbps", bssidItem.SupportedRates.ToString() );
// Display Configuration Information
NDIS_802_11_CONFIGURATION itemConfiguration = bssidItem.Configuration;
Console.WriteLine( " Configuration:" );
Console.WriteLine( " Beacon Period: {0} Kusec", itemConfiguration.BeaconPeriod );
Console.WriteLine( " ATIM Window: {0} Kusec", itemConfiguration.ATIMWindow );
// Calculate and Display Frequency and Channel
uint channel = 0;
if( itemConfiguration.DSConfig >= 2412000 )
{
channel = ( (itemConfiguration.DSConfig - 2412000)/5000 ) + 1;
}
Console.WriteLine( " DSConfig: {0} MHz (CH {1})", itemConfiguration.DSConfig/1000, channel );
// Display information elements from beacon or probe response messages
int IELength = bssidItem.IELength;
if( IELength > 0 )
{
}
}
}
else
Console.WriteLine( " BSSID List: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Possibly illustrate Reloading Defaults, etc.
if( testSetInformation && adapter.CanSetInformation )
{
// Make a call to reload defaults
returnValue = adapter.SetInformation( Ndis.Oid.OID_802_11_RELOAD_DEFAULTS ); // No parameter required
// Make a call to remove a WEP key
uint keyIndex = 0; // NDIS_802_11_KEY_INDEX is a ULONG...
returnValue = adapter.SetInformation( Ndis.Oid.OID_802_11_REMOVE_WEP, keyIndex ); // Make a call to disassociate
returnValue = adapter.SetInformation( Ndis.Oid.OID_802_11_DISASSOCIATE ); // No parameter required
}
Console.WriteLine();
}
#endregion /////////////////////////////////////////////////////////////////////////////
#region DisplayGeneralOperationCharacteristics Test
/// <summary>
/// Make NDIS queries and display AdapterObject general operational characteristics.
/// </summary>
/// <param name="adapter">Specifies the adapter to be queried.</param>
/// <remarks>These are various queries from the OID_GEN_XYZ family. Here we use helper
/// functions designed to simplify fetching operational characteristics.</remarks>
static void DisplayGeneralOperationCharacteristics( AdapterObject adapter )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Adapter General Operational Characteristics" );
uint returnValue = 0; // Get Adapter's Vendor Description String
string vendorDescription;
returnValue = adapter.QueryInformation( Ndis.Oid.OID_GEN_VENDOR_DESCRIPTION, out vendorDescription ); if( returnValue == 0 )
Console.WriteLine( " Vendor Description: {0}", vendorDescription );
else
Console.WriteLine( " Vendor Description: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// For this simple console sample application make a list of statistics OIDs to
// query and then query each OID OID in the list in a loop. All statistic OID return
// values are fetched as Uint32.
//
// The loop displays the OID using ToString, so it is not "pretty" but easy to implement.
// Build list of statistics OIDs To query.
Ndis.Oid[] queryList =
new Ndis.Oid[]{
//
// Mandatory General Statistics Queries
//
Ndis.Oid.OID_GEN_MAXIMUM_FRAME_SIZE,
Ndis.Oid.OID_GEN_MAXIMUM_TOTAL_SIZE,
Ndis.Oid.OID_GEN_CURRENT_LOOKAHEAD,
Ndis.Oid.OID_GEN_MAXIMUM_LOOKAHEAD,
Ndis.Oid.OID_GEN_LINK_SPEED
};
// Query each OID in the list.
for( int i = 0; i < queryList.GetLength(0); ++i )
{
uint statistic = 0;
returnValue = adapter.QueryInformation( queryList[i], ref statistic, 0 ); if( returnValue == 0 )
Console.WriteLine( " {0}: {1}", queryList[i].ToString(), statistic );
else
Console.WriteLine( " {0}: Query Failed; Status: {1}", queryList[i].ToString(), (Ndis.Status )returnValue );
}
// Get Current NDIS packet filter value
PacketTypes packetFilter = PacketTypes.None;
returnValue = adapter.QueryInformation( ref packetFilter ); Console.WriteLine( " Current Packet Filter: {0}", packetFilter.ToString() );
// Get Physical Medium
// -------------------
// Note that support for OID_GEN_PhysicalMedium is optional. It is usually
// supported on 802.11 adapters but not otherwise.
Ndis.PhysicalMedium physicalMedium = Ndis.PhysicalMedium.Max;
returnValue = adapter.QueryInformation( ref physicalMedium ); if( returnValue == 0 )
Console.WriteLine( " Physical Medium: {0}", physicalMedium.ToString() );
else
Console.WriteLine( " Physical Medium: Query Failed; Status: {0}", (Ndis.Status )returnValue );
// Get Media Connect State
MediaState connectState = Ndis.MediaState.Unknown;
returnValue = adapter.QueryInformation( ref connectState ); Console.WriteLine( " Media Connect Status: {0}", connectState.ToString() );
// Get Medium In Use
Ndis.Medium ndisMedium = Ndis.Medium.Max;
returnValue = adapter.QueryInformation( ref ndisMedium ); Console.WriteLine( " Media In Use: {0}", ndisMedium.ToString() );
Console.WriteLine(); // Display Supported OID List
// --------------------------
// This is really just ot illustrate making a query on an array of uint's using the
// out method parameter keyword.
uint[] oidList = null;
returnValue = adapter.QueryInformation( Ndis.Oid.OID_GEN_SUPPORTED_LIST, out oidList ); Console.WriteLine( " Supported OID List:" ); if( returnValue == 0 )
{
if( oidList == null )
{
Console.WriteLine( " Empty List" );
}
else
{
int length = oidList.GetLength(0);
Console.WriteLine( " {0} Supported OIDs", length );
for( int i = 0; i < length; ++i )
{
if( oidList[i] >= (uint )0xFF000000 )
{
// Display Proprietary OIDs in HEX format
Console.WriteLine( " {0} - 0x{1:X8}", i, oidList[i] );
}
else
{
// Display OID Enumeration Name for Known OIDs
Console.WriteLine( " {0} - {1} (0x{2:X8})", i, (Ndis.Oid )oidList[i], oidList[i] );
}
}
}
}
else
Console.WriteLine( " Supported OID List: Query Failed; Status: {0}", (Ndis.Status )returnValue );
Console.WriteLine(); Console.WriteLine(); // Display Media-Specific Operational Characteristics
switch( ndisMedium )
{
case Ndis.Medium.Dix:
case Ndis.Medium.Ieee802_3:
DisplayEthernetStatistics( adapter );
DisplayEthernetOperationalCharacteristics( adapter );
break;
case Ndis.Medium.Ieee1394:
break;
default:
break;
}
}
#endregion /////////////////////////////////////////////////////////////////////////////
#region SetInformationTest Test
/// <summary>
/// Make NDIS queries and display the NDIS packet filter setting.
/// </summary>
/// <param name="adapter">Specifies the adapter to be tested.</param>
/// <remarks>These are various queries from the OID_GEN_XYZ family. Here we use helper
/// functions designed to simplify fetching operational characteristics.</remarks>
static void SetInformationTest( AdapterObject adapter )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Set Information Test" );
if( !adapter.CanSetInformation )
{
Console.WriteLine( " Cannot set information using this AdapterObject" );
return;
}
// Get Initial NDIS packet filter value
PacketTypes originalFilter = PacketTypes.None;
uint returnValue = adapter.QueryInformation( ref originalFilter ); Console.WriteLine( " Initial Packet Filter: {0}", originalFilter.ToString() );
// Set NDIS packet filter to PROMISCUOUS
returnValue = adapter.SetInformation( PacketTypes.Promiscuous );
if( returnValue == 0 )
{
// Get NDIS packet filter value after setting
PacketTypes updatedFilter = PacketTypes.None;
returnValue = adapter.QueryInformation( ref updatedFilter ); Console.WriteLine( " SetPacketFilter: Successful; New Filter: {0}", updatedFilter.ToString() );
// Restore Original NDIS Packet Filter
returnValue = adapter.SetInformation( originalFilter );
// Get NDIS packet filter value after resetting
returnValue = adapter.QueryInformation( ref updatedFilter );
Console.WriteLine( " Packet Filter After Resetting: {0}", updatedFilter.ToString() );
}
else
Console.WriteLine( " SetPacketFilter: Failed; Status: {0}", (Ndis.Status )returnValue );
Console.WriteLine();
}
#endregion /////////////////////////////////////////////////////////////////////////////
#region Trivial Send Packet Test
/// <summary>
/// Trivial send packet example.
/// </summary>
/// <param name="adapter">Specifies the adapter to be tested.</param>
/// <remarks>This trivial sample illustrates how to use the Rawether .NET
/// SendSinglePacket function.</remarks>
static void SendPacketTest( AdapterObject adapter, int numPackets )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Send Packet Test" );
if( !adapter.CanSendPackets )
{
Console.WriteLine( " Cannot send packets using using this AdapterObject" );
return;
}
// This test only operates on 802.3 adapters
if( adapter.MediaInUse != Ndis.Medium.Ieee802_3 )
{
Console.WriteLine( " SendPacketTest cannot send on medium {0}", adapter.MediaInUse );
return;
}
EthernetPacket packet = new EthernetPacket(); // Create a PacketWriter for Packet Data
// -------------------------------------
// For sure a simple byte array can be used instead of a memory stream. More later
// on this topic.
PacketWriter packetWriter = new PacketWriter( packet );
// Initialize the Packet MAC Header
// --------------------------------
// Destination MAC Address -> Broadcast Address (0xFFFFFFFF)
// Source MAC Address -> Fetched from the Adapter
// Ethernet Type -> DEC Experimental (0x6000)
//
// The packet to be sent will look like this when it is sent on the network (from
// an actual capture):
//
// Packet No.: 0000000001 Time: 0342003053 msec Length: 64/64
// Ethernet Dest: FF.FF.FF.FF.FF.FF Src: 00.40.F4.00.07.B5 Type: 0x6000
// 000000: FF FF FF FF FF FF 00 40 : F4 00 07 B5 60 00 23 50 .......@....`.#P
// 000010: 43 41 55 53 41 20 52 61 : 77 65 74 68 65 72 20 2E CAUSA Rawether .
// 000020: 4E 45 54 20 2D 20 43 23 : 20 56 65 72 73 69 6F 6E NET - C# Version
// 000030: 2E 20 00 00 00 00 00 00 : 00 00 00 00 00 00 00 00 . ..............
//
packetWriter.Write( Ndis.NDIS_802_3_ADDRESS.Broadcast );
packetWriter.Write( adapter.EthernetCurrentAddress ); // AdapterObject has automatic query for this...
packetWriter.Write( PacketWriter.HostToNetOrder( (ushort )Ethernet.EtherType.ETHERTYPE_DECEXPER ) );
// Initialize Packet Payload
string aString = "PCAUSA Rawether .NET - C# Version. ";
packetWriter.Write( aString );
uint packetTotalSize = (uint )packet.Position; for( int i = 0; i < numPackets; ++i )
{
uint returnValue;
Console.WriteLine( "Sending Packet {0} of {1}", i + 1, numPackets );
Console.WriteLine( "{0}", packet.ToString() );
// Send The Packet
// --------------
// The SendSinglePacket function will block the current thread and send the network
// frame synchronously.
//
try
{
// returnValue = adapter.SendSinglePacket( packet.GetBuffer(), packetTotalSize );
returnValue = adapter.SendSinglePacket( packet );
}
catch( Rawether.Exceptions.AdapterIOException e )
{
Console.WriteLine( "SendSinglePacket: AdapterIOException: {0}", e.LastError );
break;
}
if( returnValue == 0 )
{
Console.WriteLine( " SendPacket: Successful" );
Thread.Sleep( 10 );
}
else
{
Console.WriteLine( " SendPacket: Failed; Status: {0}", (Ndis.Status )returnValue );
break;
}
}
Console.WriteLine();
}
#endregion #region Receive Packets Test /// <summary>
/// Event that is used to shutdown the receiver thread.
/// </summary>
static event EventHandler ReceiverShutdownEvent;
/// <summary>
/// Invoke to shutdown the receiver thread.
/// </summary>
/// <param name="e"></param>
static void SignalShutdown(AdapterObject adapter, EventArgs e)
{
if( ReceiverShutdownEvent == null )
{
Console.WriteLine( "SignalShutdown: ReceiverShutdownEvent is null " );
return;
}
foreach( EventHandler handler in ReceiverShutdownEvent.GetInvocationList() )
{
if( e == null )
{
handler( adapter, null );
}
else
{
handler( adapter, e );
}
}
}
/// <summary>
/// Class defining receive thread, state information and asynchronous packet read callback.
/// </summary>
public class ReceiveHandler
{
public AdapterObject adapter;
public int count;
public int callsHandled = 0;
public bool receiverShutdown = false;
private AsyncCallback readCallback = null;
/// <summary>
/// Constructor
/// </summary>
/// <param name="adapter">The AdapterObject that packets are being received on.</param>
/// <param name="count">Simply illustrates initializing a parameter in the ReceiveHandler
/// class when it is constructed.</param>
public ReceiveHandler( AdapterObject adapter, int count )
{
this.adapter = adapter;
this.count = count;
readCallback = new AsyncCallback( PacketReadCallback );
}
/// <summary>
/// Shutdown event handler.
/// </summary>
/// <param name="sender">Object passed to SignalShutdown.</param>
/// <param name="e">EventArgs passed to SignalShutdown.</param>
public void Shutdown(object sender, EventArgs e)
{
Console.WriteLine("Shutdown Event Called.");
receiverShutdown = true;
}
/// <summary>
/// Display representative packet data.
/// </summary>
/// <param name="packet">The packet data to be displayed.</param>
public void DisplayPacket( EthernetPacket packet )
{
PacketReader packetReader = new PacketReader( packet );
Console.WriteLine( "BinaryReader: Offset: {0}; Data: {1}", packet.Position, packetReader.ReadEthernetAddress() );
Console.WriteLine( "BinaryReader: Offset: {0}; Data: {1}", packet.Position, packetReader.ReadEthernetAddress() );
Console.WriteLine( "BinaryReader: Offset: {0}; Data: {1}", packet.Position, (Ethernet.EtherType )PacketReader.NetToHostOrder( packetReader.ReadUInt16() ) );
/*
Packet Number: 22 Timestamp: 185822000 msec Length: 554
Dest: 00-06-25-8C-EE-6D Src: 00-40-F4-00-07-B5 Type: ETHERTYPE_IP
*** Is LOOPBACK ***
*/
// The packet ToString method provides basic information about the packet
Console.WriteLine( "{0}", packet.ToString() );
if( packet.DestinationAddress.IsBroadcast == true )
{
Console.WriteLine( " *** Dest is BROADCAST ***" );
}
if( packet.DestinationAddress.IsMulticast == true )
{
Console.WriteLine( " *** Dest is MULTICAST ***" );
}
if( adapter.IsEthernet == true )
{
if( packet.DestinationAddress == adapter.EthernetCurrentAddress )
{
Console.WriteLine( " *** Is DIRECTED ***" );
}
if( packet.SourceAddress == adapter.EthernetCurrentAddress )
{
Console.WriteLine( " *** Is LOOPBACK ***" );
}
}
Console.WriteLine();
}
/// <summary>
/// Callback method to be called when the asynchronous packet read operation is completed.
/// </summary>
/// <param name="ar">The IAsyncResult associated with the BeginGetPacket or GetPacket call
/// that started this operation.</param>
/// <remarks>Under some condifions this callback can be re-entered as soon as the BeginGetPacket
/// call is made (below).</remarks>
public void PacketReadCallback( IAsyncResult ar )
{
++callsHandled;
if( this.receiverShutdown == true )
{
return;
}
AdapterObject adapter = (AdapterObject )ar.AsyncState; EthernetPacket packet; try
{
// Since the media is 802.3 packet data is returned as EthernetPacket
packet = (EthernetPacket )adapter.EndGetPacket( ar );
}
catch( Rawether.Exceptions.AdapterIOException e )
{
Console.WriteLine( "PacketReadCallback: AdapterIOException: {0}", e.LastError );
SignalShutdown( adapter, null );
return;
}
DisplayPacket( packet ); if( this.receiverShutdown != true )
{
try
{
ar = adapter.BeginGetPacket( readCallback, adapter );
}
catch( Rawether.Exceptions.AdapterIOException e )
{
Console.WriteLine( "PacketReadCallback: AdapterIOException: {0}", e.LastError );
SignalShutdown( adapter, null );
return;
}
}
}
/// <summary>
/// The ReceiveHandler thread start procedure.
/// </summary>
public void ThreadProc()
{
uint returnValue;
// Get Media Connect State
MediaState connectState = Ndis.MediaState.Unknown;
adapter.QueryInformation( ref connectState ); if( connectState == MediaState.Disconnected )
{
Console.WriteLine( " This AdapterObject is in Disconnected state" );
receiverShutdown = true;
return;
}
else if( connectState == MediaState.Unknown )
{
Console.WriteLine( " This AdapterObject is in UNKNOWN connect state" );
Console.WriteLine( " Packets might not be received on this adapter" );
}
// Set NDIS packet filter to PROMISCUOUS
// -------------------------------------
// This effectively "turns on" the packet reception capability of the driver.
returnValue = adapter.SetInformation( PacketTypes.Promiscuous );
if( returnValue != 0 )
{
Console.WriteLine( " Unable to set NDIS packet filter to Promiscuous mode" );
returnValue = adapter.SetInformation( PacketTypes.AllLocal );
}
if( returnValue != 0 )
{
Console.WriteLine( " Unable to set NDIS packet filter" );
receiverShutdown = true;
return;
}
ReceiverShutdownEvent += new EventHandler(Shutdown); // // Optional Calls to Configure the Packet Read (Receive) Queue // // ----------------------------------------------------------- // // These three optional calls can be made to adjust the configuration of the // // packet read queue. The parameters passed in the example calls are actually // // the default values that are used if the calls were not made at all. // // // Configure read (receive) queue sizes. (Optional) // adapter.ConfigureReadQueue( 65535, 3 ); // Three 64KB buffers // // // Specify the read idle timeout. (Optional) // adapter.SetReadIdleTimeout( 300 ); // 300 milliseconds // Create a BPF program that accepts only IP packets
ulong[] bpfProgram = new ulong[]
{
// Load accumulator with "half-word" (UInt16) extracted from packet at offset 12.
// This is the offset to the Ethernet Type/Length field.
Bpf.Statement( Bpf.LD + Bpf.H + Bpf.ABS, 12),
// Compare in accumulator the accumulator to ETHERTYPE_IP.
// Branch to instruction that returns accept value (pc+0) if equal.
// Branch to instruction that returns reject value (pc+1) if not equal.
Bpf.Jump( Bpf.JMP + Bpf.JEQ + Bpf.K, Ethernet.EtherType.ETHERTYPE_IP, 0, 1),
// Instruction that returns accept value.
Bpf.Statement( Bpf.RET + Bpf.K, UInt32.MaxValue),
// Instruction that returns reject value (i.e., accept zero bytes).
Bpf.Statement( Bpf.RET + Bpf.K, 0)
};
// Pass the BPF program to the adapter. // adapter.SetBpfProgram( bpfProgram ); // Disable reception of send packets that are looped back into the receive path. // adapter.EnableLoopback( false ); #if !ZNEVER
// Read test using asynchronous callback
adapter.BeginGetPacket( readCallback, adapter );
while( this.receiverShutdown != true )
{
Console.WriteLine( "ThreadProc: Handled {0} calls", this.callsHandled );
Thread.Sleep( 1000 );
}
#else
// Read test using Begin/End methods
while( this.receiverShutdown != true )
{
IAsyncResult ar = adapter.BeginGetPacket( null, null );
// Since the media is 802.3 packet data is returned as EthernetPacket
EthernetPacket packet = (EthernetPacket )adapter.EndGetPacket( ar );
DisplayPacket( packet );
}
#endif
// Remove the BPF program. Driver will accept all packets.
// Note: Not really necessary. Just exercising the API.
adapter.SetBpfProgram( null );
ReceiverShutdownEvent -= new EventHandler(Shutdown); // Set NDIS packet filter to NONE
// ------------------------------
// This effectively "turns off" the packet reception capability of the driver.
//
// We check IsOpen because there could have been a surprise removal of the adapter.
// Making the SetInformation call on an adapter that has laready been closed will
// generate another exception...
if( adapter.IsOpen == true )
{
returnValue = adapter.SetInformation( PacketTypes.None );
if( returnValue != 0 )
{
Console.WriteLine( " Unable to set NDIS packet filter to None mode" );
}
}
Console.WriteLine( "ThreadProc: Exiting" );
receiverShutdown = true;
}
}
/// <summary>
/// Trivial receive packets example.
/// </summary>
/// <param name="adapter">Specifies the adapter to be tested.</param>
/// <remarks>This trivial sample illustrates how to use the Rawether .NET
/// XXXX function.</remarks>
static void ReceivePacketsTest( AdapterObject adapter )
{
Console.WriteLine( "*****************************************" );
Console.WriteLine( "Receive Packets Test" );
if( !adapter.CanReceivePackets )
{
Console.WriteLine( " Cannot receive packets using using this AdapterObject" );
return;
}
// This test only operates on 802.3 adapters
if( adapter.MediaInUse != Ndis.Medium.Ieee802_3 )
{
Console.WriteLine( " ReceivePacketsTest cannot receive on medium {0}", adapter.MediaInUse );
return;
}
ReceiveHandler recvHandler = new ReceiveHandler( adapter, 500 ); Thread t = new Thread( new ThreadStart( recvHandler.ThreadProc ) );
t.Name = "ReceiveHandler"; t.Start(); for (int i = 0; i < 60; i++)
{
if( ( t.IsAlive != true ) || ( recvHandler.receiverShutdown == true ) )
{
break;
}
Console.WriteLine( "Main Thread: Loop: {0}; Handled {1} receive events calls", i, recvHandler.callsHandled );
Thread.Sleep(1000);
SendPacketTest( adapter, 20 );
}
if( t.IsAlive == true )
{
SignalShutdown( adapter, null );
}
Console.WriteLine("Main thread: Call Join(), to wait until ReceiveProc ends.");
t.Join();
Console.WriteLine("Main thread: ThreadProc.Join has returned.");
Console.WriteLine();
}
#endregion /// <summary>
/// The main entry point for the EnumTest application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Console.WriteLine( "Rawether.NET Adapter Enumeration Test Application (Visual C#)" );
Console.WriteLine( "Copyright (c) 2000-2004 Printing Communications Associates, Inc" );
Console.WriteLine();
Console.WriteLine( "Friendly Name: {0}", AppDomain.CurrentDomain.FriendlyName );
Console.WriteLine( "OS : {0}", Environment.OSVersion );
Console.WriteLine( "Date: {0}", DateTime.Now.ToLocalTime() );
Console.WriteLine();
// Create an Instance of the Desired Rawether Driver Object
// --------------------------------------------------------
// This may throw exceptions if the specified driver is not present or has faults.
DriverObject ndisDriver = null;
try
{
// ndisDriver = new PcaFltDriver();
ndisDriver = new PcaMprProtDriver();
// ndisDriver = new PcaMuxDriver();
// ndisDriver = new PcaLwfDriver();
}
catch( Rawether.Exceptions.DriverNotPresent )
{
Console.WriteLine( "Rawether NDIS driver is not present" );
return;
}
// Verify that NDIS driver has a protocol interface
if( ndisDriver.HasProtocolInterface != true )
{
Console.WriteLine( "{0} does not have a protocol interface", ndisDriver.Description );
return;
}
Console.WriteLine( "Using {0} Version {1}", ndisDriver.Description, ndisDriver.Version );
Console.WriteLine();
// Create The Adapter Collection
AdapterCollection adapterList = ndisDriver.GetAdapterCollection();
// Perform The Adapter Enumeration
foreach( BindingName adapterName in adapterList )
{
Console.WriteLine( "*****************************************" );
// Display AdapterName Information
Console.WriteLine( "Friendly Name : {0}", adapterName.InstanceName );
Console.WriteLine( "DeviceName Name: {0}", adapterName.DeviceName );
AdapterObject adapter; // Open an AdapterObject on the found AdapterName
try
{
adapter = ndisDriver.OpenAdapter( adapterName );
}
catch( Rawether.Exceptions.OpenAdapterFailedException )
{
Console.WriteLine( "OpenAdapter: FAILED." );
continue;
}
Console.WriteLine( "OpenAdapter: SUCCESSFUL" ); Console.WriteLine(); DisplayGeneralStatistics( adapter ); DisplayGeneralOperationCharacteristics( adapter ); SetInformationTest( adapter ); SendPacketTest( adapter, 20 ); // Get Media Connect State
MediaState connectState = Ndis.MediaState.Unknown;
adapter.QueryInformation( ref connectState ); // NOTE: Rawether .NET reports "Disconnected" only if the adapter actually supports
// the OID_GEN_MEDIA_CONNECT_STATE query. If the OID is not supported the state
// will be "Unknown".
if( connectState == MediaState.Disconnected )
{
Console.WriteLine( " This AdapterObject is in Disconnected state" );
Console.WriteLine( " It is probable that no packets will be received" );
Console.WriteLine( " **********************************************" );
Console.WriteLine( " * Skipping test receive test on this adapter *" );
Console.WriteLine( " *********************************************" );
adapter.CloseAdapter();
continue;
}
else if( connectState == MediaState.Unknown )
{
Console.WriteLine( " This AdapterObject is in UNKNOWN connect state" );
Console.WriteLine( " It is possible that no packets will be received" );
Console.WriteLine( " Continuing receive test on this adapter, but it may hang..." );
}
ReceivePacketsTest( adapter ); adapter.CloseAdapter();
}
Console.WriteLine( "Done" );
}
}
}
|
Mailing Lists ·
PCAUSA Newsletter
·
PCAUSA Discussion List
|