118

Я использую классы .NET Framework для получения IP-адресов для моей машины.

Dns.GetHostAddresses(Dns.GetHostName())

У меня есть адаптер VirtualBox, который имеет адреса IPv4 и IPv6. Используя код .NET, я получаю IPv6-адрес в виде fe80::71a3:2b00:ddd3:753f%16

Обратите внимание на% 16 в конце?

Однако, если я запрашиваю то же самое с помощью WMI , я получаю адрес как «fe80::71a3:2b00:ddd3:753f»

Итак, имеет ли% 16 какое-то особое значение?

Редактировать:

У меня просто было еще несколько замечаний по этому поводу. И они очень хорошо соответствуют тому, что сказал Стивен Дженнингс в своем ответе.

Я установил Vmware, чтобы посмотреть, какой IPv6-адрес выдан. Адреса были: fe80:: 3dd0: 7f8e: 57b7: 34d5% 19

fe80::b059:65f4:e877:c40% 20

Ясно, что числа после% не являются каким-либо шестнадцатеричным представлением. Я проверил все свойства, доступные для сетевого адаптера, используя Wmi, и обнаружил, что числа точно такие же, как у свойства InterfaceIndex каждого сетевого адаптера. Согласно MSDN, он однозначно идентифицирует каждый сетевой адаптер, и это свойство было представлено в Vista.

Что меня еще смущало, так это то, почему класс IPAddress позволил бы вам создать IP-адрес в этом формате, если он не был действительным. Ответ был предоставлен Стивеном. Номер является идентификатором области. IPAddress имеет конструктор, который принимает адрес и идентификатор области видимости.

Ох, и все эти три сетевых адаптера были локальными. Подтвердил это через ipconfig

Здорово. Это было интересно!

3 ответа3

126

Число после «%» - это идентификатор области.

IPv6 определяет как минимум три области достижимости для адресов:

  1. Глобально адресуемый. Это адрес IPv6, предоставленный вам вашим провайдером. Он доступен для использования в общедоступном Интернете.

  2. Link-местные. Это похоже на 169.254.XX диапазон Это адрес, который компьютер назначает себе для облегчения локальной связи. Эти адреса не распространяются в общедоступном Интернете, потому что они не являются глобально уникальными.

  3. Узел-местный. Это адрес, который идентифицирует локальный интерфейс, подобный 127.0.0.1. По сути, это адрес ::1.

Microsoft опубликовала эту статью, описывающую адресацию IPv6, и это наименее запутанная статья, которую я нашел. В статье указывается, что наличие идентификатора области в вашем адресе означает, что это адрес локальной ссылки. Вы также можете сказать, что это локальная ссылка, потому что адрес начинается с fe80 .

Ясная, просто понятная информация по этой теме, кажется, редка, поэтому я собираю остальную часть этого, основываясь на моем лучшем понимании RFC 4007 и другой информации там.

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

20

Адреса IPv6 с префиксом fe80::/64 являются локальными ссылочными адресами, которые создаются путем объединения этого префикса с аппаратным адресом сетевого устройства, 71a3: 2b00: ddd3: 753f в вашем примере. (Аналог в IPv4 - 169.254.0.0/16.) Поскольку префикс одинаков для всех локальных адресов на компьютере, иногда для маршрутизации может потребоваться информация о том, на какой интерфейс вы ссылаетесь. И это то, что указывает число после процента, называемого индексом зоны. Особенности зависят от операционной системы: в Windows %16 - это номер интерфейса 16; например, в Linux вы можете увидеть что-то вроде %eth0 .

Некоторые инструменты или API будут считать этот индекс зоны неважным или неявным для своих целей. Например, в Linux инструмент ifconfig не показывает его, поскольку очевидно, к какому интерфейсу относится адрес. Но в целом это следует учитывать.

15

Символы после% (в вашем примере это числа) являются идентификатором интерфейса. Эти символы используются для идентификации "сетевого интерфейса", который люди часто называют "сетевой картой". Например, это может помочь определить, будет ли пакет использовать проводную карту Ethernet или беспроводной адаптер Wi-Fi.

Я предполагаю, что вы используете Microsoft Windows. Он использует числа в качестве идентификаторов интерфейса.

Для сравнения: Unix-подобные системы могут использовать буквы после знака%. например: fe80::71a3:2b00:ddd3:753f%eth0

В этом случае идентификатор интерфейса eth0 соответствует имени сетевой карты.

В Microsoft Windows вы можете получить список (числовых) идентификаторов интерфейса, используя одну из командных строк, которые проверяют таблицу маршрутизации. Я предпочитаю « netstat -nr », поскольку он также работает в других операционных системах, но Microsoft Windows также поддерживает « route print ». Полученный результат, о котором сообщается, скорее всего, будет длиннее экрана, поэтому будьте готовы прокрутить назад, если только вы не перейдете к большему.

например, в моей системе:

=========================================================================== Interface List 14...5c f9 dd 6d 98 b8 ......Realtek PCIe GBE Family Controller 12...e0 06 e6 7e fc 4e ......Bluetooth Device (Personal Area Network) 1...........................Software Loopback Interface 1 13...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter 15...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #2 ===========================================================================

В этом случае адрес, такой как fe80::71a3:2b00:ddd3:753f% 14, будет ссылаться на мой контроллер семейства Realtek PCIe GBE. "GBE" относится к Gigabit Ethernet.

Теперь вот сложная часть: если вы хотите пропинговать удаленный адрес, вам может понадобиться использовать адрес IPv6 удаленной системы, но идентификатор интерфейса локальной системы. Так, например, если я использую Компьютер A и у меня есть локальный IPv6-адрес fe80:: 1, связанный с Интерфейсом номер 14, и я хочу пропинговать Компьютер B, и у него есть локальный IPv6-адрес fe80:: 2, связанный с его интерфейс номер 16, то это то, что я хотел бы использовать:

ping fe80::2%14

Таким образом, команда ping отправит пакет ICMPv6 на удаленный IPv6-адрес (fd80::2), который принадлежит удаленному компьютеру, и будет использовать интерфейс с идентификатором 14 для этого. Идентификатор интерфейса 14 - это номер системы, которую я использую, а не удаленная система.

Теперь давайте посмотрим, почему это может быть необходимо.

Если я хочу пропинговать IPv6-адрес Google (который на момент написания этого ответа был 2607:f8b0:400a:802::200e), то таблица маршрутизации проверит, какая сетевая карта обрабатывает адреса, начинающиеся с 2607:f8b0:400a:802. В таблице маршрутизации будет указано, что ни одна из моих сетевых карт не подключена напрямую к сети с использованием адресов, начинающихся с 2607:f8b0:400a:802, поэтому мой компьютер будет использовать адрес "шлюза". Если бы я подключался к другой сети, которая является частью организации, в которой я работаю, у меня мог бы быть специальный адрес "шлюза", который направляет трафик в частную сеть. В этом случае у меня нет более конкретного шлюза, поэтому я буду использовать IPv6 "шлюз по умолчанию". Именно так IPv6 работает большую часть времени, за исключением локальных адресов. Это также, как IPv4 работал большую часть времени. (Я упростил этот пример, предположив, что размер подсети IPv6 равен /64, поскольку описание всего процесса сделало бы это описание еще более длинным.)

В соответствии с разделом 2.8 RFC 4291 каждый компьютер, использующий IPv6, должен назначать локальный адрес канала каждому сетевому интерфейсу. В разделе 2.5.6 RFC 4291 показаны биты, с которых должны начинаться локальные адреса каналов, в результате чего локальные адреса ссылок начинаются с «fe80:0000:0000:0000:» (хотя многие из этих нулей свернуты в двойное двоеточие ). Тот факт, что эти адреса начинаются с «fe80:», также описан в RFC 4291, раздел 2.4.

Если вы попытаетесь пропинговать удаленную систему (например, «2607:f8b0:400a:802»), общий процесс обычно состоит в том, чтобы определить сеть или подсеть, частью которой является адрес, что делается путем просмотра битов. в начале адреса. Затем эти биты используются для определения способа маршрутизации трафика.

Однако этот процесс не работает для локального адреса канала IPv6, поскольку каждый отдельный (рабочий, активный) сетевой интерфейс имеет локальный адрес канала, начинающийся с «fe80:» в подсети с использованием префикса / размера подсети «/ 64" . Если вы работаете на ноутбуке, вы, вероятно, обнаружите, что и ваша карта Ethernet, и ваш адаптер Wi-Fi будут иметь такой IPv6-адрес.

Теперь, когда вы отправляете свой ping на fe80::2, вы хотите, чтобы ваш компьютер отправил этот пакет на правильную сетевую карту. Если у вас есть принтер, подключенный к проводной сети, вы не хотите отправлять трафик с вашей карты Wi-Fi, используя сетевой путь / маршрут, который не приведет к трафику, поступающему на принтер. И если вы пытаетесь установить связь с беспроводным устройством с помощью вашей карты Wi-Fi, вы не хотите, чтобы ваш трафик выходил из карты Ethernet.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .