133 lines
3.6 KiB
C
133 lines
3.6 KiB
C
//
|
|
// Created by ako on 8/22/25.
|
|
//
|
|
#define _GNU_SOURCE
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <netinet/ip.h>
|
|
#include <netinet/if_ether.h>
|
|
#include <netpacket/packet.h>
|
|
#include <net/ethernet.h>
|
|
#include <errno.h>
|
|
#include "nethdr.h"
|
|
#include "npcap_handle.h"
|
|
#include <netpacket/packet.h>
|
|
#include <net/if.h>
|
|
#include <netinet/ip_icmp.h>
|
|
#include <netinet/tcp.h>
|
|
#include <netinet/udp.h>
|
|
|
|
void cleanup(int socket, unsigned char* buffer) {
|
|
close(socket);
|
|
free(buffer);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
if (geteuid() != 0)
|
|
{
|
|
printf("Please run me as root.\n");
|
|
return 1;
|
|
}
|
|
|
|
int sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
|
if (sock_raw < 0)
|
|
{
|
|
fprintf(stderr, "Unable to connect to network socket.\n");
|
|
return -1;
|
|
}
|
|
|
|
unsigned char *buffer = (unsigned char *) calloc(65536, sizeof(unsigned char));
|
|
|
|
if (buffer == NULL) {
|
|
fprintf(stderr, "Unable to connect to allocate memory.\n");
|
|
cleanup(sock_raw, buffer);
|
|
return 1;
|
|
}
|
|
|
|
struct sockaddr_ll sourceaddr;
|
|
socklen_t sourceaddr_len = sizeof(sourceaddr);
|
|
|
|
int loopback_ifindex = if_nametoindex("lo");
|
|
if (loopback_ifindex == 0) {
|
|
perror("if_nametoindex for lo");
|
|
cleanup(sock_raw, buffer);
|
|
return 1;
|
|
}
|
|
|
|
while (1) {
|
|
ssize_t buflen = recvfrom(sock_raw, buffer, 65536, 0, (struct sockaddr *)&sourceaddr, &sourceaddr_len);
|
|
|
|
if (buflen == -1) {
|
|
perror("Couldn't read from socket");
|
|
cleanup(sock_raw, buffer);
|
|
return 1;
|
|
}
|
|
|
|
if (sourceaddr.sll_ifindex == loopback_ifindex) {
|
|
continue;
|
|
}
|
|
printf("\n===== Paquet reçu =====\n");
|
|
printf("Paquet de %ld octets\n", buflen);
|
|
|
|
// Debug
|
|
printf("Hexdump du paquet :\n");
|
|
for (int i = 0; i < buflen; i++) {
|
|
printf("%02x ", buffer[i]);
|
|
if ((i + 1) % 8 == 0) printf(" ");
|
|
if ((i + 1) % 32 == 0) printf("\n");
|
|
}
|
|
printf("\n");
|
|
|
|
//
|
|
// COUCHE 2
|
|
//
|
|
// Décodage entête Ethernet
|
|
struct ethhdr *eth = (struct ethhdr *)buffer;
|
|
handle_eth(eth);
|
|
|
|
|
|
//
|
|
// COUCHE 3
|
|
//
|
|
switch (ntohs(eth->h_proto))
|
|
{
|
|
// Décodage entête ARP
|
|
case ETH_P_ARP:
|
|
struct arphdr_c *arp = (struct arphdr_c *) (buffer + sizeof(struct ethhdr));
|
|
handle_arp(arp);
|
|
break;
|
|
|
|
case ETH_P_IP:
|
|
struct iphdr *ip = (struct iphdr *) (buffer + sizeof(struct ethhdr));
|
|
handle_ip(ip);
|
|
|
|
switch (ip->protocol) {
|
|
case 0x01:
|
|
struct icmphdr *icmp = (struct icmphdr *) (buffer + sizeof(struct ethhdr) + ip->ihl * 4);
|
|
handle_icmp(icmp);
|
|
break;
|
|
case 0x06:
|
|
struct tcphdr *tcp = (struct tcphdr *) (buffer + sizeof(struct ethhdr) + ip->ihl * 4);
|
|
handle_tcp(tcp);
|
|
break;
|
|
case 0x11:
|
|
struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct ethhdr) + ip->ihl * 4);
|
|
handle_udp(udp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// printf("\n=======================\n");
|
|
}
|
|
cleanup(sock_raw, buffer);
|
|
}
|