Dlaczego w adresie IPv6 jest znak procentu „%”?

125

Korzystam z .NET Frameworkklas, aby uzyskać adresy IP dla mojego komputera.

Dns.GetHostAddresses(Dns.GetHostName())

Mam adapter VirtualBox, który ma zarówno adres IPv4, jak i adres IPv6. Za pomocą kodu .NET otrzymuję adres IPv6 jakofe80::71a3:2b00:ddd3:753f%16

Zwróć uwagę na% 16 na końcu?

Jednak jeśli WMIzapytam o to samo za pomocą , otrzymam adres jako „fe80 :: 71a3: 2b00: ddd3: 753f”

Czy więc% 16 ma jakieś szczególne znaczenie?

Edytować:

Właśnie miałem na ten temat kilka spostrzeżeń. I całkiem dobrze pasują do tego, co powiedział Stephen Jennings w swojej odpowiedzi.

Zainstalowałem Vmware, aby zobaczyć, jaki adres IPv6 wydał. Adresy to: fe80 :: 3dd0: 7f8e: 57b7: 34d5% 19

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

Oczywiście liczby po% nie są reprezentacją szesnastkową. Sprawdziłem wszystkie właściwości karty sieciowej za pomocą Wmi i stwierdziłem, że liczby są dokładnie takie same jak właściwość InterfaceIndex każdej karty sieciowej. Zgodnie z MSDN jednoznacznie identyfikuje każdą kartę sieciową, a ta właściwość została wprowadzona w systemie Vista.

To, co mnie nadal myliło, to dlaczego klasa IPAddress pozwala ci utworzyć adres IP w tym formacie, chyba że jest prawidłowy. Odpowiedzi udzielił Stephen. Liczba jest identyfikatorem zakresu. Adres IP ma konstruktor, który akceptuje adres ORAZ identyfikator zakresu.

Aha, i wszystkie te trzy karty sieciowe były połączone lokalnie. Potwierdził to za pomocą ipconfig

Chłodny. To było interesujące !!

Amith George
źródło
2
Nie miałem pojęcia, co to było, zanim zapytałeś. Nauczyłem się również czegoś fajnego na temat IPv6 (jakie są nerdy).
Stephen Jennings
@Stephen, więc wcześniej pracowałeś z ipv6? Byłem zaskoczony, że szybko to przybiłeś. Przez pewien czas korzystałem z Google'a, zanim opublikowałem tutaj pytanie. Dobra robota!
Amith George
Wyszukiwanie „procent adresu IPv6” dało mi nazwę, której potrzebowałem, a stamtąd wyszukiwanie i próba zrozumienia mylącej dokumentacji technicznej zajęło mi najwięcej czasu. Rozumiem, co IPv6 próbuje osiągnąć, ale jest wiele nowych koncepcji, których nie udało mi się zbadać i zrozumieć. To był jeden i nic nie daje lepszego zrozumienia niż próba wyjaśnienia komuś innemu.
Stephen Jennings
Alternatywną notacją może być fe80:10( 0x0010istota 16). Używam tego w przeglądarce podczas pracy z lokalnymi adresami IPv6, ale nie jestem w 100% pewien, że jest to zgodne ze standardami. (Używanie procentu w adresach URL jest niechlujne w przeglądarkach; w rzeczywistości nie mogłem w ogóle tego zrobić).
Arjan

Odpowiedzi:

134

Liczba po „%” jest identyfikatorem zakresu.

IPv6 definiuje co najmniej trzy zakresy osiągalności dla adresów:

  1. Adresowalny na całym świecie. Jest to adres IPv6 podany przez dostawcę usług internetowych. Jest dostępny do użytku w publicznym Internecie.

  2. Link lokalny. Jest to podobne do zakresu 169.254.XX. Jest to adres, który komputer przypisuje sobie w celu ułatwienia komunikacji lokalnej. Te adresy nie są rozsyłane w publicznym Internecie, ponieważ nie są unikalne na całym świecie.

  3. Węzeł lokalny. Jest to adres identyfikujący interfejs lokalny, podobny do 127.0.0.1. Zasadniczo jest to adres :: 1.

Microsoft opublikował ten artykuł opisujący adresowanie IPv6 , który jest najmniej mylącym artykułem, jaki znalazłem. Artykuł wskazuje, że obecność identyfikatora zakresu w twoim adresie oznacza, że ​​jest to adres lokalny dla łącza . Możesz także powiedzieć, że jest to link lokalny, ponieważ adres zaczyna się od fe80.

Jasne, zrozumiałe informacje na ten temat wydają się być rzadkie, dlatego resztę zestawiam w oparciu o moje najlepsze zrozumienie RFC 4007 i innych informacji tam dostępnych.

Komputer może mieć wiele adresów lokalnych dla łącza, każdy o innym zasięgu. Identyfikator zakresu wskazuje, dla którego zakresu jest adres. Na przykład wyobraź sobie scenariusz komputera z dwoma kartami sieciowymi, z których każdy ma adres lokalny dla łącza w różnych sieciach. Jeśli spróbujesz wysłać coś na inny adres zaczynający się od fe80, skąd komputer będzie wiedział, którą kartę sieciową wysłać? Identyfikator zakresu wydaje się być rozwiązaniem tego.

Stephen Jennings
źródło
Dzięki! Zmodyfikowałem moje pytanie, aby dodać dodatkowe rzeczy, które obserwowałem podczas oczekiwania na odpowiedź. A kiedy przyszedłem je opublikować, byłem zaskoczony, widząc twoją odpowiedź potwierdzającą obserwacje :)
Amith George
Niezła odpowiedź. Zobaczę, czy w pełni to zrozumiałem. Tak więc urządzenie z dwiema kartami sieciowymi może połączyć się z dwoma różnymi routerami i otrzymać przypisany ten sam adres DHCP fe80::42. Ponadto routery mają ten sam adres fe80::1. Teraz fe80::1%Xmożna go użyć do rozróżnienia routerów, ale fe80::42%Xjest mało użyteczny dla klienta, prawda?
user123444555621
2
@ Pumbaa80 Klient wysyła wiadomości, aby fe80::1%1dotrzeć do routera podłączonego do karty sieciowej nr 1, i wysyła wiadomości, fe80::1%2aby dotrzeć do routera podłączonego do karty sieciowej nr 2. Nawiasem mówiąc, adresy lokalne dla łącza są konfigurowane automatycznie przez komputer hosta, a nie przez DHCP, więc prawdopodobnie nie przypisałby swoim dwóm kartom sieciowym tego samego adresu IP. Pamiętaj również, że lokalne adresy link nie są routowalne, więc zwykle nie będziesz wysyłać wiadomości do routera, będziesz wysyłał wiadomości między dwoma hostami.
Stephen Jennings
eksperymentalnie, wydaje się, krocząca %nnmoże zostać pominięte w przypadku przynajmniej niektórych poleceń, na przykład ping, tracert.
matt wilkie
Bardzo dobra odpowiedź. Wystarczy wspomnieć, że identyfikator zakresu jest zerowy, jest wyjątkowy i wydaje się wskazywać, że algorytm specyficzny dla implementacji wybiera identyfikator zakresu z listy interfejsów z tym zakresem tego adresu IP.
Arran Cudbard-Bell
21

Adresy IPv6 z prefiksem fe80 :: / 64 są adresami lokalnymi dla łącza, które są tworzone przez połączenie tego prefiksu z adresem sprzętowym urządzenia sieciowego, 71a3: 2b00: ddd3: 753f w twoim przykładzie. (Analog w IPv4 to 169.254.0.0/16.) Ponieważ prefiks jest taki sam dla wszystkich lokalnych adresów łącza na maszynie, routing może czasem wymagać znajomości interfejsu, do którego się odnosi. I to właśnie określa liczba po procentu, zwana indeksem strefy. Specyfika zależy od systemu operacyjnego: w systemie Windows %16interfejs ma numer 16; na przykład w Linuksie możesz zobaczyć coś takiego %eth0.

Niektóre narzędzia lub interfejsy API uznają ten indeks strefy za nieważny lub niejawny dla swoich celów. Na przykład w systemie Linux ifconfignarzędzie tego nie pokazuje, ponieważ jest oczywiste, do którego interfejsu należy adres. Ale ogólnie należy to wziąć pod uwagę.

Peter Eisentraut
źródło
18

Znaki po% (które w twoim przykładzie są liczbami) to identyfikator interfejsu. Znaki te są używane do identyfikacji „interfejsu sieciowego”, który ludzie często nazywają „kartą sieciową”. Na przykład może pomóc ustalić, czy pakiet będzie korzystał z przewodowej karty Ethernet, czy bezprzewodowej karty Wi-Fi.

Zgaduję, że używasz Microsoft Windows. Używa liczb jako identyfikatorów interfejsów.

Dla porównania, systemy uniksopodobne mogą używać liter po znaku%. na przykład:fe80::71a3:2b00:ddd3:753f%eth0

W takim przypadku identyfikator interfejsu eth0odpowiada nazwie karty sieciowej.

W systemie Microsoft Windows można uzyskać listę (numerycznych) identyfikatorów interfejsu, korzystając z jednego z wierszy poleceń, które sprawdzają tablicę routingu. Wolę „ netstat -nr”, ponieważ działa to również w innych systemach operacyjnych, ale Microsoft Windows obsługuje także „ route print”. Wynikowy raport, który zostanie zgłoszony, prawdopodobnie będzie trwał ponad ekran, więc przygotuj się na przewijanie do tyłu, chyba że przejdziesz dalej.

np. w moim systemie:

=========================================================================== 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 ===========================================================================

W takim przypadku adres taki jak fe80 :: 71a3: 2b00: ddd3: 753f% 14 oznaczałby mój kontroler rodziny Realtek PCIe GBE. „GBE” odnosi się do Gigabit Ethernet.

Oto podchwytliwa część: jeśli chcesz pingować adres zdalny, może być konieczne użycie adresu IPv6 systemu zdalnego, ale identyfikatora interfejsu systemu lokalnego. Na przykład, jeśli używam komputera A i mam lokalny adres IPv6 fe80 :: 1 podłączony do interfejsu nr 14, i chcę pingować komputer B i ma on lokalny adres IPv6 fe80 :: 2 podłączony do jego interfejs numer 16, wtedy użyłbym tego:

ping fe80::2%14

Tak więc pingpolecenie wyśle ​​pakiet ICMPv6 na zdalny adres IPv6 (fd80 :: 2), który należy do zdalnego komputera, i użyje do tego interfejsu z identyfikatorem 14. Identyfikator interfejsu 14 to numer z systemu, którego używam, a nie z systemu zdalnego.

Spójrzmy teraz, dlaczego może to być konieczne.

Jeśli chcę wysłać polecenie ping do adresu IPv6 Google (który w chwili pisania tej odpowiedzi to 2607: f8b0: 400a: 802 :: 200e), wówczas tabela routingu sprawdzi, które karty sieciowe obsługują adresy zaczynające się od 2607: f8b0: 400a: 802. Tabela routingu wskaże, że żadna z moich kart sieciowych nie jest podłączona bezpośrednio do sieci przy użyciu adresów zaczynających się od 2607: f8b0: 400a: 802, więc mój komputer ostatecznie użyje adresu „bramy”. Gdybym łączył się z inną siecią należącą do organizacji, dla której pracuję, mógłbym mieć specjalny adres „bramy” kierujący ruch do sieci prywatnej. W takim przypadku nie mam bardziej szczegółowej bramy, więc użyję „domyślnej bramy” IPv6. Tak działa IPv6 przez większość czasu, z wyjątkiem adresów lokalnych dla łącza. Tak też przez większość czasu działało IPv4.

Zgodnie z RFC 4291 sekcja 2.8 każdy komputer korzystający z protokołu IPv6 powinien przypisać adres lokalny łącza do każdego interfejsu sieciowego. RFC 4291 sekcja 2.5.6 pokazuje bity, od których muszą zaczynać się adresy lokalne link, co powoduje, że adresy lokalne link zaczynają się od „fe80: 0000: 0000: 0000:” (chociaż wiele z tych zer jest zwiniętych do podwójnego dwukropka ). Fakt, że adresy te zaczynają się od „fe80:” jest również opisany w RFC 4291 sekcja 2.4 .

Jeśli próbujesz wysłać polecenie ping do zdalnego systemu (np. „2607: f8b0: 400a: 802”), ogólnym procesem jest zazwyczaj wykrycie sieci lub podsieci, której częścią jest adres, co odbywa się poprzez sprawdzenie bitów na początku adresu. Następnie te bity są używane do określania sposobu kierowania ruchem.

Jednak ten proces nie działa dla adresu lokalnego łącza IPv6, ponieważ każdy pojedynczy (operacyjny, aktywny) interfejs sieci ma adres lokalny łącza rozpoczynający się od „fe80:” w podsieci przy użyciu prefiksu / rozmiaru podsieci „/ 64 ". Jeśli korzystasz z laptopa, prawdopodobnie zauważysz, że zarówno karta Ethernet, jak i karta Wi-Fi powinny mieć taki adres IPv6.

Teraz, gdy wysyłasz ping do fe80 :: 2, chcesz, aby komputer wysłał ten pakiet z właściwej karty sieciowej. Jeśli masz drukarkę podłączoną do sieci przewodowej, nie chcesz wysyłać ruchu z karty Wi-Fi, używając ścieżki / trasy sieci, która nie spowoduje, że ruch dotrze do drukarki. A jeśli próbujesz komunikować się z urządzeniem bezprzewodowym za pomocą karty Wi-Fi, nie chcesz, aby ruch wychodził z karty Ethernet.

Rozwiązaniem jest określenie, które urządzenie sieciowe ma korzystać z ruchu. Taki jest cel identyfikatora sieci.

TOOGAM
źródło
2
Ok, po ponownym przeczytaniu odpowiedzi Petera Eisentrauta , wygląda na to, że jest technicznie poprawny. Mam nadzieję, że moje szczegóły zapewnią trochę więcej przejrzystości. Nie zgadzam się z odpowiedzią Stephena Jenningsa , ponieważ ta odpowiedź sprawia, że ​​„identyfikator zakresu” identyfikuje „link lokalny” jako zakres. Jednak dwa różne interfejsy sieciowe mogą być „linkami lokalnymi”, ale nie będą używać tego samego „zakresu” (na przykładach pokazanych na jego numerowanej liście). Zamiast tego mówię, że te liczby identyfikują „interfejs” sieci.
TOOGAM