Packet Sniffing with an Embedded Module


Use of a packet sniffer in government agencies has always been a controversial topic. You might ask, “what is packet sniffing and what can it do?” A packet sniffer is a software or hardware tool that can intercept and log traffic on an Ethernet network.In layman’s terms, everything in network is just 1s and 0s going through the wire. For example, if I could take the data and decipher it before it gets to your network device or computer, I could read all your e-mails, log on to your social networking website, or figure out everything that you see on the Internet and more! All this important information is packed into parsable packages known as Ethernet frames which I will talk about later. Nevertheless, a packet sniffer is not always used with mischievous intent. With a packet sniffer, you could:

  • audit information
  • monitor bandwidth usage
  • diagnose problems or bottlenecks in the network
  • discover devices on the network
  • detect network intrusion through packet analysis
  • convert traffic into a readable format
  • log traffic

Upon reading this article, you will acquire some basic understanding of networking and packet sniffing, and be able to successfully capture traffic between uncontrolled end points for a variety of purposes.


Before we begin, we need a few tools to make the packet sniffer. For my setup, I used:
NetBurner MOD54417 development kit, USB and Serial cable, and a software called Wireshark.

development kit

Hardware Switching

Using the MOD54417 is particularly important since it has a hardware switch that could decide where to forward data. The MOD54417 can utilize hardware switching to have packets forwarded to a desired port at very high rates. This is also feasible in the software level. However, since all packets are delivered to the processor first, it would be costly, slow, and not as robust as a hardware switch implementation. The following snippet of code shows you how to configure the MOD54417’s hardware switch:

void UserMain(void * pd) {
    init();  // automatically configures many system functions such as initializing TCP/IP stack
    EnablePromiscuous();  // this function will configure hardware switching

Enabling promiscuous mode lets the board to hardware switch.

Promiscuous Mode

A network device with switching capability can be set in promiscuous mode. In this mode, the device can monitor and read all traffic and pass it to the device’s processing unit prior to the traffic reaching it’s end point (stack). Our device will be in promiscuous mode to listen to all data that is intended for other machines and network devices.

Ethernet Frame

Now that we are listening to every packet on the network, what do we do with it? We are getting packets, but what is a packet? Simply put, a packet is data packaged in mostly one kind of box called an Ethernet frame that is transmitted over the network.

ethernet frame

This box encapsulates different kinds of structures. The different encapsulated data can be recognized by their respective headers. An Ethernet frame has a structure that resembles a Russian Matroska toy in a sense that each layer is encapsulated recursively.

This image is referenced from “”; used with permission.

Bypassing The Stack

Back to the sniffing-we want to read this Ethernet frame before it is modified or filtered in the stack because we want all of the data. In order to do this, we have to make a custom packet handler. The custom handler will allow us to get our hands on the Ethernet frame before it reaches the stack. In order to do this, we need the system to allow Custom Ethernet Handlers.

 * To do this, you must go into Nburnincludepredef.h
 * and uncomment line

Then, we define a new type and our own custom handler function:

/* In our workspaceproject namemain.cpp */
 typedef int (*netDoRXFunc)(PoolPtr, WORD, int);

/* so that we can define our own custom handler function: */
  int myNetDoRX(PoolPtr pp, WORD w, int if_num) {
    ... // code for filter and error condition check goes here

    // location current packet placement
    packetToStore = (packet*) (capBuffer + bufferIndex);

    // populating packet data
    packetToStore->lenPdata = w;
    packetToStore->time = pp->dwTime;
    packetToStore->timeFrac = pp->dwTimeFraction;
    memcpy(packetToStore->pData, pp->pData, w);

    bufferIndex += w + sizeof(packet);
    totalP += 1;


/* System will register our custom handler when this line is called */

This is a part of custom handler where we copy out the raw data and save it into the device’s memory which will be called every time incoming packet is received and processed.

Making it Readable

We are almost there! We just need to convert the saved data into a readable format. A very basic and standard format to save captured packet data is the Packet Capture (PCAP) format. The general structure of a PCAP file is as follows:


Global Header is made of

struct fileHeader {
    DWORD MAGIC;               // = 0xa1b2c3d4
    WORD MAJORVR;              // = 0x0002
    WORD MINORVR;              // = 0x0004 as current PCAP version is 2.4
    DWORD THISZONE;            // current time zone
    DWORD SIGFIGS;             // time stamp accuracy
    DWORD SNAPLEN;             // snapshot length
    DWORD NETWORK;             // type of network, Ethernet is 0x00000001
} __attribute__( ( packed ) );

The PCAP file will be read by a software called Wireshark. Wireshark is a free and open-source packet analyzer used for troubleshooting, analysis, software and communications protocol development, and education. Also, note that first 32 bytes is a standard called a Magic number; it specifies endianness of the rest of the file. I chose my board to write out the PCAP file in big endian since it is the device’s native endianness. Below is example run of the successfully capturing and storing PCAP file with our application and displaying it on Wireshark without any losing packets:

sample PCAP


The packet sniffer is finished. However, as with every project, there is always room for improvement. For my next project, I want to improve this product’s scalability. Currently, this product is set to safely store 50MB worth of packets before it flushes everything out to start anew. This limit could be reached very quickly in a larger network with heavier traffic. I want to add a feature to allow it to store larger amounts of data into the SD card as it sniffs. This would also allow the user to retrieve the data at their convenience.


Finally at this point, we basically have a product similar to Carnivore. Carnivore was a software made by the FBI back in 1997 using a customizable packet sniffer that could monitor all e-mail and electronic communications. However, a little disclaimer I might add is that you should not use this packet sniffer on a network without permission; its all fun and games until someone gets thrown in jail. If you want to see more and in details of how I coded, check out the source code!

Share this post

Subscribe to our Newsletter

Get monthly updates from our Learn Blog with the latest in IoT and Embedded technology news, trends, tutorial and best practices. Or just opt in for product change notifications.

Leave a Reply