You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2022/08/29 13:23:39 UTC

[plc4x] branch develop updated: fix(plc4j/utils): Added a check for libpcap and the version to the ArpUtils giving error messages if anything is missing.

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 1216bbcd6 fix(plc4j/utils): Added a check for libpcap and the version to the ArpUtils giving error messages if anything is missing.
1216bbcd6 is described below

commit 1216bbcd6e9aa99a39264404d29aec40fc9bfd70
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Aug 29 15:23:32 2022 +0200

    fix(plc4j/utils): Added a check for libpcap and the version to the ArpUtils giving error messages if anything is missing.
---
 plc4j/utils/raw-sockets/pom.xml                    |  4 ++
 .../utils/rawsockets/netty/utils/ArpUtils.java     | 44 ++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/plc4j/utils/raw-sockets/pom.xml b/plc4j/utils/raw-sockets/pom.xml
index aa093dd74..ab767e489 100644
--- a/plc4j/utils/raw-sockets/pom.xml
+++ b/plc4j/utils/raw-sockets/pom.xml
@@ -71,6 +71,10 @@
       <groupId>commons-net</groupId>
       <artifactId>commons-net</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.slf4j</groupId>
diff --git a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java
index ec42c53bc..b93a444a9 100644
--- a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java
+++ b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java
@@ -18,6 +18,7 @@
  */
 package org.apache.plc4x.java.utils.rawsockets.netty.utils;
 
+import org.apache.commons.lang3.SystemUtils;
 import org.apache.commons.net.util.SubnetUtils;
 import org.pcap4j.core.*;
 import org.pcap4j.packet.ArpPacket;
@@ -28,6 +29,8 @@ import org.pcap4j.packet.namednumber.ArpOperation;
 import org.pcap4j.packet.namednumber.EtherType;
 import org.pcap4j.util.ByteArrays;
 import org.pcap4j.util.MacAddress;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -38,7 +41,32 @@ import java.util.stream.Collectors;
 
 public class ArpUtils {
 
+    private static final Logger logger = LoggerFactory.getLogger(ArpUtils.class);
+
     public static Set<InetAddress> scanNetworkDevice(PcapNetworkInterface nif) {
+        // Check if libpcap is available.
+        try {
+            String libVersion = Pcaps.libVersion();
+            if(libVersion.startsWith("libpcap version ")) {
+                libVersion = libVersion.substring(16);
+                // If we're on MacOS we need to check if we're at least at version 1.10.1 as the default bundled with
+                // the os has issues.
+                if(SystemUtils.IS_OS_MAC) {
+                    if (!checkVersionAtLeast(libVersion, "1.10.1")) {
+                        logger.warn("On MacOS libpcap 1.10.1 is required, this system uses libpcap " + libVersion + ". " +
+                            "When using libpcap from homebrew, make sure to have added the library path. " +
+                            "On Intel MacOS this is usually done by setting '-Djna.library.path=/usr/local/Cellar/libpcap/1.10.1/lib' " +
+                            "on M1 this is '-Djna.library.path=/opt/homebrew/Cellar/libpcap/1.10.1/lib'");
+                        return Collections.emptySet();
+                    }
+                }
+            } else {
+                return Collections.emptySet();
+            }
+        } catch (Exception e) {
+            return Collections.emptySet();
+        }
+
         Set<InetAddress> foundAddresses = new HashSet<>();
         try{
             // Calculate all ip addresses, this device can reach.
@@ -270,6 +298,22 @@ public class ArpUtils {
         return Optional.empty();
     }
 
+    private static boolean checkVersionAtLeast(String current, String minimum) {
+        String[] currentSegments = current.split("\\.");
+        String[] minimumSegments = minimum.split("\\.");
+        int numSegments = Math.min(currentSegments.length, minimumSegments.length);
+        for (int i = 0; i < numSegments; ++i) {
+            int currentSegment = Integer.parseInt(currentSegments[i]);
+            int minimumSegment = Integer.parseInt(minimumSegments[i]);
+            if (currentSegment < minimumSegment) {
+                return false;
+            } else if (currentSegment > minimumSegment) {
+                return true;
+            }
+        }
+        return currentSegments.length >= minimumSegments.length;
+    }
+
     public static void main(String[] args) throws Exception {
         for (PcapNetworkInterface dev : Pcaps.findAllDevs()) {
             final Set<InetAddress> inetAddresses = scanNetworkDevice(dev);