示例#1
0
def do_beaconing(args, interfaces=None):
    """Sends out beacons based on the given arguments, and waits for replies.

    :param args: The command-line arguments.
    :param interfaces: The interfaces to send out beacons on.
        Must be the result of `get_all_interfaces_definition()`.
    """
    if args.source is None:
        source_ip = '::'
    else:
        source_ip = args.source
    protocol = BeaconingSocketProtocol(reactor,
                                       process_incoming=True,
                                       debug=True,
                                       interface=source_ip,
                                       port=args.port,
                                       interfaces=interfaces)
    if args.destination is None:
        destination_ip = "::ffff:" + BEACON_IPV4_MULTICAST
    elif ':' not in args.destination:
        destination_ip = "::ffff:" + args.destination
    else:
        destination_ip = args.destination
    if "224.0.0.118" in destination_ip:
        protocol.send_multicast_beacons(interfaces, verbose=args.verbose)
    else:
        log.msg("Sending unicast beacon to '%s'..." % destination_ip)
        beacon = create_beacon_payload("solicitation")
        protocol.send_beacon(beacon, (destination_ip, BEACON_PORT))
    reactor.callLater(args.timeout, lambda: reactor.stop())
    reactor.run()
    return protocol
示例#2
0
 def test__sends_and_receives_unicast_beacons(self):
     # Note: Always use a random port for testing. (port=0)
     logger = self.useFixture(TwistedLoggerFixture())
     protocol = BeaconingSocketProtocol(
         reactor,
         port=0,
         process_incoming=True,
         loopback=True,
         interface="::",
         debug=True,
     )
     self.assertThat(protocol.listen_port, Not(Is(None)))
     listen_port = protocol.listen_port._realPortNumber
     self.write_secret()
     beacon = create_beacon_payload("solicitation", {})
     rx_uuid = beacon.payload["uuid"]
     destination = random.choice(["::ffff:127.0.0.1", "::1"])
     protocol.send_beacon(beacon, (destination, listen_port))
     # Pretend we didn't send this packet. Otherwise we won't reply to it.
     # We have to do this now, before the reactor runs again.
     transmitted = protocol.tx_queue.pop(rx_uuid, None)
     # Since we've instructed the protocol to loop back packets for testing,
     # it should have sent a multicast solicitation, received it back, sent
     # an advertisement, then received it back. So we'll wait for two
     # packets to be sent.
     yield wait_for_rx_packets(protocol, 2)
     # Grab the beacon we know we transmitted and then received.
     received = protocol.rx_queue.pop(rx_uuid, None)
     self.assertThat(transmitted, Equals(beacon))
     self.assertThat(received[0].json["payload"]["uuid"], Equals(rx_uuid))
     # Grab the subsequent packets from the queues.
     transmitted = protocol.tx_queue.popitem()[1]
     received = protocol.rx_queue.popitem()[1]
     # We should have received a second packet to ack the first beacon.
     self.assertThat(received[0].json["payload"]["acks"], Equals(rx_uuid))
     # We should have transmitted an advertisement in response to the
     # solicitation.
     self.assertThat(transmitted.type, Equals("advertisement"))
     # This tests that the post gets closed properly; otherwise the test
     # suite will complain about things left in the reactor.
     yield protocol.stopProtocol()
     # In debug mode, the logger should have printed each packet.
     self.assertThat(
         logger.output,
         DocTestMatches("...Beacon received:...Own beacon received:..."),
     )