Example #1
0
    def test__build(self):
        mac = factory.getRandomMACAddress()
        discover = DHCPDiscoverPacket(mac)
        discover._build()

        expected = (b'\x01\x01\x06\x00' + discover.transaction_ID +
                    b'\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
                    b'\x00\x00\x00\x00\x00\x00\x00\x00' + discover.packed_mac +
                    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
                    b'\x00' * 67 + b'\x00' * 125 +
                    b'\x63\x82\x53\x63\x35\x01\x01\x3d\x06' +
                    discover.packed_mac + b'\x37\x03\x03\x01\x06\xff')

        self.assertEqual(expected, discover.packet)
Example #2
0
 def test__deferDHCPRequests(self):
     clock = Clock()
     monitor = DHCPRequestMonitor('lo', clock)
     mock_addErrback = mock.MagicMock()
     mock_deferredListResult = mock.MagicMock()
     mock_deferLater = self.patch(detect_module, 'deferLater')
     mock_deferLater.return_value = mock.MagicMock()
     mock_deferLater.return_value.addErrback = mock_addErrback
     mock_DeferredList = self.patch(detect_module, 'DeferredList')
     mock_DeferredList.return_value = mock_deferredListResult
     mock_deferredListResult.addErrback = mock_addErrback
     expected_calls = [
         call(
             clock, seconds + 0.1, send_dhcp_request_packet,
             DHCPDiscoverPacket(transaction_id=monitor.transaction_id,
                                seconds=seconds), 'lo')
         for seconds in DHCP_REQUEST_TIMING
     ]
     monitor.deferDHCPRequests()
     self.assertThat(mock_deferLater, MockCallsMatch(*expected_calls))
     self.assertThat(
         mock_DeferredList,
         MockCallsMatch(
             call(monitor.deferredDHCPRequests,
                  fireOnOneErrback=True,
                  consumeErrors=True)))
     # Expect addErrback to be called both on each individual Deferred, plus
     # one more time on the DeferredList.
     expected_errback_calls = [
         call(monitor.deferredDHCPRequestErrback)
         for _ in range(len(DHCP_REQUEST_TIMING) + 1)
     ]
     self.assertThat(mock_addErrback,
                     MockCallsMatch(*expected_errback_calls))
Example #3
0
    def test_init_sets_transaction_ID(self):
        transaction_id = make_transaction_ID()
        self.patch(detect_module,
                   'make_transaction_ID').return_value = (transaction_id)

        discover = DHCPDiscoverPacket(factory.getRandomMACAddress())

        self.assertEqual(transaction_id, discover.transaction_ID)
Example #4
0
 def test__sends_expected_packet(self):
     mock_socket = patch_socket(self)
     mock_socket.bind = mock.MagicMock()
     mock_socket.sendto = mock.MagicMock()
     self.patch(detect_module.get_interface_ip).return_value = '127.0.0.1'
     self.patch(
         detect_module.get_interface_mac).return_value = '00:00:00:00:00:00'
     request = DHCPDiscoverPacket()
     send_dhcp_request_packet(request, 'lo')
     self.assertThat(mock_socket.bind,
                     MockCallsMatch(call(('127.0.0.1', BOOTP_CLIENT_PORT))))
     self.assertThat(
         mock_socket.sendto,
         MockCallsMatch(
             call(request.packet, ('<broadcast>', BOOTP_SERVER_PORT))))
Example #5
0
 def test__builds_packet(self):
     mac = factory.make_mac_address()
     seconds = random.randint(0, 1024)
     xid = factory.make_bytes(4)
     discover = DHCPDiscoverPacket(transaction_id=xid,
                                   mac=mac,
                                   seconds=seconds)
     seconds_bytes = seconds.to_bytes(2, "big")
     expected = (b"\x01\x01\x06\x00" + xid + seconds_bytes +
                 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
                 b"\x00\x00\x00\x00\x00\x00" + discover.mac_bytes +
                 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
                 b"\x00" * 67 + b"\x00" * 125 +
                 b"\x63\x82\x53\x63\x35\x01\x01" +
                 discover.client_uid_option + b"\x37\x03\x03\x01\x06\xff")
     self.assertEqual(expected, discover.packet)
Example #6
0
 def test__packet_property_after_init_with_mac_and_no_transaction_id(self):
     discover = DHCPDiscoverPacket(factory.make_mac_address())
     self.assertIsNotNone(discover.packet)
Example #7
0
 def test_init_sets_mac_bytes(self):
     mac = factory.make_mac_address()
     discover = DHCPDiscoverPacket(mac)
     self.assertEqual(discover.mac_string_to_bytes(mac), discover.mac_bytes)
Example #8
0
 def test_init_sets_transaction_id(self):
     transaction_id = make_dhcp_transaction_id()
     self.patch(detect_module,
                "make_dhcp_transaction_id").return_value = transaction_id
     discover = DHCPDiscoverPacket(factory.make_mac_address())
     self.assertEqual(transaction_id, discover.transaction_id)
Example #9
0
 def test__send_requests_and_await_replies(self):
     # This test is a bit large because it covers the entire functionality
     # of the `send_requests_and_await_replies()` method. (It could be
     # split apart into multiple tests, but the large amount of setup work
     # and interdependencies makes that a maintenance burden.)
     mock_socket = patch_socket(self)
     mock_socket.bind = mock.MagicMock()
     mock_socket.recvfrom = mock.MagicMock()
     mock_socket.setsockopt = mock.MagicMock()
     mock_socket.settimeout = mock.MagicMock()
     # Pretend we were successful at deferring the DHCP requests.
     self.patch_autospec(detect_module, "blockingCallFromThread")
     # This method normally blocks for ~10 seconds, so take control of the
     # monotonic clock and make sure the last call to `recvfrom()` happens
     # just as we hit the reply timeout.
     mock_time_monotonic = self.patch(detect_module.time.monotonic)
     mock_time_monotonic.side_effect = (
         # Start time (before loop starts).
         10,
         # First reply (truncated packet).
         11,
         # Second reply (not a match to our transaction).
         12,
         # Third reply (Matching reply with server identifier option).
         13,
         # First socket timeout (need to make sure the loop continues).
         14,
         # Second socket timeout (hey, we're done!).
         10 + detect_module.REPLY_TIMEOUT,
     )
     mock_xid = factory.make_bytes(4)
     valid_dhcp_reply = factory.make_dhcp_packet(
         transaction_id=mock_xid,
         include_server_identifier=True,
         server_ip="127.1.1.1",
     )
     mock_get_xid = self.patch(detect_module.make_dhcp_transaction_id)
     mock_get_xid.return_value = mock_xid
     # Valid DHCP packet, but not a match because it doesn't have a
     # Server Identifier option.
     valid_non_match = DHCPDiscoverPacket(mac="01:02:03:04:05:06",
                                          transaction_id=mock_xid).packet
     mock_socket.recvfrom.side_effect = (
         # Truncated packet, to test logging.
         (b"", ("127.0.0.1", BOOTP_SERVER_PORT)),
         (valid_non_match, ("127.0.0.2", BOOTP_SERVER_PORT)),
         (valid_dhcp_reply, ("127.0.0.3", BOOTP_SERVER_PORT)),
         socket.timeout,
         socket.timeout,
     )
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor("lo", Clock())
     result = monitor.send_requests_and_await_replies()
     self.assertThat(
         mock_socket.setsockopt,
         MockCallsMatch(
             call(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1),
             call(socket.SOL_SOCKET, socket.SO_BROADCAST, 1),
         ),
     )
     self.assertThat(mock_socket.bind, MockCallsMatch(call(("", 68))))
     self.assertThat(
         mock_socket.settimeout,
         MockCallsMatch(call(detect_module.SOCKET_TIMEOUT)),
     )
     self.assertThat(
         mock_socket.recvfrom,
         MockCallsMatch(call(2048), call(2048), call(2048), call(2048),
                        call(2048)),
     )
     # One of the response packets was truncated.
     self.assertThat(
         logger.output,
         DocTestMatches("Invalid DHCP response...Truncated..."),
     )
     self.assertThat(result, HasLength(1))
     # Ensure we record the fact that the reply packet came from a different
     # IP address than the server claimed to be.
     self.assertThat(result, Contains(DHCPServer("127.1.1.1", "127.0.0.3")))
Example #10
0
 def test_init_sets_packet(self):
     discover = DHCPDiscoverPacket(factory.getRandomMACAddress())
     self.assertIsNotNone(discover.packet)
Example #11
0
 def test_init_sets_packed_mac(self):
     mac = factory.getRandomMACAddress()
     discover = DHCPDiscoverPacket(mac)
     self.assertEqual(discover.string_mac_to_packed(mac),
                      discover.packed_mac)