From a4b6a22868ccac778537e21137e949803b93a8e3 Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Sat, 31 May 2025 14:05:07 +0200 Subject: [PATCH] prepare to QUIC migration --- README.md | 3 ++ src/common/const.h | 9 ++++ src/server/capture.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 README.md create mode 100644 src/server/capture.cpp diff --git a/README.md b/README.md new file mode 100644 index 0000000..828e2ce --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Interface forwarder + +do not work with IPv6 Jumbograms diff --git a/src/common/const.h b/src/common/const.h index d96e9f4..d01926b 100644 --- a/src/common/const.h +++ b/src/common/const.h @@ -2,4 +2,13 @@ #define _IF_CONST_HG_ #define CERTS_DIR "certs/" #define PORT 11723 + +enum message_type { + RESERVED_TYPE, + KEEP_ALIVE_TYPE, + KEEPING_ALIVE_TYPE, + SET_IP_ADDR_TYPE, + IP_PACKET_TYPE, + TERMINATE_CONNECTION_TYPE +}; #endif \ No newline at end of file diff --git a/src/server/capture.cpp b/src/server/capture.cpp new file mode 100644 index 0000000..6f41d76 --- /dev/null +++ b/src/server/capture.cpp @@ -0,0 +1,97 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this is max size standard Ipv4/6 packet can be +// what in understand in practise it is much lower around 1500 bytes +#define IP_PACKET_BUFFER_SIZE 65536 + +int get_interface_index(const char *interface_name) { + struct ifaddrs *ifaddr, *ifa; + int interface_index = -1; + + if (getifaddrs(&ifaddr) == -1) { + return -1; + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + + if (strcmp(ifa->ifa_name, interface_name) == 0) { + interface_index = if_nametoindex(interface_name); + break; + } + } + + freeifaddrs(ifaddr); + return interface_index; +} + +int listen_for_ip_packets(const std::string interface_name) { + int raw_ip_scoketfd; + unsigned char buffer[IP_PACKET_BUFFER_SIZE]; + + struct sockaddr_ll saddr; + socklen_t saddr_len = sizeof(saddr); + + // Create raw socket for packet capture + raw_ip_scoketfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)); + if (raw_ip_scoketfd < 0) { + perror("Failed to create raw socket"); + std::cerr << "Make sure you're running as root!" << std::endl; + return 1; + } + + // Get interface index + int if_index = get_interface_index(interface_name.c_str()); + if (if_index < 0) { + std::cerr << "Interface " << interface_name << " not found!" << std::endl; + close(raw_ip_scoketfd); + return 1; + } + + // Bind socket to specific interface + memset(&saddr, 0, sizeof(saddr)); + saddr.sll_family = AF_PACKET; + saddr.sll_protocol = htons(ETH_P_IP); + saddr.sll_ifindex = if_index; + + if (bind(raw_ip_scoketfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { + perror("Failed to bind to interface"); + close(raw_ip_scoketfd); + return 1; + } + + std::cout << "Listening for IP packets on interface: " << interface_name + << " (index: " << if_index << ")" << std::endl; + + // Main packet capture loop + while (true) { + int packet_size = recvfrom(raw_ip_scoketfd, buffer, IP_PACKET_BUFFER_SIZE, + 0, (struct sockaddr *)&saddr, &saddr_len); + + if (packet_size < 0) { + perror("Error receiving packet"); + continue; + } + + // Only process IP packets (skip non-IP traffic) + if (packet_size >= sizeof(struct ethhdr) + sizeof(struct iphdr)) { + process_packet(buffer, packet_size); + } + } + + close(raw_ip_scoketfd); + return 0; +}