Вопрос про "тройное рукопожатие" TCP.
. ack 36563 win 5840
в мане есть пример, в котором обращают внимание на то,
что там должен быть маленький инт.
...
csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024>
rtsg.1023 > csam.login: . ack 1 win 4096
rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096
csam.login > rtsg.1023: . ack 2 win 4096
rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
...
Csam replies with a similar packet except it includes a piggy-backed ack for rtsg’s SYN. Rtsg then acks csam’s SYN.
The ‘.’ means no flags were set. The packet contained no data so there is no data sequence number. Note that the ack
sequence number is a small integer (1). The first time tcpdump sees a tcp ‘conversation’, it prints the sequence number
from the packet. On subsequent packets of the conversation, the difference between the current packet’s sequence
number and this initial sequence number is printed. This means that sequence numbers after the first can be interpreted as
relative byte positions in the conversation’s data stream (with the first data byte each direction being ‘1’). ‘-S’ will override
this feature, causing the original sequence numbers to be output.
я считываю seq_num с пакета, который пришел...
ip = (struct iphdr *data + sizeof(struct ethhdr;
arp = (struct arphdr *data + sizeof(struct ethhdr;
tcp = (struct tcphdr *data + sizeof(struct ethhdr) + sizeof(struct iphdr;
ack = tcp->seq;
а вот так определена структура tcphdr
struct tcphdr {
unsigned short source;
unsigned short dest;
unsigned long seq;
unsigned long ack_seq;
unsigned short doff:4;
unsigned char flags;
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
};
и когда отправляю присваиваю
tcp->ack = ack
16:21:38.054883 IP 192.168.234.128.1572 > 192.168.234.129.www: S 655360:655360(0) win 5840
16:21:38.054952 IP 192.168.234.129.www > 192.168.234.128.1572: S 3230511284:3230511284(0) ack 655361 win 5840 <mss 1460>
16:21:38.104384 IP 192.168.234.128.1572 > 192.168.234.129.www: . ack 0 win 5840
16:21:38.104424 IP 192.168.234.129.www > 192.168.234.128.1572: R 3230511284:3230511284(0) win 0
tcp_hdr->ack_seq = ack; // ack - мы получили от сервера в виде seq_num
Видно из этого, что когда я получаю seq я его не увеличиваю на 1, получается разность 0, так показывает tcpdump
Но вот если я делую вот так:
tcp_hdr->ack_seq = ack+1; // ack - мы получили от сервера в виде seq_num
то получается вот такой результат tcpdump
16:23:01.767069 IP 192.168.234.128.1574 > 192.168.234.129.www: S 655360:655360(0) win 5840
16:23:01.767087 IP 192.168.234.129.www > 192.168.234.128.1574: S 3322993742:3322993742(0) ack 655361 win 5840 <mss 1460>
16:23:04.818329 IP 192.168.234.128.1574 > 192.168.234.129.www: . ack 16777216 win 5840
16:23:04.818352 IP 192.168.234.129.www > 192.168.234.128.1574: R 3323002880:3323002880(0) win 0
эта "+1" прибавляет почему-то 16777216.... почему, я думай надо каким-то методом другим делать "+1"... необычным... может знаешь?
я бы тупо подумал про порядок байт на хосте и в сети
а подробнее можно?
ботай функции htons, htonl и т.д.
а подробнее можно?в кратце, в сети принят определенный формат записи целых чисел.
в твоем компе - этот способ записи может быть другим
соответственно - после получения пакета, его надо преобразовать в компьютерный формат, а при отправке - обратно в сетевой
для этого есть функции htons, htonl и т.д.
Спасибо, кажется заработало
Оставить комментарий
t1h0n0ff
В общем проблема такая, решил реализовать на уровне SOCK_RAW тройное рукопожатие SYN, SYN/ACK, ACK.Вроде написал, в итоге получается, что в ответ на мой последний ACK мне приходит пакет о разрыве соединения, то есть с флагом RST.
вот как работает моя програма, я отследил пакеты, которые приходя и уходят на сервер
а вот как устраиват соединение к примеру оперы с этим же сервером(пробовал в основном на HTTP)
Вроде как вы видите, все почти одинаково, но опера получается статус ESTABLISHED, а со своей программой SYN_RESV, что-то в этом духе.
Еще проверил утилитой tcpdum получилось вот так,
моя программа:
К примеру опера
Может кто знает, как быть, что нужно сделать, чтобы соединение прошло успешно?