Exemplo n.º 1
0
 def send_DHCPv6_Reply(self, pkt):
     """
         Sends out the DHCPv6 Reply message.
     """
     header = self.build_reply_headers(pkt)
     trid = pkt[DHCP6_InfoRequest].trid
     srv_duid = header[Ether].src
     cli_id = DHCP6OptClientId(duid=pkt[DHCP6OptClientId].duid)
     srv_id = DHCP6OptServerId(duid=DUID_LL(lladdr=srv_duid))
     sendp(
         header / DHCP6_Reply(trid=trid) / cli_id / srv_id,
         iface=self.iface,
         verbose=False,
     )
Exemplo n.º 2
0
    def craft_dhcp_request(self, hw=None):
        """Generates a DHCPv6 Request packet
        
        Args:
            hw (str|bytes, optional): Defaults to MAC of Scapy's `conf.iface`.
                Client MAC address to use for DUID LL.
        
        Returns:
            scapy.layers.inet.IPv6: DHCPv6 Request packet
        """
        if not hw:
            _, hw = get_if_raw_hwaddr(conf.iface)
        else:
            hw = mac_str_to_bytes(hw)

        # TODO
        # Request Message
        # - sent by clients
        # - includes a server identifier option
        # - the content of Server Identifier option must match server's DUID
        # - includes a client identifier option
        # - must include an ORO Option (even with hints) p40
        # - can includes a reconfigure Accept option indicating whether or
        #   not the client is willing to accept Reconfigure messages from
        #   the server (p40)
        # - When the server receives a Request message via unicast from a
        # client to which the server has not sent a unicast option, the server
        # discards the Request message and responds with a Reply message
        # containing Status Code option with the value UseMulticast, a Server
        # Identifier Option containing the server's DUID, the client
        # Identifier option from the client message and no other option.
        dhcp_request = (IPv6(dst="ff02::1:2") / UDP(sport=546, dport=547) /
                        DHCP6_Request(trid=self.xid) /
                        DHCP6OptServerId(duid=self.server_id) /
                        DHCP6OptElapsedTime() /
                        DHCP6OptClientId(duid=DUID_LL(lladdr=hw)) /
                        DHCP6OptIA_NA(iaid=0))
        if settings.DEBUG:
            print(dhcp_request.show())
        return dhcp_request
Exemplo n.º 3
0
    def craft_discover(self, hw=None):
        """Generates a DHCPv6 Solicit packet
        
        Args:
            hw (str|bytes, optional): Defaults to MAC of Scapy's `conf.iface`.
                Client MAC address to use for DUID LL.
        
        Returns:
            scapy.layers.inet.IPv6: DHCPv6 Solicit packet
        """
        if not hw:
            _, hw = get_if_raw_hwaddr(conf.iface)
        else:
            hw = mac_str_to_bytes(hw)

        dhcp_solicit = (IPv6(dst="ff02::1:2") / UDP(sport=546, dport=547) /
                        DHCP6_Solicit(trid=self.xid) / DHCP6OptElapsedTime() /
                        DHCP6OptClientId(duid=DUID_LL(lladdr=hw)) /
                        DHCP6OptIA_NA(iaid=0))
        if settings.DEBUG:
            print(dhcp_solicit.show())
        return dhcp_solicit
Exemplo n.º 4
0
def testfunc(child):
    iface = os.environ["TAP"]

    pkt = wait_for_dhcpv6_pkt(iface)
    # the packet was a solicit
    assert DHCP6_Solicit in pkt
    # check if the sender is the upstream interface of the node
    upstream_netif = get_upstream_netif(child)
    print(upstream_netif)
    upstream_hwaddrs = get_hwaddrs(child, upstream_netif)
    assert DHCP6OptClientId in pkt and DUID_LL in pkt[DHCP6OptClientId].duid
    assert pkt[DHCP6OptClientId].duid[DUID_LL].lladdr in upstream_hwaddrs
    # and it is asking for a prefix delegation
    assert DHCP6OptIA_PD in pkt

    # reply to solicit with advertise and a prefix provided
    trid = pkt[DHCP6_Solicit].trid
    srv_duid = "aa:bb:cc:dd:ee:ff"
    cli_id = DHCP6OptClientId(duid=pkt[DHCP6OptClientId].duid)
    srv_id = DHCP6OptServerId(duid=DUID_LL(lladdr=srv_duid))
    prefix = "2001:db8:{:x}:{:x}::".format(random.randint(0, 0xffff),
                                           random.randint(0, 0xffff))
    ia_pd = DHCP6OptIA_PD(T1=12000,
                          T2=13000,
                          iaid=pkt[DHCP6OptIA_PD].iaid,
                          iapdopt=[
                              DHCP6OptIAPrefix(preflft=14000,
                                               validlft=15000,
                                               prefix=prefix,
                                               plen=64)
                          ])
    # start sniffer to catch incoming request
    sniffer = start_sniffer(iface,
                            stop_filter=lambda pkt: DHCP6_Request in pkt)
    sendp(build_reply_headers(pkt) / DHCP6_Advertise(trid=trid) / cli_id /
          srv_id / ia_pd,
          iface=iface,
          verbose=False)

    # wait for request
    pkt = wait_for_dhcpv6_pkt(iface, sniffer)
    # the packet was indeed a request
    assert DHCP6_Request in pkt
    # and from the client
    assert DHCP6OptClientId in pkt and DUID_LL in pkt[DHCP6OptClientId].duid
    assert pkt[DHCP6OptClientId].duid[DUID_LL].lladdr in upstream_hwaddrs
    # and it is trying to talk to this server
    assert DHCP6OptServerId in pkt and DUID_LL in pkt[DHCP6OptServerId].duid
    assert pkt[DHCP6OptServerId].duid[DUID_LL].lladdr == srv_duid
    # and is still asking for a prefix delegation
    assert DHCP6OptIA_PD in pkt

    # reply to request with reply and a prefix provided
    trid = pkt[DHCP6_Request].trid
    sendp(build_reply_headers(pkt) / DHCP6_Reply(trid=trid) / cli_id / srv_id /
          ia_pd,
          iface=iface,
          verbose=False)
    time.sleep(1)

    # check if global address was configured
    child.sendline("ifconfig {}".format(get_downstream_netif(child)))
    # remove one trailing ':' from prefix just to be safe ;-)
    child.expect(r"inet6 addr:\s+{}[0-9a-fA-F:]+\s".format(prefix[:-1]))
    print("SUCCESS")