Вопрос про "тройное рукопожатие" TCP.

t1h0n0ff

В общем проблема такая, решил реализовать на уровне SOCK_RAW тройное рукопожатие SYN, SYN/ACK, ACK.
Вроде написал, в итоге получается, что в ответ на мой последний ACK мне приходит пакет о разрыве соединения, то есть с флагом RST.
вот как работает моя програма, я отследил пакеты, которые приходя и уходят на сервер
==ETHERNET_HEADER============================
MAC destination :00:0c:29:23:69:71
MAC source :00:0c:29:0f:63:d0
Packet type ID field :0x800
==IP_HEADER==================================
IP version :4
IP header length :5
TOS :0
Total length :40
ID :3290
Fragment offset :0x4000
MF :0
DF :1
TTL :64
Protocol :6
IP source :192.168.234.128
IP destination :192.168.234.129
==TCP_HEADER=================================
Port source :1554
Port destination :80
Sequence number :100
Ack number :0
Data offset :5
FIN:0,SYN:1,RST:0,PSH:0,ACK:0,URG:0,ECE:0,CWR:0
Window :5840
Urgent pointer :0
#############################################
==ETHERNET_HEADER============================
MAC destination :00:0c:29:0f:63:d0
MAC source :00:0c:29:23:69:71
Packet type ID field :0x800
==IP_HEADER==================================
IP version :4
IP header length :5
TOS :0
Total length :44
ID :0
Fragment offset :0x4000
MF :0
DF :1
TTL :64
Protocol :6
IP source :192.168.234.129
IP destination :192.168.234.128
==TCP_HEADER=================================
Port source :80
Port destination :1554
Sequence number :35398
Ack number :100
Data offset :6
FIN:0,SYN:1,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :5840
Urgent pointer :0
#############################################
==ETHERNET_HEADER============================
MAC destination :00:0c:29:23:69:71
MAC source :00:0c:29:0f:63:d0
Packet type ID field :0x800
==IP_HEADER==================================
IP version :4
IP header length :5
TOS :0
Total length :40
ID :3291
Fragment offset :0
MF :0
DF :0
TTL :64
Protocol :6
IP source :192.168.234.128
IP destination :192.168.234.129
==TCP_HEADER=================================
Port source :1554
Port destination :80
Sequence number :100
Ack number :35398
Data offset :5
FIN:0,SYN:0,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :5840
Urgent pointer :0
################################

а вот как устраиват соединение к примеру оперы с этим же сервером(пробовал в основном на HTTP)
==ETHERNET_HEADER============================
MAC destination :00:50:56:c0:00:08
MAC source :00:0c:29:0f:63:d0
Packet type ID field :0x800
==IP_HEADER==================================
IP version :4
IP header length :5
TOS :0
Total length :48
ID :47188
Fragment offset :0x4000
MF :0
DF :1
TTL :128
Protocol :6
IP source :192.168.234.1
IP destination :192.168.234.129
==TCP_HEADER=================================
Port source :3626
Port destination :80
Sequence number :45732
Ack number :0
Data offset :7
FIN:0,SYN:1,RST:0,PSH:0,ACK:0,URG:0,ECE:0,CWR:0
Window :65535
Urgent pointer :0
#############################################
==ETHERNET_HEADER============================
MAC destination :00:0c:29:0f:63:d0
MAC source :00:50:56:c0:00:08
Packet type ID field :0x800
==IP_HEADER==================================
IP version :4
IP header length :5
TOS :0
Total length :48
ID :0
Fragment offset :0x4000
MF :0
DF :1
TTL :64
Protocol :6
IP source :192.168.234.129
IP destination :192.168.234.1
==TCP_HEADER=================================
Port source :80
Port destination :3626
Sequence number :51156
Ack number :45732
Data offset :7
FIN:0,SYN:1,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :5840
Urgent pointer :0
#############################################
==ETHERNET_HEADER============================
MAC destination :00:50:56:c0:00:08
MAC source :00:0c:29:0f:63:d0
Packet type ID field :0x800
==IP_HEADER==================================
IP version :4
IP header length :5
TOS :0
Total length :40
ID :47190
Fragment offset :0x4000
MF :0
DF :1
TTL :128
Protocol :6
IP source :192.168.234.1
IP destination :192.168.234.129
==TCP_HEADER=================================
Port source :3626
Port destination :80
Sequence number :45732
Ack number :51156
Data offset :5
FIN:0,SYN:0,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :65535
Urgent pointer :0
################################

Вроде как вы видите, все почти одинаково, но опера получается статус ESTABLISHED, а со своей программой SYN_RESV, что-то в этом духе.
Еще проверил утилитой tcpdum получилось вот так,
моя программа:
 12:15:31.504190 IP 192.168.234.128.1550 > 192.168.234.129.www: S 6553600:6553600(0) win 5840
12:15:31.739613 IP 192.168.234.129.www > 192.168.234.128.1550: S 534606125:534606125(0) ack 6553601 win 5840 <mss 1460>
12:15:31.761737 IP 192.168.234.128.1550 > 192.168.234.129.www: . ack 36563 win 5840
12:15:31.761819 IP 192.168.234.129.www > 192.168.234.128.1550: R 534642688:534642688(0) win 0

К примеру опера
12:16:12.184171 IP 192.168.234.1.3846 > 192.168.234.129.www: S 470605274:470605274(0) win 65535 <mss 1460,nop,nop,sackOK>
12:16:12.184198 IP 192.168.234.129.www > 192.168.234.1.3846: S 564727089:564727089(0) ack 470605275 win 5840 <mss 1460,nop,nop,sackOK>
12:16:12.184201 IP 192.168.234.1.3846 > 192.168.234.129.www: . ack 1 win 65535
12:16:12.184204 IP 192.168.234.1.3846 > 192.168.234.129.www: P 1:448(447) ack 1 win 65535
12:16:12.184207 IP 192.168.234.129.www > 192.168.234.1.3846: . ack 448 win 6432
12:16:12.187241 IP 192.168.234.129.www > 192.168.234.1.3846: P 1:194(193) ack 448 win 6432
12:16:12.325257 IP 192.168.234.1.3846 > 192.168.234.129.www: . ack 194 win 65342

Может кто знает, как быть, что нужно сделать, чтобы соединение прошло успешно?

slonishka

рискну предположить, что дело в 36563 тут:
. 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.

t1h0n0ff

НУ это понятно.. вот как это сделать в коде.....
я считываю 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

t1h0n0ff

Дошел вот до этого:
 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"... необычным... может знаешь?

smit1

16777216 == 0x1000000
я бы тупо подумал про порядок байт на хосте и в сети

t1h0n0ff

а подробнее можно?

Dasar

ботай функции htons, htonl и т.д.

Dasar

а подробнее можно?
в кратце, в сети принят определенный формат записи целых чисел.
в твоем компе - этот способ записи может быть другим
соответственно - после получения пакета, его надо преобразовать в компьютерный формат, а при отправке - обратно в сетевой
для этого есть функции htons, htonl и т.д.

t1h0n0ff

Спасибо, кажется заработало ;)
Оставить комментарий
Имя или ник:
Комментарий: