Skip to content

Commit e2b6c96

Browse files
committed
Alessandro's Concealment module now works in persistent mode
1 parent b15ad08 commit e2b6c96

28 files changed

+4030
-22
lines changed

dhalsim/physical_process.py

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,55 @@ def __init__(self, intermediate_yaml):
124124
self.db_sleep_time = random.uniform(0.01, 0.1)
125125
self.logger.info("DB Sleep time: " + str(self.db_sleep_time))
126126

127+
def set_sync(self, flag):
128+
"""
129+
Set this plcs sync flag in the sync table. When this is 1, the physical process
130+
knows this plc finished the requested iteration.
131+
On a :code:`sqlite3.OperationalError` it will retry with a max of :code:`DB_TRIES` tries.
132+
Before it reties, it will sleep for :code:`DB_SLEEP_TIME` seconds.
133+
:param flag: True for sync to 1, False for sync to 0
134+
:type flag: bool
135+
:raise DatabaseError: When a :code:`sqlite3.OperationalError` is still raised after
136+
:code:`DB_TRIES` tries.
137+
"""
138+
#"UPDATE sync SET flag=2"
139+
self.db_query("UPDATE sync SET flag=?", True, (int(flag),))
140+
141+
def db_query(self, query, write=False, parameters=None):
142+
"""
143+
Execute a query on the database
144+
On a :code:`sqlite3.OperationalError` it will retry with a max of :code:`DB_TRIES` tries.
145+
Before it reties, it will sleep for :code:`DB_SLEEP_TIME` seconds.
146+
This is necessary because of the limited concurrency in SQLite.
147+
:param query: The SQL query to execute in the db
148+
:type query: str
149+
:param write: Boolean flag to indicate if this query will write into the database
150+
:param parameters: The parameters to put in the query. This must be a tuple.
151+
:raise DatabaseError: When a :code:`sqlite3.OperationalError` is still raised after
152+
:code:`DB_TRIES` tries.
153+
"""
154+
for i in range(self.DB_TRIES):
155+
try:
156+
with sqlite3.connect(self.data["db_path"]) as conn:
157+
cur = conn.cursor()
158+
if parameters:
159+
cur.execute(query, parameters)
160+
else:
161+
cur.execute(query)
162+
conn.commit()
163+
164+
if not write:
165+
return cur.fetchone()[0]
166+
else:
167+
return
168+
except sqlite3.OperationalError as exc:
169+
self.logger.info(
170+
"Failed to connect to db with exception {exc}. Trying {i} more times.".format(
171+
exc=exc, i=self.DB_TRIES - i - 1))
172+
time.sleep(self.db_sleep_time)
173+
174+
self.logger.error("Failed to connect to db. Tried {i} times.".format(i=self.DB_TRIES))
175+
raise DatabaseError("Failed to execute db query in database")
127176

128177
def prepare_wntr_simulator(self):
129178
self.logger.info("Preparing wntr simulation")
@@ -577,7 +626,7 @@ def set_to_db(self, what, value):
577626
time.sleep(self.db_sleep_time)
578627
self.logger.error(
579628
"Failed to connect to db. Tried {i} times.".format(i=self.DB_TRIES))
580-
raise DatabaseError("Failed to get master clock from database")
629+
raise DatabaseError("Failed to set value to database")
581630

582631
def get_from_db(self, what):
583632
"""Returns the first element of the result tuple."""
@@ -645,10 +694,12 @@ def simulate_with_epynet(self, iteration_limit, p_bar):
645694
time.sleep(self.WAIT_FOR_FLAG)
646695

647696
# Notify the PLCs they can start receiving remote values
648-
with sqlite3.connect(self.data["db_path"]) as conn:
649-
c = conn.cursor()
650-
c.execute("UPDATE sync SET flag=2")
651-
conn.commit()
697+
self.set_sync(2)
698+
699+
#with sqlite3.connect(self.data["db_path"]) as conn:
700+
# c = conn.cursor()
701+
# c.execute("UPDATE sync SET flag=2")
702+
# conn.commit()
652703

653704
# Wait for the PLCs to apply control logic
654705
while not self.get_plcs_ready(3):
@@ -696,10 +747,11 @@ def simulate_with_epynet(self, iteration_limit, p_bar):
696747
self.write_results(self.results_list)
697748

698749
# Set sync flags for nodes
699-
with sqlite3.connect(self.data["db_path"]) as conn:
700-
c = conn.cursor()
701-
c.execute("UPDATE sync SET flag=0")
702-
conn.commit()
750+
self.set_sync(0)
751+
#with sqlite3.connect(self.data["db_path"]) as conn:
752+
# c = conn.cursor()
753+
# c.execute("UPDATE sync SET flag=0")
754+
# conn.commit()
703755

704756
simulation_time = simulation_time + internal_epynet_step
705757
conn = sqlite3.connect(self.data["db_path"])
@@ -722,10 +774,11 @@ def simulate_with_wntr(self, iteration_limit, p_bar):
722774
time.sleep(self.WAIT_FOR_FLAG)
723775

724776
# Notify the PLCs they can start receiving remote values
725-
with sqlite3.connect(self.data["db_path"]) as conn:
726-
c = conn.cursor()
727-
c.execute("UPDATE sync SET flag=2")
728-
conn.commit()
777+
self.set_sync(2)
778+
#with sqlite3.connect(self.data["db_path"]) as conn:
779+
# c = conn.cursor()
780+
# c.execute("UPDATE sync SET flag=2")
781+
# conn.commit()
729782

730783
# Wait for the PLCs to apply control logic
731784
while not self.get_plcs_ready(3):
@@ -765,10 +818,11 @@ def simulate_with_wntr(self, iteration_limit, p_bar):
765818
self.write_results(self.results_list)
766819

767820
# Set sync flags for nodes
768-
with sqlite3.connect(self.data["db_path"]) as conn:
769-
c = conn.cursor()
770-
c.execute("UPDATE sync SET flag=0")
771-
conn.commit()
821+
self.set_sync(0)
822+
#with sqlite3.connect(self.data["db_path"]) as conn:
823+
# c = conn.cursor()
824+
# c.execute("UPDATE sync SET flag=0")
825+
# conn.commit()
772826

773827
def update_tanks(self, network_state=None):
774828
"""Update tanks in database."""

dhalsim/python2/automatic_attacker.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,22 @@ def start_attack(self):
7070
"""Start a attack process."""
7171
generic_plc_path = None
7272
if self.this_attacker_data['type'] == 'mitm':
73+
self.logger.debug("Launching mitm attack script")
7374
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "mitm_attack.py"
7475
elif self.this_attacker_data['type'] == 'server_mitm':
76+
self.logger.debug("Launching server mitm attack script")
7577
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "cppo_server_mitm_attack.py"
7678
elif self.this_attacker_data['type'] == 'naive_mitm':
79+
self.logger.debug("Launching naive mitm attack script")
7780
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "naive_attack.py"
7881
elif self.this_attacker_data['type'] == 'simple_dos':
82+
self.logger.debug("Launching simple dos attack script")
7983
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "simple_dos_attack.py"
8084
elif self.this_attacker_data['type'] == 'concealment_mitm':
85+
self.logger.debug("Launching concealmentmitm attack script")
8186
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "concealment_mitm.py"
8287
elif self.this_attacker_data['type'] == 'unconstrained_blackbox_concealment_mitm':
88+
self.logger.debug("Launching blackboc concealment attack script")
8389
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "black_box_concealment_attack.py"
8490
elif self.this_attacker_data['type'] == 'replay_mitm':
8591
generic_plc_path = Path(__file__).parent.parent.absolute() / "network_attacks" / "replay_mitm.py"

dhalsim/python2/generic_plc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ def db_query(self, query, write=False, parameters=None):
370370
time.sleep(self.db_sleep_time)
371371

372372
self.logger.error("Failed to connect to db. Tried {i} times.".format(i=self.DB_TRIES))
373-
raise DatabaseError("Failed to get master clock from database")
373+
raise DatabaseError("Failed to execute query in database")
374374

375375
def get_master_clock(self):
376376
"""

examples/ctown_topology/ctown_plcs.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
- name: PLC4 # PLC4, T3,
3434
sensors:
3535
- T3
36-
- T4
3736
- name: PLC5 # PLC5, PU8F PU10F PU11F J302 J306 J307 J317, PU8 PU10 PU11
3837
sensors:
3938
- PU8F
@@ -47,9 +46,9 @@
4746
- PU8
4847
- PU10
4948
- PU11
50-
#- name: PLC6 # PLC6, T4,
51-
# sensors:
52-
# - T4
49+
- name: PLC6 # PLC6, T4,
50+
sensors:
51+
- T4
5352
- name: PLC7 # PLC7, T5,
5453
sensors:
5554
- T5
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
inp_file: ctown_map.inp
2+
iterations: 2880
3+
network_topology_type: complex
4+
plcs: !include ctown_plcs.yaml
5+
log_level: debug
6+
simulator: epynet
7+
demand: pdd
8+
output_path: attack_output_01
9+
demand_patterns: events/demands_ctown_01.csv
10+
initial_tank_data: events/tanks_ctown_01.csv
11+
attacks: !include dataset_attacks/attack_01.yaml
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
inp_file: ctown_map.inp
2+
iterations: 2880
3+
network_topology_type: complex
4+
plcs: !include ctown_plcs.yaml
5+
log_level: debug
6+
simulator: epynet
7+
demand: pdd
8+
output_path: attack_output_02
9+
demand_patterns: events/demands_ctown_01.csv
10+
initial_tank_data: events/tanks_ctown_01.csv
11+
attacks: !include dataset_attacks/attack_02.yaml
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
inp_file: ctown_map.inp
2+
iterations: 2880
3+
network_topology_type: complex
4+
plcs: !include ctown_plcs.yaml
5+
log_level: debug
6+
simulator: epynet
7+
demand: pdd
8+
output_path: attack_output_03
9+
demand_patterns: events/demands_ctown_01.csv
10+
initial_tank_data: events/tanks_ctown_01.csv
11+
attacks: !include dataset_attacks/attack_03.yaml
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
inp_file: ctown_map.inp
2+
iterations: 2880
3+
network_topology_type: complex
4+
plcs: !include ctown_plcs.yaml
5+
log_level: debug
6+
simulator: epynet
7+
demand: pdd
8+
output_path: attack_output_04
9+
demand_patterns: events/demands_ctown_01.csv
10+
initial_tank_data: events/tanks_ctown_01.csv
11+
attacks: !include dataset_attacks/attack_04.yaml
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
inp_file: ctown_map.inp
2+
iterations: 2880
3+
network_topology_type: complex
4+
plcs: !include ctown_plcs.yaml
5+
log_level: debug
6+
simulator: epynet
7+
demand: pdd
8+
output_path: attack_output_05
9+
demand_patterns: events/demands_ctown_01.csv
10+
initial_tank_data: events/tanks_ctown_01.csv
11+
attacks: !include dataset_attacks/attack_05.yaml

0 commit comments

Comments
 (0)