33import java .io .BufferedReader ;
44import java .io .FileReader ;
55import java .io .IOException ;
6+ import java .io .InputStreamReader ;
67import java .util .ArrayList ;
78import java .util .HashMap ;
89
10+
911/**
1012 * Created by mat on 09/12/15.
1113 *
1517 * IP address HW type Flags HW address Mask Device
1618 * 192.168.18.11 0x1 0x2 00:04:20:06:55:1a * eth0
1719 * 192.168.18.36 0x1 0x2 00:22:43:ab:2a:5b * eth0
20+ *
21+ * Also looks at the output from `ip sleigh show` command
22+ *
1823 */
1924public class ARPInfo {
2025
@@ -24,8 +29,7 @@ private ARPInfo() {
2429
2530
2631 /**
27- * Try to extract a hardware MAC address from a given IP address using the
28- * ARP cache (/proc/net/arp).
32+ * Try to extract a hardware MAC address from a given IP address
2933 *
3034 * @param ip - IP address to search for
3135 * @return the MAC from the ARP cache or null in format "01:23:45:67:89:ab"
@@ -35,24 +39,13 @@ public static String getMACFromIPAddress(String ip) {
3539 return null ;
3640 }
3741
38- for (String line : getLinesInARPCache ()) {
39- String [] splitted = line .split (" +" );
40- if (splitted .length >= 4 && ip .equals (splitted [0 ])) {
41- String mac = splitted [3 ];
42- if (mac .matches ("..:..:..:..:..:.." )) {
43- return mac ;
44- } else {
45- return null ;
46- }
47- }
48- }
49- return null ;
42+ HashMap <String , String > cache = getAllIPAndMACAddressesInARPCache ();
43+ return cache .get (ip );
5044 }
5145
5246
5347 /**
54- * Try to extract a IP address from the given MAC address using the
55- * ARP cache (/proc/net/arp).
48+ * Try to extract a IP address from the given MAC address
5649 *
5750 * @param macAddress in format "01:23:45:67:89:ab" to search for
5851 * @return the IP address found or null in format "192.168.0.1"
@@ -66,15 +59,16 @@ public static String getIPAddressFromMAC(String macAddress) {
6659 throw new IllegalArgumentException ("Invalid MAC Address" );
6760 }
6861
69- for ( String line : getLinesInARPCache ()) {
70- String [] splitted = line . split ( " +" );
71- if (splitted . length >= 4 && macAddress . equals ( splitted [ 3 ] )) {
72- return splitted [ 0 ] ;
62+ HashMap < String , String > cache = getAllIPAndMACAddressesInARPCache ();
63+ for ( String ip : cache . keySet ()) {
64+ if (cache . get ( ip ). equalsIgnoreCase ( macAddress )) {
65+ return ip ;
7366 }
7467 }
7568 return null ;
7669 }
7770
71+
7872 /**
7973 * Returns all the ip addresses currently in the ARP cache (/proc/net/arp).
8074 *
@@ -95,19 +89,24 @@ public static ArrayList<String> getAllMACAddressesInARPCache() {
9589
9690
9791 /**
98- * Returns all the IP/MAC address pairs currently in the ARP cache (/proc/net/arp).
92+ * Returns all the IP/MAC address pairs currently in the following places
93+ *
94+ * 1. ARP cache (/proc/net/arp).
95+ * 2. `ip neigh show` command
9996 *
10097 * @return list of IP/MAC address pairs found
10198 */
10299 public static HashMap <String , String > getAllIPAndMACAddressesInARPCache () {
103- HashMap <String , String > macList = new HashMap <> ();
100+ HashMap <String , String > macList = getAllIPandMACAddressesFromIPSleigh ();
104101 for (String line : getLinesInARPCache ()) {
105102 String [] splitted = line .split (" +" );
106103 if (splitted .length >= 4 ) {
107104 // Ignore values with invalid MAC addresses
108105 if (splitted [3 ].matches ("..:..:..:..:..:.." )
109106 && !splitted [3 ].equals ("00:00:00:00:00:00" )) {
110- macList .put (splitted [0 ], splitted [3 ]);
107+ if (!macList .containsKey (splitted [0 ])) {
108+ macList .put (splitted [0 ], splitted [3 ]);
109+ }
111110 }
112111 }
113112 }
@@ -142,4 +141,37 @@ private static ArrayList<String> getLinesInARPCache() {
142141 return lines ;
143142 }
144143
144+
145+ /**
146+ * Get the IP / MAC address pairs from `ip sleigh show` command
147+ *
148+ * @return hashmap of ips and mac addresses
149+ */
150+ private static HashMap <String , String > getAllIPandMACAddressesFromIPSleigh () {
151+ HashMap <String , String > macList = new HashMap <>();
152+
153+ try {
154+ Runtime runtime = Runtime .getRuntime ();
155+ Process proc = runtime .exec ("ip neigh show" );
156+ proc .waitFor ();
157+ int exit = proc .exitValue ();
158+
159+ InputStreamReader reader = new InputStreamReader (proc .getInputStream ());
160+ BufferedReader buffer = new BufferedReader (reader );
161+ String line ;
162+ while ((line = buffer .readLine ()) != null ) {
163+ String [] splits = line .split (" " );
164+ if (splits .length < 4 ) {
165+ continue ;
166+ }
167+ macList .put (splits [0 ], splits [4 ]);
168+ }
169+
170+ } catch (IOException | InterruptedException e ) {
171+ e .printStackTrace ();
172+ }
173+
174+ return macList ;
175+ }
176+
145177}
0 commit comments