Для использования divert-сокетов в Linux, вам понадобятся две вещи - модифицированные патчем исходные тексты ядра и исходные тексты пакета ipchains версии 1.3.9, также модифицированные соответствующим патчем.
Оба патча можно взять с веб-сайта divert-сокетов http://www.anr.mcnc.org/~divert Для ядра существуют два варианта - патч к неизмененным исходным текстам ядра версии 2.2.12, или готовые модифицированные исходные тексты ядра 2.2.12 (значительно большие по размеру, чем патч). ipchains находится там же, в виде уже модифицированного пакета с исходными текстами.
Собрать ipchains достаточно просто - дайте команду
make |
Для включения поддержки divert-сокетов, вам надо пересобрать ядро, предварительно настроив его командой:
make config или make menuconfig или make xconfig |
Чтобы использовать divert-сокеты, вам надо включить в ядро поддержку firewall и IP-firewall. На работу divert-сокетов влияют три опции сборки ядра:
Включает поддержку divert-сокетов в ядре.
Определяет поведение правил DIVERT: по умолчанию правило DIVERT, описанное в firewall, отбрасывает пакеты, при отсутствии программы на порте, определенном этим правилом, то есть действует аналогично правилу DENY.
При включении данной опции, эти пакеты будут проходить дальше через firewall. Опцию можно использовать, если вам нужно статическое правило в firewall, но вы не хотите, чтобы с портом divert-сокетов постоянно работала ваша программа.
Определяет, выполнять ли дефрагментирование при передаче данных в сокет. По умолчанию код divert-сокет получает отдельные фрагменты пакетов, имеющих больший, чем MTU, размер и посылает их в таком же виде программе. Задача дефрагментации в этом случае лежит на приложении, использующем divert-сокеты. Более того, приложение не может послать фрагмент пакета, больший, чем MTU - он сразу будет отброшен (это ограничение ядра, а не divert-сокетов - ядра Linux версии до 2.2.x НЕ фрагментируют пакеты с установленной опцией IP_HDRINCL). Обычно в таком поведении нет ничего страшного - в основном, вы просто пересылаете те же фрагменты пакетов, которые получили, и все прекрасно работает - в этом случае, размер фрагментов не будет больше MTU.
Если вы включите опцию always defragment, то все дефрагментирование будет производиться в ядре. Это сильно уменьшает производительность механизма перехвата - каждый большой пакет, который вы хотите перехватить, должен быть сначала собран из фрагментов, и только после этого будет передан вашей программе. Затем, когда вы захотите послать его дальше, он будет снова разбит на части (если в ядре включить эту опцию, то оно будет фрагментировать пакеты, имеющие флаг IP_HDRINCL)
В ядрах Linux версии 2.0.36 подобный выбор не предоставлялся из-за неправильной структуры кода firewall - он обрабатывал только первый фрагмент пакета, а с остальными фрагментами поступал так же, как и с первым, не обрабатывая их. В результате этого, если первый фрагмент был отброшен firewall, то и все остальные отбрасывались дефрагментатором. Поэтому для нормальной работы с divert-сокетами в этой версии ядра вы ДОЛЖНЫ были использовать опцию always defragment для того, чтобы получать весь пакет, а не только его первый фрагмент.
В версии 2.2.12 структура кода firewall была исправлена, и вы можете сами решать, будет ли ядро заниматься (де)фрагментацией, или вы будете делать этой в своей программе.
ВНИМАНИЕ: в версии 1.0.4 divert-сокетов функция дефрагментирования не реализована. Работа над этим продолжается.