| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 | 
							- #!/usr/bin/env ucode
 
- 'use strict';
 
- import { vlist_new, is_equal, wdev_create, wdev_set_mesh_params, wdev_remove, wdev_set_up, phy_open } from "/usr/share/hostap/common.uc";
 
- import { readfile, writefile, basename, readlink, glob } from "fs";
 
- let libubus = require("ubus");
 
- let keep_devices = {};
 
- let phy = shift(ARGV);
 
- let command = shift(ARGV);
 
- let phydev;
 
- function iface_stop(wdev)
 
- {
 
- 	if (keep_devices[wdev.ifname])
 
- 		return;
 
- 	wdev_remove(wdev.ifname);
 
- }
 
- function iface_start(wdev)
 
- {
 
- 	let ifname = wdev.ifname;
 
- 	if (readfile(`/sys/class/net/${ifname}/ifindex`)) {
 
- 		wdev_set_up(ifname, false);
 
- 		wdev_remove(ifname);
 
- 	}
 
- 	let wdev_config = {};
 
- 	for (let key in wdev)
 
- 		wdev_config[key] = wdev[key];
 
- 	if (!wdev_config.macaddr && wdev.mode != "monitor")
 
- 		wdev_config.macaddr = phydev.macaddr_next();
 
- 	wdev_create(phy, ifname, wdev_config);
 
- 	wdev_set_up(ifname, true);
 
- 	if (wdev.freq)
 
- 		system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`);
 
- 	if (wdev.mode == "adhoc") {
 
- 		let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ];
 
- 		if (wdev.bssid)
 
- 			push(cmd, wdev.bssid);
 
- 		for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
 
- 			if (wdev[key])
 
- 				push(cmd, key, wdev[key]);
 
- 		system(cmd);
 
- 	} else if (wdev.mode == "mesh") {
 
- 		let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ];
 
- 		for (let key in [ "mcast-rate", "beacon-interval" ])
 
- 			if (wdev[key])
 
- 				push(cmd, key, wdev[key]);
 
- 		system(cmd);
 
- 		wdev_set_mesh_params(ifname, wdev);
 
- 	}
 
- }
 
- function iface_cb(new_if, old_if)
 
- {
 
- 	if (old_if && new_if && is_equal(old_if, new_if))
 
- 		return;
 
- 	if (old_if)
 
- 		iface_stop(old_if);
 
- 	if (new_if)
 
- 		iface_start(new_if);
 
- }
 
- function drop_inactive(config)
 
- {
 
- 	for (let key in config) {
 
- 		if (!readfile(`/sys/class/net/${key}/ifindex`))
 
- 			delete config[key];
 
- 	}
 
- }
 
- function add_ifname(config)
 
- {
 
- 	for (let key in config)
 
- 		config[key].ifname = key;
 
- }
 
- function delete_ifname(config)
 
- {
 
- 	for (let key in config)
 
- 		delete config[key].ifname;
 
- }
 
- function add_existing(phy, config)
 
- {
 
- 	let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
 
- 	wdevs = map(wdevs, (arg) => basename(arg));
 
- 	for (let wdev in wdevs) {
 
- 		if (config[wdev])
 
- 			continue;
 
- 		if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
 
- 			continue;
 
- 		if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
 
- 			config[wdev] = {};
 
- 	}
 
- }
 
- function usage()
 
- {
 
- 	warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
 
- Commands:
 
- 	set_config <config> [<device]...] - set phy configuration
 
- 	get_macaddr <id>		  - get phy MAC address for vif index <id>
 
- `);
 
- 	exit(1);
 
- }
 
- const commands = {
 
- 	set_config: function(args) {
 
- 		let statefile = `/var/run/wdev-${phy}.json`;
 
- 		let new_config = shift(args);
 
- 		for (let dev in ARGV)
 
- 			keep_devices[dev] = true;
 
- 		if (!new_config)
 
- 			usage();
 
- 		new_config = json(new_config);
 
- 		if (!new_config) {
 
- 			warn("Invalid configuration\n");
 
- 			exit(1);
 
- 		}
 
- 		let old_config = readfile(statefile);
 
- 		if (old_config)
 
- 			old_config = json(old_config);
 
- 		let config = vlist_new(iface_cb);
 
- 		if (type(old_config) == "object")
 
- 			config.data = old_config;
 
- 		add_existing(phy, config.data);
 
- 		add_ifname(config.data);
 
- 		drop_inactive(config.data);
 
- 		let ubus = libubus.connect();
 
- 		let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
 
- 		let macaddr_list = [];
 
- 		if (type(data) == "object" && data.macaddr)
 
- 			macaddr_list = data.macaddr;
 
- 		ubus.disconnect();
 
- 		phydev.macaddr_init(macaddr_list);
 
- 		add_ifname(new_config);
 
- 		config.update(new_config);
 
- 		drop_inactive(config.data);
 
- 		delete_ifname(config.data);
 
- 		writefile(statefile, sprintf("%J", config.data));
 
- 	},
 
- 	get_macaddr: function(args) {
 
- 		let data = {};
 
- 		for (let arg in args) {
 
- 			arg = split(arg, "=", 2);
 
- 			data[arg[0]] = arg[1];
 
- 		}
 
- 		let macaddr = phydev.macaddr_generate(data);
 
- 		if (!macaddr) {
 
- 			warn(`Could not get MAC address for phy ${phy}\n`);
 
- 			exit(1);
 
- 		}
 
- 		print(macaddr + "\n");
 
- 	},
 
- };
 
- if (!phy || !command | !commands[command])
 
- 	usage();
 
- phydev = phy_open(phy);
 
- if (!phydev) {
 
- 	warn(`PHY ${phy} does not exist\n`);
 
- 	exit(1);
 
- }
 
- commands[command](ARGV);
 
 
  |