Jak zmienić zachowanie globalnego adresu rozgłoszeniowego (255.255.255.255) w systemie Windows?

10

Pożądane zachowanie

Gdy aplikacja wysyła pakiet na adres IP globalnej emisji 255.255.255.255, chciałbym, aby pakiet został przesłany na adres globalnej emisji Ethernet ( ff:ff:ff:ff:ff:ff) na wszystkich interfejsach.

W systemie Linux i prawdopodobnie także w innych systemach operacyjnych wydaje się, że to działa. Windows XP i Windows 7 wykazują różne zachowania w tym zakresie i żadne z nich nie jest pożądane w mojej sytuacji.

Zachowanie Windows XP

Pakiet zostanie poprawnie wysłany do pierwszego interfejsu sieciowego (kolejność interfejsów jest określona w „Połączenia sieciowe / Ustawienia zaawansowane / zaawansowane”). Zostanie również wysłany do innych interfejsów.

Jak dotąd wszystko jest w porządku. Problem polega na tym, że podczas wysyłania do innych interfejsów adresem źródłowym pakietu rozgłoszeniowego jest adres IP pierwszego interfejsu. Na przykład wyobraź sobie tę konfigurację sieci (kolejność jest ważna):

  • Adapter 1: adres IP 192.168.0.1
  • Adapter 2: adres IP 10.0.0.1
  • Adapter 3: adres IP 172.17.0.1

Teraz, jeśli wyślę pakiet rozgłoszeniowy, zostaną wysłane następujące pakiety (z źródłowym i docelowym adresem IP):

  • Na adapterze 1: 192.168.0.1=>255.255.255.255
  • Na adapterze 2: 192.168.0.1=>255.255.255.255
  • Na adapterze 3: 192.168.0.1=>255.255.255.255

    W praktyce aplikacje korzystające z pakietów rozgłoszeniowych nie będą działać na żadnym interfejsie innym niż adapter 1. Moim zdaniem jest to rażący błąd w stosie TCP / IP systemu Windows XP.

Zachowanie Windows 7

Modyfikacja kolejności interfejsu sieciowego nie wydaje się mieć żadnego wpływu na system Windows 7. Zamiast tego, transmisja wydaje się być kontrolowana przez tablicę tras IP.

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0   10.202.254.254       10.202.1.2    286
          0.0.0.0          0.0.0.0      192.168.0.1      192.168.0.3     10
       10.202.0.0      255.255.0.0         On-link        10.202.1.2    286
       10.202.1.2  255.255.255.255         On-link        10.202.1.2    286
   10.202.255.255  255.255.255.255         On-link        10.202.1.2    286
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    306
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    306
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    306
      192.168.0.0    255.255.255.0         On-link       192.168.0.3    266
      192.168.0.3  255.255.255.255         On-link       192.168.0.3    266
    192.168.0.255  255.255.255.255         On-link       192.168.0.3    266
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    306
        224.0.0.0        240.0.0.0         On-link       192.168.0.3    266
        224.0.0.0        240.0.0.0         On-link        10.202.1.2    286
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    306
  255.255.255.255  255.255.255.255         On-link       192.168.0.3    266
  255.255.255.255  255.255.255.255         On-link        10.202.1.2    286
===========================================================================

Widzisz 255.255.255.255trasy? Tak, kontrolują pakiety rozgłoszeniowe. W tej sytuacji pakiety rozgłoszeniowe będą wysyłane przez, 192.168.0.3ponieważ mają niższą metrykę ... ale nie do innych interfejsów.

Możesz zmienić interfejs, przez który globalne pakiety emisji będą wysyłane bardzo łatwo (po prostu dodaj trwałą 255.255.255.255trasę o niskim wskaźniku). Ale bez względu na to, jak bardzo się starasz, pakiety emisji będą wysyłane tylko na jednym interfejsie, a nie na wszystkich tak, jak chciałbym.

Wniosek

  • Windows 7 wysyła pakiety rozgłoszeniowe tylko do jednego interfejsu. Możesz wybrać który, ale nie o to tutaj chodzi.
  • Windows XP wysyła pakiety rozgłoszeniowe do wszystkich interfejsów, ale wysyła je tylko zgodnie z oczekiwaniami do jednego interfejsu, co w praktyce jest równoważne zachowaniu systemu Windows 7.

Cel

Chcę raz na zawsze zmienić obsługę globalnej emisji IP w systemie Windows (najlepiej Windows 7). Oczywiście lepszym sposobem byłoby wprowadzenie jakiejś obsługiwanej zmiany konfiguracji (włamanie do rejestru lub podobne), ale jestem otwarty na wszystkie sugestie.

Jakieś pomysły?

Etienne Dechamps
źródło
Czego używasz do generowania tych transmisji. Nie mogę zmusić mojego stosu XP do robienia czegokolwiek innego niż ukierunkowane transmisje. tj. 10.202.255.255 w twoim przypadku.
Scott Lundberg,
Czy możesz odwołać się do dokumentu RFC lub innego dokumentu wskazującego opisywane prawidłowe zachowanie? Chociaż zgadzam się, że jest to pożądane zachowanie, aby nazwać to poprawnym zachowaniem, należy odwoływać się do specyfikacji określającej to, co jest prawidłowe. Czy to możliwe, że konkretna implementacja routingu jest pozostawiona dostawcy (w tym przypadku Microsoft)?
Jason R. Coombs
Scott Lundberg: wiele aplikacji (zwłaszcza gier) wyśle ​​globalną transmisję. Możesz wygenerować niektóre za pomocą netcat: na przykład „nc -v -u 255.255.255.255 5000”.
Etienne Dechamps,
Jason R. Coombs: rzeczywiście, może miałem zły wybór słów. Powinienem był zastosować „pożądane zachowanie”. Nie sądzę, żeby istniała RFC, ale mogę się mylić.
Etienne Dechamps,
Czy wysyłasz pakiet TCP lub UDP? Zgodnie z tym ma to znaczenie social.msdn.microsoft.com/Forums/en/peertopeer/thread/… .
Nissan Fan

Odpowiedzi:

6

Nie dlatego, że jestem w obronie Microsoftu, ale po przeczytaniu następujących RFC, które próbują zdefiniować sposób działania emisji, nie sądzę, że Microsoft koniecznie narusza jakiekolwiek RFC. IMO problem powinien zostać rozwiązany na poziomie aplikacji (tj. Ukierunkowane transmisje, a nie globalne), które uderzą w odpowiednie trasy w tablicy routingu i będą wysyłane tylko z właściwego interfejsu dla tej sieci IP.

Obaj twierdzą, że nie ma zdefiniowanego standardu dla transmisji. Wspomina również w 919, że należy wybrać konkretny interfejs fizyczny dla transmisji. W przypadku maszyny z wieloma domami i wieloma kartami sieciowymi, która generuje transmisję, nie sądzę, aby jasno określono, co powinno się stać. Transmisje nigdy nie powinny być przekazywane przez routery z jednego interfejsu do drugiego, więc czy komputer z systemem Windows jest routerem, czy nie w tym przypadku?
Jeśli działa jako router, to każdy host odpowiadający na transmisję z niepoprawnym adresem IP dla tej sieci (Adaptery 2 i 3 w twoim przykładzie) powinien odesłać pakiet z powrotem na adres ethernetowy Adaptery 2 i 3 w odpowiedzi na Adapter Adres IP 1 i host systemu Windows powinny skierować go do odpowiedniego interfejsu.
Brzmi myląco ... ale nie mogę wymyślić lepszego sposobu na wyrażenie tego

I wreszcie, RFC 919 wyraźnie mówi Z RFC 919

Ponieważ zakładamy, że problem został już rozwiązany w warstwie łącza danych, host IP, który chce
wysłać transmisję lokalną lub ukierunkowaną, musi jedynie
podać odpowiedni adres docelowy i wysłać datagram jak
zwykle. Wszelkie zaawansowane algorytmy muszą znajdować się tylko w bramach.

Odczyt sugerujący, że źródłowy adres IP nie ma znaczenia dla transmisji.


Ponieważ każda aplikacja wydaje się obsługiwać transmisje inaczej, myślę, że na tym spoczywa odpowiedzialność. Na przykład. nbtstatwysyła ukierunkowane transmisje na komputerach obsługujących wiele kart sieciowych, podczas gdy gry mogą korzystać z transmisji globalnych.
Krótko mówiąc, aplikacja powinna zostać naprawiona, a nie system operacyjny w tym przypadku ...

EDYCJA: Oto link do tych samych okoliczności, ale w Linuksie. Jądro Linuksa obsługuje go, wysyłając tylko jeden pakiet z domyślnego interfejsu (w tym przykładzie NIC A). Zalecają, aby aplikacja wyliczyła karty sieciowe i wysłała skierowaną transmisję do każdej karty sieciowej. Połączyć

Scott Lundberg
źródło
2
Nie rozumiem związku między akapitem cytowanym w RFC 919 a adresem źródłowym. Wydaje mi się oczywiste, że wysyłanie pakietu IP na interfejsie z adresem źródłowym innego interfejsu zawsze jest błędem, niezależnie od charakteru pakietu emisji / emisji pojedynczej. Mam na myśli, że nie można rozsądnie powiedzieć „źródłowy adres IP nie ma znaczenia dla transmisji”, oczywiście, że tak! Skąd jeszcze aplikacje powinny wiedzieć, kto wysłał transmisję?
Etienne Dechamps,
1
„W 919 wspomniano również, że do transmisji należy wybrać konkretny interfejs fizyczny”. Gdzie? „Adres 255.255.255.255 oznacza emisję w lokalnej sieci sprzętowej” (RFC919 7.)? W takim przypadku z szacunkiem się nie zgadzam. Dyskutujemy, co zrobić z transmisjami na poziomie hosta, a nie na poziomie sieci. Poza tym powiedziano poniżej, że host może „nadawać do wszystkich swoich bezpośrednich sąsiadów za pomocą 255.255.255.255”. Wszyscy jego najbliżsi sąsiedzi. Nie „wszyscy sąsiedzi na określonym interfejsie sieciowym”.
Etienne Dechamps,
1
„Aplikacje nie dbają o to, który interfejs wysłał transmisję. Muszą tylko na nie odpowiedzieć”. Huh ... oni też muszą wysyłać audycje, nie tylko na nie odpowiadać. Rozważ przypadek przeglądarki LAN gameserver. Wysyła pakiety rozgłoszeniowe w celu wykrycia serwerów gier w sieci. Jeśli pakiety rozgłoszeniowe nie zostaną wysłane do wszystkich interfejsów, przeglądarka gameserver nie pokaże serwerów gier osiągalnych za pośrednictwem tych interfejsów. Innymi słowy, epicka porażka.
Etienne Dechamps,
1
„Nie jestem pewien, ale myślę, że system operacyjny widzi żądanie 255.255.255.255 i mówi, że musi wysłać to na wszystkich interfejsach (aby znaleźć wszystkich bezpośrednich sąsiadów), ale zostało to zażądane z określonej aplikacji powiązanej z określony adres IP (może być domyślny na podstawie metryki). ” Zgadzam się. To nie znaczy, że jest to właściwe. Moim zdaniem całkowicie narusza zasadę najmniejszego zaskoczenia z punktu widzenia twórcy aplikacji, który po prostu oczekuje, że pakiet zostanie wysłany do wszystkich na wszystkich interfejsach.
Etienne Dechamps,
4
Nie jestem pewien, co masz na myśli przez powielenie. RFC specjalnie zabraniają przekazywania pakietów rozgłoszeniowych. Powinien zostać wysłany tylko jeden pakiet, co moim zdaniem stanowi sedno naszej dyskusji. Gdyby system operacyjny działał tak, jak mówisz, musiałby wygenerować 9 pakietów ogółem (3 dla każdego interfejsu), ponieważ warstwa IP musiałaby wygenerować trzy pakiety z osobnymi źródłowymi adresami IP (jeden dla każdej karty sieciowej w warstwie 3), a następnie każda karta sieciowa musiałaby wysyłać je w sieci Ethernet (warstwa 2). Jeśli istnieją trasy między sieciami, otrzymasz 3 odpowiedzi z powrotem! Który jest prawidłowy?
Scott Lundberg,
4

Wreszcie rozwiązałem to programowo. Napisałem bardzo małe oprogramowanie o nazwie WinIPBroadcast, które zajmuje się przekazywaniem ramek rozgłoszeniowych do wszystkich interfejsów.

Działa z ciekawym faktem: możliwe jest otrzymywanie lokalnie generowanych globalnych pakietów rozgłoszeniowych podczas słuchania na adres pętli zwrotnej (127.0.0.1). WinIPBroadcast nasłuchuje na adres lokalny dla wszystkich emisji za pomocą gniazd RAW, a następnie dla każdego pakietu transmisji, przekazuje go do wszystkich interfejsów oprócz preferowanego.

Etienne Dechamps
źródło
Ponieważ stos okien jest rozwidleniem stosu BSD, jestem ciekawy, czy BSD wykazuje takie samo zachowanie.
x0n 22.04.11
Twoje oprogramowanie nie działa. The program can't start becuase api-ms-win-core-rtlsupport-l1-2-0.dll is missing from your computer.. Powodzenia w znalezieniu tego .dllw Google.
Alex G
@AlexG: to dziwne, myślałem, że naprawiłem ten problem przez github.com/dechamps/WinIPBroadcast/commit/… . Czy na pewno korzystasz z ostatniej wersji (1.6)? Zgłoś błąd na github.com/dechamps/WinIPBroadcast/issues, a ja przyjrzę się.
Etienne Dechamps,