Код:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace RawEthernet
{
class RawEthernet
{
[STAThread]
static void Main(string[] args)
{
RawEthernet rawether = new RawEthernet();
if (rawether.m_bDriverOpen)
{
Console.WriteLine("Handle to NDIS Driver: " + rawether.Handle.ToString());
}
else
{
Console.WriteLine("ERROR: NDIS Driver could not be opened\n");
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
return;
}
AdaptersInfo[] aiAdapters = rawether.EnumerateAdapters();
Console.WriteLine("\nThe following adapters can be used to send packets:");
foreach (AdaptersInfo ai in aiAdapters)
{
Console.WriteLine("\t" + ai.ToString());
}
Console.Write("\nChoose the adapter number that you want to send from: ");
int adIndex = Convert.ToInt32(Console.ReadLine());
if (!rawether.BindAdapter(aiAdapters[adIndex].AdapterID))
{
Console.WriteLine("ERROR: Could not bind to the adapter.\n");
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
return;
}
else
{
Console.WriteLine("\nAdapter " + aiAdapters[adIndex].AdapterID +
" is ready for writing...\n");
}
// ok, now we are ready to write a raw packet on the adapter
// create a generic raw packet (must be at least 16 bytes long)
byte[] packet = new byte[] {0xff,0xff,0xff,0xff,0xff,0xff, //destination mac
0x00,0x02,0x3e,0x4c,0x49,0xaa, //source mac
0x08,0x00, //protocol
0x01,0x02,0x03,0x04,0x05,0x06}; //generic data
rawether.DoWrite(packet);
rawether.DoWrite(packet);
rawether.DoWrite(packet);
Console.WriteLine("\nPress enter to exit...");
Console.ReadLine();
rawether.CloseDriver();
rawether = null;
}
#region ATTRIBUTES
private string m_sNdisProtDriver = "\\\\.\\\\NdisProt";
private IntPtr m_iHandle = IntPtr.Zero;
private bool m_bDriverOpen = false;
private bool m_bAdapterBound = false;
#endregion ATTIBUTES
#region PROPERTIES
public IntPtr Handle { get { return this.m_iHandle; } }
public bool IsDriverOpen { get { return this.m_bDriverOpen; } }
public bool IsAdapterBound { get { return this.m_bAdapterBound; } }
#endregion PROPERTIES
#region CONSTRUCTOR
public RawEthernet()
{
// Open a handle to the NDIS Device driver
this.m_bDriverOpen = this.OpenDriver();
}
#endregion CONSTRUCTOR
#region METHODS
private bool OpenDriver()
{
this.m_iHandle = CreateFile(this.m_sNdisProtDriver,
GENERIC_WRITE|GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ((int)this.m_iHandle <= 0)
{
this.m_iHandle = IntPtr.Zero;
return false;
}
return true;
}
private AdaptersInfo[] EnumerateAdapters()
{
int adapterIndex = 0;
bool validAdapter = true;
AdaptersInfo[] aiTemp = new AdaptersInfo[10];
do
{
byte[] buf = new byte[1024];
uint iBytesRead = 0;
NDISPROT_QUERY_BINDING ndisprot = new NDISPROT_QUERY_BINDING();
ndisprot.BindingIndex = (ulong)adapterIndex;
uint bufsize = (uint)Marshal.SizeOf(ndisprot);
unsafe
{
fixed (void* vpBuf = buf)
{
// use the DeviceIoControl API to query the adapters
validAdapter = DeviceIoControl(this.m_iHandle,
IOCTL_NDISPROT_QUERY_BINDING, (void*)&ndisprot,
bufsize, vpBuf, (uint)buf.Length,
&iBytesRead, 0);
}
}
if (!validAdapter) break;
string tmpinfo = Encoding.Unicode.GetString(buf).Trim((char)0x00);
tmpinfo = tmpinfo.Substring(tmpinfo.IndexOf("\\"));
aiTemp[adapterIndex].Index = adapterIndex;
aiTemp[adapterIndex].AdapterID = tmpinfo.Substring(0,
tmpinfo.IndexOf("}")+1);
aiTemp[adapterIndex].AdapterName = tmpinfo.Substring(
tmpinfo.IndexOf("}")+1).Trim((char)0x00);
adapterIndex++;
}while (validAdapter || adapterIndex < 10);
AdaptersInfo[] aiReturn = new AdaptersInfo[adapterIndex];
for (int i=0;i<aiReturn.Length;i++)
aiReturn[i] = aiTemp[i];
return aiReturn;
}
private bool BindAdapter(string adapterID)
{
char[] ndisAdapter = new char[256];
int iNameLength = 0, i = 0;
for (i=0;i<adapterID.Length;i++)
{
ndisAdapter[i] = adapterID[i];
iNameLength++;
}
ndisAdapter[i] = '\0';
uint uiBytesReturned;
unsafe
{
fixed (void* vpNdisAdapter = &ndisAdapter[0])
{
// Call the DeviceIoControl API to bind the adapter to the handle
return DeviceIoControl(this.m_iHandle, IOCTL_NDISPROT_OPEN_DEVICE,
vpNdisAdapter, (uint)(iNameLength*sizeof(char)), null, 0,
&uiBytesReturned, 0);
}
}
}
private bool CloseDriver()
{
return CloseHandle(this.m_iHandle);
}
private bool DoWrite(byte[] packet)
{
uint uiSentCount = 0;
bool packetSent = false;
unsafe
{
fixed (void* pvPacket = packet)
{
packetSent = WriteFile(this.m_iHandle, pvPacket, (uint)packet.Length,
&uiSentCount, 0);
}
}
if (!packetSent)
{
Console.WriteLine("ERROR: Packet not sent: 0 bytes written");
return false;
}
Console.WriteLine("Packet sent: " + uiSentCount.ToString() + "bytes written");
return true;
}
#endregion METHODS
#region CONSTANTS
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const uint OPEN_EXISTING = 0x00000003;
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
private const int INVALID_HANDLE_VALUE = -1;
private const uint IOCTL_NDISPROT_QUERY_BINDING = 0x12C80C;
private const uint IOCTL_NDISPROT_OPEN_DEVICE = 0x12C800;
#endregion CONSTANTS
#region IMPORTS
[DllImport("kernel32", SetLastError=true)]
private static extern IntPtr CreateFile(
string _lpFileName,
uint _dwDesiredAccess,
uint _dwShareMode,
uint _lpSecurityAttributes,
uint _dwCreationDisposition,
uint _dwFlagsAndAttributes,
uint _hTemplateFile);
[DllImport("kernel32", SetLastError=true)]
private static extern unsafe bool WriteFile(
IntPtr _hFile,
void* _lpBuffer,
uint _nNumberOfBytesToWrite,
uint* _lpNumberOfBytesWritten,
uint _lpOverlapped);
[DllImport("kernel32", SetLastError=true)]
private static extern bool CloseHandle(
IntPtr _hObject);
[DllImport("kernel32", SetLastError=true)]
private static extern unsafe bool DeviceIoControl(
IntPtr _hDevice,
uint _dwIoControlCode,
void* _lpInBuffer,
uint _nInBufferSize,
void* lpOutBuffer,
uint _nOutBufferSize,
uint* _lpBytesReturned,
uint _lpOverlapped);
#endregion IMPORTS
#region STRUCTS
[StructLayout(LayoutKind.Sequential)]
private struct NDISPROT_QUERY_BINDING
{
public ulong BindingIndex;
public ulong DeviceNameOffset;
public ulong DeviceNameLength;
public ulong DeviceDescrOffset;
public ulong DeviceDescrLength;
}
#endregion STRUCTS
}
public struct AdaptersInfo
{
#region ATTRIBUTES
private int m_iIndex;
private string m_sAdapterID;
private string m_sAdapterName;
#endregion ATTRIBUTES
#region PROPERTIES
public int Index {get{return m_iIndex;}set{m_iIndex = value;}}
public string AdapterID {get{return m_sAdapterID;}set{m_sAdapterID = value;}}
public string AdapterName {get{return m_sAdapterName;}set{m_sAdapterName = value;}}
#endregion PROPERTIES
#region CONSTRUCTOR
public AdaptersInfo(int index, string adapterID, string adapterName)
{
// set the attributes according to the passed args
this.m_iIndex = index;
this.m_sAdapterID = adapterID;
this.m_sAdapterName = adapterName;
}
#endregion CONSTRUCTOR
#region METHODS
public override string ToString()
{
return this.m_iIndex + ". " + this.m_sAdapterID + " - " + this.m_sAdapterName;
}
#endregion METHODS
}
}