| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import * as nl80211 from "nl80211";
- import * as rtnl from "rtnl";
- import { readfile } from "fs";
- const iftypes = {
- ap: nl80211.const.NL80211_IFTYPE_AP,
- mesh: nl80211.const.NL80211_IFTYPE_MESH_POINT,
- sta: nl80211.const.NL80211_IFTYPE_STATION,
- adhoc: nl80211.const.NL80211_IFTYPE_ADHOC,
- monitor: nl80211.const.NL80211_IFTYPE_MONITOR,
- };
- function wdev_remove(name)
- {
- nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name });
- }
- function __phy_is_fullmac(phyidx)
- {
- let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx });
- return !data.software_iftypes.ap_vlan;
- }
- function phy_is_fullmac(phy)
- {
- let phyidx = int(trim(readfile(`/sys/class/ieee80211/${phy}/index`)));
- return __phy_is_fullmac(phyidx);
- }
- function find_reusable_wdev(phyidx)
- {
- if (!__phy_is_fullmac(phyidx))
- return null;
- let data = nl80211.request(
- nl80211.const.NL80211_CMD_GET_INTERFACE,
- nl80211.const.NLM_F_DUMP,
- { wiphy: phyidx });
- for (let res in data)
- if (trim(readfile(`/sys/class/net/${res.ifname}/operstate`)) == "down")
- return res.ifname;
- return null;
- }
- function wdev_create(phy, name, data)
- {
- let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`));
- wdev_remove(name);
- if (!iftypes[data.mode])
- return `Invalid mode: ${data.mode}`;
- let req = {
- wiphy: phyidx,
- ifname: name,
- iftype: iftypes[data.mode],
- };
- if (data["4addr"])
- req["4addr"] = data["4addr"];
- if (data.macaddr)
- req.mac = data.macaddr;
- nl80211.error();
- let reuse_ifname = find_reusable_wdev(phyidx);
- if (reuse_ifname &&
- (reuse_ifname == name ||
- rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false))
- nl80211.request(
- nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
- wiphy: phyidx,
- dev: name,
- iftype: iftypes[data.mode],
- });
- else
- nl80211.request(
- nl80211.const.NL80211_CMD_NEW_INTERFACE,
- nl80211.const.NLM_F_CREATE,
- req);
- let error = nl80211.error();
- if (error)
- return error;
- if (data.powersave != null) {
- nl80211.request(nl80211.const.NL80211_CMD_SET_POWER_SAVE, 0,
- { dev: name, ps_state: data.powersave ? 1 : 0});
- }
- return null;
- }
- const vlist_proto = {
- update: function(values, arg) {
- let data = this.data;
- let cb = this.cb;
- let seq = { };
- let new_data = {};
- let old_data = {};
- this.data = new_data;
- if (type(values) == "object") {
- for (let key in values) {
- old_data[key] = data[key];
- new_data[key] = values[key];
- delete data[key];
- }
- } else {
- for (let val in values) {
- let cur_key = val[0];
- let cur_obj = val[1];
- old_data[cur_key] = data[cur_key];
- new_data[cur_key] = val[1];
- delete data[cur_key];
- }
- }
- for (let key in data) {
- cb(null, data[key], arg);
- delete data[key];
- }
- for (let key in new_data)
- cb(new_data[key], old_data[key], arg);
- }
- };
- function is_equal(val1, val2) {
- let t1 = type(val1);
- if (t1 != type(val2))
- return false;
- if (t1 == "array") {
- if (length(val1) != length(val2))
- return false;
- for (let i = 0; i < length(val1); i++)
- if (!is_equal(val1[i], val2[i]))
- return false;
- return true;
- } else if (t1 == "object") {
- for (let key in val1)
- if (!is_equal(val1[key], val2[key]))
- return false;
- for (let key in val2)
- if (!val1[key])
- return false;
- return true;
- } else {
- return val1 == val2;
- }
- }
- function vlist_new(cb) {
- return proto({
- cb: cb,
- data: {}
- }, vlist_proto);
- }
- export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac };
|