def setUp(self):
     self.packet_fixture = bytes.fromhex(
         '0e'  # Message type Leasequery
         'e86f0c'  # Transaction ID
         '0001'  # Option type 1: OPTION_CLIENT_ID
         '000a'  # Option length: 10
         '0003'  # DUID type: DUID_LL
         '0001'  # Hardware type: Ethernet
         '001ee6f77d00'  # MAC Address
         '002c'  # Option type 44: OPTION_LQ_QUERY
         '0017'  # Option length: 23
         '01'  # Query type: QUERY_BY_ADDRESS
         'fe800000000000000000000000000001'  # Link address: fe80::1
         '0006'  # Option type: OPTION_ORO
         '0002'  # Option length: 2
         '002f'  # Requested option: OPTION_LQ_RELAY_DATA
     )
     self.message_fixture = LeasequeryMessage(
         transaction_id=bytes.fromhex('e86f0c'),
         options=[
             ClientIdOption(duid=LinkLayerDUID(
                 hardware_type=1,
                 link_layer_address=bytes.fromhex('001ee6f77d00'))),
             LQQueryOption(
                 query_type=QUERY_BY_ADDRESS,
                 link_address=IPv6Address('fe80::1'),
                 options=[
                     OptionRequestOption(
                         requested_options=[OPTION_LQ_RELAY_DATA]),
                 ]),
         ])
     self.parse_packet()
Example #2
0
 def setUp(self):
     self.relayed_solicit_message = RelayForwardMessage(
         hop_count=1,
         link_address=IPv6Address('2001:db8:ffff:1::1'),
         peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
         options=[
             RelayMessageOption(relayed_message=RelayForwardMessage(
                 hop_count=0,
                 link_address=IPv6Address('::'),
                 peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'),
                 options=[
                     RelayMessageOption(relayed_message=SolicitMessage(
                         transaction_id=bytes.fromhex('f350d6'),
                         options=[
                             ElapsedTimeOption(elapsed_time=0),
                             ClientIdOption(duid=LinkLayerDUID(hardware_type=1,
                                                               link_layer_address=bytes.fromhex('3431c43cb2f1'))),
                             IANAOption(iaid=bytes.fromhex('c43cb2f1')),
                             IAPDOption(iaid=bytes.fromhex('c43cb2f1')),
                             OptionRequestOption(requested_options=[
                                 OPTION_DNS_SERVERS,
                             ]),
                         ],
                     )),
                     InterfaceIdOption(interface_id=b'Fa2/3'),
                     RemoteIdOption(enterprise_number=9,
                                    remote_id=bytes.fromhex('020023000001000a0003000100211c7d486e')),
                 ])
             ),
             InterfaceIdOption(interface_id=b'Gi0/0/0'),
             RemoteIdOption(enterprise_number=9, remote_id=bytes.fromhex('020000000000000a0003000124e9b36e8100')),
             RelayIdOption(duid=LinkLayerDUID(hardware_type=1, link_layer_address=bytes.fromhex('121212121212'))),
         ],
     )
Example #3
0
    def test_query_by_address_with_relay_data(self):
        bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False)
        bundle.response = reply_message

        ia_na_option = bundle.response.get_option_of_type(IANAOption)
        ia_address = ia_na_option.get_option_of_type(IAAddressOption)

        query = LQQueryOption(QUERY_BY_ADDRESS, options=[ia_address, OptionRequestOption([OPTION_LQ_RELAY_DATA])])

        self.query(bundle, query, [LQRelayDataOption])
Example #4
0
    def test_query_by_address_with_extra_data(self):
        bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False)
        bundle.response = reply_message

        ia_na_option = bundle.response.get_option_of_type(IANAOption)
        ia_address = ia_na_option.get_option_of_type(IAAddressOption)

        query = LQQueryOption(QUERY_BY_ADDRESS, options=[ia_address, OptionRequestOption([OPTION_DNS_SERVERS])])

        self.query(bundle, query, [RecursiveNameServersOption])
    def setUp(self):
        self.option_bytes = bytes.fromhex(
            '002c'  # Option type 44: OPTION_LQ_QUERY
            '0017'  # Option length: 23
            '01'  # Query type: QUERY_BY_ADDRESS
            'fe800000000000000000000000000001'  # Link address: fe80::1
            '0006'  # Option type: OPTION_ORO
            '0002'  # Option length: 2
            '002f'  # Requested option: OPTION_LQ_RELAY_DATA
        )
        self.option_object = LQQueryOption(
            query_type=QUERY_BY_ADDRESS,
            link_address=IPv6Address('fe80::1'),
            options=[
                OptionRequestOption(requested_options=[OPTION_LQ_RELAY_DATA]),
            ])

        self.parse_option()
Example #6
0
                 ClientIdOption(duid=LinkLayerDUID(
                     hardware_type=1,
                     link_layer_address=bytes.fromhex('3431c43cb2f1'))),
                 RapidCommitOption(),
                 IANAOption(iaid=bytes.fromhex('c43cb2f1')),
                 IAPDOption(iaid=bytes.fromhex('c43cb2f1'),
                            options=[
                                IAPrefixOption(
                                    prefix=IPv6Network('::/0')),
                            ]),
                 ReconfigureAcceptOption(),
                 OptionRequestOption(requested_options=[
                     OPTION_DNS_SERVERS,
                     OPTION_NTP_SERVER,
                     OPTION_SNTP_SERVERS,
                     OPTION_IA_PD,
                     OPTION_IA_NA,
                     OPTION_VENDOR_OPTS,
                     OPTION_SOL_MAX_RT,
                     OPTION_INF_MAX_RT,
                 ]),
                 VendorClassOption(enterprise_number=872),
             ],
         )),
         InterfaceIdOption(interface_id=b'Fa2/3'),
         RemoteIdOption(enterprise_number=9,
                        remote_id=bytes.fromhex(
                            '020023000001000a0003000100211c7d486e')),
     ])),
 InterfaceIdOption(interface_id=b'Gi0/0/0'),
 RemoteIdOption(
     enterprise_number=9,
Example #7
0
 def setUp(self):
     self.option_bytes = bytes.fromhex('0006000400030004')
     self.option_object = OptionRequestOption(
         requested_options=[OPTION_IA_NA, OPTION_IA_TA])
     self.parse_option()
Example #8
0
def main(args: Iterable[str]) -> int:
    """
    The main program

    :param args: Command line arguments
    :return: The program exit code
    """
    # Handle command line arguments
    options = handle_args(args)
    set_verbosity_logger(logger, options.verbosity)

    query = options.create(options)

    # Add ORO for relay data
    if options.relay_data:
        query.options.append(OptionRequestOption([OPTION_LQ_RELAY_DATA]))

    # Generate the outgoing message
    transaction_id = random.getrandbits(24).to_bytes(3, 'big')
    message_out = LeasequeryMessage(
        transaction_id,
        [ClientIdOption(EnterpriseDUID(40208, b'LeaseQueryTester')), query])

    # Create client socket
    if options.tcp:
        client = TCPClientSocket(options)
    else:
        # Check permission
        if os.getuid() != 0:
            raise RuntimeError("This tool needs to be run as root")

        client = UDPClientSocket(options)

    destination = client.send(message_out)
    logger.info("Sent to {}:\n{}".format(destination, message_out))

    # Wait for responses
    wait_for_multiple = options.server.is_multicast or options.tcp

    start = time.time()
    deadline = start + 3

    received = 0

    while time.time() < deadline:
        client.set_timeout(deadline - time.time())
        try:
            sender, message_in = client.recv()
            received += 1

            logger.info("Received from {}:\n{}".format(sender, message_in))

            if options.tcp:
                # Check bulk leasequery ending
                if isinstance(message_in, LeasequeryReplyMessage):
                    if not message_in.get_option_of_type(ClientDataOption):
                        # Reply without data, the end
                        break

                if isinstance(message_in, LeasequeryDoneMessage):
                    break

            if not wait_for_multiple:
                break
        except socket.timeout:
            pass

    logger.info(
        gettext.ngettext("{} response received", "{} responses received",
                         received).format(received))

    return 0