Created
March 18, 2023 12:45
-
-
Save networkextension/3b250450a6ada160696114c8f2aca6b6 to your computer and use it in GitHub Desktop.
packet_capture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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