public static Ethernet buildNdpAdv(Ip6Address srcIp,
                                       MacAddress srcMac,
                                       Ethernet request) {

        checkNotNull(srcIp, "IP address cannot be null");
        checkNotNull(srcMac, "MAC address cannot be null");
        checkNotNull(request, "Request cannot be null");
        checkArgument(request.getEtherType() == Ethernet.TYPE_IPV6,
                "EtherType must be IPv6");

        final IPv6 ipv6Request = (IPv6) request.getPayload();

        checkArgument(ipv6Request.getNextHeader() == IPv6.PROTOCOL_ICMP6,
                "Protocol must be ICMP6");

        final ICMP6 icmpv6 = (ICMP6) ipv6Request.getPayload();

        checkArgument(icmpv6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION,
                "ICMP6 type must be NEIGHBOR_SOLICITATION");

        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(request.getSourceMAC());
        eth.setSourceMACAddress(srcMac);
        eth.setEtherType(Ethernet.TYPE_IPV6);
        eth.setVlanID(request.getVlanID());

        IPv6 ipv6 = new IPv6();
        ipv6.setSourceAddress(srcIp.toOctets());
        ipv6.setDestinationAddress(ipv6Request.getSourceAddress());
        ipv6.setHopLimit(NDP_HOP_LIMIT);
        ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6);

        ICMP6 icmp6 = new ICMP6();
        icmp6.setIcmpType(ICMP6.NEIGHBOR_ADVERTISEMENT);
        icmp6.setIcmpCode(RESERVED_CODE);

        NeighborAdvertisement nadv = new NeighborAdvertisement();
        nadv.setTargetAddress(srcIp.toOctets());
        nadv.setSolicitedFlag(NDP_SOLICITED_FLAG);
        nadv.setOverrideFlag(NDP_OVERRIDE_FLAG);
        nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
                srcMac.toBytes());

        icmp6.setPayload(nadv);
        ipv6.setPayload(icmp6);
        eth.setPayload(ipv6);
        return eth;
    }
@Test
    public void testBuildNdpAdv() {
        Ethernet eth = new Ethernet();
        eth.setSourceMACAddress(MAC_ADDRESS);
        eth.setDestinationMACAddress(MAC_ADDRESS2);

        IPv6 ipv6 = new IPv6();
        ipv6.setSourceAddress(IPV6_SOURCE_ADDRESS);
        ipv6.setDestinationAddress(IPV6_DESTINATION_ADDRESS);
        ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6);

        eth.setEtherType(Ethernet.TYPE_IPV6);
        eth.setPayload(ipv6);

        ICMP6 icmp6 = new ICMP6();
        icmp6.setIcmpType(ICMP6.NEIGHBOR_SOLICITATION);
        icmp6.setIcmpCode(NeighborAdvertisement.RESERVED_CODE);
        ipv6.setPayload(icmp6);

        final Ethernet ethResponse = NeighborAdvertisement.buildNdpAdv(IP_6_ADDRESS, MAC_ADDRESS2, eth);

        assertTrue(ethResponse.getDestinationMAC().equals(MAC_ADDRESS));
        assertTrue(ethResponse.getSourceMAC().equals(MAC_ADDRESS2));
        assertTrue(ethResponse.getEtherType() == Ethernet.TYPE_IPV6);

        final IPv6 responseIpv6 = (IPv6) ethResponse.getPayload();

        assertArrayEquals(responseIpv6.getSourceAddress(), ipv6.getDestinationAddress());
        assertArrayEquals(responseIpv6.getDestinationAddress(), ipv6.getSourceAddress());
        assertTrue(responseIpv6.getNextHeader() == IPv6.PROTOCOL_ICMP6);

        final ICMP6 responseIcmp6 = (ICMP6) responseIpv6.getPayload();

        assertTrue(responseIcmp6.getIcmpType() == ICMP6.NEIGHBOR_ADVERTISEMENT);
        assertTrue(responseIcmp6.getIcmpCode() == NeighborAdvertisement.RESERVED_CODE);

        final NeighborAdvertisement responseNadv = (NeighborAdvertisement) responseIcmp6.getPayload();

        assertArrayEquals(responseNadv.getTargetAddress(), IPV6_DESTINATION_ADDRESS);
        assertTrue(responseNadv.getSolicitedFlag() == NeighborAdvertisement.NDP_SOLICITED_FLAG);
        assertTrue(responseNadv.getOverrideFlag() == NeighborAdvertisement.NDP_OVERRIDE_FLAG);
        assertThat(responseNadv.getOptions(),
                hasItem(hasOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS, MAC_ADDRESS2.toBytes())));
    }