Давай программировать стек TCP/IP. Part 1: Ethernet & ARP — 23 марта 2026 г. в 08:08:51.913
Давай программировать стек TCP/IP. Part 1: Ethernet & ARP Написание собственного стека TCP/IP может показаться сложной задачей. Действительно, за более чем тридцать лет существования TCP накопилось множество спецификаций. Однако основная спецификация на удивление компактна — важные части включают разбор заголовков TCP, автомат конечных состояний, контроль перегрузок и вычисление времени ожидания повторной передачи. Наиболее распространенные протоколы второго и третьего уровней — Ethernet и IP, соответственно, — в сравнении с TCP гораздо проще. В этой серии статей мы реализуем минимальный стек TCP/IP в пространстве пользователя для Linux. Цель этих публикаций и создаваемого ПО исключительно образовательная — углубленное изучение сетевого и системного программирования. TUN/TAP устройства Чтобы перехватывать сетевой трафик низкого уровня из ядра Linux, мы будем использовать TAP-устройство Linux. Если кратко, TUN/TAP устройства часто применяются приложениями в пространстве пользователя для работы с трафиком на уровне L3 и L2 соответственно. Популярным примером является туннелирование, когда пакет инкапсулируется внутри полезной нагрузки другого пакета. Преимущество TUN/TAP устройств в том, что их легко настроить в программе в пространстве пользователя, и они уже используются во множестве программ, таких как OpenVPN. Поскольку мы хотим строить стек сетевого взаимодействия, начиная со второго уровня, нам потребуется TAP-устройство. Мы создаем его следующим образом: /* * Taken from Kernel Documentation/networking/tuntap.txt */ int tun_alloc(char *dev) { struct ifreq ifr; int fd, err; if( (fd = open("/dev/net/tap", O_RDWR)) < 0 ) { print_error("Cannot open TUN/TAP dev"); exit(1); } CLEAR(ifr); /* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */ ifr.ifr_flags = IFF_TAP | IFF_NO_PI; if( *dev ) { strncpy(ifr.ifr_name, dev, IFNAMSIZ); } if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ print_error("ERR: Could not ioctl tun: %s\n", strerror(errno)); close(fd); return err; } strcpy(dev, ifr.ifr_name); return fd; } https://www.saminiir.com/lets-code-tcp-ip-stack-1-ethernet-arp/ 👉 @Bookflow

