public void handlePnDcpPacket(PnDcp_Pdu pdu, EthernetPacket ethernetPacket) {
        // Inspect the PDU itself
        // (in this case we only process identify response packets)
        if (pdu instanceof PnDcp_Pdu_IdentifyRes) {
            PnDcp_Pdu_IdentifyRes identifyResPDU = (PnDcp_Pdu_IdentifyRes) pdu;

            Map<String, PnDcp_Block> blocks = new HashMap<>();
            for (PnDcp_Block block : identifyResPDU.getBlocks()) {
                String blockName = block.getOption().name() + "-" + block.getSuboption().toString();
                blocks.put(blockName, block);
            }

            // The mac address of the device we found
            org.pcap4j.util.MacAddress srcAddr = ethernetPacket.getHeader().getSrcAddr();
            // The mac address of the local network device
            org.pcap4j.util.MacAddress dstAddr = ethernetPacket.getHeader().getDstAddr();

            String deviceTypeName = "unknown";
            if (blocks.containsKey(DEVICE_TYPE_NAME)) {
                PnDcp_Block_DevicePropertiesDeviceVendor block = (PnDcp_Block_DevicePropertiesDeviceVendor) blocks.get(DEVICE_TYPE_NAME);
                deviceTypeName = new String(block.getDeviceVendorValue());
            }

            String deviceName = "unknown";
            if (blocks.containsKey(DEVICE_NAME_OF_STATION)) {
                PnDcp_Block_DevicePropertiesNameOfStation block = (PnDcp_Block_DevicePropertiesNameOfStation) blocks.get(DEVICE_NAME_OF_STATION);
                deviceName = new String(block.getNameOfStation());
            }

            String role = "unknown";
            if (blocks.containsKey(DEVICE_ROLE)) {
                role = "";
                PnDcp_Block_DevicePropertiesDeviceRole block = (PnDcp_Block_DevicePropertiesDeviceRole) blocks.get(DEVICE_ROLE);
                if (block.getPnioSupervisor()) {
                    role += ",SUPERVISOR";
                }
                if (block.getPnioMultidevive()) {
                    role += ",MULTIDEVICE";
                }
                if (block.getPnioController()) {
                    role += ",CONTROLLER";
                }
                if (block.getPnioDevice()) {
                    role += ",DEVICE";
                }
                // Cut off the first comma
                if (!role.isEmpty()) {
                    role = role.substring(1);
                } else {
                    role = "unknown";
                }
            }

            String remoteAddress = "unknown";
            String remoteSubnetMask = "unknown";
            if (blocks.containsKey(IP_OPTION_IP)) {
                PnDcp_Block_IpParameter block = (PnDcp_Block_IpParameter) blocks.get(IP_OPTION_IP);
                try {
                    InetAddress addr = InetAddress.getByAddress(block.getIpAddress());
                    remoteAddress = addr.getHostAddress();
                    InetAddress netMask = InetAddress.getByAddress(block.getSubnetMask());
                    remoteSubnetMask = netMask.getHostAddress();
                } catch (UnknownHostException e) {
                    remoteAddress = "invalid";
                }
            }

            // Some devices need to get an IP address assigned by the Profinet Master.
            // In this case we'll use the MAC address as connection address.
            Map<String, String> options = Collections.emptyMap();
            if("0.0.0.0".equals(remoteAddress)) {
                remoteAddress = srcAddr.toString();
                options = Collections.singletonMap("ip-address", "{some-ip-address}");
            }

            // Get the Vendor-Id and the Device-Id
            String vendorId = "unknown";
            String deviceId = "unknown";
            if (blocks.containsKey(DEVICE_ID)) {
                PnDcp_Block_DevicePropertiesDeviceId block = (PnDcp_Block_DevicePropertiesDeviceId) blocks.get(DEVICE_ID);
                vendorId = String.format("%04X", block.getVendorId());
                deviceId = String.format("%04X", block.getDeviceId());
            }

            // If this is a Siemens device
            // If there are non-siemens devices that support S7Comm, we can extend the code.
            boolean supportsS7Comm = false;
            switch (vendorId) {
                case "002A":
                    switch (deviceId) {
                        // This is an S7 1200
                        case "010D":
                            supportsS7Comm = true;
                            break;
                        // This is an S7 1200
                        case "010E":
                            supportsS7Comm = true;
                            break;
                    }
                    break;
            }

            // Only add devices we know support the S7Comm protocol.
            if(supportsS7Comm) {
                Map<String, PlcValue> attributes = new HashMap<>();
                attributes.put("ipAddress", new PlcSTRING(remoteAddress));
                attributes.put("subnetMask", new PlcSTRING(remoteSubnetMask));
                attributes.put("macAddress", new PlcSTRING(srcAddr.toString()));
                attributes.put("localMacAddress", new PlcSTRING(dstAddr.toString()));
                attributes.put("deviceTypeName", new PlcSTRING(deviceTypeName));
                attributes.put("deviceName", new PlcSTRING(deviceName));
                attributes.put("vendorId", new PlcSTRING(vendorId));
                attributes.put("deviceId", new PlcSTRING(deviceId));
                attributes.put("role", new PlcSTRING(role));
                attributes.put("packetType", new PlcSTRING("dcp"));

                String name = deviceTypeName + " - " + deviceName;

                PlcDiscoveryItem value = new DefaultPlcDiscoveryItem(
                    "s7", "tcp",
                    remoteAddress, options, name, attributes);
                values.add(value);

                // If we have a discovery handler, pass it to the handler callback
                if (handler != null) {
                    handler.handle(value);
                }

                logger.debug("Found new device: '{}' with connection-url '{}'",
                    value.getName(), value.getConnectionUrl());
            }
        }
    }
This Discoverer makes use of part of the Profinet driver.
As every S7 device we know supports Profinet, we'll use the Profinet auto-discovery mechanism
and filter out the devices for which we know support the S7 comm protocol.
plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java