Read RAW Socket in Unix Using C Programming

🎯 Introduction

In the realm of network programming, raw sockets provide a powerful tool for developers to access and manipulate network packets at a low level. They allow the programmer to work directly with the network layer, bypassing the transport layer (e.g., TCP, UDP). This level of access is particularly useful for crafting custom network protocols, network monitoring, and network security applications. In this blog post, we will delve into the concept of raw sockets, provide a detailed explanation of the C program, and explore its output to understand how it reads and interprets raw network packets.

🎯 Concept of RAW Sockets

A raw socket is a type of socket that provides direct access to the underlying network protocols, such as IP (Internet Protocol). It enables the programmer to handle the IP header and data directly, giving full control over the entire packet, including its headers and payloads. Unlike higher-level sockets, like SOCK_STREAM (TCP) and SOCK_DGRAM (UDP), which handle data at the transport layer, raw sockets work at the network layer.

Using raw sockets, developers can build custom protocols, implement low-level network monitoring and sniffing tools, perform network diagnostics, and even create custom firewalls or intrusion detection systems. However, working with raw sockets requires a good understanding of network protocols and imposes additional responsibilities on the developer, such as checksum calculation and handling protocol-specific intricacies.

🎯 Detailed Explanation of the C Program

👉 Source Code


#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/ip.h>


int main() {

    int sockfd;

    char buff[8192] = "";

    struct iphdr *ip;


    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);


    while (read(sockfd, buff, 8192)) {

        ip = (struct iphdr *)buff;

        printf("\nSource: %s \n", inet_ntoa(ip->saddr));

        printf("Destination: %s\n", inet_ntoa(ip->daddr));

    }

    return 0;

}


👉 Explanation

In this C program, we use a raw socket to receive and read network packets. Let's break down the important parts of the code:

Header Files: 

The necessary header files are included to access socket-related functions and structures.

Socket Creation: 

The socket() function is called to create a raw socket. The arguments passed are AF_INET (IPv4), SOCK_RAW (raw socket type), and IPPROTO_ICMP (the protocol we want to capture, in this case, ICMP). Raw sockets allow us to receive all packets of the specified protocol.

Packet Reception: 

The program enters a while loop to continuously read packets from the raw socket using the read() system call. The function reads up to 8192 bytes of data from the socket and stores it in the buff buffer.

Packet Analysis: 

The received packet is then treated as an IP packet. We cast the buffer buff to a pointer of type struct iphdr (IP header structure) named ip. This allows us to access the IP header fields directly.

Source and Destination Printing: 

We extract the source and destination IP addresses from the IP header using inet_ntoa, a function that converts IP addresses from binary to a readable string format. The extracted addresses are then printed to the console.

🎯 Sample Output

[root@localhost ~]# ./a.out

Source: 172.16.29.123 

Destnation: 172.16.29.60

Source: 172.16.29.123 

Destnation: 172.16.29.60

Source: 172.16.29.123 

Destnation: 172.16.29.60

Source: 172.16.29.123 

Destnation: 172.16.29.60

Source: 172.16.29.123 

Destnation: 172.16.29.60

Source: 172.16.29.123 

Destnation: 172.16.29.60

Source: 172.16.29.123 

Destnation: 172.16.29.60

🎯 Summary

In this blog post, we explored the concept of raw sockets in Unix using C programming. We learned that raw sockets provide direct access to network protocols, allowing developers to handle IP packets at a low level. The C program provided reads ICMP packets from a raw socket and prints the source and destination IP addresses from each packet.

🎯 Key Points