diff --git a/CHANGELOG.md b/CHANGELOG.md index 8766da6f..c16e876f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Add dedicated port list for alive detection (Boreas only) as scanner preference if supplied via OSP. [#327](https://github.com/greenbone/ospd-openvas/pull/327) - Add methods for adding VTs to the redis cache.[#337](https://github.com/greenbone/ospd-openvas/pull/337) +- Add support for supplying alive test methods via seperate elements. [#331](https://github.com/greenbone/ospd-openvas/pull/331) ### Changed - Get all results from main kb. [#285](https://github.com/greenbone/ospd-openvas/pull/285) diff --git a/ospd_openvas/preferencehandler.py b/ospd_openvas/preferencehandler.py index f9c4c1c3..9c36221f 100644 --- a/ospd_openvas/preferencehandler.py +++ b/ospd_openvas/preferencehandler.py @@ -62,6 +62,27 @@ class AliveTest(IntEnum): ALIVE_TEST_TCP_SYN_SERVICE = 16 +def alive_test_methods_to_bit_field( + icmp: bool, tcp_syn: bool, tcp_ack: bool, arp: bool, consider_alive: bool +) -> int: + """Internally a bit field is used as alive test. This function creates + such a bit field out of the supplied alive test methods. + """ + + icmp_enum = AliveTest.ALIVE_TEST_ICMP if icmp else 0 + tcp_syn_enum = AliveTest.ALIVE_TEST_TCP_SYN_SERVICE if tcp_syn else 0 + tcp_ack_enum = AliveTest.ALIVE_TEST_TCP_ACK_SERVICE if tcp_ack else 0 + arp_enum = AliveTest.ALIVE_TEST_ARP if arp else 0 + consider_alive_enum = ( + AliveTest.ALIVE_TEST_CONSIDER_ALIVE if consider_alive else 0 + ) + + bit_field = ( + icmp_enum | tcp_syn_enum | tcp_ack_enum | arp_enum | consider_alive_enum + ) + return bit_field + + def _from_bool_to_str(value: int) -> str: """The OpenVAS scanner use yes and no as boolean values, whereas ospd uses 1 and 0.""" @@ -289,9 +310,26 @@ def build_alive_test_opt_as_prefs( in string format to be added to the redis KB. """ target_opt_prefs_list = [] - if target_options and target_options.get('alive_test'): + alive_test = None + + if target_options: + # Alive test speciefied as bit field. + alive_test = target_options.get('alive_test') + # Alive test speciefied as individual methods. + alive_test_methods = target_options.get('alive_test_methods') + # alive_test takes precedence over alive_test_methods + if alive_test is None and alive_test_methods: + alive_test = alive_test_methods_to_bit_field( + icmp=target_options.get('icmp') == '1', + tcp_syn=target_options.get('tcp_syn') == '1', + tcp_ack=target_options.get('tcp_ack') == '1', + arp=target_options.get('arp') == '1', + consider_alive=target_options.get('consider_alive') == '1', + ) + + if target_options and alive_test: try: - alive_test = int(target_options.get('alive_test')) + alive_test = int(alive_test) except ValueError: logger.debug( 'Alive test settings not applied. ' @@ -387,37 +425,61 @@ def build_alive_test_opt_as_prefs( def prepare_alive_test_option_for_openvas(self): """ Set alive test option. Overwrite the scan config settings.""" settings = Openvas.get_settings() - if settings and self.target_options.get('alive_test'): + if settings and ( + self.target_options.get('alive_test') + or self.target_options.get('alive_test_methods') + ): alive_test_opt = self.build_alive_test_opt_as_prefs( self.target_options ) - self.kbdb.add_scan_preferences(self.scan_id, alive_test_opt) + if alive_test_opt: + self.kbdb.add_scan_preferences(self.scan_id, alive_test_opt) def prepare_boreas_alive_test(self): """Set alive_test for Boreas if boreas scanner config (BOREAS_SETTING_NAME) was set""" settings = Openvas.get_settings() - alive_test = -1 + alive_test = None alive_test_ports = None + target_options = self.target_options if settings: boreas = settings.get(BOREAS_SETTING_NAME) if not boreas: return - alive_test_ports = self.target_options.get('alive_test_ports') - alive_test_str = self.target_options.get('alive_test') - if alive_test_str is not None: - try: - alive_test = int(alive_test_str) - except ValueError: - logger.debug( - 'Alive test preference for Boreas not set. ' - 'Invalid alive test value %s.', - alive_test_str, - ) - # ALIVE_TEST_SCAN_CONFIG_DEFAULT if no alive_test provided - else: + else: + return + + if target_options: + alive_test_ports = target_options.get('alive_test_ports') + # Alive test was speciefied as bit field. + alive_test = target_options.get('alive_test') + # Alive test was speciefied as individual methods. + alive_test_methods = target_options.get('alive_test_methods') + # takes precedence over + if alive_test is None and alive_test_methods: + alive_test = alive_test_methods_to_bit_field( + icmp=target_options.get('icmp') == '1', + tcp_syn=target_options.get('tcp_syn') == '1', + tcp_ack=target_options.get('tcp_ack') == '1', + arp=target_options.get('arp') == '1', + consider_alive=target_options.get('consider_alive') == '1', + ) + + if alive_test is not None: + try: + alive_test = int(alive_test) + except ValueError: + logger.debug( + 'Alive test preference for Boreas not set. ' + 'Invalid alive test value %s.', + alive_test, + ) + # Use default alive test as fall back alive_test = AliveTest.ALIVE_TEST_SCAN_CONFIG_DEFAULT + # Use default alive test if no valid alive_test was provided + else: + alive_test = AliveTest.ALIVE_TEST_SCAN_CONFIG_DEFAULT # If a valid alive_test was set then the bit mask # has value between 31 (11111) and 1 (10000) @@ -437,7 +499,8 @@ def prepare_boreas_alive_test(self): # Add portlist if present. Validity is checked on Boreas side. if alive_test_ports is not None: pref = "{pref_key}|||{pref_value}".format( - pref_key=BOREAS_ALIVE_TEST_PORTS, pref_value=alive_test_ports + pref_key=BOREAS_ALIVE_TEST_PORTS, + pref_value=alive_test_ports, ) self.kbdb.add_scan_preferences(self.scan_id, [pref]) diff --git a/tests/test_preferencehandler.py b/tests/test_preferencehandler.py index 1eb76666..21db86e8 100644 --- a/tests/test_preferencehandler.py +++ b/tests/test_preferencehandler.py @@ -36,6 +36,7 @@ BOREAS_ALIVE_TEST, BOREAS_ALIVE_TEST_PORTS, PreferenceHandler, + alive_test_methods_to_bit_field, ) @@ -203,6 +204,13 @@ def test_build_alive_test_opt_empty(self): self.assertEqual(ret, []) + # alive test was supplied via seperate xml element + w = DummyDaemon() + target_options_dict = {'alive_test_methods': '1', 'icmp': '0'} + p = PreferenceHandler('1234-1234', None, w.scan_collection, None) + ret = p.build_alive_test_opt_as_prefs(target_options_dict) + self.assertEqual(ret, []) + def test_build_alive_test_opt(self): w = DummyDaemon() @@ -220,6 +228,21 @@ def test_build_alive_test_opt(self): self.assertEqual(ret, alive_test_out) + # alive test was supplied via sepertae xml element + w = DummyDaemon() + alive_test_out = [ + "1.3.6.1.4.1.25623.1.0.100315:1:checkbox:Do a TCP ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:2:checkbox:TCP ping tries also TCP-SYN ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:7:checkbox:TCP ping tries only TCP-SYN ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:3:checkbox:Do an ICMP ping|||yes", + "1.3.6.1.4.1.25623.1.0.100315:4:checkbox:Use ARP|||no", + "1.3.6.1.4.1.25623.1.0.100315:5:checkbox:Mark unrechable Hosts as dead (not scanning)|||yes", + ] + target_options_dict = {'alive_test_methods': '1', 'icmp': '1'} + p = PreferenceHandler('1234-1234', None, w.scan_collection, None) + ret = p.build_alive_test_opt_as_prefs(target_options_dict) + self.assertEqual(ret, alive_test_out) + def test_build_alive_test_opt_fail_1(self): w = DummyDaemon() logging.Logger.debug = Mock() @@ -243,7 +266,8 @@ def test_set_target(self, mock_kb): p.prepare_target_for_openvas() p.kbdb.add_scan_preferences.assert_called_with( - p.scan_id, ['TARGET|||192.168.0.1'], + p.scan_id, + ['TARGET|||192.168.0.1'], ) @patch('ospd_openvas.db.KbDB') @@ -258,7 +282,8 @@ def test_set_ports(self, mock_kb): p.prepare_ports_for_openvas() p.kbdb.add_scan_preferences.assert_called_with( - p.scan_id, ['port_range|||80,443'], + p.scan_id, + ['port_range|||80,443'], ) @patch('ospd_openvas.db.KbDB') @@ -271,7 +296,8 @@ def test_set_main_kbindex(self, mock_kb): p.prepare_main_kbindex_for_openvas() p.kbdb.add_scan_preferences.assert_called_with( - p.scan_id, ['ov_maindbid|||2'], + p.scan_id, + ['ov_maindbid|||2'], ) @patch('ospd_openvas.db.KbDB') @@ -364,7 +390,8 @@ def test_set_host_options(self, mock_kb): p.prepare_host_options_for_openvas() p.kbdb.add_scan_preferences.assert_called_with( - p.scan_id, ['exclude_hosts|||192.168.0.1'], + p.scan_id, + ['exclude_hosts|||192.168.0.1'], ) @patch('ospd_openvas.db.KbDB') @@ -423,7 +450,10 @@ def test_set_reverse_lookup_opt(self, mock_kb): p.kbdb.add_scan_preferences.assert_called_with( p.scan_id, - ['reverse_lookup_only|||yes', 'reverse_lookup_unify|||no',], + [ + 'reverse_lookup_only|||yes', + 'reverse_lookup_unify|||no', + ], ) @patch('ospd_openvas.db.KbDB') @@ -431,6 +461,8 @@ def test_set_boreas_alive_test_with_settings(self, mock_kb): # No Boreas config setting (BOREAS_SETTING_NAME) set w = DummyDaemon() ov_setting = {'not_the_correct_setting': 1} + t_opt = {} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) with patch.object(Openvas, 'get_settings', return_value=ov_setting): p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) p.scan_id = '456-789' @@ -450,7 +482,8 @@ def test_set_boreas_alive_test_with_settings(self, mock_kb): p.kbdb.add_scan_preferences = MagicMock() p.prepare_boreas_alive_test() - p.kbdb.add_scan_preferences.assert_not_called() + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||2'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) # ALIVE_TEST_TCP_SYN_SERVICE as alive test. w = DummyDaemon() @@ -514,6 +547,167 @@ def test_set_boreas_alive_test_with_settings(self, mock_kb): ] p.kbdb.add_scan_preferences.assert_has_calls(calls) + @patch('ospd_openvas.db.KbDB') + def test_set_boreas_alive_test_not_as_enum(self, mock_kb): + # No Boreas config setting (BOREAS_SETTING_NAME) set + w = DummyDaemon() + ov_setting = {'not_the_correct_setting': 1} + t_opt = {} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + p.kbdb.add_scan_preferences.assert_not_called() + + # Boreas config setting set but invalid alive_test. + w = DummyDaemon() + t_opt = {'alive_test_methods': "1", 'arp': '-1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||2'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # ICMP was chosen as alive test. + w = DummyDaemon() + t_opt = {'alive_test_methods': "1", 'icmp': '1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||2'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # tcp_syn as alive test. + w = DummyDaemon() + t_opt = {'alive_test_methods': "1", 'tcp_syn': '1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||16'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # tcp_ack as alive test. + w = DummyDaemon() + t_opt = {'alive_test_methods': "1", 'tcp_ack': '1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||1'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # arp as alive test. + w = DummyDaemon() + t_opt = {'alive_test_methods': "1", 'arp': '1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||4'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # arp as alive test. + w = DummyDaemon() + t_opt = {'alive_test_methods': "1", 'consider_alive': '1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||8'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # all alive test methods + w = DummyDaemon() + t_opt = { + 'alive_test_methods': "1", + 'icmp': '1', + 'tcp_ack': '1', + 'tcp_syn': '1', + 'arp': '1', + 'consider_alive': '1', + } + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||31'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + # TCP-SYN alive test and dedicated port list for alive scan provided. + w = DummyDaemon() + t_opt = { + 'alive_test_ports': "80,137", + 'alive_test_methods': "1", + 'tcp_syn': '1', + } + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + calls = [ + call(p.scan_id, [BOREAS_ALIVE_TEST + '|||16']), + call(p.scan_id, [BOREAS_ALIVE_TEST_PORTS + '|||80,137']), + ] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + + @patch('ospd_openvas.db.KbDB') + def test_set_boreas_alive_test_enum_has_precedence(self, mock_kb): + w = DummyDaemon() + t_opt = { + 'alive_test_methods': "1", + 'consider_alive': '1', + 'alive_test': AliveTest.ALIVE_TEST_ICMP, + } + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + ov_setting = {BOREAS_SETTING_NAME: 1} + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_boreas_alive_test() + + # has icmp and not consider_alive + calls = [call(p.scan_id, [BOREAS_ALIVE_TEST + '|||2'])] + p.kbdb.add_scan_preferences.assert_has_calls(calls) + @patch('ospd_openvas.db.KbDB') def test_set_boreas_alive_test_without_settings(self, mock_kb): w = DummyDaemon() @@ -545,6 +739,40 @@ def test_set_alive_no_setting(self, mock_kb): p.kbdb.add_scan_preferences.assert_not_called() + @patch('ospd_openvas.db.KbDB') + def test_set_alive_no_invalid_alive_test(self, mock_kb): + w = DummyDaemon() + + t_opt = {'alive_test': -1} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + + ov_setting = {'some_setting': 1} + + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_alive_test_option_for_openvas() + + p.kbdb.add_scan_preferences.assert_not_called() + + @patch('ospd_openvas.db.KbDB') + def test_set_alive_no_invalid_alive_test_no_enum(self, mock_kb): + w = DummyDaemon() + + t_opt = {'alive_test_methods': '1', 'icmp': '-1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + + ov_setting = {'some_setting': 1} + + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_alive_test_option_for_openvas() + + p.kbdb.add_scan_preferences.assert_not_called() + @patch('ospd_openvas.db.KbDB') def test_set_alive_pinghost(self, mock_kb): w = DummyDaemon() @@ -571,5 +799,130 @@ def test_set_alive_pinghost(self, mock_kb): p.prepare_alive_test_option_for_openvas() p.kbdb.add_scan_preferences.assert_called_with( - p.scan_id, alive_test_out, + p.scan_id, + alive_test_out, ) + + @patch('ospd_openvas.db.KbDB') + def test_prepare_alive_test_not_supplied_as_enum(self, mock_kb): + w = DummyDaemon() + + alive_test_out = [ + "1.3.6.1.4.1.25623.1.0.100315:1:checkbox:Do a TCP ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:2:checkbox:TCP ping tries also TCP-SYN ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:7:checkbox:TCP ping tries only TCP-SYN ping|||no", + "1.3.6.1.4.1.25623.1.0.100315:3:checkbox:Do an ICMP ping|||yes", + "1.3.6.1.4.1.25623.1.0.100315:4:checkbox:Use ARP|||no", + "1.3.6.1.4.1.25623.1.0.100315:5:checkbox:Mark unrechable Hosts as dead (not scanning)|||yes", + ] + + t_opt = {'alive_test_methods': '1', 'icmp': '1'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + + ov_setting = {'some_setting': 1} + + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_alive_test_option_for_openvas() + + p.kbdb.add_scan_preferences.assert_called_with( + p.scan_id, + alive_test_out, + ) + + @patch('ospd_openvas.db.KbDB') + def test_prepare_alive_test_no_enum_no_alive_test(self, mock_kb): + w = DummyDaemon() + + t_opt = {'alive_test_methods': '1', 'icmp': '0'} + w.scan_collection.get_target_options = MagicMock(return_value=t_opt) + + ov_setting = {'some_setting': 1} + + with patch.object(Openvas, 'get_settings', return_value=ov_setting): + p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None) + + p.scan_id = '456-789' + p.kbdb.add_scan_preferences = MagicMock() + p.prepare_alive_test_option_for_openvas() + + p.kbdb.add_scan_preferences.assert_not_called() + + def test_alive_test_methods_to_bit_field(self): + + self.assertEqual( + AliveTest.ALIVE_TEST_TCP_ACK_SERVICE, + alive_test_methods_to_bit_field( + icmp=False, + tcp_ack=True, + tcp_syn=False, + arp=False, + consider_alive=False, + ), + ) + + self.assertEqual( + AliveTest.ALIVE_TEST_ICMP, + alive_test_methods_to_bit_field( + icmp=True, + tcp_ack=False, + tcp_syn=False, + arp=False, + consider_alive=False, + ), + ) + + self.assertEqual( + AliveTest.ALIVE_TEST_ARP, + alive_test_methods_to_bit_field( + icmp=False, + tcp_ack=False, + tcp_syn=False, + arp=True, + consider_alive=False, + ), + ) + + self.assertEqual( + AliveTest.ALIVE_TEST_CONSIDER_ALIVE, + alive_test_methods_to_bit_field( + icmp=False, + tcp_ack=False, + tcp_syn=False, + arp=False, + consider_alive=True, + ), + ) + + self.assertEqual( + AliveTest.ALIVE_TEST_TCP_SYN_SERVICE, + alive_test_methods_to_bit_field( + icmp=False, + tcp_ack=False, + tcp_syn=True, + arp=False, + consider_alive=False, + ), + ) + + all_alive_test_methods = ( + AliveTest.ALIVE_TEST_SCAN_CONFIG_DEFAULT + | AliveTest.ALIVE_TEST_TCP_ACK_SERVICE + | AliveTest.ALIVE_TEST_ICMP + | AliveTest.ALIVE_TEST_ARP + | AliveTest.ALIVE_TEST_CONSIDER_ALIVE + | AliveTest.ALIVE_TEST_TCP_SYN_SERVICE + ) + self.assertEqual( + all_alive_test_methods, + alive_test_methods_to_bit_field( + icmp=True, + tcp_ack=True, + tcp_syn=True, + arp=True, + consider_alive=True, + ), + )