-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmacdisplay.py
More file actions
109 lines (92 loc) · 3.62 KB
/
macdisplay.py
File metadata and controls
109 lines (92 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from pwnagotchi.ui.components import Text
from pwnagotchi.ui.view import WHITE
import pwnagotchi.plugins as plugins
import pwnagotchi
import subprocess
import threading
import logging
import time
import os
LOG_FILE = "/home/pi/macdisplay.log"
logging.basicConfig(level=logging.INFO)
def log_to_file(message):
with open(LOG_FILE, "a") as f:
f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {message}\n")
def run_and_log(command):
try:
log_to_file(f"Running: {' '.join(command)}")
result = subprocess.run(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=True
)
log_to_file(f"Output:\n{result.stdout.strip()}")
return result.stdout.strip()
except subprocess.CalledProcessError as e:
log_to_file(f"Error:\n{e.stderr.strip()}")
raise
def wait_for_interface(interface, up=True, timeout=10):
for _ in range(timeout):
result = subprocess.run(["ip", "link", "show", interface], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if (up and b"state UP" in result.stdout) or (not up and b"state DOWN" in result.stdout):
return True
time.sleep(1)
return False
class MacDisplay(plugins.Plugin):
__author__ = "your_name"
__version__ = "1.2"
__license__ = "GPL3"
__description__ = "Changes MAC, sets monitor mode, logs output, and displays MAC info on boot with face."
def __init__(self):
self.mac_text = ""
self.displayed = False
self.failed = False
def on_loaded(self):
logging.info("[macdisplay] Plugin loaded.")
try:
run_and_log(["ip", "link", "set", "wlan0", "down"])
wait_for_interface("wlan0", up=False)
output = run_and_log(["macchanger", "-r", "wlan0"])
run_and_log(["iw", "dev", "wlan0", "set", "type", "monitor"])
run_and_log(["ip", "link", "set", "wlan0", "up"])
wait_for_interface("wlan0", up=True)
# Parse MAC output
lines = output.splitlines()
old_mac = next((l for l in lines if "Permanent MAC" in l), "")
new_mac = next((l for l in lines if "New MAC" in l), "")
self.mac_text = f"{old_mac}\n{new_mac}" if old_mac and new_mac else "MAC change failed"
self.failed = False
except subprocess.CalledProcessError as e:
self.mac_text = f"MAC setup failed:\n{e}"
logging.error(f"[macdisplay] MAC setup error: {e}")
self.failed = True
log_to_file(f"Final MAC text: {self.mac_text}")
def on_ui_setup(self, ui):
ui.add_element(
"mac_display",
Text(
color=WHITE,
value="",
position=(5, 5),
font=pwnagotchi.ui.fonts.Small
)
)
def on_ready(self, ui):
if not self.displayed:
self.displayed = True
# Set face depending on success
if self.failed:
ui.set("face", "(╯°□°)╯︵ ┻━┻")
else:
ui.set("face", "^_^")
# Show MAC info
ui.set("mac_display", self.mac_text)
# Clear after delay
def hide_after_delay():
time.sleep(10)
with ui._lock:
ui.set("mac_display", "")
ui.set("face", "-_-") # Optional: reset face
threading.Thread(target=hide_after_delay, daemon=True).start()