Skip to content

Commit b6a398f

Browse files
committed
[examples] Add example of traffic interception
1 parent f8e233a commit b6a398f

File tree

3 files changed

+151
-0
lines changed

3 files changed

+151
-0
lines changed

examples/arp_response.hex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
XX XX XX XX XX XX
2+
XX XX XX XX XX XX
3+
08 06
4+
00 01
5+
08 00
6+
06
7+
04
8+
00 02
9+
7A 62 65 74 68 31
10+
0A 00 00 65
11+
XX XX XX XX XX XX
12+
XX XX XX XX

examples/arp_spoof_response.zbscr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
.comp 12
3+
eq16 0x0806 # Type: ARP
4+
5+
eq16 0x0001 # Hardware: Ethernet
6+
eq16 0x0800 # Protocol: IPv4
7+
eq8 0x06 # Hardware size: 6
8+
eq8 0x04 # Protocol size: 4
9+
eq16 0x0002 # Opcode: Reply
10+
11+
.extr 22
12+
ext 6 # Extract sender's MAC address
13+
14+
.edit 22
15+
set32 0xC0FFEE00 # Overwrite sender's MAC address
16+
setr 2

examples/frame_detector.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python3
2+
"""
3+
zbnt/python-client
4+
Copyright (C) 2020 Oscar R.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
"""
19+
20+
import asyncio
21+
from zbnt import ZbntClient, TrafficGenerator, Devices, Properties, discover_devices
22+
23+
output_file = open("results.csv", "w")
24+
25+
def write_fd_measurement(dev_id, measurement_data):
26+
measurement_data = list(measurement_data)
27+
measurement_data[-1] = measurement_data[-1].hex()
28+
29+
output_file.write(",".join(map(str, measurement_data)))
30+
output_file.write("\n")
31+
32+
async def main():
33+
# Scan for devices, ask the user to select one if multiple devices are found
34+
35+
devices = await discover_devices(4)
36+
37+
if len(devices) == 0:
38+
print("Error: No devices found")
39+
exit(1)
40+
41+
if len(devices) > 1:
42+
print("Available devices:\n")
43+
44+
for i in range(len(devices)):
45+
print("{0}) {1} ({2})".format(i + 1, devices[i]["name"], devices[i]["address"]))
46+
47+
req_dev = int(input("\nSelect a device [1-{0}]: ".format(len(devices)))) - 1
48+
49+
if req_dev < 0 or req_dev >= len(devices):
50+
print("Error: Invalid device selected")
51+
exit(1)
52+
53+
print("")
54+
else:
55+
req_dev = 0
56+
57+
req_dev = devices[req_dev]
58+
59+
# Connect to selected device, load a bitstream
60+
61+
print("- Connecting to {0} ({1})".format(req_dev["name"], req_dev["address"]))
62+
63+
client = await ZbntClient.connect(req_dev["address"], req_dev["port"])
64+
65+
if client == None:
66+
print("Error: Failed to connect to device")
67+
exit(1)
68+
69+
print("- Connected!")
70+
71+
if not await client.load_bitstream("dual_tgen_detector"):
72+
print("Error: Failed to load bitstream")
73+
exit(1)
74+
75+
print("- Bitstream loaded")
76+
77+
# Get handle to the timer, eth0 traffic generator and eth0 stats collector
78+
79+
timer = client.get_device(Devices.DEV_SIMPLE_TIMER)
80+
tgen0 = client.get_device(Devices.DEV_TRAFFIC_GENERATOR, {0})
81+
fd0 = client.get_device(Devices.DEV_FRAME_DETECTOR, {2, 3})
82+
83+
# Set function to be called every time the server sends measurement data
84+
85+
fd0.measurement_handler = write_fd_measurement
86+
87+
# Tell the server to start the run, this will initialize the DMA core
88+
89+
await client.start_run()
90+
91+
# Configure tgen0, sc0 and the timer
92+
93+
template_bytes, template_mask = TrafficGenerator.load_frame_template("arp_response.hex")
94+
script_bytes = fd0.load_script("arp_spoof_response.zbscr")
95+
96+
await fd0.set_property(Properties.PROP_FRAME_SCRIPT, script_bytes, {"index": 0})
97+
await fd0.set_property(Properties.PROP_ENABLE_SCRIPT, 1)
98+
await fd0.set_property(Properties.PROP_ENABLE_LOG, True)
99+
await fd0.set_property(Properties.PROP_ENABLE, True)
100+
101+
await tgen0.set_property(Properties.PROP_FRAME_TEMPLATE, template_bytes)
102+
await tgen0.set_property(Properties.PROP_FRAME_TEMPLATE_MASK, template_mask)
103+
await tgen0.set_property(Properties.PROP_FRAME_SIZE, 64)
104+
await tgen0.set_property(Properties.PROP_FRAME_GAP, 12500000)
105+
await tgen0.set_property(Properties.PROP_ENABLE, True)
106+
107+
await timer.set_property(Properties.PROP_TIMER_LIMIT, 10 * timer.freq)
108+
await timer.set_property(Properties.PROP_ENABLE, True)
109+
110+
# Wait until all data has been sent and the server stops the run
111+
112+
await client.wait_for_run_end()
113+
114+
# Get overflow counters
115+
116+
res, (overflow_a2b, overflow_b2a) = await fd0.get_property(Properties.PROP_OVERFLOW_COUNT)
117+
118+
if res:
119+
print("- Overflow counters: {0}, {1}".format(overflow_a2b, overflow_b2a))
120+
121+
asyncio.run(main())
122+
123+
output_file.close()

0 commit comments

Comments
 (0)