Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

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

42K
28 ноября 2008 года
mcsaimer
12 / / 28.11.2008
Пытаюсь сам написать тройное рукопожатие SYN, SYN/ACK, ACK
вроде написал, использую 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


Вот так получается.. не пойму почему... вроде все правильно делаю.....

вот пример как работает к примеру Опера
Код:
#клиент посылает пакет SYN  ##################
==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
#############################################


а вот как моя программа
Код:
#клиент посылает пакет SYN  ##################
==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:
14
28 ноября 2008 года
Phodopus
3.3K / / 19.06.2008
Я TCP не помню, но на вскидку Opera ID нумерует по порядку, а вы - нет
42K
28 ноября 2008 года
mcsaimer
12 / / 28.11.2008
Изменил... все равно не работает.
2
30 ноября 2008 года
squirL
5.6K / / 13.08.2003
Цитата: mcsaimer

Вот лог программы 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


Вот так получается.. не пойму почему... вроде все правильно делаю.....


объясните, что за значение я выделил и как оно получилось?

42K
30 ноября 2008 года
mcsaimer
12 / / 28.11.2008
Хм.. и правда, что это за число...

вот как выглядят рукопожатия, если конектиться Мазилой)

 
Код:
16:49:21.388216 IP 192.168.1.2.57425 > 192.168.1.3.http: S 2424505743:2424505743(0) win 5840 <mss 1460,sackOK,timestamp 9084641 0,nop,wscale 6>
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)) странно.. что за число..
2
30 ноября 2008 года
squirL
5.6K / / 13.08.2003
Цитата: mcsaimer
Хм.. и правда, что это за число...

вот как выглядят рукопожатия, если конектиться Мазилой)

 
Код:
16:49:21.388216 IP 192.168.1.2.57425 > 192.168.1.3.http: S 2424505743:2424505743(0) win 5840 <mss 1460,sackOK,timestamp 9084641 0,nop,wscale 6>
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, и почему у вас не работает ;) если не разберетесь - пишите

42K
30 ноября 2008 года
mcsaimer
12 / / 28.11.2008
В RFC 793 как-то очень мудренно написано... не мог бы ты на пальцах объяснить?
2
30 ноября 2008 года
squirL
5.6K / / 13.08.2003
Цитата: mcsaimer
В RFC 793 как-то очень мудренно написано... не мог бы ты на пальцах объяснить?


да не проблема

число, которое я выделил берется не от балды. ты должен считать номер последовательности сервера, который он тебе присылает и увеличить на 1
т. е. вместо 351765564, ты должен послать 2600238021

42K
30 ноября 2008 года
mcsaimer
12 / / 28.11.2008
А как это так прибавили 1, странноо... в какой заголовок это написать. Кстати, я сейчас сижу в RusNet в комнает #codenet может зайдешь?
42K
30 ноября 2008 года
mcsaimer
12 / / 28.11.2008
как передается это номер?

если у нас структуру TCP и IP заголовка я заполняю так:

Код:
/*  Заполняем 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 который нам нужен, откуда вот из этого берется этот номер... подскажите.. горит вообще...
42K
30 ноября 2008 года
mcsaimer
12 / / 28.11.2008
я глянул что означает вот эта пара
 
Код:
2600238020:2600238020(0)


first:last(nbytes), где first и last - номер последовательности первого и последнего байта пакета, nbytes - количество байтов данных, елси равен нулю, то first и last совпадают....

а в строчки, где выделенное число, оно означает следующий номер последовательности (ISN + 1), я что-то не могу уловить связь между первым и вторым.. вот не пойму почему у Оперы например аск получается с (ISN + 1) = 1 и как мне этого добиться, со своими TCP и IP заголовками.
2
01 декабря 2008 года
squirL
5.6K / / 13.08.2003
процитирую классика:
Цитата:
При установлении нового соединения, взводится флаг SYN. Поле номера последовательности (sequence number field) содержит исходный номер последовательности (ISN - initial sequence number), который выбирается хостом для данного соединения. Номер последовательности первого байта данных, который посылается этим хостом, будет равен ISN плюс один, потому что флаг SYN занимает собой номер последовательности. <......>
Так как каждый байт, который участвует в обмене, пронумерован, номер подтверждения (acknowledgment number) это следующий номер последовательности, который ожидает получить отправитель подтверждения. Это номер последовательности плюс 1 последнего успешно принятого байта данных.


поле номер последовательности - это 32-битное поле в TCP заголовке. после полей порта источника и порта назначения.

соответственно - тебе надо считать номер последовательности, который прислал тебе сервер, номер подтверждения (в случае, если передано 0 байт, они будут совпадать), увеличить номер подтверждения на 1 и отослать с ack

42K
01 декабря 2008 года
mcsaimer
12 / / 28.11.2008
Цитата: squirL
процитирую классика:

поле номер последовательности - это 32-битное поле в TCP заголовке. после полей порта источника и порта назначения.

соответственно - тебе надо считать номер последовательности, который прислал тебе сервер, номер подтверждения (в случае, если передано 0 байт, они будут совпадать), увеличить номер подтверждения на 1 и отослать с ack



как проверить, что передано 0 байт?

42K
01 декабря 2008 года
mcsaimer
12 / / 28.11.2008
Дошел вот до этого:

 
Код:
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"... необычным... может знаешь?
42K
01 декабря 2008 года
mcsaimer
12 / / 28.11.2008
проблема была в htons.... надо было вот так

 
Код:
tcp_hdr->ack = htonl(ntohl(ack)+1);


вот так не присылается rst пакет, но и естаблиш в netstat'e не появляется..... че еще не учитываю не пойму.
42K
01 декабря 2008 года
mcsaimer
12 / / 28.11.2008
Заработало ;)
2
01 декабря 2008 года
squirL
5.6K / / 13.08.2003
:) пока я с работы до дома добрался - уже и помощь не нужна :)
42K
04 декабря 2008 года
mcsaimer
12 / / 28.11.2008
Спасибо за помощь ;) очень помог )
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог