LINUX.ORG.RU

[TCP] Как работает этот протокол?


0

0

Я смотрел исходники ядра, но так и не понял, потому и задаю вопрос сюда

Интересует структура «struct tcp_sock» из linux/tcp.h , и даже точнее поле rcv_nxt

Как происходит заполнение данных этой структуры? Меня интересует следующее. Например создалось соединение с какой-то системой , структура struct tcp_sock заполнена различными значениями. Как мне внедриться в поток передаваемых данных?. Я создаю отдельный пакет, заполняю его аналогично пакету, который должен быть передан ( правильно заполнены все заголовки, и ACK и SYN в tcp , так чтоб другая сторона корректно приняла данный пакет ). Отправляю новый пакет в через dev->queue_xmit . Он корректно принимается на противоположной стороне, и другая сторона отвечает новым пакетом с новыми SYN и ACK . Пакет приходит от противоположной стороны, но не принимается «стеком TCP», Wireshark пишет, что «TCP ACK segment lost » другими словами syn и ack не те , что ожидает tcp поток....оно и понятно )... Надо при отправке моего пакета через dev->queue_xmit модифицировать структуру «struct tcp_sock» Так чтоб, tcp поток принял ответ на созданный мной пакет, как будто, он был частью потока. Собственно, как это сделать?? какие поля и как , нужно модифицировать в этой «struct tcp_sock»

Deleted

Не знаю, что нужно менять в структурах ядра, но Wireshark не читает эту структуру, а сам следит за номерами sequence numbers. То есть либо вы отправлете неправильный пакет, либо его не видит Wireshark. Относительно ACK и SYN я вобще не понял, SYN флаг принято устанавливать только в начале соединения. Прочитайте rfc 793.

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

Читал, потому и задал вопрос, так как полностью запутался.

Я отправляю правильный пакет, так как он корректно принимается второй стороной ( она принимает его, как часть потока данных ). И отвечает на этот пакет. Пакет приходит на сторону, где был внедрён пакет, и не принимается, так как seq и ack не совпадают с ожидаемыми. Как понимаю, чтоб принялся этот пакет, нужно подредактировать некие данные из «struct tcp_sock» но какие именно.. и как их правильно заполнить, я хз. Вот жду решения)

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

> Пакет приходит на сторону, где был внедрён пакет, и не принимается, так как seq и ack не совпадают с ожидаемыми. Как понимаю, чтоб принялся этот пакет, нужно подредактировать некие данные из «struct tcp_sock» но какие именно..

Так и подредактируй ожидаемые seq/ack на правильные, на такие, словно пакет был выслан (ну то есть не «словно», а он и был выслан - тобою).

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

>и не принимается, так как seq и ack не совпадают с ожидаемыми

ну и очень правильно, это защита, чтобы никто не мог вклиниться и подсовывать свои пакеты после установления соединения. надо случайное число угадывать.

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

Вот только, какие поля в этой структуре подредактировать?
Сейчас перед глазами книга linux сетевая архитектура, в ней написано переменная
snd_next - следующий номер последовательности для отправки
rcv_nxt - что мы хотим получить в следующий раз
snd_una - первый байт , для которого нужно подтверждение
snd_sml - последний байт послед. отправленного небольшого пакета
rtt_seq - номер последовательности для обновления rttvar
write_seq - tail(+1) данные в буфере отправки tcp
syn_seq - последний полученный SYN

Мне не понятно почти всё, например snd_next , номер последовательности, для следующей отправки... для какой следующей? текущей? которая будет прям сейчас происходить? или когда придёт ответ с другой стороны (на данный пакет) и с этим значением будут проверки?.... да и вообще номер последовательности это именно seq ?
rcv_nxt - что мы хотим получить в следующий раз?...действительно что ? )

вообще из вышеперечисленных полей, мне болееменее понятно только write_seq ...



При перехвате исходящего пакета в функции __ip_local_out
и выводе данных исходящего пакета с данными(в нём seq = 1 ack = 471 длина пакета 754 (это получено при просмотре wireshark))
получаю это

tp->rcv_nxt = 3625537301
tp->copied_seq = 3625537301
tp->rcv_wup = 3625537301
tp->snd_nxt = 3132908105
tp->snd_una = 3132908105
tp->snd_up = 3132908105
tp->write_seq = 3132908859
И так постоянно ) (числа меняются..но смысл остаётся, что rcv_nxt == copied_seq == rcv_wup)

При модификации этих данных (естественно не правильной модификации) данные перестают пересылаться


Почему я не могу посмотреть данные tp->rcv_nxt и тд?
что делать дальше?

(заранее sorry за плохо изложенные мысли. Не спал 20 часов...сидел с этой проблемой)

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

зачем угадывать, он слушает трафик и знает seq в обоих направлениях

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

это неправильный seq, это seq от начала соединения, для удобства чтения в wiresharke видимо, в реальности в пакете он другой, незнаю как в wiresharke реальный seq посомтреть, в tcpdumpe это флаг -S

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

Я не помню деталей протокола TCP, давно уже не имел с этим дел. Но думаю rcv_nxt - это ожидаемый SEQ от следующего пакета который придет.

Нужно читать rfc и смотреть код, как там эти поля заполняются. Там может быть очень много разных проверок на корректность полученного пакета.

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

Вроде, rcv_nxt инкрементируется, а copied_seq и rcv_wup устанавливаются при обработке пакета. rcv_nxt это seq для ожидаемого нами приходящего пакета. Дампните пакеты полностью и посмотрите их заголовки, там же прямо эти значения есть в полях seq и ack_seq.

Но относительно всей этой вашей затеи я не знаю. ИМХО, лучше пытаться именно отправлять данные через сокет, чем создавать пакет, так как если он не дойдёт, то ядро должно будет что-то отправить повторно. То есть если отправлять пакет, то вам нужно не просто править seq-номера, но и правильно заносить данные в очередь сокета.

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

Как мне нормально передать данные через сокет? нашёл функцию tcp_queue_skb кажется она ставит skb в очередь отправки. Но я не смог найти её адреса.

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

>Но я не смог найти её адреса.

А зачем вам адрес? Или вы хотите написать модуль, а ядро не патчить? А какую именно функцию нужно дёргать я сказать не могу, новые ядра я особо не изчал, а старые уже забыл. Сама задача не совсем понятна, вам действительно нужно отправлять ещё один пакет, а не модифицировать содержимое существующего пакета?

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