prepare to QUIC migration

This commit is contained in:
PoliEcho 2025-05-31 14:05:07 +02:00
parent aac8841c0a
commit a4b6a22868
3 changed files with 109 additions and 0 deletions

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Interface forwarder
do not work with IPv6 Jumbograms

View File

@ -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

97
src/server/capture.cpp Normal file
View File

@ -0,0 +1,97 @@
#include <arpa/inet.h>
#include <cstring>
#include <ifaddrs.h>
#include <iostream>
#include <linux/if_packet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string>
#include <sys/socket.h>
#include <unistd.h>
// 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;
}