Obter MAC de um host na rede

8 respostas
striker07

Olá pessoal! Estou mexendo com um projeto aqui, que conta com vários hosts em uma rede com DHCP. No meu server, eu tenho um banco onde armazeno a lista de dispositivos. A princípio tentei armazenar por IP, mas com o DHCP, quase sempre os hosts estão mudando de IP quando são desligados e ligados novamente. A alternativa seria salvar a informação do MAC de cada dispositivo, para eu saber que ele é ele. Tentei utilizar o método getHardwareAddress() da classe NetworkInterface, mas não consigo uma instância dela a partir do endereço IP (talvez ela só funcione para interfaces de rede locais?). Alguém sabe alguma forma de eu conseguir obter o MAC de um dispositivo na rede?

8 Respostas

J

O serviço precisa te enviar o endereço físico por broadcast.

O

Procure por alguma biblioteca em Java que implemente o protocolo ARP.

striker07

Depois de ralar um pouco e perder mais um pouco dos meus cabelos ainda sobreviventes, criei uma classe que faz a busca da tabela ARP do próprio SO. Se alguém tiver algum palpite para melhorá-la, fique à vontade:

package net.rafaeltoledo.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;

public abstract class NetworkUtils {

	public static String getMacAddress(String ip) {
		String macAddr = null;
		
		try {
			// Host Windows
			String osName = System.getProperty("os.name");
			if (osName.contains("Windows")) {
				Process child = Runtime.getRuntime().exec("arp -a");
				InputStream in = child.getInputStream();
				String output = "";
				int c;
				while ((c = in.read()) != -1) {
					output += (char) c;
				}
				in.close();
				
				String line = null;
				String[] splitted = output.split("\n");
				for (String portion : splitted) {
					if (line.contains(ip)) {
						line = portion;
					}
				}
				
				splitted = line.split(" +");
				for (String portion : splitted) {
					if (portion.matches("..-..-..-..-..-..")) {
						macAddr = portion;
					}
				}
			} else {
				// Host Linux
				BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp"));
				String line;
				while ((line = br.readLine()) != null) {
					String[] splitted = line.split(" +");
					if (splitted != null && splitted.length >= 4 && ip.equals(splitted[0])) {
						if (splitted[3].matches("..:..:..:..:..:..")) {
							macAddr = splitted[3].replace(":", "-");
						}
					}
				}
				br.close();
			}
		} catch (IOException ex) {
			System.err.println(ex.getMessage());
			macAddr = null;
		}

		return macAddr;
	}
}
O

Dei uma googlada e achei esta biblioteca:

http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/

Nunca usei…

E

De qualquer forma, se seu servidor suportar “automatic allocation”, então os IPs não vão ficar mudando tanto assim. Mas como você disse, se puder consultar a tabela de ARP, é uma boa alternativa.

striker07

Eu também achei, mas ela usa JNI por baixo do pano… e já tive tanto problema no projeto que estou mexendo por causa de JNI/JNA e Sistemas 64 bits, que desanimei de mexer…

striker07

Quando vai implantar o sistema, eu prefiro não contar com a sorte :slight_smile:

J
striker07:
Depois de ralar um pouco e perder mais um pouco dos meus cabelos ainda sobreviventes, criei uma classe que faz a busca da tabela ARP do próprio SO. Se alguém tiver algum palpite para melhorá-la, fique à vontade:
package net.rafaeltoledo.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;

public abstract class NetworkUtils {

	public static String getMacAddress(String ip) {
		String macAddr = null;
		
		try {
			// Host Windows
			String osName = System.getProperty("os.name");
			if (osName.contains("Windows")) {
				Process child = Runtime.getRuntime().exec("arp -a");
				InputStream in = child.getInputStream();
				String output = "";
				int c;
				while ((c = in.read()) != -1) {
					output += (char) c;
				}
				in.close();
				
				String line = null;
				String[] splitted = output.split("\n");
				for (String portion : splitted) {
					if (line.contains(ip)) {
						line = portion;
					}
				}
				
				splitted = line.split(" +");
				for (String portion : splitted) {
					if (portion.matches("..-..-..-..-..-..")) {
						macAddr = portion;
					}
				}
			} else {
				// Host Linux
				BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp"));
				String line;
				while ((line = br.readLine()) != null) {
					String[] splitted = line.split(" +");
					if (splitted != null && splitted.length >= 4 && ip.equals(splitted[0])) {
						if (splitted[3].matches("..:..:..:..:..:..")) {
							macAddr = splitted[3].replace(":", "-");
						}
					}
				}
				br.close();
			}
		} catch (IOException ex) {
			System.err.println(ex.getMessage());
			macAddr = null;
		}

		return macAddr;
	}
}

você está usando um programa externo para fazer isso, mas resolve o problema.

Criado 24 de fevereiro de 2012
Ultima resposta 27 de fev. de 2012
Respostas 8
Participantes 4