Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src-draft/trunk]: src Add support for cloning wlan devices
details: https://anonhg.NetBSD.org/src-all/rev/7d44933c55b0
branches: trunk
changeset: 370966:7d44933c55b0
user: Martin Husemann <martin%NetBSD.org@localhost>
date: Fri Sep 25 19:42:03 2020 +0200
description:
Add support for cloning wlan devices
diffstat:
sbin/ifconfig/Makefile.common | 2 +
sbin/ifconfig/ieee80211.c | 132 +++++++++++++++++++++++++++++++++-
sbin/ifconfig/ifconfig.c | 39 +++++++---
sbin/ifconfig/parse.c | 28 ++++++-
sbin/ifconfig/parse.h | 31 ++++++++
sys/net/if_ethersubr.c | 4 +-
sys/net80211/ieee80211_crypto_ccmp.c | 3 +-
7 files changed, 214 insertions(+), 25 deletions(-)
diffs (truncated from 471 to 300 lines):
diff -r a1ef205ea3c0 -r 7d44933c55b0 sbin/ifconfig/Makefile.common
--- a/sbin/ifconfig/Makefile.common Fri Sep 25 19:40:03 2020 +0200
+++ b/sbin/ifconfig/Makefile.common Fri Sep 25 19:42:03 2020 +0200
@@ -13,9 +13,11 @@
INCS+= af_inetany.h env.h extern.h media.h parse.h util.h
SRCS+= af_inet.c af_inetany.c env.c ether.c \
ifconfig.c media.c parse.c tunnel.c util.c vlan.c
+
.ifndef NOIEEE80211
SRCS+= ieee80211.c
.endif
+
.ifndef SMALLPROG
SRCS+= agr.c l2tp.c lagg.c
.endif
diff -r a1ef205ea3c0 -r 7d44933c55b0 sbin/ifconfig/ieee80211.c
--- a/sbin/ifconfig/ieee80211.c Fri Sep 25 19:40:03 2020 +0200
+++ b/sbin/ifconfig/ieee80211.c Fri Sep 25 19:42:03 2020 +0200
@@ -78,6 +78,9 @@
static void list_scan(prop_dictionary_t);
static int mappsb(u_int , u_int);
static int mapgsm(u_int , u_int);
+int clone_command(prop_dictionary_t env, prop_dictionary_t oenv);
+int wlan_clone_command(prop_dictionary_t env, prop_dictionary_t oenv);
+static int wlan_clone_fixup(struct match*, int, int);
static int sethidessid(prop_dictionary_t, prop_dictionary_t);
static int setapbridge(prop_dictionary_t, prop_dictionary_t);
@@ -111,8 +114,10 @@
static const char * iename(int);
extern struct pinteger parse_chan, parse_frag, parse_rts;
-extern struct pstr parse_bssid, parse_ssid, parse_nwkey;
+extern struct pstr parse_bssid, parse_ssid, parse_nwkey, wlan_device;
extern struct pinteger parse_powersavesleep;
+extern struct pbranch wlan_or_opt_silent_family;
+extern struct pkw wlan_mode;
static const struct kwinst ieee80211boolkw[] = {
{.k_word = "hidessid", .k_key = "hidessid", .k_neg = true,
@@ -133,6 +138,34 @@
static struct pkw lists = PKW_INITIALIZER(&lists, "ieee80211 lists", NULL,
"list", listskw, __arraycount(listskw), &command_root.pb_parser);
+static const struct kwinst kw80211modes[] = {
+ {.k_word = "sta", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_STA },
+ {.k_word = "ahdemo", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_AHDEMO },
+ {.k_word = "adhoc-demo", .k_key = "mode", // alias for previous
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_AHDEMO },
+ {.k_word = "ibss", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_IBSS },
+ {.k_word = "adhoc", .k_key = "mode", // alias for previous
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_IBSS },
+ {.k_word = "ap", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_HOSTAP },
+ {.k_word = "hostap", .k_key = "mode", // alias for previous
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_HOSTAP },
+ {.k_word = "wds", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_WDS },
+ {.k_word = "tdma", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = -1 }, /* XXX ??? */
+ {.k_word = "mesh", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_MBSS },
+ {.k_word = "monitor", .k_key = "mode",
+ .k_type = KW_T_INT, .k_int = IEEE80211_M_MONITOR },
+};
+
+struct pkw wlan_mode = PKW_INITIALIZER1(&wlan_mode, "802.11 modes", NULL, NULL,
+ kw80211modes, __arraycount(kw80211modes), NULL, wlan_clone_fixup);
+
static const struct kwinst kw80211kw[] = {
{.k_word = "bssid", .k_nextparser = &parse_bssid.ps_parser}
, {.k_word = "-bssid", .k_exec = unsetifbssid,
@@ -191,6 +224,73 @@
struct pstr parse_bssid = PSTR_INITIALIZER1(&parse_bssid, "bssid", setifbssid,
"bssid", false, &command_root.pb_parser);
+struct pstr wlan_device = PSTR_INITIALIZER2(&wlan_device, "wlandev", NULL,
+ "wlandev", false, &wlan_or_opt_silent_family.pb_parser, wlan_clone_fixup,
+ true);
+
+/*
+ * We accumlute various changes originally directed at clone_command()
+ * into a single extended call redirected to wlan_clone_command
+ * (but with the environment gathered by all previous matches).
+ */
+static int
+wlan_clone_fixup(struct match *matches, int index, int max_index)
+{
+ int i;
+
+ /*
+ * Make every match trying to exec clone_command or
+ * wlan_clone_command do nothing.
+ */
+ for (i = 0; i < index; i++) {
+ if (matches[i].m_exec == clone_command ||
+ matches[i].m_exec == wlan_clone_command) {
+ matches[i].m_exec = NULL;
+ matches[i].m_override_parser_exec = true;
+ }
+ }
+
+ /*
+ * Now make myself exec wlan_clone_command.
+ */
+ matches[index].m_exec = wlan_clone_command;
+ matches[index].m_override_parser_exec = true;
+
+ return 0;
+}
+
+int
+wlan_clone_command(prop_dictionary_t env, prop_dictionary_t oenv)
+{
+ struct if_cclonearg carg;
+ struct ieee80211_clone_params req;
+ const char *parent;
+ int mode;
+
+ if (!prop_dictionary_get_cstring_nocopy(env, "wlandev", &parent)) {
+ warn("wlandev required");
+ return -1;
+ }
+
+ memset(&carg, 0, sizeof carg);
+ memset(&req, 0, sizeof req);
+ /* set some defaults */
+ req.icp_opmode = IEEE80211_M_STA;
+
+ carg.ifc_arg_size = sizeof req;
+ carg.ifc_args = &req;
+ strlcpy(req.icp_parent, parent, sizeof req.icp_parent);
+ if (prop_dictionary_get_int(env, "mode", &mode))
+ req.icp_opmode = mode;
+
+ if (direct_ioctl(env, SIOCIFCREATEARGS, &carg) == -1) {
+ warn("%s", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
static int
set80211(prop_dictionary_t env, uint16_t type, int16_t val, int16_t len,
u_int8_t *data)
@@ -235,14 +335,22 @@
struct ifmediareq ifmr;
memset(&ifmr, 0, sizeof(ifmr));
- if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1)
+ if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1) {
;
- else if (ifmr.ifm_current & IFM_IEEE80211_ADHOC)
- return IEEE80211_M_IBSS; /* XXX ahdemo */
- else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
+ } else if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
+ if (ifmr.ifm_current & IFM_FLAG0)
+ return IEEE80211_M_AHDEMO;
+ else
+ return IEEE80211_M_IBSS;
+ } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) {
return IEEE80211_M_HOSTAP;
- else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
+ } else if (ifmr.ifm_current & IFM_IEEE80211_IBSS) {
+ return IEEE80211_M_IBSS;
+ } else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) {
return IEEE80211_M_MONITOR;
+ } else if (ifmr.ifm_current & IFM_IEEE80211_MBSS) {
+ return IEEE80211_M_MBSS;
+ }
return IEEE80211_M_STA;
}
@@ -737,15 +845,24 @@
static void
scan_and_wait(prop_dictionary_t env)
{
+ struct ieee80211_scan_req sr;
int sroute;
+ memset(&sr, 0, sizeof sr);
+ sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE
+ | IEEE80211_IOC_SCAN_BGSCAN
+ | IEEE80211_IOC_SCAN_NOPICK
+ | IEEE80211_IOC_SCAN_ONCE;
+ sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
+
sroute = prog_socket(PF_ROUTE, SOCK_RAW, 0);
if (sroute < 0) {
warn("socket(PF_ROUTE,SOCK_RAW)");
return;
}
/* NB: only root can trigger a scan so ignore errors */
- if (set80211(env, IEEE80211_IOC_SCAN_REQ, 0, 0, NULL) >= 0) {
+ if (set80211(env, IEEE80211_IOC_SCAN_REQ, 0, sizeof sr,
+ (uint8_t*)&sr) >= 0) {
char buf[2048];
struct if_announcemsghdr *ifan;
struct rt_msghdr *rtm;
@@ -1398,3 +1515,4 @@
register_statistics(&statistics);
register_usage(&usage);
}
+
diff -r a1ef205ea3c0 -r 7d44933c55b0 sbin/ifconfig/ifconfig.c
--- a/sbin/ifconfig/ifconfig.c Fri Sep 25 19:40:03 2020 +0200
+++ b/sbin/ifconfig/ifconfig.c Fri Sep 25 19:42:03 2020 +0200
@@ -112,7 +112,8 @@
bool gflagset[10 + 26 * 2];
static int carrier(prop_dictionary_t);
-static int clone_command(prop_dictionary_t, prop_dictionary_t);
+int clone_command(prop_dictionary_t, prop_dictionary_t);
+int wlan_clone_command(prop_dictionary_t, prop_dictionary_t);
static void do_setifpreference(prop_dictionary_t);
static int flag_index(int);
static void init_afs(void);
@@ -170,9 +171,10 @@
extern struct pbranch command_root;
extern struct pbranch opt_command;
-extern struct pbranch opt_family, opt_silent_family;
-extern struct pkw cloning, silent_family, family, ifcaps, ifflags, misc;
-extern struct pstr parse_linkstr;
+extern struct pbranch opt_family, wlan_or_opt_silent_family;
+extern struct pkw cloning, silent_family, family, ifcaps, ifflags, misc,
+ wlan_create;
+extern struct pstr parse_linkstr, wlan_device, wlan_mode;
struct pinteger parse_metric = PINTEGER_INITIALIZER(&parse_metric, "metric", 10,
setifmetric, "metric", &command_root.pb_parser);
@@ -225,10 +227,17 @@
.k_nextparser = &command_root.pb_parser}
};
+static const struct kwinst wlan_createkw[] = {
+ {.k_word = "wlandev", .k_key = "wlandev",
+ .k_nextparser = &wlan_device.ps_parser}
+ , {.k_word = "wlanmode", .k_key = "wlanmode",
+ .k_nextparser = &wlan_mode.ps_parser}
+};
+
/* key: clonecmd */
static const struct kwinst clonekw[] = {
{.k_word = "create", .k_type = KW_T_INT, .k_int = SIOCIFCREATE,
- .k_nextparser = &opt_silent_family.pb_parser},
+ .k_nextparser = &wlan_or_opt_silent_family.pb_parser},
{.k_word = "destroy", .k_type = KW_T_INT, .k_int = SIOCIFDESTROY}
};
@@ -243,6 +252,11 @@
struct pterm no_cmds = PTERM_INITIALIZER(&no_cmds, "no commands", no_cmds_exec,
"none");
+struct pkw wlan_create =
+ PKW_INITIALIZER(&wlan_create, "wlan-create", NULL, "wlan-create",
+ wlan_createkw, __arraycount(wlan_createkw),
+ &wlan_or_opt_silent_family.pb_parser);
+
struct pkw family_only =
PKW_INITIALIZER(&family_only, "family-only", NULL, "af", familykw,
__arraycount(familykw), &no_cmds.pt_parser);
@@ -278,8 +292,9 @@
struct branch opt_clone_brs[] = {
{.b_nextparser = &cloning.pk_parser}
, {.b_nextparser = &opt_family.pb_parser}
-}, opt_silent_family_brs[] = {
- {.b_nextparser = &silent_family.pk_parser}
+}, wlan_or_opt_silent_family_brs[] = {
+ {.b_nextparser = &wlan_create.pk_parser }
+ , {.b_nextparser = &silent_family.pk_parser}
, {.b_nextparser = &command_root.pb_parser}
}, opt_family_brs[] = {
{.b_nextparser = &family.pk_parser}
@@ -339,9 +354,10 @@
struct pbranch opt_clone = PBRANCH_INITIALIZER(&opt_clone,
"opt-clone", opt_clone_brs, __arraycount(opt_clone_brs), true);
-struct pbranch opt_silent_family = PBRANCH_INITIALIZER(&opt_silent_family,
- "optional silent family", opt_silent_family_brs,
- __arraycount(opt_silent_family_brs), true);
+struct pbranch wlan_or_opt_silent_family = PBRANCH_INITIALIZER(
+ &wlan_or_opt_silent_family,
+ "wlan config or optional silent family", wlan_or_opt_silent_family_brs,
+ __arraycount(wlan_or_opt_silent_family_brs), true);
struct pbranch opt_family = PBRANCH_INITIALIZER(&opt_family,
"opt-family", opt_family_brs, __arraycount(opt_family_brs), true);
@@ -946,7 +962,7 @@
exit(EXIT_SUCCESS);
}
-static int
+int
clone_command(prop_dictionary_t env, prop_dictionary_t oenv)
{
Home |
Main Index |
Thread Index |
Old Index