public static Ethernet buildNdpSolicit(Ip6Address targetIp,
                                           Ip6Address sourceIp,
                                           Ip6Address destinationIp,
                                           MacAddress sourceMac,
                                           MacAddress destinationMac,
                                           VlanId vlan) {

        checkNotNull(targetIp, "Target IP address cannot be null");
        checkNotNull(sourceIp, "Source IP address cannot be null");
        checkNotNull(destinationIp, "Destination IP address cannot be null");
        checkNotNull(sourceMac, "Source MAC address cannot be null");
        checkNotNull(destinationMac, "Destination MAC address cannot be null");
        checkNotNull(vlan, "Vlan cannot be null");

        // Here we craft the Ethernet packet.
        Ethernet ethernet = new Ethernet();
        ethernet.setEtherType(Ethernet.TYPE_IPV6)
                .setDestinationMACAddress(destinationMac)
                .setSourceMACAddress(sourceMac);
        ethernet.setVlanID(vlan.id());
        // IPv6 packet is created.
        IPv6 ipv6 = new IPv6();
        ipv6.setSourceAddress(sourceIp.toOctets());
        ipv6.setDestinationAddress(destinationIp.toOctets());
        ipv6.setHopLimit(NDP_HOP_LIMIT);
        // Create the ICMPv6 packet.
        ICMP6 icmp6 = new ICMP6();
        icmp6.setIcmpType(ICMP6.NEIGHBOR_SOLICITATION);
        icmp6.setIcmpCode(RESERVED_CODE);
        // Create the Neighbor Solicitation packet.
        NeighborSolicitation ns = new NeighborSolicitation();
        ns.setTargetAddress(targetIp.toOctets());
        // DAD packets should not contain SRC_LL_ADDR option
        if (!Arrays.equals(sourceIp.toOctets(), Ip6Address.ZERO.toOctets())) {
            ns.addOption(NeighborDiscoveryOptions.TYPE_SOURCE_LL_ADDRESS, sourceMac.toBytes());
        }
        // Set the payloads
        icmp6.setPayload(ns);
        ipv6.setPayload(icmp6);
        ethernet.setPayload(ipv6);

        return ethernet;
    }
@Test
    public void testBuildNdpSolicit() throws Exception {
        final Ethernet ethPacket = NeighborSolicitation.buildNdpSolicit(TARGET_IP,
                SRC_IP, DST_IP, SRC_MAC, DST_MAC, VLAN_ID);

        assertTrue(ethPacket.getDestinationMAC().equals(DST_MAC));
        assertTrue(ethPacket.getSourceMAC().equals(SRC_MAC));
        assertTrue(ethPacket.getEtherType() == Ethernet.TYPE_IPV6);
        assertTrue(ethPacket.getVlanID() == VLAN_ID.id());

        final IPv6 ipPacket = (IPv6) ethPacket.getPayload();

        assertArrayEquals(ipPacket.getSourceAddress(), SRC_IP.toOctets());
        assertArrayEquals(ipPacket.getDestinationAddress(), DST_IP.toOctets());

        final ICMP6 icmp6Packet = (ICMP6) ipPacket.getPayload();
        final NeighborSolicitation nsPacket = (NeighborSolicitation) icmp6Packet.getPayload();

        assertArrayEquals(nsPacket.getTargetAddress(), TARGET_IP.toOctets());

        assertEquals("Non-DAD NS should have 1 option", 1, nsPacket.getOptions().size());
        assertEquals("The option should be SRC_LL_ADDR type", TYPE_SOURCE_LL_ADDRESS,
                nsPacket.getOptions().stream().findFirst().get().type());
    }