Как я себе сие представляю:
добавляем цепь
iptables -N dns
через которую идет udp на 53 порт
iptables -A OUTPUT -p udp --dport 53 -j dns
и в ней уже сам u32
iptables -A dns -m u32 --u32 $filter -j DROP
Теперь о фильтре. Длина пакета - 3-4 байты, нужен предпоследний байт пакета с типом запроса, т.е. (длина пакета - 2). Как реализовать "-" в одном условии - для меня загадка, ибо отрицательный оффсет -0xffff=0xffff0001 , поэтому:
0 & 0x2 = 0x2 && 0 & 0xfffd @ 0 & 0xff0000 = 0x1c0000
0 & 0x2 = 0x2 && : если 7 бит 4 байта = 1
0 & 0xfffd @ : сбрасываем его (-2) и первые 2 байта, и переходим на получившийся оффсет
0 & 0xffff0000 = 0x1c0000 : сравниваем с АААА, тип запроса ipv6 address
0 & 0x2 = 0x0 && 0 & 0xfffb @ 2 & 0xff0000 = 0x1c0000
аналогично, только сначала -4 потом +2.
Все бы хорошо, но не работает.
В основном просто интересно. В плане применения - в некоторых программах, по всей видимости криво реализующих свое днс, сначала посылается запрос АААА (дико ложат на то что ipv6.disable=1 в грабе), а затем только А для ipv4, и вроде бы как днс провайдера (или роутера) неадекватно реагирует, или они итоговый ответ с боками обрабатывают, в сумме - мутное дело. Но в зависимости от фазы луны, или кеша днс, или мирового равновесия АААА может быть не послан - и, чудо, коннект происходит. Конкретно - xchat ( и да, если пересобрать без ipv6, вполне верится в неподверженность). Казалось бы, при чем тут opera, но в незапамятные времена те же симптомы подвигли на использование огнелиса.
UPD: туговато со счетом, сравнивать нужно не [-2] байт а [-4].
Итого:
iptables -N dns
iptables -A OUTPUT -p udp --dport 53 -j dns
iptables -A dns -m u32 --u32 "0 & 0x4 = 0x4 && 0 & 0xfffb @ 0 & 0xff0000 = 0x1c0000" -j DROP
iptables -A dns -m u32 --u32 "0 & 0x4 = 0x0 && 0 & 0xfff7 @ 4 & 0xff0000 = 0x1c0000" -j DROP