Como alterar o comportamento do endereço de transmissão global (255.255.255.255) no Windows?

10

Comportamento desejado

Quando um aplicativo envia um pacote para o endereço IP de broadcast global 255.255.255.255, eu gostaria que o pacote fosse enviado para o endereço de broadcast global Ethernet ( ff:ff:ff:ff:ff:ff), em todas as interfaces.

No Linux e provavelmente em outros sistemas operacionais, isso parece funcionar. O Windows XP e o Windows 7 exibem comportamentos diferentes sobre isso, e nenhum comportamento é desejável para a minha situação.

Comportamento do Windows XP

O pacote será enviado corretamente para a primeira interface de rede (a ordem da interface é especificada em "Conexões de rede / Configurações avançadas / avançadas"). Também será enviado para as outras interfaces.

Tudo está certo até agora. O problema é que, ao enviar para as outras interfaces, o endereço de origem do pacote de transmissão é o endereço IP da primeira interface. Por exemplo, imagine esta configuração de rede (a ordem é importante):

  • Adaptador 1: Endereço IP 192.168.0.1
  • Adaptador 2: endereço IP 10.0.0.1
  • Adaptador 3: endereço IP 172.17.0.1

Agora, se eu enviar um pacote de broadcast, os seguintes pacotes serão enviados (com endereços IP de origem e de destino):

  • No adaptador 1: 192.168.0.1=>255.255.255.255
  • No adaptador 2: 192.168.0.1=>255.255.255.255
  • No adaptador 3: 192.168.0.1=>255.255.255.255

    Na prática, os aplicativos que usam pacotes de transmissão não funcionarão em nenhuma outra interface além do adaptador 1. Na minha opinião, esse é um bug flagrante na pilha TCP / IP do Windows XP.

Comportamento do Windows 7

Modificar a ordem da interface de rede não parece ter efeito no Windows 7. Em vez disso, a transmissão parece ser controlada pela tabela de rotas 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
===========================================================================

Veja as 255.255.255.255rotas? Sim, eles controlam pacotes de transmissão. Nesta situação, os pacotes de broadcast serão enviados via o 192.168.0.3porque possui a métrica mais baixa ... mas não para as outras interfaces.

Você pode alterar a interface através da qual os pacotes de transmissão global serão enviados com muita facilidade (basta adicionar uma 255.255.255.255rota persistente com uma métrica baixa). Mas não importa o quanto você tente, os pacotes de transmissão serão enviados apenas em uma única interface, nem todas, como eu gostaria.

Conclusão

  • O Windows 7 envia apenas pacotes de transmissão para uma interface. Você pode escolher qual, mas esse não é o ponto aqui.
  • O Windows XP envia pacotes de difusão para todas as interfaces, mas somente os envia conforme o esperado para uma interface, o que na prática é equivalente ao comportamento do Windows 7.

O objetivo

Quero alterar esse suporte global de transmissão de IP no Windows (de preferência no Windows 7) de uma vez por todas. É claro que a melhor maneira seria ter algum tipo de alteração de configuração suportada (corte de registro ou similar), mas estou aberto a todas as sugestões.

Alguma ideia?

Etienne Dechamps
fonte
O que você está usando para gerar essas transmissões. Não consigo que minha pilha XP faça nada além de transmissões direcionadas. ou seja, 10.202.255.255 no seu caso.
21475 Scott Lundberg #
Você pode fazer referência a um RFC ou outro documento que indica o comportamento correto que você descreve? Embora eu concorde com o comportamento desejado, chamá-lo de comportamento correto deve fazer referência a uma especificação que define o que é correto. Será que a implementação de roteamento específica é deixada para o provedor (neste caso, a Microsoft)?
21139 Jason R. Coombs
Scott Lundberg: muitos aplicativos (especialmente jogos) enviarão transmissão global. Você pode gerar alguns usando o netcat: "nc -v -u 255.255.255.255 5000" por exemplo.
Etienne Dechamps
Jason R. Coombs: de fato, talvez eu tenha uma má escolha de palavras. Eu deveria ter usado "comportamento desejável". Não acho que exista uma RFC para isso, mas posso estar errado.
Etienne Dechamps
Você está enviando um pacote TCP ou UDP? De acordo com isso, importa social.msdn.microsoft.com/Forums/en/peertopeer/thread/… .
Nissan Fan

Respostas:

6

Não que eu esteja no negócio de defender a Microsoft, mas depois de ler as seguintes RFCs que tentam definir como as transmissões funcionam, não acho que a Microsoft esteja necessariamente violando quaisquer RFCs. Na IMO, o problema deve ser corrigido no nível do aplicativo (ou seja, transmissões direcionadas, não globais), que atingirá as rotas apropriadas na tabela de roteamento e será enviado apenas da interface correta para a rede IP.

Ambos afirmam que não há um padrão definido para transmissões. Também menciona em 919 que uma interface física específica deve ser selecionada para a transmissão. No caso de uma máquina com várias placas de rede e multi-NIC gerando a transmissão, não acho que esteja claramente indicado o que deve acontecer. As transmissões nunca devem ser transmitidas pelos roteadores de uma interface para a outra, então a máquina Windows é um roteador ou não neste caso?
Se estiver atuando como um roteador, qualquer host que responda à transmissão com o endereço IP incorreto para essa rede (adaptadores 2 e 3 no seu exemplo) deverá enviar o pacote de volta ao endereço Ethernet dos adaptadores 2 e 3 em resposta ao adaptador O endereço IP de um e o host do Windows devem roteá-lo para a interface adequada.
Isso parece confuso ... mas não consigo pensar em uma maneira melhor de expressar isso

E, finalmente, o RFC 919 diz especificamente do RFC 919

Como assumimos que o problema já foi resolvido na camada de enlace, um host IP que deseja
enviar uma transmissão local ou uma transmissão direta precisa apenas
especificar o endereço de destino apropriado e enviar o datagrama como de
costume. Quaisquer algoritmos sofisticados precisam residir apenas em gateways.

Leitura que sugere que o endereço IP de origem é irrelevante para uma transmissão.


Como cada aplicativo parece lidar com as transmissões de maneira diferente, acho que é aí que reside a responsabilidade. Por exemplo. nbtstatenvia difusões direcionadas em máquinas com várias placas de rede, enquanto os jogos podem usar difusões globais.
Em suma, o aplicativo deve ser corrigido, não o SO neste caso ...

EDIT: Aqui está um link para as mesmas circunstâncias, mas no Linux. O kernel do linux lida com isso enviando apenas um pacote da interface padrão (NIC A neste exemplo). Eles recomendam que o aplicativo enumere as NICs e envie uma transmissão direcionada para cada NIC. Ligação

Scott Lundberg
fonte
2
Não entendo a relação entre o parágrafo que você está citando da RFC 919 e o endereço de origem. Parece-me óbvio que é sempre errado enviar um pacote IP em uma interface com o endereço de origem de outra interface, independentemente da natureza de broadcast / unicast do pacote. Quero dizer, você não pode dizer razoavelmente "o endereço IP de origem é irrelevante para uma transmissão", é claro que é! De que outra forma os aplicativos devem saber quem enviou a transmissão?
Etienne Dechamps
1
"Também menciona em 919 que uma interface física específica deve ser selecionada para a transmissão". Onde? "O endereço 255.255.255.255 indica uma transmissão em uma rede de hardware local" (RFC919 7.)? Nesse caso, discordo respeitosamente. Estamos discutindo o que fazer com as transmissões no nível do host, não no nível da rede. Além disso, é dito logo abaixo que um host pode "transmitir a todos os seus vizinhos imediatos usando 255.255.255.255". Todos os seus vizinhos imediatos. Nem "todos os vizinhos em uma interface de rede específica".
Etienne Dechamps
1
"Os aplicativos não se importam com qual interface enviou a transmissão. Eles apenas precisam responder a ela." Huh ... eles precisam enviar transmissões também, não apenas responder a elas. Considere o caso de um navegador de servidor de jogos da LAN. Ele envia pacotes de transmissão para descobrir servidores de jogos na rede. Se os pacotes de transmissão não forem enviados para todas as interfaces, o navegador do servidor de jogos não mostrará servidores de jogos acessíveis através dessas interfaces. Em outras palavras, falha épica.
Etienne Dechamps
1
"Não tenho certeza, mas acho que o sistema operacional está vendo a solicitação 255.255.255.255 e dizendo que precisa enviá-lo em todas as interfaces (para encontrar todos os vizinhos imediatos), mas foi solicitado a partir de um aplicativo específico, vinculado a um IP específico (pode ser o padrão com base na métrica) ". Concordo. Isso não significa que é a coisa certa a fazer. Na minha opinião, viola completamente o princípio da menor surpresa do ponto de vista do desenvolvedor de aplicativos, que apenas espera que o pacote seja enviado a todos em todas as interfaces.
Etienne Dechamps
4
Não tenho certeza do que você quer dizer com duplicado. Os RFCs proíbem especificamente o encaminhamento de pacotes de transmissão. Deve haver apenas um pacote enviado, que eu acho que é o cerne da nossa discussão. Se o sistema operacional fizesse o que você disse, ele teria que gerar 9 pacotes totais (3 para cada interface) porque a camada IP teria que gerar três pacotes com IPs de origem separados (um para cada NIC na camada 3) e, em seguida, cada placa de rede teria que enviá-las para a Ethernet (camada 2). Se houver rotas entre redes, você receberá três respostas de volta! Qual deles está certo?
21811 Scott Lundberg #
4

Finalmente, eu resolvi isso programaticamente. Eu escrevi um software muito pequeno chamado WinIPBroadcast que cuida de retransmitir os quadros de transmissão para todas as interfaces.

Funciona usando um fato interessante: é possível receber pacotes de transmissão global gerados localmente ao escutar no endereço de loopback (127.0.0.1). O WinIPBroadcast escuta no endereço local toda a transmissão usando soquetes RAW e, em seguida, para cada pacote de transmissão, o retransmite para todas as interfaces, exceto a preferida.

Etienne Dechamps
fonte
Como a pilha do Windows é uma bifurcação da pilha do BSD, estou curioso para saber se o BSD apresenta o mesmo comportamento.
X0n
Seu software não funciona. The program can't start becuase api-ms-win-core-rtlsupport-l1-2-0.dll is missing from your computer.. Boa sorte em encontrar isso .dllno Google.
Alex G
@ AlexG: isso é estranho, eu pensei que tinha resolvido esse problema através do github.com/dechamps/WinIPBroadcast/commit/… . Tem certeza de que está executando a última versão (1.6)? Sinta-se à vontade para registrar um bug em github.com/dechamps/WinIPBroadcast/issues e eu darei uma olhada.
Etienne Dechamps