Как учить протоколы без чтения RFC: как сэкономить время при разработке

Kate

Administrator
Команда форума
Если вы разрабатывает приложение, работающее по сети, или проводите отладку работы такого приложения, доскональное знание работы сетевых протоколов сильно облегчит вашу задачу. Первоисточником подобного знания являются RFC и, к счастью, они с давних времен находятся в открытом доступе. Более того, прочитать их можно даже консольных браузером links, так как кроме текста в них ничего не содержится.

Тем не менее, скорее всего большинство читателей Хабра никогда не читали полностью текст хотя бы одного RFC, даже RFC-2616. Помимо зубодробительного стиля бюрократических документов, помехой может служить языковой барьер. К тому же чаще всего нужно понять какой-то определенный аспект архитектуры протокола: длину и тип полей, код возврата, расположение внутри заголовка. Для этого вовсе не обязательно читать все от корки до корки.

Как раз для этого случая написан Protocol, довольно простое консольное приложение, написанное на Python. Оно имеет двоякое назначение.

  • Предоставить разработчикам и инженерам возможность легко и просто увидеть диаграмму заголовков самых распространенных сетевых протоколов прямиком из командной строки.
  • Предоставить исследователям и инженерам возможность быстро создавать ASCII диаграммы заголовков, для своих собственных пользовательских протоколов.

Установка и настройка​


Исходный код находится на GitHub, скачать можно стандартным способом.

git clone https://github.com/luismartingarcia/protocol.git


Настройка производится командой с правами пользователя root.

setup.py install

Так как программа на данный момент не имеет стандартного механизма установки дистрибутивов Linux, или Python, лучше запомнить куда копируются файлы.

running install

running build

running build_scripts

creating build

creating build/scripts-3.9

copying and adjusting protocol -> build/scripts-3.9

copying constants.py -> build/scripts-3.9

copying specs.py -> build/scripts-3.9

changing mode of build/scripts-3.9/protocol from 644 to 755

changing mode of build/scripts-3.9/constants.py from 644 to 755

changing mode of build/scripts-3.9/specs.py from 644 to 755

running install_scripts

copying build/scripts-3.9/protocol -> /usr/bin

copying build/scripts-3.9/constants.py -> /usr/bin

copying build/scripts-3.9/specs.py -> /usr/bin

changing mode of /usr/bin/protocol to 755

changing mode of /usr/bin/constants.py to 755

changing mode of /usr/bin/specs.py to 755

running install_egg_info

Writing /usr/lib/python3.9/site-packages/protocol-0.1-py3.9.egg-info

Запускаем protocol​


У программы имеются два основных режима работы:

  1. protocol <название существующего протокола>;
  2. protocol <спецификации собственного протокола>.

Доступны следующие стандартные протоколы

ethernet : Ethernet

8021q : IEEE 802.1q

dot1q : IEEE 802.1q

tcp : Transmission Control Protocol (TCP)

udp : User Datagram Protocol (TCP)

ip : Internet Protocol (IP), version 4.

ipv6 : Internet Protocol (IP), version 6.

icmp : Internet Control Message Protocol (ICMP)

icmp-destination: : ICMP Destination Unreachable

icmp-time : ICMP Time Exceeded

icmp-parameter : ICMP Parameter Problem

icmp-source : ICMP Source Quench

icmp-redirect : ICMP Redirect

icmp-echo : ICMP Echo Request/Reply

icmp-timestamp : ICMP Timestamp Request/Reply

icmp-information : ICMP Information Request/Reply

icmpv6 : ICMP for IPv6 (ICMPv6)

icmpv6-destination : ICMPv6 Destination Unreachable

icmpv6-big : ICMPv6 Packet Too Big

icmpv6-time : ICMPv6 Time Exceeded

icmpv6-parameter : ICMPv6 Parameter Problem

icmpv6-echo : ICMPv6 Echo Request/Reply

icmpv6-rsol : ICMPv6 Router Solicitation

icmpv6-radv : ICMPv6 Router Advertisement

icmpv6-nsol : ICMPv6 Neighbor Solicitation

icmpv6-nadv : ICMPv6 Neighbor Advertisement

icmpv6-redirect : ICMPv6 Redirect

Вот примеры использования утилиты.

|12:09:41|admin@redeye:[~]> protocol ip

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Version| IHL |Type of Service| Total Length |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Identification |Flags| Fragment Offset |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Time to Live | Protocol | Header Checksum |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Source Address |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Destination Address |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Options | Padding |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|12:09:45|admin@redeye:[~]> protocol ipv6

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Version| Traffic Class | Flow Label |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Payload Length | Next Header | Hop Limit |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| |

+ +

| |

+ Source Address +

| |

+ +

| |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| |

+ +

| |

+ Destination Address +

| |

+ +

| |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


В одной команде можно указать сразу несколько протоколов, разделив их пробелом.

|12:34:16|admin@redeye:[~]> protocol icmp-time icmp-timestamp

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Type | Code | Checksum |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Unused |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| |

+ Internet Header + 64 bits of Original Data Datagram +

| |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Type | Code | Checksum |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Identifier | Sequence Number |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Originate Timestamp |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Receive Timestamp |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Transmit Timestamp |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Protocol догадлив, не обязательно набирать название протокола полностью, если уж совсем лень можно например вместо dot1q набрать dot. Однако, как в случае с автодополнением, при неоднозначном выборе предлагается выбрать одну из альтернатив.

|12:43:25|admin@redeye:[~]> protocol icmpv6-r

Ambiguous protocol specifier 'icmpv6-r'. Did you mean any of these?

icmpv6-radv

icmpv6-redirect

icmpv6-rsol


Собственные разработки​


Наиболее важной чертой спецификации протокола являются списки полей. Можно указать их для собственного протокола следующим образом.

|12:55:16|mikayel@redeye:[~]> protocol «Source:16,Reserved:40,RTT:8»

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Source | |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+

| Reserved | RTT |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Дополнительные опции расширяют возможности форматирования ASCII диаграммы. Можно указать количество битов на линию, задать символы для разделителя и псевдографики. Предыдущая команда с опциями псевдодографики выдаст следующее.

|16:02:05|mikayel@redeye:[~]> protocol «Source:16,Reserved:40,RTT:8?\

numbers=y,startchar=*,endchar=*,evenchar=-,oddchar=-,sepchar=|»

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

*---------------------------------------------------------------*

| Source | |

*-------------------------------* *---------------*

| Reserved | RTT |

*---------------------------------------------------------------*


Protocol + tshark​


Более полную информацию по структуре сетевых протоколов можно получить, открыв в tshark сохраненный pcap/pcapng файл сетевого трафика. Если смотреть только в tshark можно за деревьями не заметить леса, а вместе с Protocol — то что надо.

|16:08:05|admin@redeye:[~]> sudo tshark -r /tmp/exmp.pcap -V

Transmission Control Protocol, Src Port: 48378, Dst Port: 443, Seq: 1, Ack: 1, Len: 0

Source Port: 48378

Destination Port: 443

[Stream index: 0]

[TCP Segment Len: 0]

Sequence Number: 1 (relative sequence number)

Sequence Number (raw): 1120003294

[Next Sequence Number: 1 (relative sequence number)]

Acknowledgment Number: 1 (relative ack number)

Acknowledgment number (raw): 4090007166

1000 .... = Header Length: 32 bytes (8)

Flags: 0x010 (ACK)

000. .... .... = Reserved: Not set

...0 .... .... = Nonce: Not set

.... 0... .... = Congestion Window Reduced (CWR): Not set

.... .0.. .... = ECN-Echo: Not set

.... ..0. .... = Urgent: Not set

.... ...1 .... = Acknowledgment: Set

.... .... 0... = Push: Not set

.... .... .0.. = Reset: Not set

.... .... ..0. = Syn: Not set

.... .... ...0 = Fin: Not set

[TCP Flags: ·······A····]

Window: 501

[Calculated window size: 501]

[Window size scaling factor: -1 (unknown)]

Checksum: 0xfbe8 [unverified]

[Checksum Status: Unverified]

Urgent Pointer: 0

Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps

TCP Option — No-Operation (NOP)

Kind: No-Operation (1)

TCP Option — No-Operation (NOP)

Kind: No-Operation (1)

TCP Option — Timestamps: TSval 2014817649, TSecr 2606727549

Kind: Time Stamp Option (8)

Length: 10

Timestamp value: 2014817649

Timestamp echo reply: 2606727549

|16:28:51|admin@redeye:[~]> protocol tcp

0 1 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Source Port | Destination Port |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Sequence Number |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Acknowledgment Number |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Offset| Res. | Flags | Window |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Checksum | Urgent Pointer |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Options | Padding |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Конечно такие программы, как Protocol, и tshark не могут и не должны заменить собой чтение первоисточников, т․ е․ RFC, однако они позволяют сильно сэкономить время программистов и системных администраторов.


Источник статьи: https://habr.com/ru/company/macloud/blog/560406/
 
Сверху