Click here to Skip to main content
11,576,993 members (59,306 online)
Click here to Skip to main content

Raw Ethernet Packet Sending

, 24 Oct 2003 373.1K 6.7K 140
Rate this:
Please Sign up or sign in to vote.
This article explains how to send a raw Ethernet packet using C# and a NDIS Protocol Driver.

Sample Image - "SendRawPacket.jpg

Introduction

This purpose of this article is to explain how to send a raw Ethernet packet using C# on a Microsoft platform. A raw Ethernet packet is the complete Layer 2 network frame that is sent to the physical wire. Sending a frame like this allows you to manipulate the target and source MAC addresses and the Layer 3 protocol fields.

Background

You may be thinking, "Why would anyone want to do this?". Well, I was trying to create an application (using C#) that would make a typical Windows computer with 2 NICs act as a Layer 2 Network device. My goal was to listen for packets on a network interface and send the exact same packet out of the opposite interface, basically a packet repeater. To do this, I needed to be able to read a raw Ethernet packet (easy) and then write that same raw Ethernet packet (difficult). The sent packet needed to be exactly like the read packet, Ethernet header and all. I did a great deal of research online, and did not find a whole lot of info, just a few hints here and there.

The first problem was that Windows does not include a way to programmatically send a raw Ethernet packet. After some research, I realized that I needed to create a NDIS Protocol Driver (PassThru and Intermediate drivers will also work) to interface with the network adapters at a very low level. Luckily, the Windows Driver Development Kits (DDKs) included samples that would accomplish this for me. Great, the hard part down right......yeah, that is what I thought too. Now I had to interface with the driver from managed C# code.

Well, enough of the background.....on to the code.....

Part 1 - NDIS Protocol Driver

So, like I said, the DDK provides a suitable NDIS driver for sending raw packets. I compiled this, creating the .inf and .sys files for the driver (I have included the compiled driver, altered to fit my needs, in the attached zip file). After running a few test, I found that I could:

  1. Only receive packets destined for me and
  2. I could only send packets with a source address of my adapter.

Well, this was not acceptable. I needed to receive any packets on my LAN segment, and send those same packets regardless of the source address. So after looking through the driver code, I figured out how to accomplish that.

To receive any packets, the driver had to be set to Promiscuous mode. The following code segment was what was altered to accomplish this.

// ndisprot.h
// line 177
// Add NDIS_PACKET_TYPE_PROMISCUOUS to support promiscuous mode reading

#define NUIOO_PACKET_FILTER  (NDIS_PACKET_TYPE_DIRECTED|    \
                              NDIS_PACKET_TYPE_MULTICAST|   \
                              NDIS_PACKET_TYPE_BROADCAST|   \
                              NDIS_PACKET_TYPE_PROMISCUOUS)     // **Added**

To send any packets, the following code segment had to be commented out

// send.c
// line 136
// Comment out to support sending packets from any MAC source address

     // To prevent applications from sending packets with spoofed
     // mac address, we will do the following check to make sure the source 
     // address in the packet is same as the current MAC address of the NIC.
     //
     if ((pIrp->RequestorMode == UserMode) && 
          !NPROT_MEM_CMP(pEthHeader->SrcAddr, 
          pOpenContext->CurrentAddress, NPROT_MAC_ADDR_LEN))
     {
            DEBUGP(DL_WARN, ("Write: Failing with invalid Source address"));
            NtStatus = STATUS_INVALID_PARAMETER;
            break;
     }

Once those changes were made, the NDIS Driver performed perfect for what I needed.

Part 2 - C# RawEthernet Application

The code for the RawEthernet application is commented fairly well, so I am not going to go into a lot of detail on the code here. I am just going to highlight the important steps in the code.

Writing information to a device driver is somewhat similar to writing to a file. We open the driver file by calling the CreateFile API. This returns a handle that we can use to write to and read from the driver. Next, we can bind the driver handle to a specific adapter by using the DeviceIoControl API. Binding the adapter lets us access the NDIS Driver on a specific network adapter. After all this, the writing is simple. We use the WriteFile API. The ReadFile API can be used in a similar manner to read incoming network data as well.

To send a packet, we have to create a byte representation on the packet that we want to send. The following shows the Ethernet header (first 14 bytes of packet) in byte format

DD DD DD DD DD DD SS SS SS SS SS SS PP PP <data follows>
  • D = Destination MAC Address
  • S = Source MAC Address
  • P = Next Layer Protocol (0800 = IP)

You can use a packet sniffer (Ethereal, Snoop, EtherPeeks) to verify that you are sending a raw data packet on the network medium. The packet that this application currently sends is a very simple data packet that served no purpose other than to show the concept. This can easily be changed to reflect a real packet, such as a ping or anything else that you can think of.

Running the sample

NDIS Driver

You can install the NDIS Driver by opening your network adapter properties and clicking the "Install" button, selecting "Protocol", and then choosing "Have Disk". Then browse to the .inf file and click "OK". This will then load the driver onto every adapter that you have in your system.

Important - Make sure that it is enabled, there should be a check in the box next to "Raw Packet NDIS Protocol Driver".

Important - Open a command prompt and type "net start ndisprot" to start the driver service.

Note - The beauty of having this driver is that you can disable every other protocol in the Adapter's protocol list (i.e. Internet Protocol) and you will still be able to send and receive packets. Your machine will not even have an address, but because we are working at Layer 2, you don't need one. (This driver will work even if you keep all of the other protocols enabled)

RawEthernet application

The zip file contains the source and compiled binary for the RawEthernet application. Once the driver is installed and enabled, simply run the EXE to see the packets being sent.

Other items

I have been working on getting this to work asynchronously so that I can send and receive on the same adapter at the same time. When I get some more time, I will put out an article on how async file works.

That is about it for now...if you have any questions or comments, feel free to contact me.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

miahrugger
Web Developer
United States United States
MCSE, MCSD, MCDBA, CCNA

You may also be interested in...

Comments and Discussions

 
QuestionStream continuously Pin
Member 107056517-Apr-14 22:53
memberMember 107056517-Apr-14 22:53 
QuestionHow to Receive Frame.........Need Help Pin
Member 1054093523-Jan-14 1:38
memberMember 1054093523-Jan-14 1:38 
QuestionCan't add driver as protocol Pin
Florian Rosmann8-Oct-13 8:18
memberFlorian Rosmann8-Oct-13 8:18 
AnswerRe: Can't add driver as protocol Pin
ipetrovic1125-Jul-14 1:51
memberipetrovic1125-Jul-14 1:51 
GeneralMy vote of 5 Pin
Marco Bertschi26-Jun-13 8:36
professionalMarco Bertschi26-Jun-13 8:36 
QuestionWindows 7 NDIS driver problem Pin
Member 800437224-Feb-12 12:44
memberMember 800437224-Feb-12 12:44 
AnswerRe: Windows 7 NDIS driver problem Pin
Gonzalo Brusella7-Mar-12 10:31
memberGonzalo Brusella7-Mar-12 10:31 
AnswerRe: Windows 7 NDIS driver problem Pin
mfogar012-May-12 21:48
membermfogar012-May-12 21:48 
GeneralMy vote of 5 Pin
G. Cadel21-Jul-11 8:36
memberG. Cadel21-Jul-11 8:36 
QuestionC/C++ interface to driver (Visual C++) unicode enviroment [modified] Pin
Ulterior19806-Jul-11 4:47
memberUlterior19806-Jul-11 4:47 
GeneralMy vote of 5 Pin
Ulterior198030-Jun-11 15:02
memberUlterior198030-Jun-11 15:02 
GeneralThis example in VB.NET Pin
emicroxxx8-Sep-10 4:08
memberemicroxxx8-Sep-10 4:08 
GeneralMy vote of 5 Pin
sanjaykhan200418-Jul-10 19:34
membersanjaykhan200418-Jul-10 19:34 
GeneralDriver could not be opened Pin
msba5815-Jul-10 10:37
membermsba5815-Jul-10 10:37 
GeneralGreat article Pin
Sebastien LEBRETON25-Mar-10 7:36
memberSebastien LEBRETON25-Mar-10 7:36 
GeneralRe: Great article Pin
WDanielS30-Mar-10 2:24
memberWDanielS30-Mar-10 2:24 
GeneralVista Pin
Nneet12-Jan-09 3:07
memberNneet12-Jan-09 3:07 
GeneralRe: Vista Pin
Nneet16-Jan-09 0:13
memberNneet16-Jan-09 0:13 
QuestionMissing packets (HELP) Pin
Remco Postma5-Jan-09 4:29
memberRemco Postma5-Jan-09 4:29 
AnswerRe: Missing packets (HELP) Pin
deathmarch2-Feb-09 1:26
memberdeathmarch2-Feb-09 1:26 
QuestionSending packets speed Pin
pr_Ilya9-Dec-08 1:58
memberpr_Ilya9-Dec-08 1:58 
AnswerRe: Sending packets speed Pin
JimmyO17-Sep-09 20:25
memberJimmyO17-Sep-09 20:25 
QuestionCan I use this program to make a product ? Pin
zifq26-Nov-08 2:57
memberzifq26-Nov-08 2:57 
GeneralCannot get it to work Pin
charleswalker16-Sep-08 20:41
membercharleswalker16-Sep-08 20:41 
QuestionDoRead? Pin
BigBenDk1-Aug-08 0:03
memberBigBenDk1-Aug-08 0:03 
GeneralReadFile with variable bytesToRead number Pin
annoyingwebsite@dodgeit.com2-Jun-08 22:29
memberannoyingwebsite@dodgeit.com2-Jun-08 22:29 
GeneralRe: ReadFile with variable bytesToRead number Pin
BigBenDk1-Aug-08 3:54
memberBigBenDk1-Aug-08 3:54 
GeneralFix for loopback adapter Pin
cjones28520-Mar-08 3:26
membercjones28520-Mar-08 3:26 
QuestionTimeOut on ReadFile Pin
Keld18-Feb-08 2:02
memberKeld18-Feb-08 2:02 
GeneralNot supported for some wifi cards Pin
quantjump20-Nov-07 12:47
memberquantjump20-Nov-07 12:47 
GeneralI have troubles with the installation... Pin
SoFx009-Oct-07 1:38
memberSoFx009-Oct-07 1:38 
GeneralRe: I have troubles with the installation... Pin
tricychloramine16-Oct-07 11:28
membertricychloramine16-Oct-07 11:28 
GeneralRe: I have troubles with the installation... Pin
SoFx0017-Oct-07 5:02
memberSoFx0017-Oct-07 5:02 
GeneralDropping packets Pin
TTTCoder2-Sep-07 11:00
memberTTTCoder2-Sep-07 11:00 
GeneralUse on unconnected NIC Pin
iwdu1507-Aug-07 15:52
memberiwdu1507-Aug-07 15:52 
Generalcalling the RawEthernet by C and adding new commands to the original C# program Pin
bouteh27-Jun-07 16:16
memberbouteh27-Jun-07 16:16 
GeneralOVERLAPPED IO Pin
Nigel de Costa12-Jun-07 0:59
memberNigel de Costa12-Jun-07 0:59 
GeneralRe: OVERLAPPED IO Pin
BigBenDk4-Aug-08 6:03
memberBigBenDk4-Aug-08 6:03 
GeneralRe: OVERLAPPED IO Pin
Nigel de Costa4-Aug-08 6:06
memberNigel de Costa4-Aug-08 6:06 
QuestionTcpIp and Ndis Packet ! Pin
Mandorle12-Apr-07 0:15
memberMandorle12-Apr-07 0:15 
Generalto read data from ethernet interface Pin
Member #38600225-Mar-07 20:33
memberMember #38600225-Mar-07 20:33 
QuestionProblems with simultaneous sends and receives Pin
Stinger.91119-Feb-07 21:12
memberStinger.91119-Feb-07 21:12 
AnswerRe: Problems with simultaneous sends and receives Pin
chocobu25-Jun-07 3:21
memberchocobu25-Jun-07 3:21 
Questionsend raw data via virtual adapter [modified] Pin
Eddie_20064-Feb-07 19:22
memberEddie_20064-Feb-07 19:22 
Questionnet start ndisprot -- Error Pin
Member #135162019-Jan-07 0:15
memberMember #135162019-Jan-07 0:15 
AnswerRe: net start ndisprot -- Error Pin
Eddie_20063-Feb-07 17:30
memberEddie_20063-Feb-07 17:30 
AnswerRe: net start ndisprot -- Error Pin
it9tnc4-Feb-07 1:14
memberit9tnc4-Feb-07 1:14 
QuestionNot work on Vista RTM Pin
u85265059-Jan-07 20:37
memberu85265059-Jan-07 20:37 
AnswerRe: Not work on Vista RTM Pin
meet_you20081-Apr-07 17:29
membermeet_you20081-Apr-07 17:29 
GeneralICMP is not resolved. Pin
hitesh_au20-Dec-06 2:05
memberhitesh_au20-Dec-06 2:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150603.1 | Last Updated 25 Oct 2003
Article Copyright 2003 by miahrugger
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid