Давайте рассмотрим ситуацию, как показано на рисунке ниже. У нас есть сеть из 3-х хостов, два их которых находятся в одном сегменте сети, а третий хост в другом. Оба сегмента сети соединяет маршрутизатор.
Если хост 1 c IP адресом 10.0.0.1 захочет отправить пакет хосту 2 с IP адресом 10.0.0.2, то:
-
хост 1 проверит, есть ли хост 2 в ARP-кэше
-
если нет, то отправит в сеть ARP-запрос
-
подождет ARP-ответ от хоста 2
-
отправит желаемый пакет хосту 2
Это мы уже знаем. А еще мы говорили, что сетевой уровень и IP протокол в частности должен уметь доставлять пакеты от одного хоста к другому даже если хост назначения находится в другой сети. Если хост 1 захочет отправить пакет хосту 3 с IP адресом 172.16.0.3, что он должен сделать?
Глядя на схему не сложно догадаться, что хост 1 должен отправить пакет на маршрутизатор А, а тот в свою очередь отправит пакет на хост 3. Но хост 1 не видит этой схемы, у него нет информации о топологии сети и настройках всех хостов. Как он должен догадаться, что в этом случае он должен отправлять пакет на маршрутизатор А?
Для решения этой проблемы давайте заведем на хостах еще одну таблицу и назовем ее “Таблица маршрутизации”. Эта таблица будет состоять из 2-х полей:
-
IP адрес назначения
-
IP адрес маршрутизатора
Если IP адрес назначения находится в нашем сегменте сети, то в качестве IP адреса маршрутизатора будем выступать мы сами. А если IP адрес назначения будет находиться в другой сети, то IP адрес маршрутизатора будет IP адрес маршрутизатор.
Обновим нашу схему, как показано на рисунке ниже. Добавим 2 IP адреса для маршрутизатора А. Один для связи с одним сегментом сети, второй для связи со вторым сегментом сети. Т.е. IP 10.0.0.100 для связи с хостом 1 и хостом 2, а 172.16.0.100 для связи с хостом 3.
Тогда таблица маршрутизации для хоста 1 будет выглядеть как на таблице.
IP адрес назначения |
IP адрес маршрутизатора |
10.0.0.2 |
10.0.0.1 |
172.16.0.3 |
10.0.0.100 |
10.0.0.100 |
10.0.0.1 |
Каждый раз, когда хост 1 будет отправлять пакет, он будет заглядывать в таблицу вмаршрутизации.
Если хост 1 захочет отправить пакет хосту 2 (чей IP 10.0.0.2), то:
-
хост 1 ищет в таблице маршрутизации IP адрес 10.0.0.2. Этому адресу соответствует IP адрес маршрутизатора 10.0.0.1
-
та как IP адрес маршрутизатора совпадает с IP адресом самого хоста, значит он сам знает как доставить пакет по адресу 10.0.0.2 и передает этот пакет на канальный уровень
-
а дальше мы уже знаем: смотрим ARP-кэш, ARP-запрос, ARP-ответ и отправка пакета.
А если хост 1 хочет отправить пакет хосту 3 с IP адресом 172.16.0.3, то:
-
хост 1 ищет в таблице маршрутизации IP адрес 172.16.0.3. Этому адресу соответствует IP адрес маршрутизатора 10.0.0.100
-
IP адрес маршрутизатора не совпадает с IP адресом хоста, значит, нужно отправить пакет маршрутизатору с IP адреса 10.0.0.100 и пусть он дальше доставляет пакет
-
передаем пакет на канальный уровень с указанием, что MAC адрес назначения будет MAC адрес хоста с IP адресом 10.0.0.100 (это маршрутзатор). Очень важный момент, хоть IP адрес назначения в данном случае 172.16.0.3, но на канальном уровне мы доставляем пакет на маршрутизатор, как показано на рисунке ниже.
-
и теперь начинается знакомый нам процесс, хост 1 смотрит в ARP-кэш в поисках MAC адреса для IP 10.0.0.100 (router_A).
-
если его там нет, то отправляет ARP-запрос, после получения ARP-ответа отправляет пакет в сеть
-
маршрутизатор А получив пакет смотрит уже в свою таблицу маршрутизации и так же как и хост 1 пытается понять куда дальше отправлять пакет.
Таким образом, используя таблицу маршрутизации хост может понять, как отправлять пакет - самому или на маршрутизатор.
Важно запомнить, что таблица маршрутизации находится на каждом хосте, который подключен к сети Интернет. А не только на маршрутизаторе. Без таблицы маршрутизации хост не поймет, когда он может сам доставить пакет, а когда нужно передать его на маршрутизатор.
Давайте добавим в наш пример еще несколько хостов, как на рисунке ниже.
Получается, что для такой сети таблица маршрутизации на хосте 1 должна стать как в таблице ниже
IP адрес назначения |
IP адрес маршрутизатора |
10.0.0.2 |
10.0.0.1 |
10.0.0.5 |
10.0.0.1 |
10.0.0.100 |
10.0.0.1 |
172.16.0.3 |
10.0.0.100 |
172.16.0.4 |
10.0.0.100 |
Т.е. мы добавили в сеть два хоста и теперь хост 1 должен о них как-то узнать и добавить их в свою таблицу маршрутизации. А если мы добавим еще 100 хостов, что тогда? Владельцы всех хостов должны как-то обмениваться информацией о том, кто и куда подключен и своим IP адресом?!
Описанный выше способ доставки пакетов из одной сети в другую хоть и рабочий, но не эффективный. Большую сеть так не построить. Для решения этой проблемы предлагается ввести понятие IP сеть. IP сеть - это множество IP адресов. Очень важно обратить внимание, что множество IP адресов, а не хостов.
Исторически, весь диапазон IP адресов (т.е все 4 байта) разбили на 5 классов сетей (A, B, C, D, E). Это означало, что одна часть IP адреса теперь указывает на класс сети, а остальная часть идентифицирует хост.
Сети класса А лежат в диапазоне от 0.0.0.0 до 127.255.255.255. Для идентификатора сети используется 1 байт, а остальные 3 байта для идентификации хоста.
В одной сети класса А может находиться до 16 777 215 (256 * 256 * 256) хостов. Правда, таких сетей не много, всего 128. Вот пример некоторых сетей класса А:
-
8.0.0.0 - 8.255.255.255
-
10.0.0.0 - 10.255.255.255
-
104.0.0.0 - 104.255.255.255
Сети класса B лежат в диапазоне от 128.0.0.0 до 191.255.255.255. Для идентификатора сети используется первые два байта, а остальные 2 байта для идентификации хоста.
В одной сети класса B может находиться до 65 535 (256 * 256) хостов. Вот пример некоторых сетей класса B:
-
169.254.0.0 - 169.254.255.255
-
172.16.0.0 - 172.16.255.255
-
190.56.0.0 - 190.56.255.255
Сети класса C лежат в диапазоне от 192.0.0.0 до 223.255.255.255. Для идентификатора сети используется первые 3 байта, а оставшийся бай для идентификации хоста.
В одной сети класса C может находиться всего 255 хостов. Вот пример некоторых сетей класса С:
-
192.168.1.0 - 192.168.1.255
-
204.16.6.0 - 204.16.6.255
-
220.215.65.0 - 220.215.65.255
Сеть класса D от 224.0.0.0 до 239.255.255.255. Класс D - это одна сеть и ее адреса используется для групповых адресов. Часто, IP адреса из этого класса назначают себе принтеры, сканеры, маршрутизаторы и другие устройства работающие по сети. Дальше по курсу мы подробно об этом поговорим. А пока просто запомним, что это групповые адреса.
Сеть класса E от 240.0.0.0 до 255.255.255.255. Класс E - зарезервирована "для использования в будущем" (https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.txt). Ее можно было бы начать использовать, но многие реализации TCP/IP не умеют или не хотят работать с IP из этого блока. Переписать все реализации TCP/IP в мире - это слишком большая проблема, а в свете активно внедряемого IPv6, задача становится еще менее реалистичной. Поэтому, эта сеть не используется и вряд ли когда-либо будет использоваться в глобальной сети в будущем.
Благодаря классовой адресации любой хост теперь мог четко ответить на вопрос, IP адрес, на который я хочу отправить пакет находится в моей сети или нет?
Вернемся к нашей сети (для удобства я ее повторил).
Используя классовую адресацию наша таблица маршрутизации на хосте 1 будет выглядеть как в таблице ниже.
IP адрес назначения |
IP адрес маршрутизатора |
10.0.0.0 |
10.0.0.1 |
172.16.0.0 |
10.0.0.100 |
Если адрес назначения находится в сети 10.0.0.0 (напомню, это класс A и адреса в этой сети лежат в диапазоне от 10.0.0.0 до 10.255.255.255), то адрес маршрутизатора 10.0.0.1, т.е. мы сами будем доставлять пакет на этот хост.
А если адрес назначения находится в сети 172.16.0.0 (это класс B и адреса для этой сети лежат в диапазоне от 172.16.0.0 до 172.16.255.255), то адрес маршрутизатора 10.0.0.100.
Таким образом, даже если завтра мы добавим 1000 новых хостов в обе сети, то для хоста 1 ничего менять не придется. Он так же успешно сможет доставлять пакеты как внутри своей IP сети, так и для сети 172.16.0.0. И никаких новых записей в таблицу маршрутизации вводить не придется.
Проблема классовой адресации заключалась в ее негибкости. Если вам нужна сеть из 4000 IP адресов, что делать? Получать 16 сетей класса C или брать одну класса B? А если вам нужна сеть из 40 000 IP адресов? Хорошо, для 40 000 адресов возьмем одну сеть класса B. Как известно, сеть класса B содержит 65535 адресов, а нам нужно только 40 000. куда девать остальные 25 535, а это более 50% от того, что мы будем использовать?
Итог - классовая маршрутизация классная, решает возникшие проблемы, но не эффективная.
Зачем, что в профессиональном общении довольно часто можно услышать использование терминов из классовой адресации, что-то типа “Возьми себе сеть класса C и играйся там”. Теперь понятно, что под этим понимается.
Бесклассовая адресация (англ. Classless Inter-Domain Routing, англ. CIDR) - метод IP-адресации, позволяющий гибко управлять пространством IP-адресов. Бесклассовая адресация предлагает вместо жестко закрепленных правил адресации сети использовать маску подсети. Цель маски подсети сказать, какие биты в IP адресе указывают на идентификатор сети, а какие биты указывают на идентификатор хоста.
Для примера давайте рассмотрим уже знакомую нам IP сеть класса B 172.16.0.0. В этой сети первые 2 байта IP адреса указывают на идентификатор сети, а следующие два байта указывают на идентификатор хоста.
А теперь давайте запишем точно такую же сеть в бесклассовой адресации. Помимо IP адреса нам понадобится еще маска подсети (маска, маска сети, маска подсети - это все одно и тоже). Адрес сети будет прежний, 172.16.0.0, а маска подсети будет 255.255.0.0.
Там, где бит у маски подсети установлен в 1, означает, что соответствующий бит в IP адресе указывает на идентификатор сети. А там, где бит у маски подсети установлен в 0, означает, что соответствующий бит в IP адресе указывает на идентификатор хоста. Так как в нашей сети первые два байта (16 бит) указывают на идентификатор сети, то и первые 16 бит маски подсети должны быть установлены в 1. В десятичной записи 8 бит установленных в 1 дают число 255. Поэтому первые два байта нашей маски 255.255.
С идентификатором хоста делаем так же. В нашей сети для идентификации хоста выделены вторые 2 байта. Значит это место в маске мы заполняем 0.
Таким образом, сеть класса B 172.16.0.0 можно записать в бесклассовой адресации как 172.16.0.0/255.255.0.0. Обычно маска подсети записывается через слеш (/) после IP адреса сети.
Как это работает?! Чтобы определить, попадает ли IP адрес в сеть 172.16.0.0 c маской 255.255.0.0 мы делаем следующее: 1. Берем IP адрес, например, 172.16.0.3 2. Делаем операцию “побитовое И” с маской подсети 3. Полученный результат сравниваем с адресом сети 4. Если результат равен адресу сети, значит IP адрес принадлежит этой сети 5. Если нет, то и нет.
В нашем случае, IP адрес 172.16.0.3 принадлежит сети 172.16.0.0/255.255.0.0, так как после применения маски подсети мы получили адрес сети 172.16.0.0.
Если мы возьмем IP адрес 172.16.126.254 и тоже применим к нему маску 255.255.0.0, то в результат получим 172.16.0.0. Что будет указывать на то, что и этот IP адрес принадлежит сети 172.16.0.0.
По сути, там где у маски подсети стоит бит в 1 означает, что соответствующий бит в IP адресе останется таким, каким и был. А там, где у маски подсети стоит бит 0 означает, что соответствующий бит в IP адресе обнулится. Был он 1 или 0, неважно, он станет 0.
А теперь давайте возьмем IP адрес 172.13.0.3 и применим маску 255.255.0.0. В итоге получится 172.13.0.0, что не равно 172.16.0.0. Значит, IP адрес 172.13.0.3 не принадлежит сети 172.16.0.0.
Таким образом, с помощью маски можно задавать IP сеть. Единственное ограничение, что количество хостов в сети должно быть кратно степени 2: 2, 4, 8, 16 и так далее. Но на практике этого вполне достаточно.
Обычно, маску подсети записывают через слеш от адреса сети. Например, 10.0.0.0/255.0.0.0 или 172.16.0.0/255.255.0.0.
Когда только предложили использовать маску подсети для обозначения IP сети, то она могла быть любой. Даже вот такой 255.255.0.255. Особенность такой маски в том, что она позволяет задать множество IP адресов с так называемыми дырками. Для примера, возьмем вот такую сеть 192.168.0.2/255.255.0.255. В эту сеть будут входить следующие IP адреса:
-
192.168.0.2
-
192.168.1.2
-
192.168.2.2
-
192.168.3.2
-
…
-
192.168.255.2
Хоть в теории это очень гибко, на практике сетевые администраторы использовали только маски, которые давали бы непрерывный диапазон. Например:
-
192.168.2.0/255.255.255.0
-
169.254.143.128/255.255.255.128.
Поэтому, со временем ввели правило, которое гласило, что маска подсети не может содержать подпоследовательность в битах 01. Т.е. уже не получится сделать маску 255.255.0.255, так как после 0 последовали бы 1, а так делать нельзя.
А раз нельзя делать подпоследовательность 01, значит мы можем просто сказать количество единичных бит в маске и она будет однозначно понята всеми. Друигми словами, маску 255.255.255.0 теперь можно записать как 24, а маску 255.0.0.0 как 8. И получается, что сеть 192.168.1.0/255.255.255.0 теперь можно записать как 192.168.1.0/24, а сеть 172.16.0.0/255.255.0.0 как 172.16.0.0/16.
Теперь становится понятно, что означает /24 на примерах. На рисунке 60 хост 1 имеет IP 10.0.0.1 и маску 24 означает, что хост 1 имеет IP 10.0.0.1, который принадлежит IP сети 10.0.0.0/24 (а это 10.0.0.0 - 10.0.0.255)
В каждой IP сети есть два особых адреса, это самый первый и самый последний. Например, возьмем IP сеть 192.168.1.0/24.
-
Самый первый адрес в этой сети это 192.168.1.0, его называют адресом сети. Это тот самый адрес, который будет получаться, если взять любой адрес из этой сети и наложить на него маску (выполнить побитовое И). Например, возьмем 192.168.1.25/24, как показано на рисунке, в результате мы получим 192.168.1.0
-
Самый последний адрес в этой сети это 192.168.1.255, он является широковещательным адресом для этой сети. Это означает, что все хосты в этой IP сети будут принимать и обрабатывать пакет, если такой IP адрес будет указан в качестве назначения. Другими словами, если хост хочет отправить пакет всем хостам в своей IP сети, он может отправить его на широковещательный адрес. Кстати говоря, самый последний адрес в сети это такой адрес, в котором биты отведенные под идентификацию хоста установлены в 1.
Устанавливать себе в качестве IP адреса широковещательный адрес сети не стоит. Может быть ОС и позволит вам это сделать, но тогда ваш хост не сможет ни с кем обмениваться данными. Протоколы реализуются таким образом, чтобы не генерировать ответы, если адрес отправителя широковещательный. Например, если вы отправите ARP или другой IP пакет в сеть, где IP адрес отправителя будет широковещательным, вам никто не ответит. Это такая защита от наводнения сети пакетами (flooding).
Давайте на минуту представим, если бы так происходило. Тогда, отправив на любой хост IP пакет с широковещательным IP адресом отправителя, этот хост должен будет ему ответить. Отвечать он будет на широковещательный адрес, т.е. на сетевом уровне будет стоять широковещательный адрес и на канальном уровне будет стоять широковещательный адрес (FF:FF:FF:FF:FF:FF). Такой пакет будет доставлен всем хостам в данной сети. Хотя очевидно, что никакого смысла в этом не будет.
А вот устанавливать себе адрес сети (первый адрес) можно. Хотя в сложившейся сетевой практике так не поступают.
Для примера сделаем сеть из 3-х хостов и возьмем IP сеть 192.168.1.0/24 как показано на рисунке:
-
Хосту 1 назначим первый IP адрес, т.е. адрес сети, 192.168.1.0/24
-
Хосту 2 назначим обычный IP адрес, пусть это будет 192.168.1.50/24
-
А хосту 3 назначим широковещательный IP адрес для этой сети, т.е. 192.168.1.255/24
А теперь на хосте 1 выполним поочередно две команды:
-
Команду ping на широковещательный адрес - ping -c 1 -b 192.168.1.255. Команда ping отправляет специальный ICMP-запрос, получив который, хост должен отправить ICMP-ответ. Мы добавим в команду ping опцию -c 1 (отправить только 1 пакет) и -b (разрешить отправку на широковещательный адрес).
-
Команду ping на IP адрес 192.168.1.50, т.е. на хост 2.
Первым делом мы видим ICMP-запрос на широковещательный адрес. Оба хоста (2 и 3) получают этот пакет. На широковещательный запрос ICMP-ответ не отправляется. Однако, мы видим, что хост 3 пытается отправить ICMP-ответ, так как он интерпретирует этот адрес не как широковещательный, а как свой. Это проявляется в отправке ARP-запросов. На эти ARP-запросы никто не отвечает. Это связано с тем, что IP адрес отправителя широковещательный. Как мы говорили, на такие пакеты хосты не отвечают.
После этого мы видим, как хост 1 отправляет ARP-запрос, а после получения ARP-ответа от хоста 2, обменивается с ним ICMP-запросом и ICMP-ответом.
Итого, как я и сказал. Первый адрес сети является нормальным адресом и может быть использован в сети. Хотя, сложившаяся сетевая практика такова, что этот адрес стараются не использовать, для удобства администрирования. А вот последний адрес сети является широковещательным и его не нужно использовать в качестве адреса хоста.
Маска делит IP адрес на две части, одна часть - идентификатор сети, вторая часть - идентификатор хоста. Например, 192.168.1.0/24:
-
первые три байта: 192.168.1 - идентификатор сети
-
последний байт - идентификатор хоста
А если мы запишем 192.168.1.25/32 - получается, что все 4 байта это адрес сети? Маска /32 означает конкретный IP адрес.
Еще есть интересная маска /31. Встречается она довольно редко. Маска /31 говорит, что для адресации хоста мы выделяем только последний бит. Для примера рассмотрим сеть 172.16.12.0/31, как на рисунке.
Получается, что в этой сети всего два IP адреса:
-
172.16.12.0
-
172.16.12.1
Первый желательно не использовать, а второй широковещательный. Даже если мы будем использовать первый адрес (адрес сети), то второй все равно широковещательный. Получается IP сеть из 1 рабочего хоста. На первый взгляд, смысла в этом никакого. И в обычных сетях такую маску не встретить.
Однако, некоторое современное сетевое оборудование может поддерживать такие маски для построения сетей "точка-точка" из группы маршрутизаторов. Например, для построения сложных сетей в ЦОД (Центр обработки данных). Поддержка которой включается на оборудовании отдельно.