Skip to content

Commit c342c9f

Browse files
Added improvement for Android 10 devices where /proc/net was restricted (stealthcopter#66)
This uses `ip sleigh show` to list ip/mac pairs
1 parent 7cb2a5a commit c342c9f

File tree

2 files changed

+56
-24
lines changed

2 files changed

+56
-24
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ buildscript {
66
jcenter()
77
}
88
dependencies {
9-
classpath 'com.android.tools.build:gradle:3.5.1'
9+
classpath 'com.android.tools.build:gradle:3.5.3'
1010
// NOTE: Do not place your application dependencies here; they belong
1111
// in the individual module build.gradle files
1212
}

library/src/main/java/com/stealthcopter/networktools/ARPInfo.java

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import java.io.BufferedReader;
44
import java.io.FileReader;
55
import java.io.IOException;
6+
import java.io.InputStreamReader;
67
import java.util.ArrayList;
78
import java.util.HashMap;
89

10+
911
/**
1012
* Created by mat on 09/12/15.
1113
*
@@ -15,6 +17,9 @@
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
*/
1924
public 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

Comments
 (0)