@Override
    protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
        if(!((remoteAddress instanceof RawSocketPassiveAddress) || (remoteAddress instanceof InetSocketAddress) || (remoteAddress instanceof RawSocketAddress))) {
            logger.error("Expecting remote address of type RawSocketPassiveAddress or InetSocketAddress");
            pipeline().fireExceptionCaught(
                new PcapException("Expecting remote address of type RawSocketPassiveAddress or InetSocketAddress"));
            return;
        }
        this.localAddress = localAddress;
        this.remoteAddress = remoteAddress;

        PcapNetworkInterface nif = null;
        // Try to get the device name of the network interface that we want to open.
        if(remoteAddress instanceof RawSocketPassiveAddress) {
            RawSocketPassiveAddress rawSocketPassiveAddress = (RawSocketPassiveAddress) remoteAddress;
            String deviceName = getDeviceName(rawSocketPassiveAddress);
            if (deviceName == null) {
                logger.error("Network device not specified and couldn't detect it automatically");
                pipeline().fireExceptionCaught(
                    new PcapException("Network device not specified and couldn't detect it automatically"));
                return;
            }

            // Get a handle to the network-device and open it.
            nif = Pcaps.getDevByName(deviceName);
        } else if (remoteAddress instanceof InetSocketAddress) {
            InetSocketAddress inetSocketAddress = (InetSocketAddress) remoteAddress;
            InetAddress address = inetSocketAddress.getAddress();
            deviceLoop:
            for (PcapNetworkInterface dev : Pcaps.findAllDevs()) {
                // We're only interested in real running network interfaces, skip the rest.
                if (dev.isLoopBack()) {
                    continue;
                }

                // Go through all configured addresses and subnets and if we find a matching
                // device, use that as nif.
                for (PcapAddress curAddress : dev.getAddresses()) {
                    if((curAddress.getAddress() == null) || (curAddress.getNetmask() == null)) {
                        continue;
                    }
                    if((address instanceof Inet4Address) && !(curAddress instanceof PcapIpV4Address)) {
                        continue;
                    }
                    if((address instanceof Inet6Address) && !(curAddress instanceof PcapIpV6Address)) {
                        continue;
                    }
                    final SubnetUtils.SubnetInfo subnetInfo = new SubnetUtils(curAddress.getAddress().getHostAddress(), curAddress.getNetmask().getHostAddress()).getInfo();
                    if(subnetInfo.isInRange(address.getHostAddress())) {
                        nif = dev;
                        // Update the local address
                        this.localAddress = new InetSocketAddress(curAddress.getAddress(), 0);
                        this.localMacAddress = dev.getLinkLayerAddresses().stream()
                            .filter(linkLayerAddress -> linkLayerAddress instanceof MacAddress).map(linkLayerAddress -> (MacAddress) linkLayerAddress)
                            .findFirst().orElse(null);
                        break deviceLoop;
                    }
                }
            }
        }
        // This would be generally to use a remote MAC address as target.
        else {
            // Here we would need to do a reverse ARP lookup to find the
            throw new RuntimeException("Not Implemented yet ");
            // TODO: Implement finding out which device is used for communicating with a given MAC address.
        }

        if (nif == null) {
            logger.error(String.format("Couldn't find network device for %s", remoteAddress));
            pipeline().fireExceptionCaught(
                new PcapException(String.format("Couldn't find network device for %s", remoteAddress)));
            return;
        }

        // If desired: Try to get the mac address of the remote station by sending an ARP request.
        if(config.isResolveMacAddress()) {
            if ((this.remoteMacAddress == null) && (this.remoteAddress instanceof InetSocketAddress)) {
                this.remoteMacAddress = ArpUtils.resolveMacAddress(nif, (InetSocketAddress) this.remoteAddress,
                    (InetSocketAddress) this.localAddress, localMacAddress).orElse(null);
            }
        }

        receiveHandle = nif.openLive(65535, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);
        if(logger.isDebugEnabled()) {
            logger.debug(String.format("Listening on device %s", nif.getName()));
        }

        // If the address allows fine-tuning which packets to process, set a filter to reduce the load.
        // If no remote mac address is set, we'll set it to 00:00:00:00:00, which is an invalid address
        // and therefore no traffic will be incoming.
        // TODO: Make configurable, if we should accept from any source or not.
        MacAddress tempRemoteMacAddress = remoteMacAddress != null ? remoteMacAddress : MacAddress.getByAddress(new byte[]{0,0,0,0,0,0});
        String filter = config.getMacBasedFilterString(localMacAddress, tempRemoteMacAddress);
        if(!filter.isEmpty()) {
            receiveHandle.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
        }

        // Create a buffer where the raw socket worker can send data to.
        ByteBuf buffer = Unpooled.buffer();

        // Start a thread that processes the callbacks from the raw socket and simply
        // forwards the bytes read to the buffer.
        loopThread = new Thread(() -> {
            try {
                receiveHandle.loop(-1,
                    (PacketListener) packet -> buffer.writeBytes(config.getPacketHandler().getData(packet)));
            } catch (PcapNativeException | NotOpenException e) {
                // TODO this should close everything automatically
                logger.error("Pcap4j loop thread died!", e);
                pipeline().fireExceptionCaught(e);
            } catch (InterruptedException e) {
                // This usually happens when the raw socket transport is closed.
            }
        });
        loopThread.start();

        if(remoteAddress instanceof RawSocketPassiveAddress) {
            // Right now we're using an output stream that simply discards everything.
            // This is ok while implementing passive drivers for protocols, however as
            // soon as we start implementing ethernet layer protocols, we'll have to also
            // be able to actually send data. The PcapInputStream simply acts as a
            // breaking point if no packets are coming in and the read operation would
            // simply block indefinitely.
            activate(new PcapInputStream(buffer), new DiscardingOutputStream());
        } else {
            PcapHandle sendHandle = nif.openLive(65535, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);
            activate(new PcapInputStream(buffer), new PcapOutputStream(sendHandle));
        }
    }
Channel based on a Pcap4J raw-socket, allowing to actively communicate based on ethernet frames.
plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannel.java