Раз у меня появился хоть и сырой, но более менее работающий виртуальный сетевой интерфейс, я продолжил реализовывать поставленную задачу.
Я начал передавать небольшие блоки данных и пытаться выводить их и при отправке и при приеме и в userspace и в kernelspace.
Для начала я определил что сам пакет лежит в
skb по указателю
skb->data, а не где то там в отдельной структуре
skb_shared_info.
Потом мне удалось получить длину пакета и всех заголовков, получить указатели на IP и TCP заголовки и в итоге вывести данные из пакета в чистом виде.
Ради эксперимента попробовал переворачивать данные внутри каждого пакета, проходящего через мой обработчик.
При этом установил условие, чтобы работать только с пакетами, содержащими TCP:
Запустил тест и заметил следующее поведение протокола TCP:
1. Отправляю текст длиной 1024 байт.
2. В модуле ядра на отправляющем хосте из skb печатается этот текст, затем происходит перестановка всех элементов с помощью такого действия:
Код: Выделить всё
unsigned char __user * buffer = kmalloc(data_len,1); //Выделение памяти под перевернутый пакет
//Изменение данных(переворот):
int k,m;
for (k = 0, m = (data_len) - 1; k < (data_len) && m >= 0; k++, m--)
{
buffer[k] = *(data_len+ m); //В этом цикле данные поэлементно копируются во временный буфер в обратном порядке
}
memcpy(data_pkt, buffer, data_len); //Возвращаю данные в перевернутом виде на то место, где они лежат в skb
kfree(buffer);
3. На принимающем хосте с помощью того же модуля ядра вывожу данные из получаемого пакета. Выводится перевернутый набор элементов.
4. И так как контрольная сумма полученного пакета не совпадает с той которая записана в заголовке TCP, то возвращается соответствующее оповещение.
5. Отправляющий хост начинает повторную пересылку и
внимание! в мой обработчик попадает пакет с перевернутыми ранее данными, переворачивается снова и отправляется.
6. На принимающем хосте в обработчик попадает пакет с нормальным текстом и в этот раз пакет принимается и в userspace появляется исходный текст.
Все сработало как надо!
Добавляю цикл с переворотом в модуль ядра на принимающей стороне и запускаю тест заново.
Результат ожидаемый:
1. Данные из пакета переворачиваются и пакет уходит к адресату
2. Хост получает пакет, переворачивает данные снова и текст появляется в userspace в неизменном виде!
Для меня это стало первым шагом. Мне удалось выполнить преобразование данных на уровне ядра на одной стороне, затем выполнить обратное преобразование на другой стороне и получить исходное сообщение.