Краткий ответ на вопрос: аппаратное обеспечение / прошивка сетевого интерфейса и ОС делают все это.
Точнее, есть пара водителей. Устройство обычно охватывает уровни 1 (физический) и 2 (канал передачи данных) OSI, т. Е. Преобразование между физическими сигналами (электрическими, радиосигналами) и битами и группирование их в кадры выполняется аппаратно / программно-аппаратным обеспечением. Драйвер устройства управляет соответствующими функциями. Уровни 3 (сеть) и 4 (транспорт) покрыты ОС, хотя привилегированные пользовательские процессы могут получить доступ к данным.
Как ОС захватывает кадр?
Как только сетевой интерфейс имеет доступный кадр, он запускает прерывание, поэтому ядро может считывать его из соответствующей области памяти ввода / вывода.
Данные заголовка кадра говорят, что делать с кадром. Если ядро (точнее: сетевой драйвер) знает тип полезной нагрузки (например, IPv4 или IPv6), то пакет (после удаления заголовков и трейлеров уровня 2) передается соответствующему драйверу сетевого уровня.
Он будет обрабатывать все особенности протокола сетевого уровня, такие как фрагментация и повторная сборка, вычисление и проверка контрольной суммы и т.д., А также все специфические задачи сетевого уровня, такие как маршрутизация и фильтрация пакетов. В зависимости от полезной нагрузки (TCP, UDP, ICMP, ICMPv6, GRE, SCTP, DCCP и т.д.) Пакет передается далее до соответствующего драйвера транспортного уровня. Он будет обрабатывать все специфичные для транспортного уровня вещи; для протоколов, ориентированных на соединение, таких как TCP, это означает, например, отслеживание состояния соединения, поддержание очередей и ведение учета; другая вещь - контроль за перегрузкой.
Как только пакет прошел этот уровень, он проходит дальше (снова после удаления заголовка транспортного уровня), но на этот раз процессу пользовательского пространства. Процесс пользовательского пространства практически не видит ничего из обработки более низкого уровня.
Теперь можно получить доступ и обрабатывать необработанные данные, такие как фреймы, из пользовательского пространства, вы можете сделать это с помощью программного обеспечения, такого как libpcap. Однако делать все это в ядре более эффективно.