Вопрос про тройное рукопожатие TCP
вроде написал, использую SOCK_RAW, программирую на си,
В и тоге получается, заполняю все поля и отправляю, приходит SYN/ACK от червера, считываю с него seq_num и отправляю ACK, вроде все как надо, все идет по плану.. в итогде он мне присылает пакет о разрыве соединения RST
Вот лог программы tcpdump
16:17:58.560303 IP 10.1.1.73.pciarray > 10.1.1.74.http: S 1614872576:1614872576(0) win 5840
16:17:58.560708 IP 10.1.1.74.http > 10.1.1.73.pciarray: S 2600238020:2600238020(0) ack 1614872577 win 5840 <mss 1460>
16:17:58.565941 IP 10.1.1.73.pciarray > 10.1.1.74.http: . ack 351765564 win 5840
16:17:58.566238 IP 10.1.1.74.http > 10.1.1.73.pciarray: R 2952003584:2952003584(0) win 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 :60
ID :32691
Fragment offset :0x4000
MF :0
DF :1
TTL :64
Protocol :6
IP source :192.168.171.135
IP destination :192.168.171.136
==TCP_HEADER=================================
Port source :3284
Port destination :80
Sequence number :25982
Ack number :0
Data offset :10
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 :60
ID :0
Fragment offset :0x4000
MF :0
DF :1
TTL :64
Protocol :6
IP source :192.168.171.136
IP destination :192.168.171.135
==TCP_HEADER=================================
Port source :80
Port destination :3284
Sequence number :26492
Ack number :25982
Data offset :10
FIN:0,SYN:1,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :5792
Urgent pointer :0
####мы отправляем ack########################
==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 :52
ID :32692
Fragment offset :0x4000
MF :0
DF :1
TTL :64
Protocol :6
IP source :192.168.171.135
IP destination :192.168.171.136
==TCP_HEADER=================================
Port source :3284
Port destination :80
Sequence number :25982
Ack number :26492
Data offset :8
FIN:0,SYN:0,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :730
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 :256
Fragment offset :0
MF :0
DF :0
TTL :255
Protocol :6
IP source :192.168.171.135
IP destination :192.168.171.136
==TCP_HEADER=================================
Port source :1555
Port destination :80
Sequence number :3448
Ack number :3448
Data offset :5
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: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.171.136
IP destination :192.168.171.135
==TCP_HEADER=================================
Port source :80
Port destination :1555
Sequence number :29917
Ack number :3448
Data offset :6
FIN:0,SYN:1,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :5840
Urgent pointer :0
####мы отправляем ack########################
==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 :256
Fragment offset :0
MF :0
DF :0
TTL :255
Protocol :6
IP source :192.168.171.135
IP destination :192.168.171.136
==TCP_HEADER=================================
Port source :1555
Port destination :80
Sequence number :3448
Ack number :29917
Data offset :5
FIN:0,SYN:0,RST:0,PSH:0,ACK:1,URG:0,ECE:0,CWR:0
Window :65535
Urgent pointer :0
#############################################
разница в том, что мне он присылает рст пакет, а Опере нет ;)))) может кто знает, поможет?:confused:
Вот лог программы tcpdump
16:17:58.560303 IP 10.1.1.73.pciarray > 10.1.1.74.http: S 1614872576:1614872576(0) win 5840
16:17:58.560708 IP 10.1.1.74.http > 10.1.1.73.pciarray: S 2600238020:2600238020(0) ack 1614872577 win 5840 <mss 1460>
16:17:58.565941 IP 10.1.1.73.pciarray > 10.1.1.74.http: . ack [COLOR="Red"]351765564[/COLOR] win 5840
16:17:58.566238 IP 10.1.1.74.http > 10.1.1.73.pciarray: R 2952003584:2952003584(0) win 0
Вот так получается.. не пойму почему... вроде все правильно делаю.....
объясните, что за значение я выделил и как оно получилось?
вот как выглядят рукопожатия, если конектиться Мазилой)
16:49:21.388704 IP 192.168.1.3.http > 192.168.1.2.57425: S 2719307001:2719307001(0) ack 2424505744 win 5792 <mss 1460,sackOK,timestamp 2391133141 9084641,nop,wscale 7>
16:49:21.388726 IP 192.168.1.2.57425 > 192.168.1.3.http: . ack 1 win 92 <nop,nop,timestamp 9084641 2391133141>
вот так.. тут кажется это число 1)) странно.. что за число..
вот как выглядят рукопожатия, если конектиться Мазилой)
16:49:21.388704 IP 192.168.1.3.http > 192.168.1.2.57425: S 2719307001:2719307001(0) ack 2424505744 win 5792 <mss 1460,sackOK,timestamp 2391133141 9084641,nop,wscale 7>
16:49:21.388726 IP 192.168.1.2.57425 > 192.168.1.3.http: . ack 1 win 92 <nop,nop,timestamp 9084641 2391133141>
вот так.. тут кажется это число 1)) странно.. что за число..
запустите tcpdump с ключиком -S и посмотрите, чему будет равняться это число :) RFC 793 почитайте. и тогда поймете и почему 1, и почему у вас не работает ;) если не разберетесь - пишите
да не проблема
число, которое я выделил берется не от балды. ты должен считать номер последовательности сервера, который он тебе присылает и увеличить на 1
т. е. вместо 351765564, ты должен послать 2600238021
если у нас структуру TCP и IP заголовка я заполняю так:
ip_hdr->ihl = 5;
ip_hdr->version = 4;
ip_hdr->tos = 0;
ip_hdr->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
ip_hdr->id = htons(3291);
ip_hdr->frag_off = htons(0x4000);
ip_hdr->ttl = 64;
ip_hdr->protocol = IPPROTO_TCP;
ip_hdr->check = 0;
ip_hdr->check = in_cksum((unsigned short *)ip_hdr, sizeof(struct iphdr));
ip_hdr->saddr = srcaddr;
ip_hdr->daddr = dstaddr;
/* Заполняем TCP-заголовок */
tcp_hdr->source = htons(sport);
tcp_hdr->dest = htons(dport);
tcp_hdr->seq = htons(getpid());
tcp_hdr->ack_seq = htons(ack_num[0]);
tcp_hdr->res1 = 0;
tcp_hdr->doff = 5;
tcp_hdr->fin = 0;
tcp_hdr->syn = 0;
tcp_hdr->rst = 0;
tcp_hdr->psh = 0;
tcp_hdr->ack = 1;
tcp_hdr->urg = 0;
tcp_hdr->ece = 0;
tcp_hdr->cwr = 0;
tcp_hdr->window = htons(5840);
tcp_hdr->check = 0;
tcp_hdr->urg_ptr = 0;
где ack_num[0] это seq_num, который мы получили в нашем SYN/ACK пакете от сервера.
Получаем примерно по таким же структурам и смотрим, тот ли это SYN/ACK который нам нужен, откуда вот из этого берется этот номер... подскажите.. горит вообще...
first:last(nbytes), где first и last - номер последовательности первого и последнего байта пакета, nbytes - количество байтов данных, елси равен нулю, то first и last совпадают....
а в строчки, где выделенное число, оно означает следующий номер последовательности (ISN + 1), я что-то не могу уловить связь между первым и вторым.. вот не пойму почему у Оперы например аск получается с (ISN + 1) = 1 и как мне этого добиться, со своими TCP и IP заголовками.
Так как каждый байт, который участвует в обмене, пронумерован, номер подтверждения (acknowledgment number) это следующий номер последовательности, который ожидает получить отправитель подтверждения. Это номер последовательности плюс 1 последнего успешно принятого байта данных.
поле номер последовательности - это 32-битное поле в TCP заголовке. после полей порта источника и порта назначения.
соответственно - тебе надо считать номер последовательности, который прислал тебе сервер, номер подтверждения (в случае, если передано 0 байт, они будут совпадать), увеличить номер подтверждения на 1 и отослать с ack
поле номер последовательности - это 32-битное поле в TCP заголовке. после полей порта источника и порта назначения.
соответственно - тебе надо считать номер последовательности, который прислал тебе сервер, номер подтверждения (в случае, если передано 0 байт, они будут совпадать), увеличить номер подтверждения на 1 и отослать с ack
как проверить, что передано 0 байт?
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
Видно из этого, что когда я получаю seq я его не увеличиваю на 1, получается разность 0, так показывает tcpdump
Но вот если я делую вот так:
то получается вот такой результат tcpdump
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"... необычным... может знаешь?
вот так не присылается rst пакет, но и естаблиш в netstat'e не появляется..... че еще не учитываю не пойму.