Skip to content

Instantly share code, notes, and snippets.

@networkextension
Created March 18, 2023 12:45
Show Gist options
  • Save networkextension/3b250450a6ada160696114c8f2aca6b6 to your computer and use it in GitHub Desktop.
Save networkextension/3b250450a6ada160696114c8f2aca6b6 to your computer and use it in GitHub Desktop.
packet_capture
#include <stdio.h>
#include <linux/if_vlan.h>
#include <netinet/ether.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#define BUFFER_SIZE 4096
#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */
struct vlan_header
{
__be16 vlan_tci;
__be16 vlan_proto;
};
int
main (int argc, char *argv[])
{
int sock, ifindex, read_size;
char *buffer;
struct ifreq ifr;
struct sockaddr_ll saddr;
socklen_t saddr_size = sizeof (saddr);
uint64_t length = 0;
// create socket
if ((sock = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
{
perror ("socket()");
exit (EXIT_FAILURE);
}
// get interface index
strncpy (ifr.ifr_name, "enp4s0d1.100", IFNAMSIZ);
if (ioctl (sock, SIOCGIFINDEX, &ifr) < 0)
{
perror ("ioctl()");
exit (EXIT_FAILURE);
}
ifindex = ifr.ifr_ifindex;
// get MAC address
if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
{
perror ("ioctl()");
exit (EXIT_FAILURE);
}
// bind to interface
memset (&saddr, 0, sizeof (saddr));
saddr.sll_family = AF_PACKET;
saddr.sll_ifindex = ifindex;
saddr.sll_protocol = htons (ETH_P_ALL);
if (bind (sock, (struct sockaddr *) &saddr, sizeof (saddr)) < 0)
{
perror ("bind()");
exit (EXIT_FAILURE);
}
// allocate buffer using mmap
buffer =
mmap (NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED, -1, 0);
if (buffer == MAP_FAILED)
{
perror ("mmap()");
exit (EXIT_FAILURE);
}
// receive packets
while (1)
{
read_size =
recvfrom (sock, buffer, BUFFER_SIZE, 0, (struct sockaddr *) &saddr,
&saddr_size);
if (read_size < 0)
{
perror ("recvfrom()");
exit (EXIT_FAILURE);
}else {
length += read_size;
printf("total read %lu",length);
}
struct ethhdr *eth_header = (struct ethhdr *) buffer;
// print source and destination MAC addresses
//printf("Source MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
// eth_header->h_source[0], eth_header->h_source[1], eth_header->h_source[2],
// eth_header->h_source[3], eth_header->h_source[4], eth_header->h_source[5]);
//printf("Destination MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
// eth_header->h_dest[0], eth_header->h_dest[1], eth_header->h_dest[2],
// eth_header->h_dest[3], eth_header->h_dest[4], eth_header->h_dest[5]);
// parse IP header
if (ntohs (eth_header->h_proto) == ETH_P_IP)
{
struct iphdr *ip_header =
(struct iphdr *) (buffer + sizeof (struct ethhdr));
// Print the source IP address
// printf("Source IP address: %s\n", inet_ntoa(*(struct in_addr*)&ip_header->saddr));
// Print the destination IP address
//printf("Destination IP address: %s\n", inet_ntoa(*(struct in_addr*)&ip_header->daddr));
// parse TCP or UDP header
if (ip_header->protocol == IPPROTO_TCP)
{
struct tcphdr *tcp_header =
(struct tcphdr *) (buffer + sizeof (struct ethhdr) +
sizeof (struct iphdr));
// printf("Source port: %u\n", ntohs(tcp_header->source));
// printf("Destination port: %u\n", ntohs(tcp_header->dest));
}
else if (ip_header->protocol == IPPROTO_UDP)
{
struct udphdr *udp_header =
(struct udphdr *) (buffer + sizeof (struct ethhdr) +
sizeof (struct iphdr));
// printf("Source port: %u\n", ntohs(udp_header->source));
// printf("Destination port: %u\n", ntohs(udp_header->dest));
}
if (ntohs (eth_header->h_proto) == ETH_P_8021Q)
{
//struct vlan_tag *vlan_tag = NULL;
//vlan_tag = (struct vlan_tag *)(eth_header+1);
struct vlan_header *vlan_hdr =
(struct vlan_header *) (eth_header + 1);
__be16 vlan_tci = vlan_hdr->vlan_tci;
int vlan_id = ntohs (vlan_tci) & VLAN_VID_MASK;
printf ("Received frame with VLAN ID %d\n", vlan_id);
//printf("Source MAC: %s\n", ether_ntoa((struct ether_addr *)eth_header->h_source));
//printf("Destination MAC: %s\n", ether_ntoa((struct ether_addr *)eth_header->h_dest));
//printf("VLAN ID: %d\n", ntohs(vlan_tag->vlan_id));
}
else
{
//printf ("Received proto %d\n", ntohs (eth_header->h_proto));
}
}
}
if (read_size < 0)
{
perror ("recvfrom()");
exit (EXIT_FAILURE);
}
close (sock);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment