Obter informações de rede do localhost

Ola gente!

Estou com um pequeno problema, tenho uma aplicação que vai enviar um pacote RTP para a rede, para isso preciso do IP de broadcast da minha rede.

Quando seto manualmente o IP do meu broadcast (que no caso é 255.255.255.0) o software funciona normalmente, porém dessa forma não tenho portabilidade.

Preciso de uma forma de obter o IP do meu broadcast (do IP da placa de rede mesmo). Eu consigo obter o endereço IP da placa sem problemas. Também tentei encontrar o endereço da máscara de sub-rede para tentar realizar o cálculo e encontrar meu broadcast, mas não consegui obter essas informações.

Alguem sabe de uma saída?

PS.: eu já consegui alterar a propriedade do sistema e levar em consideração primeiro o IPv4.

Eu acho que isso resolve:

NetworkInterface.getNetworkInterfaces();

Retorna um Enumeration de objetos NetworkInterface…

http://java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html

Eu usei esse método Marcelo

InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
System.out.println("Placa: " + networkInterface.getDisplayName());

assim eu tenho o NetworkInterface da minha placa wireless do notebook por exemplo, se eu mando exibir o Display name aparece o nome da placa certinho, a saída mostra:

Placa: Atheros AR5009 802.11a/g/n WiFi Adapter

Ai eu tento pegar as interfaces assim:

java.util.List<InterfaceAddress> lista = networkInterface.getInterfaceAddresses();
System.out.println("IP: " + lista.get(0).getAddress().getHostAddress());

Quando eu faço isso o networkInterface.getInterfaceAddresses(); retorna nulo e eu não consigo pegar as informações das interfaces.

PS.: entanglement eu sei qual o endereço da biblioteca de classe e não estaria postando aqui se mesmo assim não tivesse dando certo, na próxima vez tente postar algo mais construtivo por favor.

Caramba… fiz os testes aqui e com esse mesmo algoritmo seu, eu consigo imprimir normalmente os endereços IP… algum programa estaria bloqueando a leitura desses dados, talvez? Veja a documentação do método:

http://java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html#getInterfaceAddresses()

Apenas interfaces onde o checkConnect não retorna uma SecurityException serão exibidas… talvez o problema seja esse…

Hmm é possível. Eu li que por padrao ele pega sempre primeiro o IPv6, pra mostrar primeiro o IPv4 eu alterei a opção do sistema com esse método:

System.setProperty("java.net.preferIPv4Stack", "true");

Coloquei ele antes do método ali em cima, tentei sem ele e também não retorna nada.

Há alguma forma de desativar essa verificação de segurança?

Voce pode fazer o seu próprio método, pegue o fonte do SDK do Java e altere… aqui está o método:

[code]
private InterfaceAddress bindings[];

public java.util.List&lt;InterfaceAddress&gt; getInterfaceAddresses() {
java.util.List&lt;InterfaceAddress&gt; lst = new java.util.ArrayList&lt;InterfaceAddress&gt;(1);
SecurityManager sec = System.getSecurityManager();
for (int j=0; j&lt;bindings.length; j++) {
    try {
	if (sec != null) {
	    sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1);// essa linha aqui! comente ela!
	}
	lst.add(bindings[j]);
    } catch (SecurityException e) { }
}
	return lst;
}[/code]

A linha que tem o comentário é a linha que executa o checkConnect, se quiser, comente ela e pronto… faça os ajustes necessários na sua Classe, e teste… deve funcionar…>

Eu to tentando alterar esse método mas como faço isso?

Tentei criar minha classe com o mesmo nome, copia o conteúdo e comentar a linha mas um método init() da pau na hora de rodar. Tentei fazer uma classe que herda a NetworkInterface e sobrescrever o método mas nada também, implementar também não da…

Alguma idéia?

Não precisa “clonar” a classe toda, apenas coloque esse método dentro do seu projeto, faça as alterações, e ao invés de chamar o método “original” chame o seu…

[quote=helders]Ola gente!

Estou com um pequeno problema, tenho uma aplicação que vai enviar um pacote RTP para a rede, para isso preciso do IP de broadcast da minha rede.

Quando seto manualmente o IP do meu broadcast (que no caso é 255.255.255.0) o software funciona normalmente, porém dessa forma não tenho portabilidade.

Preciso de uma forma de obter o IP do meu broadcast (do IP da placa de rede mesmo). Eu consigo obter o endereço IP da placa sem problemas. Também tentei encontrar o endereço da máscara de sub-rede para tentar realizar o cálculo e encontrar meu broadcast, mas não consegui obter essas informações.

Alguem sabe de uma saída?

PS.: eu já consegui alterar a propriedade do sistema e levar em consideração primeiro o IPv4.[/quote]

Cara, estuda sobre TCP/IP (mais especificamente sobre subrede).

O que voce esta falando nao eh broadcast nao, alias, 255.255.255.0 jamais sera um broadcast pois eles sempre sao impar.

O broadcast é o ultimo endereco de um segmento de rede TCP/IP, quem vai definir o broadcast de uma rede é a mascara.

[]s

Kemper

Ola kemperacc,

Sei exatamente o que é broadcast :slight_smile:

O fato de querer a mascara de sub-rede é exatamente para poder CALCULAR qual o broadcast (se sei calcular eu acho que sei o suficiente sob broadcast :))

Não há uma forma de obter o endereço de broadcast em java, por isso preciso da mascara de sub-rede para conseguir calcular qual é meu endereço de broadcast, baseado em meu IP e em minha mascara de sub-rede.

Exatamente… :smiley:

E aí, algum progresso?

Bom marcelo, espero q eu tenha entendido certo, vamos la:

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Main {

    private static InterfaceAddress bindings[];

    public static java.util.List<InterfaceAddress> getInterfaceAddresses() {
        java.util.List<InterfaceAddress> lst = new java.util.ArrayList<InterfaceAddress>(1);
        SecurityManager sec = System.getSecurityManager();
        for (int j = 0; j < bindings.length; j++) {
            try {
                if (sec != null) {
                    //sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1); // essa linha aqui! comente ela! <- comentei
                }
                lst.add(bindings[j]);
            } catch (SecurityException e) {
            }
        }
        return lst;
    }

    public static void main(String[] args) throws SocketException {

        System.setProperty("java.net.preferIPv4Stack", "true");
        try {
            InetAddress localHost = Inet4Address.getLocalHost();
            NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
            System.out.println("Placa: " + networkInterface.getDisplayName());
            // Até aqui ele roda normalmente, mostra o nome da minha placa de rede certinho
            java.util.List<InterfaceAddress> lista = getInterfaceAddresses();
            System.out.println("IP: " + lista.get(0).getAddress().getHostAddress());
        } catch (UnknownHostException ex) {
        }
    }
}

Exception in thread “main” java.lang.NullPointerException
at teste.Main.getInterfaceAddresses(Main.java:17)
at teste.Main.main(Main.java:54)

Essa linha 17 corresponde ao FOR do método de cima, esse bindings[] ta vazio, eu olhei na classe NetworkInterface e não achei nada que preenche ele, o que é muito estranho, nem no construtor default…

É, realmente… estou tentando descobrir como funciona isso aí… alguém ai teria algo á dizer, pra ajudar?
Fiquei curioso agora…

Se eu descobrir algo eu posto aqui…

Talvez isso te ajude, fiz aqui agora um codigo que lista todas as interfaces e todos os ips da maquina:

Um fato interessante a ressaltar é que cada interface pode ter N ips, e cada equipamento pode ter N interfaces, agora creio que seu problema será descobrir qual broadcast voce quer!

hehehe

        try {

            Enumeration&lt;NetworkInterface&gt; ifaces = NetworkInterface.getNetworkInterfaces();

            while (ifaces.hasMoreElements()) {
                NetworkInterface iface = ifaces.nextElement();



                System.out.println("Obtendo Informacoes da interface: " + iface.getName());
                for (InterfaceAddress address : iface.getInterfaceAddresses()) {

                    System.out.println("IP........: " + address.getAddress().toString());
                    Object bc = address.getBroadcast();
                    System.out.println("Broadcast.: " + bc);
                    System.out.println("Mascara...: " + address.getNetworkPrefixLength());

                    System.out.println();

                }


            }


        } catch (SocketException ex) {
            ex.printStackTrace();
        }

Então, o problema dele é que o método getInterfaceAddresses() da API original executa uma verificação de segurança (método checkConnect(), olhe nos códigos acima o exemplo) que de alguma maneira está bloqueando a recuperação do IP da máquina dele… se não fosse por isso, seu método também funcionaria…

Gente faltou eu testar o básico, vou rodar o mesmo código em outra máquina e ver o que acontece… porque será que esse checkConnect() trava o retorno?