Документация по ОС FreeBSD Воскресенье, 05.05.2024, 01:02
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Net

Модификация ToS/DSCP/TTL/etc. на FreeBSD: ng_patch [2010]
Патчи, позволяющие матчить и изменять ToS/DSCP на FreeBSD, ходят в разных вариантах по сети уже лет шесть, вот очередная инкарнация, например. К сожалению, ни один из них так и не попал в базовую систему, хотя пример по ссылке, скажем, для конкретной задачи удобнее того, что описано ниже. Даже возникает подозрение, что это всё потому, что предыдущие решения были недостаточно общие :) Вот Maxim Ignatenko написал ноду ng_patch(4) - и её, наконец, закоммиттили, а недавно смержили в 8-STABLE (r209843) и вчера - в 7-STABLE (r210019). Работает также на 6.4, если убрать в коде CSUM_SCTP, я проверял.
В настоящее время ng_patch - единственный штатный способ поменять что-то в проходящем пакете. Зато, в отличие от других решений (в том числе на других ОС), эта нода позволяет производить последовательность операций над произвольными байтами пакета, не только ToS или TTL. В мане рассмотрены примеры изменения ToS и TTL, я же расскажу чуть подробнее, с примером для DSCP.
Байты пакета для операций рассматриваются как беззнаковые целые длиной 1, 2, 4 или 8 байт, применять можно такие операции из языка Си: присвоение нового значения (=), добавление (+=), вычитание (-=), умножение (*=), деление (/=), отрицание (= -), побитовое AND (&=), побитовое OR (|=), побитовое XOR (^=), сдвиг влево (<<=), сдвиг вправо (>>=). Исключением является отрицание, здесь данные рассмтариваются как знаковые, а аргумент не используется.
Конфигурируется нода следующими структурами, ниже рассмотрим на примере:
struct ng_patch_op {
 uint64_t value;
 uint32_t offset;
 uint16_t length; /* 1,2,4 or 8 bytes */
 uint16_t mode;
};
/* Patching modes */
#define NG_PATCH_MODE_SET 1
#define NG_PATCH_MODE_ADD 2
#define NG_PATCH_MODE_SUB 3
#define NG_PATCH_MODE_MUL 4
#define NG_PATCH_MODE_DIV 5
#define NG_PATCH_MODE_NEG 6
#define NG_PATCH_MODE_AND 7
#define NG_PATCH_MODE_OR 8
#define NG_PATCH_MODE_XOR 9
#define NG_PATCH_MODE_SHL 10
#define NG_PATCH_MODE_SHR 11

struct ng_patch_config {
 uint32_t count;
 uint32_t csum_flags;
 struct ng_patch_op ops[];
};

Теперь собственно пример. Допустим, в проходящих пакетах нам нужно выставить DSCP в AF33. Открываем RFC 791 и видим начало заголовка IP:
 0 1 2 3 
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |Version| IHL |Type of Service| Total Length |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Нужный нам байт (ровно один байт) - ToS - второй, то есть, имеет смещение 1 от начала заголовка. Далее, мы знаем, что байт ToS был переопределен под использование DSCP, в RFC 3168 он определяется так:
 0 1 2 3 4 5 6 7 
 +-----+-----+-----+-----+-----+-----+-----+-----+
 | DS FIELD, DSCP | ECN FIELD |
 +-----+-----+-----+-----+-----+-----+-----+-----+
 
 DSCP: differentiated services codepoint 
 ECN: Explicit Congestion Notification  

Нужный нам AF33 описан в RFC 2597 (впрочем, в любом справочнике по цискам и т.п. - тоже): AF33 = '011110'.
Что теперь? А вот 2 бита ECN нам трогать не надо, надо их оставить как есть. Минимальный же размер для операции - 1 байт. На помощь спешитКапитан Очевидность булева алгебра и прочая двоичная логика с дискретной математикой - применением очень сложных операций И и ИЛИ сначала надо обнулить искомые биты, а потом - сделать из них нужное нам значение. Два шага, сначала:
 +-+-+-+-+-+-+-+-+
 |s t u v w x y z| исходный байт
 +-+-+-+-+-+-+-+-+
 AND 
 +-+-+-+-+-+-+-+-+
 |0 0 0 0 0 0 1 1| значение 0x03
 +-+-+-+-+-+-+-+-+
 =
 +-+-+-+-+-+-+-+-+
 |0 0 0 0 0 0 y z|
 +-+-+-+-+-+-+-+-+

а потом:
 +-+-+-+-+-+-+-+-+
 |0 0 0 0 0 0 y z| промежуточный байт
 +-+-+-+-+-+-+-+-+
 OR
 +-+-+-+-+-+-+-+-+
 |0 1 1 1 1 0 0 0| значение AF33, сдвинутое на 2 влево: 0x78 (7=0111, 8=1000)
 +-+-+-+-+-+-+-+-+
 =
 +-+-+-+-+-+-+-+-+
 |0 1 1 1 1 0 y z| то, что надо!
 +-+-+-+-+-+-+-+-+

Итак, составляем структурки для конфигурации узла и получаем итоговые команды (это уже полная конфигурация):
/usr/sbin/ngctl -f- <<-SEQ
 mkpeer ipfw: patch 600 in
 name ipfw:600 dscp_af33
 msg dscp_af33: setconfig { count=2 csum_flags=1 ops=[ \
 { mode=7 value=0x03 length=1 offset=1 } \
 { mode=8 value=0x78 length=1 offset=1 } ] }
SEQ
/sbin/ipfw add 160 netgraph 600 ip from any to any not dst-port 80

Как можно догадаться, в командах и по тексту одинаковым цветом выделены одинаковые значения, для удобства сопоставления читателем. Операций у нас две, и поэтому count сообщает, что в массиве ops=[ ... ] будет две структуры ng_patch_op. Отдельно осталось рассмотреть полеcsum_flags - оно может принимать такие значения (см. <sys/mbuf.h>), которые можно OR-ить:
#define CSUM_IP 0x0001 /* will csum IP */
#define CSUM_TCP 0x0002 /* will csum TCP */
#define CSUM_UDP 0x0004 /* will csum UDP */
#define CSUM_SCTP 0x0040 /* will csum SCTP */

Поле инструктирует ноду сообщить IP-стеку о необходимости пересчитать контрольную сумму. Сделано это будет позже, не в самой ноде. В данном примере дается команда пересчитать контрольную сумму только IP-заголовка, другие не трогать.

Надеюсь, вышеприведенной информации достаточно, чтобы самостоятельно менять в пакетах что угодно. NB: Только учтите, что это средство - в стиле Unix, и позволяет админу прострелить себе ногу. Хитро поигравшись значениями, можно так изменить пакет, что на выходном пути IP-стека ядро свалится в панику или будут какие-нибудь еще непредсказуемые результаты.

Да, быть может, этот способ не очень дружелюбен, если нужно поменять только TOS или TTL, зато он позволяет делать куда больше вещей, и это единственный штатный способ на текущий момент.

На том всё. Удачи.


Источник: http://nuclight.livejournal.com/126002.html
Категория: Net | Добавил: oleg (17.07.2010) | Автор: Vadim Goncharov (nuclight)
Просмотров: 791 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024