Как я могу получить адрес mac клиента с помощью java? [dубликат]

Посмотрите на Yahoo! советы: https://developer.yahoo.com/performance/rules.html#expires.

Есть также советы от Google: https://developer.yahoo.com/performance/rules.html#expires

12
задан Brian Agnew 6 August 2009 в 14:54
поделиться

8 ответов

Java не предоставляет прямого способа запроса MAC-адреса хоста в вашей сети, поскольку это абстрагируется библиотеками сокетов Java.

В некотором смысле это имеет смысл, поскольку MAC-адрес хост фактически говорит очень мало. Нет такого понятия, как «MAC-адрес хоста».

  • Многие хосты будут иметь несколько сетевых адаптеров, все с отдельным MAC-адресом, с которым они могут подключиться к сети. На компьютере, на котором я сейчас работаю, есть проводной адаптер ethernet, адаптер WiFi и адаптер Firewire, и все они имеют свой собственный MAC-адрес. Это означает, что для узла нет окончательного MAC-адреса.
  • Если хост находится в другой подсети, ARP фактически даст вам MAC-адрес для последнего маршрутизатора, через который прошел ваш пакет, вместо MAC адрес хоста, который вы сканируете.

Сопоставьте обе эти проблемы вместе, а это означает, что на одном хосте может быть много разных MAC-адресов (если у него более одного сетевого адаптера) и один из MAC-адресов может представлять множество разных хостов (если трафик проходит через маршрутизатор).

Предполагая, что вы знаете все это, и вам все равно нужно получить MAC-адрес хоста, единственный способ сделать это в Java :

  • Родной для клиента, который запускает вашу программу: вы можете запустить инструмент командной строки ARP и проанализировать его вывод. Вы можете использовать какой-то вызов JNI. Я не слишком хорошо знаком с JNI, поэтому я не могу с этим поделать. Напишите отдельное маленькое собственное приложение, к которому вы можете получить доступ через Java через Telnet или какой-то такой протокол, и который будет запускать для вас команду ARP.
  • Родной для хоста, который вы хотите сканировать: вы можете использовать SNMP, как предлагают некоторые из других ответов на этот поток. Я откладываю ответы на эти ответы, чтобы сделать эту работу для вас. SNMP - отличный протокол, но имейте в виду, что OID SNMP могут быть зависимыми от платформы и зависят от поставщиков. OID, работающие в Windows, не всегда работают для Linux и наоборот. Если вы знаете, что ваш хост запускает Windows, вы можете использовать WMI . Класс Win32_NetworkAdapter содержит требуемую информацию, но имейте в виду, что это возвращает все сетевых адаптеров хоста, даже те, что Windows делает. Кроме того, он требует учетных данных администратора для хоста, который вы просматриваете. Google расскажет вам, как подключиться к WMI с Java. Если вы знаете, что ваш хост запускает OS X, вы можете запустить SSH в машину и проанализировать вывод команды system_profile . Для Linux, вероятно, существует инструмент, похожий на файл system_profile OS X .
10
ответ дан jqno 16 August 2018 в 05:38
поделиться
  • 1
    Обратите внимание: SNMP OID для кэша ARP не зависит от производителя. Это не часть MIB предприятия. – Brian Agnew 1 October 2009 в 17:27

Вдохновленный greenspand ответом, я придумал этот код, который будет запрашивать MAC-адрес с помощью команды IP и CMD с использованием указанного IP.

Обратите внимание, что этот код работает на Windows, и я считаю, что он может работать Linux тоже с небольшими изменениями.

  public static String getARPTable (String ip) throws IOException {String systemInput = "";  // обновить системную таблицу перед запросом Runtime.getRuntime (). exec ("arp -a");  Сканер s = новый сканер (Runtime.getRuntime (). Exec ("arp -a" + ip) .getInputStream ()). UseDelimiter ("\\ A");  systemInput = s.next ();  String mac = "";  Pattern pattern = Pattern.compile ("\\ s {0,} ([0-9A-Fa-f] {2} [: -]) {5} ([0-9A-Fa-f] {2})  «);  Matcher matcher = pattern.matcher (systemInput);  if (matcher.find ()) {mac = mac + matcher.group (). replaceAll ("\\ s", "");  } else {System.out.println («Не найдена строка»);  } return mac;  } public static void main (String [] args) throws IOException {System.out.println (getARPTable ("192.168.1.23"));  // печатает 74-d4-35-76-11-ef}  
0
ответ дан Abdelsalam A. Shahlol 16 August 2018 в 05:38
поделиться

Это может быть не разрешимо в контексте Java (потому что оно независимо от платформы), но вы также должны учитывать, сможете ли вы получать MAC-адреса через системную службу. Вероятно, есть ситуации, когда вы не можете надежно найти MAC-адрес через ARP, это зависит от того, зачем вам нужен MAC-адрес.

2
ответ дан benc 16 August 2018 в 05:38
поделиться
  • 1
    В лучшем случае таблицы ARP имеют самую последнюю связь IP и MAC, о которой слышала эта машина . Если ваш удаленный компьютер изменил IP-адрес, но еще не имел причины отправлять какой-либо сетевой трафик на этот аппарат (или широковещательный), тогда таблицы ARP на этом компьютере устарели и пока еще не знают об этом. – Jesse Chisholm 29 January 2015 в 21:54

Кэш arp предоставляется в качестве стандарта в наборе доступных данных SNMP. Вы можете использовать SNMP4J для записи тривиального агента для запроса этих данных.

, например. из командной строки SNMP toolset

  snmpwalk $ {hostname} 1.3.6.1.2.1.4.22.1.2  

(эта огромная строка с разделителями периодов является OID или идентификатор кеша ARP в терминах SNMP, который будет работать для всех реализаций SNMP)

4
ответ дан Brian Agnew 16 August 2018 в 05:38
поделиться
3
ответ дан greenspand 16 August 2018 в 05:38
поделиться

Как говорили другие, ARP - это путь. Ниже приведена реализация второго предложения jqnos на основе этого примера в GitSpot .

Требуются две библиотеки:

  1. системная библиотека для захвата сетевого трафика : Linux-based: libpcap из www.tcpdump.org Windows: winpcap из www.winpcap.org
  2. japcap java-библиотека, доступная из сайт jpcap sourceforge , который обеспечивает высокоуровневый интерфейс к первой библиотеке через открытый класс JNI GetMACAddress {/ ** * * @param ip address, содержащий IP * @return MAC-Address как форматированный String * @throws IOException * @throws IllegalArgumentException * / public static String getMACAdressByIp (Inet4Address ip) throws IOException, IllegalArgumentException {byte [] mac = GetMACAddress.getMACAddressByARP (ip); StringBuilder formattedMac = new StringBuilder (); boolean first = true; for (byte b: mac) {if (first) {first = false; } else {formattedMac.append (":"); } Строка hexStr = Integer.toHexString (b & amp; 0xff); if (hexStr.length () == 1) {formattedMac.append ("0"); } formattedMac.append (hexStr); } return formattedMac.toString (); } private static byte [] getMACAddressByARP (Inet4Address ip) throws IOException, IllegalArgumentException {NetworkInterface networkDevice = getNetworkDeviceByTargetIP (ip); JpcapCaptor captor = JpcapCaptor.openDevice (networkDevice, 2000, false, 3000); captor.setFilter ("arp", true); JpcapSender отправитель = captor.getJpcapSenderInstance (); InetAddress srcip = null; for (NetworkInterfaceAddress addr: networkDevice.addresses) if (addr.address instanceof Inet4Address) {srcip = addr.address; ломать; } byte [] broadcast = new byte [] {(byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255}; ARPPacket arp = new ARPPacket (); arp.hardtype = ARPPacket.HARDTYPE_ETHER; arp.prototype = ARPPacket.PROTOTYPE_IP; arp.operation = ARPPacket.ARP_REQUEST; arp.hlen = 6; arp.plen = 4; arp.sender_hardaddr = networkDevice.mac_address; arp.sender_protoaddr = srcip.getAddress (); arp.target_hardaddr = трансляция; arp.target_protoaddr = ip.getAddress (); EthernetPacket ether = новый EthernetPacket (); ether.frametype = EthernetPacket.ETHERTYPE_ARP; ether.src_mac = networkDevice.mac_address; ether.dst_mac = широковещательная передача; arp.datalink = эфир; sender.sendPacket (АРП); while (true) {ARPPacket p = (ARPPacket) captor.getPacket (); if (p == null) {throw new IllegalArgumentException (ip + "не является локальным адресом"); } if (Arrays.equals (p.target_protoaddr, srcip.getAddress ())) {return p.sender_hardaddr; }}} private static NetworkInterface getNetworkDeviceByTargetIP (Inet4Address ip) бросает IllegalArgumentException {NetworkInterface networkDevice = null; NetworkInterface [] devices = JpcapCaptor.getDeviceList (); loop: for (NetworkInterface device: devices) {для (NetworkInterfaceAddress addr: device.addresses) {if (! (addr.address instanceof Inet4Address)) {продолжить; } byte [] bip = ip.getAddress (); byte [] subnet = addr.subnet.getAddress (); byte [] bif = addr.address.getAddress (); for (int i = 0; i & lt; 4; i ++) {bip [i] = (байт) (bip [i] & amp; subnet [i]); bif [i] = (байт) (bif [i] & amp; subnet [i]); } if (Arrays.equals (bip, bif)) {networkDevice = device; разрыв петли; }}} if (networkDevice == null) {throw new IllegalArgumentException (ip + "не является локальным адресом"); } return networkDevice; }}
2
ответ дан Marco Borchert 16 August 2018 в 05:38
поделиться

Вы можете получить свой собственный MAC-адрес через:

  Enumeration & lt; NetworkInterface & gt;  it = NetworkInterface.getNetworkInterfaces ();  while (it.hasMoreElements ()) {byte [] macAddress = it.nextElement (). getHardwareAddress ();  }  

Определенно, вы не можете получить MAC-адрес другого хоста через vanilla java. Для этого вам нужно использовать выполнение процесса или собственную библиотеку.

Если вы управляете другими машинами, вы можете позволить им запросить свой собственный MAC-адрес и отправить его обратно по каналу TCP / IP, но Я предполагаю, что это не то, что вы хотите. Для получения дополнительной информации см. Ответ jqno.

5
ответ дан Reinier Zwitserloot 16 August 2018 в 05:38
поделиться
  • 1
    Возникает вопрос: «получить МАС-идентификатор хоста в моей сети», т. Е. Не свой. Я боюсь, что я должен уменьшить этот ответ. – Kees de Kooter 17 November 2014 в 09:34

ARP способ для сопоставления IP-адресов с MAC-адресами. Вот как это делает IP-стек.

Я не уверен, что есть переносимый способ получить эту информацию, поскольку она обычно важна только для разработчиков ядра и системных администраторов.

Из большого количества веб-поиска это похоже, что можно получить таблицу ARP маршрутизатора с помощью SNMP, но я не нашел много конкретной информации о том, как это сделать. Однако я нашел бесплатную библиотеку Java для SNMP здесь . Некоторые из них могут оказаться полезными.

3
ответ дан T.E.D. 16 August 2018 в 05:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: