LINUX.ORG.RU

Изменение TCP пакетов прямо перед отправкой

 


0

4

Добрый день! Собираю образ для встраиваемой системы с помощью buildroot версия ядра 4.14.40. Нужно менять содержимое всех входящих/исходящих TCP пакетов проходящих через интерфейс следующим образом: На передающей стороне:

  1. непосредственно перед отправкой в сеть нужно добалять хвост (8 байт) который должен распологаться в конце пакета перед FCS
  2. Делать дубликат пакета (отправлять сразу же пакет повторно)

На приемной стороне непосредственно перед TCP логикой:

  1. убирать хвост перед FCS

Можно ли так модернизировать код ядра? И в каких файлах это делать?

Можно ли так модернизировать код ядра? И в каких файлах это делать?

Да, можно.

Но только не следует заниматься лоботомией исходников ядра, а вместо это сделать свой «гадкий» модуль.

15 лет назад это выглядело примерно так.

Deleted
()
Ответ на: комментарий от post-factum

Вообщем нужно решить следующую задачу. Есть приложение работающее через TCP (TCP сервер), есть Ethernet интерфейс (скажем eth1 с IP 192.168.1.3). Код сервера менять нельзя. Нужно каким-то образом сделать прослойку между этим интерфейсом и приложением, которая будет добавлять/убирать резервирование пакетов (протокол PRP), при этом особенность в том что интерфейс один, а не два, т. е. оба дубликата нужно слать/принимать через один интерфейс. Т. е. TCP сервер–>?резервирование+добавка хвоста?–>eth1–>сеть–>клиент клиент–>сеть–>eth1–>?убрать резервирование и хвост?->TCP сервер

Дело в том, что не могу придумать как сделать прослойку между TCP сервером и интерфейсом, так чтобы весь трафик проходил через нее и можно было перехватить «сырой трафик» и добалять/убирать хвосты. Пробовал через tap интерфейс, но не очень получилось.

Andy041292
() автор топика

На правах идеи, если кидаешь второй пакет, то почему бы не кидать его с нужной инфой, соответствующей первому пакету.

Но вообще, хочется знать «зачем», может подскажут более интересное решение.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от Andy041292

Дело в том, что не могу придумать как сделать прослойку между TCP сервером и интерфейсом, так чтобы весь трафик проходил через нее и можно было перехватить «сырой трафик» и добалять/убирать хвосты. Пробовал через tap интерфейс, но не очень получилось

Написать свой сервер, на приемной стороне и он будет обрубать доп инфу, и уже ее досылать на локальный localhost сервер, где нельзя менять код. Номера портов у кого то придется сменить. Предлагаю ретранслятор.

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

Наверное только такое решение возможно. Вместе с портом наверное придется менять контрольную сумму IP пакета. Есть ли готовые функции для этого?

Andy041292
() автор топика
Ответ на: комментарий от Andy041292

Контрольная сумма IP пакета считается легко. Для какого языка надо?

Но если такой прокси добавить и на передающей стороне, то ничего не надо считать, просто там будет добавлять и отправлять как ни в чем не бывало, а на приемной тоже такой прокси. В итоге модифицировать пакеты не нужно будет.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

А смогу ли я в этом случае изменять те части пакета, которые не относятся к TCP/IP. Т. е. как я понимаю у прокси сервера все сокеты будут TCP/IP, а мне надо на layer 2 менять пакет, т. е. чтобы мои добавления не влияли на IP/TCP заголовок. Или я что-то не понимаю?

Andy041292
() автор топика

В ядро лезть необязательно, можно наваять свою библиотеку с интерфейсом berkley sockets и запускать тот неизменяемый сервер со своей библиотекой, подсунутой через LD_PRELOAD.

mv ★★★★★
()

Дописать и убрать байты из фрейма можно с помощью NFQUEUE. Возможно, чтобы воткнуться на L2, нужно будет выкинуть iptables и заюзать nftables, но iptables и так давно сгнил. Насчёт отправки второго пакета не уверен, надо гуглить.

Laz ★★★★★
()
Ответ на: комментарий от Laz

Не рассматривал вариант с использованием ip-заголовка? Стандартный заголовок 20 байт или 5 слов, а может быть и 31 слово. Там есть где хранить 8 байт.

Раньше для iptables был таргет TEE, он умел дублировать пакеты. Подправить его значительно проще, чем делать с нуля.

NFQUEUE будет полезен на приеме.

vel ★★★★★
()
Ответ на: комментарий от anonymous

Это XDP. Увеличить размер пакета в XDP нельзя.

xpahos ★★★★★
()
Ответ на: комментарий от xpahos

Клиент должен отбрасывать. Ну я так понимаю что, TCP и UDP стеки и так умеют это делать (отбрасывать одинаковые пакеты)

Andy041292
() автор топика
Ответ на: комментарий от Andy041292

Клиент должен отбрасывать. Ну я так понимаю что, TCP и UDP стеки и так умеют это делать (отбрасывать одинаковые пакеты)

А зачем тогда два слать, если есть SACK?

xpahos ★★★★★
()
Ответ на: комментарий от Andy041292

непосредственно перед отправкой в сеть нужно добалять хвост (8 байт)

протокол PRP

PRP trailer занимает не 6 байт?

Пробовал через tap интерфейс, но не очень получилось.

Где именно пошло не так?

gag ★★★★★
()
Ответ на: комментарий от gag

Да, вы правы PRP trailer занимает 6 байт. +2 байта для микросхемы-коммутатора для правильной коммутации (для этой микросхемы нужен свой trailer. А что касается tap-интерфейса, то привязывать сервер к виртуальному интерфейсу удается только через IP (чтобы сервер работал только через виртуальный интерфейс), и проблема потом перекидывать пакеты с виртуального интерфейса на реальный, с другим IP, т. е. менять IP, контрольную сумму и т. д., что не очень удобно… Вообще нравиться идея mv с написанием своей библиотеки сокетов и заменой их с помощью LD_PRELOAD. Вопрос только где взять исходный код berkley sockets чтобы не писать с нуля.

Andy041292
() автор топика
Ответ на: комментарий от mv

Неплохая идея, а где бы взять исходный код berkley sockets, которые используются в моей версии ядра (4.14.40), чтобы не пришлось писать с нуля функции, а просто модернизировать уже готовый код…

Andy041292
() автор топика
Ответ на: комментарий от Andy041292

Так ты дальше ядру передавай, как сделаешь, что надо. А какие сисколлы не трогаешь, так те и не переопределяй.

mv ★★★★★
()
Ответ на: комментарий от Andy041292

т. е. менять IP, контрольную сумму и т. д., что не очень удобно…

Да, разумеется, если нужно заменить содержимое, то кое-что надо будет заменить дополнительно.

Вообще нравиться идея mv с написанием своей библиотеки сокетов и заменой их с помощью LD_PRELOAD. Вопрос только где взять исходный код berkley sockets чтобы не писать с нуля. Но менять код библиотеки мне кажется ещё менее удобным.

На самом деле mv имел ввиду не замену кода, а создание обёртки. Переопределяешь send(), в ней создаёшь новый пакет, копируя всё что тебе нужно из старого и добавляя новое, потом просто вызываешь настоящий send() и всё.

gag ★★★★★
()
Последнее исправление: gag (всего исправлений: 1)

На правах вброса: свитч с мирроринг портом ничем не поможет?

Можно дублировать весь трафик на другое устройство и анализировать/менять его там не трогая трафик до основного сервера.

skyman ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.