Skip to content

Commit 5a753bb

Browse files
committed
Code dump
1 parent e95f06e commit 5a753bb

File tree

9 files changed

+286
-106
lines changed

9 files changed

+286
-106
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
service name:hostapd :%i \
1+
service <!> name:hostapd :%i \
22
[2345] hostapd -P/var/run/hostapd-%i.pid /etc/hostapd-%i.conf \
33
-- Hostapd (Wi-Fi AccessPoint, 802.1X) @%i
44

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
import subprocess
5+
import json
6+
import re
7+
import os
8+
9+
def check_interface_exists(interface):
10+
"""Check if the network interface exists"""
11+
try:
12+
result = subprocess.run(['ip', 'link', 'show', interface],
13+
capture_output=True, check=True)
14+
return True
15+
except subprocess.CalledProcessError:
16+
return False
17+
18+
def parse_iw_station_dump(interface):
19+
"""Parse iw station dump output and return JSON"""
20+
try:
21+
result = subprocess.run(['sudo', 'iw', 'dev', interface, 'station', 'dump'],
22+
capture_output=True, text=True, check=True)
23+
output = result.stdout
24+
except subprocess.CalledProcessError as e:
25+
print(f"Error running iw command: {e}", file=sys.stderr)
26+
return []
27+
except FileNotFoundError:
28+
print("Error: 'iw' command not found", file=sys.stderr)
29+
return []
30+
31+
stations = []
32+
current_station = {}
33+
34+
for line in output.split('\n'):
35+
line = line.strip()
36+
37+
if line.startswith('Station'):
38+
if current_station:
39+
stations.append(current_station)
40+
41+
mac_match = re.search(r'Station ([a-fA-F0-9:]{17})', line)
42+
current_station = {
43+
'mac-address': mac_match.group(1) if mac_match else 'unknown',
44+
'tx-speed': 'unknown',
45+
'rx-speed': 'unknown',
46+
'rssi': 0,
47+
'connected-time': 'unknown'
48+
}
49+
50+
elif 'tx bitrate:' in line:
51+
bitrate_match = re.search(r'tx bitrate:\s*(\d+\.?\d*)\s*(MBit/s|Gbit/s)', line)
52+
if bitrate_match:
53+
speed = bitrate_match.group(1)
54+
unit = bitrate_match.group(2)
55+
current_station['tx-speed'] = f"{speed} {unit.replace('Bit/s', 'bps')}"
56+
57+
elif 'rx bitrate:' in line:
58+
bitrate_match = re.search(r'rx bitrate:\s*(\d+\.?\d*)\s*(MBit/s|Gbit/s)', line)
59+
if bitrate_match:
60+
speed = bitrate_match.group(1)
61+
unit = bitrate_match.group(2)
62+
current_station['rx-speed'] = f"{speed} {unit.replace('Bit/s', 'bps')}"
63+
64+
elif 'signal:' in line and 'avg' not in line:
65+
signal_match = re.search(r'signal:\s*(-?\d+)', line)
66+
if signal_match:
67+
current_station['rssi'] = int(f"{signal_match.group(1)}")
68+
69+
elif 'connected time:' in line:
70+
time_match = re.search(r'connected time:\s*(\d+\s+\w+)', line)
71+
if time_match:
72+
current_station['connected-time'] = time_match.group(1)
73+
74+
if current_station:
75+
stations.append(current_station)
76+
77+
return stations
78+
79+
def main():
80+
if len(sys.argv) != 2:
81+
print("Usage: python3 wifi_station_parser.py <interface>")
82+
print("Example: python3 wifi_station_parser.py wifi0_ap2")
83+
sys.exit(1)
84+
85+
interface = sys.argv[1]
86+
87+
if not check_interface_exists(interface):
88+
print(f"Error: Interface '{interface}' not found", file=sys.stderr)
89+
sys.exit(1)
90+
91+
stations = parse_iw_station_dump(interface)
92+
print(json.dumps(stations, indent=2))
93+
94+
if __name__ == "__main__":
95+
main()

src/confd/src/ietf-interfaces.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net,
426426
case IFT_WIFI:
427427
return wifi_gen(NULL, cif, net);
428428
case IFT_WIFI_AP:
429-
return wifi_ap_add_iface(cif, net);
429+
return wifi_ap_add_iface(cif, net) || wifi_gen(NULL, wifi_ap_get_radio(cif), net);
430430
case IFT_ETH:
431431
return netdag_gen_ethtool(net, cif, dif);
432432
case IFT_LO:
@@ -458,15 +458,8 @@ static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net,
458458
case IFT_WIFI:
459459
return wifi_gen(dif, cif, net);
460460
case IFT_WIFI_AP: {
461-
struct lyd_node *wifi = lydx_get_child(cif, "wifi");
462-
if (wifi) {
463-
const char *radio = lydx_get_cattr(wifi, "radio");
464-
if (radio) {
465-
struct lyd_node *radio_if = lydx_get_xpathf(cif, "../interface[name='%s']", radio);
466-
if (radio_if)
467-
return wifi_ap_gen(radio_if, net);
468-
}
469-
}
461+
struct lyd_node *radio_if = wifi_ap_get_radio(cif);
462+
return wifi_gen(NULL, radio_if, net);
470463
return 0;
471464
}
472465
case IFT_DUMMY:
@@ -498,7 +491,7 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif)
498491
case IFT_ETH:
499492
return lydx_get_child(dif, "custom-phys-address");
500493
case IFT_WIFI_AP:
501-
return lydx_get_child(dif, "custom-phys-address") || wifi_ap_must_delete(dif);
494+
return lydx_get_child(dif, "custom-phys-address");
502495

503496
case IFT_GRE:
504497
case IFT_GRETAP:
@@ -635,7 +628,6 @@ static sr_error_t netdag_gen_iface(sr_session_ctx_t *session, struct dagger *net
635628
int err = 0;
636629
FILE *ip;
637630

638-
639631
err = netdag_gen_iface_timeout(net, ifname, iftype);
640632
if (err)
641633
goto err;

src/confd/src/ietf-interfaces.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ int wifi_ap_add_iface(struct lyd_node *cif,struct dagger *net);
128128
int wifi_ap_del_iface(struct lyd_node *cif,struct dagger *net);
129129
int wifi_ap_gen(struct lyd_node *cif, struct dagger *net);
130130
int wifi_gen_del(struct lyd_node *iface, struct dagger *net);
131+
int wifi_is_accesspoint(struct lyd_node *cif);
131132
bool wifi_ap_must_delete(struct lyd_node *dif);
133+
struct lyd_node *wifi_ap_get_radio(struct lyd_node *cif);
132134

133135
/* infix-if-gre.c */
134136
int gre_gen(struct lyd_node *dif, struct lyd_node *cif, FILE *ip);

0 commit comments

Comments
 (0)