Introduction
Network monitoring is a critical aspect of managing and securing modern computer networks. As organizations increasingly depend on digital infrastructure to conduct their operations, the ability to monitor network traffic in real-time has become paramount. By capturing and analyzing network traffic, administrators can identify issues, optimize performance, and prevent security breaches before they escalate into significant problems. This proactive approach not only enhances the reliability of network services but also safeguards sensitive data from potential threats. Implementing network monitoring with C++ can be highly efficient and effective due to the language’s performance and low-level access to system resources.
Learning Objectives
By the end of this article, readers will be able to:
- Understand the fundamentals of network monitoring and packet analysis.
- Utilize raw sockets in C++ to capture Ethernet and IP packets.
- Parse Ethernet and IP headers to extract essential information such as MAC and IP addresses.
- Implement a command-line application for real-time network monitoring.
Network Monitoring with C++
Network monitoring involves the continuous observation of network traffic to ensure smooth operation and security. It allows administrators to track key metrics such as bandwidth usage, packet loss, and latency. Effective monitoring is crucial for troubleshooting connectivity issues and responding swiftly to potential threats. In this project, we will focus on capturing packets at the Ethernet layer and analyzing the IP layer. The Ethernet protocol operates at Layer 2 of the OSI model, while IP operates at Layer 3. By monitoring both layers, we gain insights into the data being transmitted across the network.

C++ is an excellent choice for developing network monitoring tools due to its performance and low-level access to system resources. Using raw sockets, we can capture all packets passing through a specified interface, regardless of their protocol type.
Project Purpose
The purpose of this project is to create a basic network monitoring tool that listens for incoming packets on a specified network interface. The tool will parse Ethernet headers to retrieve source and destination MAC addresses, as well as IP headers for source and destination IP addresses. This foundational knowledge serves as a stepping stone for further exploration into more sophisticated network analysis techniques.
Read: Sending ICMP Packets with Python Socket
Let’s Start Writing Our Code
Below is a complete implementation of a simple network monitoring tool in C++. This code captures packets using raw sockets and displays relevant information such as MAC addresses and IP addresses. Now let’s break down the code for explanation.
Including Libraries
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/ethernet.h> // For Ethernet headers
#include <netinet/ip.h> // For IP headers
Defining Buffer Size
#define BUFFER_SIZE 65536 // Buffer size for incoming data
BUFFER_SIZE
: Defines the buffer size that will be used for incoming data. 65536 bytes is sufficient for most packets.
Main Function and Variable Definitions
int main() {
int sockfd;
struct sockaddr saddr;
unsigned char *buffer = new unsigned char[BUFFER_SIZE]; // Data buffer
int sockfd;
: Holds the socket file descriptor.struct sockaddr saddr;
: A structure to hold address information for incoming data.unsigned char *buffer = new unsigned char[BUFFER_SIZE];
: Dynamically allocates a buffer to store incoming data.
Creating a Raw Socket
// Create a raw socket
sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sockfd < 0) {
perror("Socket creation failed");
return 1;
}
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
: Creates a raw socket.AF_PACKET
is used to capture packets at the Ethernet layer.SOCK_RAW
specifies the raw socket type, whileETH_P_ALL
indicates that all protocols should be monitored.- Error checking is performed; if the socket cannot be created, an error message is printed, and the program exits.
Starting Listening
std::cout << "Listening... Press Ctrl+C to exit." << std::endl;
A message indicating that listening has started is printed to the console. The user can stop the program by pressing Ctrl+C.
Receiving Data in an Infinite Loop
while (true) {
// Receive data
socklen_t saddr_len = sizeof(saddr); // Define address structure size
int dataSize = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, &saddr, &saddr_len);
if (dataSize < 0) {
perror("Failed to receive data");
break; // Exit loop on error
}
- An infinite loop is initiated where incoming data will continuously be listened for.
recvfrom()
: Receives data from the socket. The incoming data is written intobuffer
, and address information is updated insaddr
.- Error checking is performed; if data cannot be received, an error message is printed, and the loop exits.
Parsing Ethernet Header
// Parse Ethernet header
struct ethhdr *eth = (struct ethhdr *)buffer;
The incoming data buffer is cast to an ethhdr
structure to access Ethernet header fields.
Printing MAC Addresses
// Print MAC addresses
std::cout << "Source MAC: "
<< std::hex
<< (int)eth->h_source[0] << ":"
<< (int)eth->h_source[1] << ":"
<< (int)eth->h_source[2] << ":"
<< (int)eth->h_source[3] << ":"
<< (int)eth->h_source[4] << ":"
<< (int)eth->h_source[5] << std::dec
<< " | ";
The source MAC address is printed in hexadecimal format. h_source
represents the source MAC address in the Ethernet header.
Printing Destination MAC Address
std::cout << "Destination MAC: "
<< std::hex
<< (int)eth->h_dest[0] << ":"
<< (int)eth->h_dest[1] << ":"
<< (int)eth->h_dest[2] << ":"
<< (int)eth->h_dest[3] << ":"
<< (int)eth->h_dest[4] << ":"
<< (int)eth->h_dest[5] << std::dec
<< " | ";
The destination MAC address is printed similarly. This indicates where the incoming packet is directed.
Checking IP Header and Printing It
// Check for IP header
if(ntohs(eth->h_proto) == ETH_P_IP) {
struct iphdr *ip = (struct iphdr *)(buffer + sizeof(struct ethhdr));
struct in_addr src_ip, dest_ip;
src_ip.s_addr = ip->saddr;
dest_ip.s_addr = ip->daddr;
std::cout << "Source IP: "
<< inet_ntoa(src_ip)
<< " | Destination IP: "
<< inet_ntoa(dest_ip);
}
If the packet contains an IP header (ntohs(eth->h_proto) == ETH_P_IP
), it parses the IP header.
- Source and destination IP addresses are assigned to
src_ip
anddest_ip
. - The
inet_ntoa()
function converts binary format IP addresses into human-readable format before printing them.
Read: Python TCP/UDP Network Traffic Listener (Part 1)
Moving to New Line
std::cout << std::endl; // Move to the next line
}
After each packet’s information has been printed, it moves to a new line.
Memory Management and Closing Socket
delete[] buffer; // Free memory
close(sockfd); // Close the socket
return 0;
}
At program termination:
- Dynamically allocated memory is freed (
delete[] buffer;
) - The socket is closed (
close(sockfd);
). This prevents memory leaks.
This breakdown illustrates how a simple network monitoring tool operates by focusing on both Ethernet and IP layers to gather valuable information about network traffic. This foundational application can be expanded into more complex network analysis tools.

Conclusion
Creating a network monitoring tool with C++ provides valuable insights into how data travels across networks. By focusing on both Ethernet and IP layers, developers can build applications that help manage and secure networks effectively. This foundational project serves as a stepping stone towards more advanced networking applications that could include features like filtering specific types of traffic or logging captured data for later analysis.
As you continue your journey in network programming, consider exploring additional protocols such as TCP or UDP for deeper insights into different types of traffic. You can also enhance your application by implementing graphical user interfaces or web-based dashboards for real-time visualization of captured data. Overall, mastering these concepts not only enhances your programming skills but also equips you with essential tools needed in today’s cybersecurity landscape where proactive measures are crucial for safeguarding digital assets, You can contact me on LinkedIn for any questions you may have..