diff --git a/.circleci/config.yml b/.circleci/config.yml index c259ddc..83a5adc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: circleci/android:api-25-alpha + - image: circleci/android:api-29 environment: GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"' steps: @@ -15,7 +15,7 @@ jobs: name: Copy Environment Vars command: scripts/cp-env-to-properties.sh - # Decrypt any secret files / keys + # Decrypt any secret files / keys - run: name: Decrypt secret files command: scripts/decrypt-secrets.sh diff --git a/app/build.gradle b/app/build.gradle index 11a38af..feb4408 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,8 +32,11 @@ android { applicationId "com.stealthcotper.networktools" minSdkVersion minSdkVer targetSdkVersion targetSdkVer - versionName appVersionName - versionCode appVersionCode + + // When updating these, remember to update the vars in the root build.gradle + versionName "0.4.5.3" + versionCode 21 + archivesBaseName = "AndroidNetworkTools" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dc42b68..bbbe649 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ diff --git a/app/src/main/java/com/stealthcotper/networktools/ANTApplication.java b/app/src/main/java/com/stealthcotper/networktools/ANTApplication.java index 1e3c649..0dc91c5 100644 --- a/app/src/main/java/com/stealthcotper/networktools/ANTApplication.java +++ b/app/src/main/java/com/stealthcotper/networktools/ANTApplication.java @@ -1,7 +1,6 @@ package com.stealthcotper.networktools; import android.app.Application; -import android.os.StrictMode; public class ANTApplication extends Application { @@ -16,17 +15,17 @@ private void initStrictMode() { // Let's be super strict so that we can discover bugs during testing - StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() - .detectAll() - .penaltyLog() - .penaltyDeath() - .build()); - - StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() - .detectAll() - .penaltyLog() - .penaltyDeath() - .build()); +// StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() +// .detectAll() +// .penaltyLog() +//// .penaltyDeath() +// .build()); +// +// StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() +// .detectAll() +// .penaltyLog() +//// .penaltyDeath() +// .build()); } } diff --git a/app/src/main/java/com/stealthcotper/networktools/MainActivity.java b/app/src/main/java/com/stealthcotper/networktools/MainActivity.java index 234edb8..b3c33d1 100644 --- a/app/src/main/java/com/stealthcotper/networktools/MainActivity.java +++ b/app/src/main/java/com/stealthcotper/networktools/MainActivity.java @@ -10,7 +10,9 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.widget.Button; import android.widget.EditText; +import android.widget.ScrollView; import android.widget.TextView; import com.stealthcopter.networktools.ARPInfo; @@ -25,12 +27,18 @@ import java.io.IOException; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private TextView resultText; private EditText editIpAddress; + private ScrollView scrollView; + private Button pingButton; + private Button wolButton; + private Button portScanButton; + private Button subnetDevicesButton; @Override protected void onCreate(Bundle savedInstanceState) { @@ -41,6 +49,11 @@ protected void onCreate(Bundle savedInstanceState) { resultText = findViewById(R.id.resultText); editIpAddress = findViewById(R.id.editIpAddress); + scrollView = findViewById(R.id.scrollView1); + pingButton = findViewById(R.id.pingButton); + wolButton = findViewById(R.id.wolButton); + portScanButton = findViewById(R.id.portScanButton); + subnetDevicesButton = findViewById(R.id.subnetDevicesButton); InetAddress ipAddress = IPTools.getLocalIPv4Address(); if (ipAddress != null){ @@ -118,6 +131,23 @@ private void appendResultsText(final String text) { @Override public void run() { resultText.append(text + "\n"); + scrollView.post(new Runnable() { + @Override + public void run() { + scrollView.fullScroll(View.FOCUS_DOWN); + } + }); + } + }); + } + + private void setEnabled(final View view, final boolean enabled) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (view != null) { + view.setEnabled(enabled); + } } }); } @@ -130,8 +160,19 @@ private void doPing() throws Exception { return; } + setEnabled(pingButton, false); + // Perform a single synchronous ping - PingResult pingResult = Ping.onAddress(ipAddress).setTimeOutMillis(1000).doPing(); + PingResult pingResult = null; + try { + pingResult = Ping.onAddress(ipAddress).setTimeOutMillis(1000).doPing(); + } catch (UnknownHostException e) { + e.printStackTrace(); + appendResultsText(e.getMessage()); + setEnabled(pingButton, true); + return; + } + appendResultsText("Pinging Address: " + pingResult.getAddress().getHostAddress()); appendResultsText("HostName: " + pingResult.getAddress().getHostName()); @@ -142,7 +183,11 @@ private void doPing() throws Exception { Ping.onAddress(ipAddress).setTimeOutMillis(1000).setTimes(5).doPing(new Ping.PingListener() { @Override public void onResult(PingResult pingResult) { - appendResultsText(String.format("%.2f ms", pingResult.getTimeTaken())); + if (pingResult.isReachable) { + appendResultsText(String.format("%.2f ms", pingResult.getTimeTaken())); + } else { + appendResultsText(getString(R.string.timeout)); + } } @Override @@ -151,11 +196,13 @@ public void onFinished(PingStats pingStats) { pingStats.getNoPings(), pingStats.getPacketsLost())); appendResultsText(String.format("Min/Avg/Max Time: %.2f/%.2f/%.2f ms", pingStats.getMinTimeTaken(), pingStats.getAverageTimeTaken(), pingStats.getMaxTimeTaken())); + setEnabled(pingButton, true); } @Override public void onError(Exception e) { // TODO: STUB METHOD + setEnabled(pingButton, true); } }); @@ -169,6 +216,8 @@ private void doWakeOnLan() throws IllegalArgumentException { return; } + setEnabled(wolButton, false); + appendResultsText("IP address: " + ipAddress); // Get mac address from IP (using arp cache) @@ -176,6 +225,7 @@ private void doWakeOnLan() throws IllegalArgumentException { if (macAddress == null) { appendResultsText("Could not fromIPAddress MAC address, cannot send WOL packet without it."); + setEnabled(wolButton, true); return; } @@ -187,7 +237,10 @@ private void doWakeOnLan() throws IllegalArgumentException { WakeOnLan.sendWakeOnLan(ipAddress, macAddress); appendResultsText("WOL Packet sent"); } catch (IOException e) { + appendResultsText(e.getMessage()); e.printStackTrace(); + } finally { + setEnabled(wolButton, true); } } @@ -196,9 +249,12 @@ private void doPortScan() throws Exception { if (TextUtils.isEmpty(ipAddress)) { appendResultsText("Invalid Ip Address"); + setEnabled(portScanButton, true); return; } + setEnabled(portScanButton, false); + // Perform synchronous port scan appendResultsText("PortScanning IP: " + ipAddress); ArrayList openPorts = PortScan.onAddress(ipAddress).setPort(21).setMethodTCP().doScan(); @@ -216,6 +272,7 @@ public void onResult(int portNo, boolean open) { public void onFinished(ArrayList openPorts) { appendResultsText("Open Ports: " + openPorts.size()); appendResultsText("Time Taken: " + ((System.currentTimeMillis() - startTimeMillis)/1000.0f)); + setEnabled(portScanButton, true); } }); @@ -226,6 +283,8 @@ public void onFinished(ArrayList openPorts) { private void findSubnetDevices() { + setEnabled(subnetDevicesButton, false); + final long startTimeMillis = System.currentTimeMillis(); SubnetDevices subnetDevices = SubnetDevices.fromLocalAddress().findDevices(new SubnetDevices.OnSubnetDeviceFound() { @@ -239,6 +298,7 @@ public void onFinished(ArrayList devicesFound) { float timeTaken = (System.currentTimeMillis() - startTimeMillis)/1000.0f; appendResultsText("Devices Found: " + devicesFound.size()); appendResultsText("Finished "+timeTaken+" s"); + setEnabled(subnetDevicesButton, true); } }); diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index b0f2b76..ff6675e 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -84,6 +84,7 @@ Port Scan Github https://github.com/stealthcopter/AndroidNetworkTools - Subnet Devices + Subnet Devices + ** Timeout ** diff --git a/build.gradle b/build.gradle index 32148d8..cc09958 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.android.tools.build:gradle:3.5.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -24,12 +24,15 @@ task clean(type: Delete) { } subprojects { - ext.compileSdkVer = 27 - ext.buildToolsVer = "27.0.3" + ext.compileSdkVer = 29 + ext.buildToolsVer = "29.0.1" ext.minSdkVer = 14 - ext.targetSdkVer = 27 + ext.targetSdkVer = 29 ext.supportLibVer = "27.1.1" - ext.appVersionName = "0.4.3" - ext.appVersionCode = 17 + // When updating these, remember to update the vars in app/build.gradle (for FDroid comptability) + // Remember to update readme, and lets keep these version numbers in line with the github releases + ext.appVersionName = "0.4.5.3" + ext.appVersionCode = 21 + } diff --git a/fastlane/metadata/android/en-US/changelogs/19.txt b/fastlane/metadata/android/en-US/changelogs/19.txt new file mode 100644 index 0000000..78a039b --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/19.txt @@ -0,0 +1 @@ +* Added fastlane structure for F-Droid inclusion diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt new file mode 100644 index 0000000..08ea232 --- /dev/null +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -0,0 +1,11 @@ +This is a sample application from the open source project Android Network Tools. If you are looking for a more complete network scanning tool, please see my other app Portdroid. + +It demonstrates the following features of the library: + +• Pinging +• Port Scanning +• Finding devices on your network +• Wake-on-lan + +The project is hosted on github. Bug reports, feature requests and contributions are all welcome: +https://github.com/stealthcopter/AndroidNetworkTools diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png new file mode 100644 index 0000000..1ed5e98 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/icon.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png new file mode 100644 index 0000000..8e847ca Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png new file mode 100644 index 0000000..8fc16f6 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt new file mode 100644 index 0000000..30ee507 --- /dev/null +++ b/fastlane/metadata/android/en-US/short_description.txt @@ -0,0 +1 @@ +This is the sample application from Android Network Tools open source library diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt new file mode 100644 index 0000000..b56ceb4 --- /dev/null +++ b/fastlane/metadata/android/en-US/title.txt @@ -0,0 +1 @@ +Network Tools Library diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b5dcd6b..1433f15 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue May 01 19:31:51 BST 2018 +#Sun Nov 03 10:39:47 GMT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/library/src/main/java/com/stealthcopter/networktools/ARPInfo.java b/library/src/main/java/com/stealthcopter/networktools/ARPInfo.java index 2c07a99..e9a2ca6 100644 --- a/library/src/main/java/com/stealthcopter/networktools/ARPInfo.java +++ b/library/src/main/java/com/stealthcopter/networktools/ARPInfo.java @@ -1,20 +1,24 @@ package com.stealthcopter.networktools; import java.io.BufferedReader; +import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; + /** - * Created by mat on 09/12/15. - * * Looks at the file at /proc/net/arp to fromIPAddress ip/mac addresses from the cache * We assume that the file has this structure: * * IP address HW type Flags HW address Mask Device * 192.168.18.11 0x1 0x2 00:04:20:06:55:1a * eth0 * 192.168.18.36 0x1 0x2 00:22:43:ab:2a:5b * eth0 + * + * Also looks at the output from `ip sleigh show` command + * */ public class ARPInfo { @@ -24,8 +28,7 @@ private ARPInfo() { /** - * Try to extract a hardware MAC address from a given IP address using the - * ARP cache (/proc/net/arp). + * Try to extract a hardware MAC address from a given IP address * * @param ip - IP address to search for * @return the MAC from the ARP cache or null in format "01:23:45:67:89:ab" @@ -35,24 +38,13 @@ public static String getMACFromIPAddress(String ip) { return null; } - for (String line : getLinesInARPCache()) { - String[] splitted = line.split(" +"); - if (splitted.length >= 4 && ip.equals(splitted[0])) { - String mac = splitted[3]; - if (mac.matches("..:..:..:..:..:..")) { - return mac; - } else { - return null; - } - } - } - return null; + HashMap cache = getAllIPAndMACAddressesInARPCache(); + return cache.get(ip); } /** - * Try to extract a IP address from the given MAC address using the - * ARP cache (/proc/net/arp). + * Try to extract a IP address from the given MAC address * * @param macAddress in format "01:23:45:67:89:ab" to search for * @return the IP address found or null in format "192.168.0.1" @@ -66,15 +58,16 @@ public static String getIPAddressFromMAC(String macAddress) { throw new IllegalArgumentException("Invalid MAC Address"); } - for (String line : getLinesInARPCache()) { - String[] splitted = line.split(" +"); - if (splitted.length >= 4 && macAddress.equals(splitted[3])) { - return splitted[0]; + HashMap cache = getAllIPAndMACAddressesInARPCache(); + for (String ip : cache.keySet()) { + if (cache.get(ip).equalsIgnoreCase(macAddress)) { + return ip; } } return null; } + /** * Returns all the ip addresses currently in the ARP cache (/proc/net/arp). * @@ -95,19 +88,24 @@ public static ArrayList getAllMACAddressesInARPCache() { /** - * Returns all the IP/MAC address pairs currently in the ARP cache (/proc/net/arp). + * Returns all the IP/MAC address pairs currently in the following places + * + * 1. ARP cache (/proc/net/arp). + * 2. `ip neigh show` command * * @return list of IP/MAC address pairs found */ public static HashMap getAllIPAndMACAddressesInARPCache() { - HashMap macList = new HashMap<>(); + HashMap macList = getAllIPandMACAddressesFromIPSleigh(); for (String line : getLinesInARPCache()) { String[] splitted = line.split(" +"); if (splitted.length >= 4) { // Ignore values with invalid MAC addresses if (splitted[3].matches("..:..:..:..:..:..") && !splitted[3].equals("00:00:00:00:00:00")) { - macList.put(splitted[0], splitted[3]); + if (!macList.containsKey(splitted[0])) { + macList.put(splitted[0], splitted[3]); + } } } } @@ -121,6 +119,12 @@ public static HashMap getAllIPAndMACAddressesInARPCache() { */ private static ArrayList getLinesInARPCache() { ArrayList lines = new ArrayList<>(); + + // If we cant read the file just return empty list + if (!new File("/proc/net/arp").canRead()){ + return lines; + } + BufferedReader br = null; try { br = new BufferedReader(new FileReader("/proc/net/arp")); @@ -142,4 +146,37 @@ private static ArrayList getLinesInARPCache() { return lines; } + + /** + * Get the IP / MAC address pairs from `ip sleigh show` command + * + * @return hashmap of ips and mac addresses + */ + public static HashMap getAllIPandMACAddressesFromIPSleigh() { + HashMap macList = new HashMap<>(); + + try { + Runtime runtime = Runtime.getRuntime(); + Process proc = runtime.exec("ip neigh show"); + proc.waitFor(); + int exit = proc.exitValue(); + + InputStreamReader reader = new InputStreamReader(proc.getInputStream()); + BufferedReader buffer = new BufferedReader(reader); + String line; + while ((line = buffer.readLine()) != null) { + String[] splits = line.split(" "); + if (splits.length < 4) { + continue; + } + macList.put(splits[0], splits[4]); + } + + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + + return macList; + } + } diff --git a/library/src/main/java/com/stealthcopter/networktools/IPTools.java b/library/src/main/java/com/stealthcopter/networktools/IPTools.java index 57c7149..26695ec 100644 --- a/library/src/main/java/com/stealthcopter/networktools/IPTools.java +++ b/library/src/main/java/com/stealthcopter/networktools/IPTools.java @@ -8,9 +8,6 @@ import java.util.Enumeration; import java.util.regex.Pattern; -/** - * Created by mat on 14/12/15. - */ public class IPTools { /** diff --git a/library/src/main/java/com/stealthcopter/networktools/Ping.java b/library/src/main/java/com/stealthcopter/networktools/Ping.java index 304c54e..6c16c2e 100644 --- a/library/src/main/java/com/stealthcopter/networktools/Ping.java +++ b/library/src/main/java/com/stealthcopter/networktools/Ping.java @@ -8,9 +8,6 @@ import java.net.InetAddress; import java.net.UnknownHostException; -/** - * Created by mat on 09/12/15. - */ public class Ping { // Only try ping using the java method diff --git a/library/src/main/java/com/stealthcopter/networktools/PortScan.java b/library/src/main/java/com/stealthcopter/networktools/PortScan.java index ef81675..73d6be2 100644 --- a/library/src/main/java/com/stealthcopter/networktools/PortScan.java +++ b/library/src/main/java/com/stealthcopter/networktools/PortScan.java @@ -11,9 +11,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -/** - * Created by mat on 14/12/15. - */ public class PortScan { private static final int TIMEOUT_LOCALHOST = 25; diff --git a/library/src/main/java/com/stealthcopter/networktools/SubnetDevices.java b/library/src/main/java/com/stealthcopter/networktools/SubnetDevices.java index f3de717..471d0bb 100644 --- a/library/src/main/java/com/stealthcopter/networktools/SubnetDevices.java +++ b/library/src/main/java/com/stealthcopter/networktools/SubnetDevices.java @@ -12,9 +12,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -/** - * Created by mat on 03/11/17. - */ public class SubnetDevices { private int noThreads = 100; @@ -23,6 +20,8 @@ public class SubnetDevices { private OnSubnetDeviceFound listener; private int timeOutMillis = 2500; private boolean cancelled = false; + + private boolean disableProcNetMethod = false; private HashMap ipMacHashMap = null; // This class is not to be instantiated @@ -71,15 +70,20 @@ public static SubnetDevices fromIPAddress(final String ipAddress) { throw new IllegalArgumentException("Invalid IP Address"); } + String segment = ipAddress.substring(0, ipAddress.lastIndexOf(".") + 1); + SubnetDevices subnetDevice = new SubnetDevices(); subnetDevice.addresses = new ArrayList<>(); // Get addresses from ARP Info first as they are likely to be reachable - subnetDevice.addresses.addAll(ARPInfo.getAllIPAddressesInARPCache()); + for(String ip : ARPInfo.getAllIPAddressesInARPCache()) { + if (ip.startsWith(segment)) { + subnetDevice.addresses.add(ip); + } + } // Add all missing addresses in subnet - String segment = ipAddress.substring(0, ipAddress.lastIndexOf(".") + 1); for (int j = 0; j < 255; j++) { if (!subnetDevice.addresses.contains(segment + j)) { subnetDevice.addresses.add(segment + j); @@ -137,6 +141,15 @@ public SubnetDevices setTimeOutMillis(int timeOutMillis) throws IllegalArgumentE return this; } + /** + * + * @param disable if set to true we will not attempt to read from /proc/net/arp + * directly. This avoids any Android 10 permissions logs appearing. + */ + public void setDisableProcNetMethod(boolean disable) { + this.disableProcNetMethod = disableProcNetMethod; + } + /** * Cancel a running scan */ @@ -163,7 +176,7 @@ public void run() { // Load mac addresses into cache var (to avoid hammering the /proc/net/arp file when // lots of devices are found on the network. - ipMacHashMap = ARPInfo.getAllIPAndMACAddressesInARPCache(); + ipMacHashMap = disableProcNetMethod ? ARPInfo.getAllIPandMACAddressesFromIPSleigh() : ARPInfo.getAllIPAndMACAddressesInARPCache(); ExecutorService executor = Executors.newFixedThreadPool(noThreads); @@ -185,7 +198,7 @@ public void run() { // Loop over devices found and add in the MAC addresses if missing. // We do this after scanning for all devices as /proc/net/arp may add info // because of the scan. - ipMacHashMap = ARPInfo.getAllIPAndMACAddressesInARPCache(); + ipMacHashMap = disableProcNetMethod ? ARPInfo.getAllIPandMACAddressesFromIPSleigh() : ARPInfo.getAllIPAndMACAddressesInARPCache(); for (Device device : devicesFound) { if (device.mac == null && ipMacHashMap.containsKey(device.ip)) { device.mac = ipMacHashMap.get(device.ip); diff --git a/library/src/main/java/com/stealthcopter/networktools/WakeOnLan.java b/library/src/main/java/com/stealthcopter/networktools/WakeOnLan.java index 53adb5f..92dc4d5 100644 --- a/library/src/main/java/com/stealthcopter/networktools/WakeOnLan.java +++ b/library/src/main/java/com/stealthcopter/networktools/WakeOnLan.java @@ -6,7 +6,6 @@ import java.net.InetAddress; /** - * Created by mat on 09/12/15. * * Tested this and it wakes my computer up :) * diff --git a/library/src/main/java/com/stealthcopter/networktools/ping/PingNative.java b/library/src/main/java/com/stealthcopter/networktools/ping/PingNative.java index decba72..c9163fd 100644 --- a/library/src/main/java/com/stealthcopter/networktools/ping/PingNative.java +++ b/library/src/main/java/com/stealthcopter/networktools/ping/PingNative.java @@ -7,9 +7,6 @@ import java.io.InputStreamReader; import java.net.InetAddress; -/** - * Created by mat on 09/12/15. - */ public class PingNative { // This class is not to be instantiated @@ -67,6 +64,7 @@ public static PingResult ping(InetAddress host, PingOptions pingOptions) throws break; } pingResult.error = pingError; + proc.destroy(); return pingResult; } diff --git a/library/src/main/java/com/stealthcopter/networktools/ping/PingResult.java b/library/src/main/java/com/stealthcopter/networktools/ping/PingResult.java index ba9cd1e..673e7a2 100644 --- a/library/src/main/java/com/stealthcopter/networktools/ping/PingResult.java +++ b/library/src/main/java/com/stealthcopter/networktools/ping/PingResult.java @@ -2,9 +2,6 @@ import java.net.InetAddress; -/** - * Created by mat on 09/12/15. - */ public class PingResult { public final InetAddress ia; public boolean isReachable; diff --git a/library/src/main/java/com/stealthcopter/networktools/ping/PingStats.java b/library/src/main/java/com/stealthcopter/networktools/ping/PingStats.java index c487390..e6d0978 100644 --- a/library/src/main/java/com/stealthcopter/networktools/ping/PingStats.java +++ b/library/src/main/java/com/stealthcopter/networktools/ping/PingStats.java @@ -2,9 +2,6 @@ import java.net.InetAddress; -/** - * Created by mat on 09/12/15. - */ public class PingStats { private final InetAddress ia; private final long noPings; diff --git a/library/src/main/java/com/stealthcopter/networktools/ping/PingTools.java b/library/src/main/java/com/stealthcopter/networktools/ping/PingTools.java index 68d79a2..98ccc78 100644 --- a/library/src/main/java/com/stealthcopter/networktools/ping/PingTools.java +++ b/library/src/main/java/com/stealthcopter/networktools/ping/PingTools.java @@ -3,9 +3,6 @@ import java.io.IOException; import java.net.InetAddress; -/** - * Created by mat on 09/12/15. - */ public class PingTools { // This class is not to be instantiated @@ -78,6 +75,9 @@ public static PingResult doJavaPing(InetAddress ia, PingOptions pingOptions) { } catch (IOException e) { pingResult.isReachable = false; pingResult.error = "IOException: " + e.getMessage(); + } catch (NullPointerException e) { + pingResult.isReachable = false; + pingResult.error = "NullPointerException: " + e.getMessage(); } return pingResult; } diff --git a/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanTCP.java b/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanTCP.java index 34050b8..f487c5c 100644 --- a/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanTCP.java +++ b/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanTCP.java @@ -5,9 +5,6 @@ import java.net.InetSocketAddress; import java.net.Socket; -/** - * Created by mat on 13/12/15. - */ public class PortScanTCP { // This class is not to be instantiated diff --git a/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanUDP.java b/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanUDP.java index fd58e56..1236832 100644 --- a/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanUDP.java +++ b/library/src/main/java/com/stealthcopter/networktools/portscanning/PortScanUDP.java @@ -5,9 +5,6 @@ import java.net.InetAddress; import java.net.SocketTimeoutException; -/** - * Created by mat on 13/12/15. - */ public class PortScanUDP { // This class is not to be instantiated diff --git a/library/src/test/java/com/stealthcopter/networktools/IPToolsTest.java b/library/src/test/java/com/stealthcopter/networktools/IPToolsTest.java index 438693c..5200065 100644 --- a/library/src/test/java/com/stealthcopter/networktools/IPToolsTest.java +++ b/library/src/test/java/com/stealthcopter/networktools/IPToolsTest.java @@ -1,5 +1,6 @@ package com.stealthcopter.networktools; +import static org.hamcrest.CoreMatchers.is; import org.junit.Ignore; import org.junit.Test; @@ -7,9 +8,7 @@ import java.net.UnknownHostException; import java.util.List; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * Created by matthew on 03/11/17. @@ -36,48 +35,25 @@ String[] getIPv6AddressesHexCompresed() { @Test public void testIsIPv4Address() { + assertIPv4Address(getIPv4Addresses(), true); + assertIPv4Address(getIPv6Addresses(), false); + assertIPv4Address(getInvalidIpAddresses(), false); + } - for (String address : getIPv4Addresses()) { - assertTrue(IPTools.isIPv4Address(address)); - } - for (String address : getIPv6Addresses()) { - assertFalse(IPTools.isIPv4Address(address)); - } - - for (String address : getInvalidIpAddresses()) { - assertFalse(IPTools.isIPv4Address(address)); - } - } @Test public void testIsIPv6Address() { - for (String address : getIPv4Addresses()) { - assertFalse(IPTools.isIPv6Address(address)); - } - - for (String address : getIPv6Addresses()) { - assertTrue(IPTools.isIPv6Address(address)); - } - - for (String address : getInvalidIpAddresses()) { - assertFalse(IPTools.isIPv6Address(address)); - } + assertIPv6Address(getIPv4Addresses(), false); + assertIPv6Address(getIPv6Addresses(), true); + assertIPv6Address(getInvalidIpAddresses(), false); } @Test public void testIsIPv6AddressesStandard() { - for (String address : getIPv4Addresses()) { - assertFalse(IPTools.isIPv6StdAddress(address)); - } - - for (String address : getIPv6Addresses()) { - assertTrue(IPTools.isIPv6StdAddress(address)); - } - - for (String address : getInvalidIpAddresses()) { - assertFalse(IPTools.isIPv6StdAddress(address)); - } + assertIPv6StdAddress(getIPv4Addresses(), false); + assertIPv6StdAddress(getIPv6Addresses(), true); + assertIPv6StdAddress(getInvalidIpAddresses(), false); } @Test @@ -123,4 +99,22 @@ public void testLocalAddressesNetwork() throws UnknownHostException { assertFalse(IPTools.isIpAddressLocalNetwork(InetAddress.getByName("8.8.8.8"))); } + private void assertIPv4Address(String[] ips, boolean isIPv4Address) { + for (String address : ips) { + assertThat(IPTools.isIPv4Address(address), is(isIPv4Address)); + } + } + + private void assertIPv6Address(String[] ips, boolean isIPv6Address) { + for (String address : ips) { + assertThat(IPTools.isIPv6Address(address), is(isIPv6Address)); + } + } + + private void assertIPv6StdAddress(String[] ips, boolean isIPv6StdAddress) { + for (String address : ips) { + assertThat(IPTools.isIPv6StdAddress(address), is(isIPv6StdAddress)); + } + } + } diff --git a/readme.md b/readme.md index ea01ea5..44cee5d 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,5 @@ +> :warning: **Not under active development**: I am no longer actively developing this project as I have other priorities. However, I will still review and accept pull requests with bug fixes and enhancements. + # Android Network Tools ![image](./app/src/main/res/mipmap-xhdpi/ic_launcher.png) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-AndroidNetworkTools-green.svg?style=true)](https://android-arsenal.com/details/1/3112) @@ -17,9 +19,14 @@ The javadoc should provide all information needed to understand the methods, but ### Sample app -The sample app is published on Google play to allow you to quickly and easier test the library. Enjoy! And please do feedback to us if your tests produce different results. +The sample app is published on Google Play & F-Droid to allow you to quickly and easier test the library. Enjoy! And please do feedback to us if your tests produce different results. -Get it on Google Play +[Get it on F-Droid](https://f-droid.org/packages/com.stealthcotper.networktools/) +[Get it on Google Play](https://play.google.com/store/apps/details?id=com.stealthcotper.networktools) ## Usage @@ -41,7 +48,7 @@ then add a library dependency. **Remember** to check for latest release [here](h ```groovy dependencies { - compile 'com.github.stealthcopter:AndroidNetworkTools:0.4.0' + compile 'com.github.stealthcopter:AndroidNetworkTools:0.4.5.3' } ``` @@ -140,7 +147,6 @@ Other useful methods: It's a standard gradle project. - # Contributing I welcome pull requests, issues and feedback. @@ -150,4 +156,3 @@ I welcome pull requests, issues and feedback. - Commit your changes (git commit -am 'Added some feature') - Push to the branch (git push origin my-new-feature) - Create new Pull Request - diff --git a/scripts/github-release.sh b/scripts/github-release.sh index e1ec1f5..2d24f84 100755 --- a/scripts/github-release.sh +++ b/scripts/github-release.sh @@ -9,9 +9,9 @@ if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi GITHUB_RELEASE_NAME="Android Network Tools Library" GITHUB_RELEASE_MODULE="library" +GITHUB_RELEASE_TOKEN=$ANDROID_NETWORK_TOOLS_GITHUB_RELEASE_TOKEN GITHUB_RELEASE_DESC="This release was automatically generated by the CI server" GITHUB_RELEASE_URL="https://api.github.com/repos/stealthcopter/AndroidNetworkTools/releases" -GITHUB_RELEASE_TOKEN=$ANDROID_NETWORK_TOOLS_GITHUB_RELEASE_TOKEN GITHUB_UPLOAD_URL="https://uploads.github.com/repos/stealthcopter/AndroidNetworkTools/releases/" function create_github_release {