Porting Sample libpcap C code to Raw Sockets User-space Network Stack Framework

I shot multi-episode video series on sample libpcap user-space C code, which you can refer (below). And long ago I shot multi-episode video series on sending custom packets via raw-sockets which you can refer (below). So here is my multi-episode video series where I demonstrate how you can port the same libpcap sample code, discussed in the earlier episode(s) to raw-socket. This code should further help you to design and architect your own user-space Network stack on top of this fundamental framework.

Refer my other video series on:
Linux (user-space) RAW Socket Programming – Generate Google’s QUIC Protocol UDP Packets ↗
Linux (user-space) RAW Socket Programming – Generate VOIP SIP UDP Packets ↗
Linux (user-space) RAW Socket Programming – Generate Layer-2 multicast STP Packets ↗
Linux (user-space) RAW Socket Programming – Generate Layer-3 IP multicast OSPF Packets ↗
Linux TUN/TAP virtual network interfaces ↗
libpcap Library | Linux User-space Network Stack Development ↗
Layer-2 (L2) Multicast Frame Deep Analysis ↗
Linux Kernel net_device data-structure ↗

Also refer:
Wiki Multicast Address ↗
tcpdump and libpcap project ↗
libpcap github ↗

Here is the source code discussed in this video episode

/* raw_socket_sniffer.c - The Linux Channel */
#include <pcap.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netpacket/packet.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <getopt.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <malloc.h>
#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#define PROMISCUOUS 1
#define NONPROMISCUOUS 0
typedef unsigned char  BYTE;    /* 8-bit   */

enum _Boolean_ { FALSE=0, TRUE=1};

int sock_fd=0;

#define MAX_PKT_BUF 2000
unsigned char pkt_buf[MAX_PKT_BUF];
unsigned int pkt_buf_len=0;

void parse_pkt(unsigned char *buf, unsigned int buf_len)
{
    struct ether_header *ep;
    struct ip *iph;
    unsigned short ether_type;
    int chcnt = 0;
    int len = buf_len;
    int i;

	for(i=0;i<buf_len;i++) 
	{ 
         printf("%02x ", buf[i]);
             
    }
	 printf("\n");
	 
	 printf("dest mac: %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
	 printf("src mac: %02x %02x %02x %02x %02x %02x \n", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
	 printf("type: %02x %02x \n", buf[12], buf[13]);
	 
	 printf("src ip: %d.%d.%d.%d \n", buf[26], buf[27], buf[28], buf[29]);
	 printf("dst ip: %d.%d.%d.%d \n", buf[30], buf[31], buf[32], buf[33]);
	 printf("protocol: %d \n", buf[23]);
	 
    // Get Ethernet header.
    ep = (struct ether_header *)buf;
    // Get upper protocol type.
    ether_type = ntohs(ep->ether_type);
    
    

    if (ether_type == ETHERTYPE_IP) {
        printf("ETHER Source Address = ");
        for (i=0; i<ETH_ALEN; ++i)
            printf("%.2X ", ep->ether_shost[i]);
        printf("\n");
        printf("ETHER Dest Address = ");
        for (i=0; i<ETH_ALEN; ++i)
            printf("%.2X ", ep->ether_dhost[i]);
        printf("\n");

        // Move packet pointer for upper protocol header.
        //packet += sizeof(struct ether_header);
        iph = (struct ip *)(buf+sizeof(struct ether_header));
        printf("IP Ver = %d\n", iph->ip_v);
        printf("IP Header len = %d\n", iph->ip_hl<<2);
        printf("IP Source Address = %s\n", inet_ntoa(iph->ip_src));
        printf("IP Dest Address = %s\n", inet_ntoa(iph->ip_dst));
        printf("IP Packet size = %d\n", len-16);
    }
    printf("-----------------------------------\n\n");
}

int create_socket(char *device)
{	int sock_fd;
   struct ifreq ifr;
   struct sockaddr_ll sll;
	memset(&ifr, 0, sizeof(ifr));
   memset(&sll, 0, sizeof(sll));

   sock_fd = socket (PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));

   if(sock_fd == 0) { printf("ERR: socket creation for device: %s\n", device); return FALSE; }
   strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
   if(ioctl(sock_fd, SIOCGIFINDEX, &ifr) == -1) { printf(" ERR: ioctl failed for device: %s\n", device); return FALSE; }
	
	sll.sll_family      = AF_PACKET;
	sll.sll_ifindex     = ifr.ifr_ifindex;
	sll.sll_protocol    = htons(ETH_P_ALL);
	if(bind(sock_fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { printf("ERR: bind failed for device: %s\n", device); return FALSE; }
  return sock_fd;
}

int main(int argc, char **argv)
{
  sock_fd = create_socket("wlp1s0");
  if( !(sock_fd) ) { printf("no sock_fd found\n"); return 0; }
  while(1) 
  {  pkt_buf_len=0;
	  pkt_buf_len = read(sock_fd, pkt_buf, MAX_PKT_BUF);
	  if(pkt_buf_len>0) { parse_pkt(pkt_buf, pkt_buf_len); }
  }
  return 0;
}