Skip to content

Commit 4698bfc

Browse files
committed
separate commands into sections
The ad-hoc way of parsing the command "tree" didn't really work out, so separate the commands better into sections and parse by that.
1 parent bd66389 commit 4698bfc

13 files changed

+136
-69
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ OBJS = iw.o genl.o event.o info.o phy.o \
1818
interface.o ibss.o station.o util.o \
1919
mesh.o mpath.o scan.o reg.o version.o \
2020
reason.o status.o connect.o link.o
21+
OBJS += sections.o
2122
ALL = iw
2223

2324
NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y)

connect.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ static int disconnect(struct nl80211_state *state,
6767
TOPLEVEL(disconnect, NULL,
6868
NL80211_CMD_DISCONNECT, 0, CIB_NETDEV, disconnect,
6969
"Disconnect from the current network.");
70-
HIDDEN(conn, establish, "", NL80211_CMD_CONNECT, 0, CIB_NETDEV, iw_conn);
7170

7271
static int iw_connect(struct nl80211_state *state, struct nl_cb *cb,
7372
struct nl_msg *msg, int argc, char **argv)
@@ -97,7 +96,7 @@ static int iw_connect(struct nl80211_state *state, struct nl_cb *cb,
9796
if (!conn_argv)
9897
return -ENOMEM;
9998
conn_argv[0] = dev;
100-
conn_argv[1] = "conn";
99+
conn_argv[1] = "connect";
101100
conn_argv[2] = "establish";
102101
for (i = 0; i < argc; i++)
103102
conn_argv[i + 3] = argv[i];
@@ -138,3 +137,4 @@ TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:616263
138137
0, 0, CIB_NETDEV, iw_connect,
139138
"Join the network with the given SSID (and frequency, BSSID).\n"
140139
"With -w, wait for the connect to finish or fail.");
140+
HIDDEN(connect, establish, "", NL80211_CMD_CONNECT, 0, CIB_NETDEV, iw_conn);

ibss.c

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "nl80211.h"
1010
#include "iw.h"
1111

12+
SECTION(ibss);
13+
1214
static int join_ibss(struct nl80211_state *state,
1315
struct nl_cb *cb,
1416
struct nl_msg *msg,

info.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static int handle_info(struct nl80211_state *state,
282282

283283
return 0;
284284
}
285-
TOPLEVEL(info, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_info,
285+
__COMMAND(NULL, info, "info", NULL, NL80211_CMD_GET_WIPHY, 0, 0, CIB_PHY, handle_info,
286286
"Show capabilities for the specified wireless device.");
287287
TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info,
288288
"List all wireless devices and their capabilities.");

interface.c

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"otherbss: show frames from other BSSes\n"\
1919
"cook: use cooked mode"
2020

21+
SECTION(interface);
22+
2123
static char *mntr_flags[NL80211_MNTR_FLAG_MAX + 1] = {
2224
"none",
2325
"fcsfail",

iw.c

+76-46
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,17 @@ static void nl80211_cleanup(struct nl80211_state *state)
9494
nl_socket_free(state->nl_sock);
9595
}
9696

97-
__COMMAND(NULL, NULL, "", NULL, 0, 0, 0, CIB_NONE, NULL, NULL);
98-
__COMMAND(NULL, NULL, "", NULL, 1, 0, 0, CIB_NONE, NULL, NULL);
99-
10097
static int cmd_size;
10198

102-
static void __usage_cmd(struct cmd *cmd, char *indent, bool full)
99+
extern struct cmd __start___cmd;
100+
extern struct cmd __stop___cmd;
101+
102+
#define for_each_cmd(_cmd) \
103+
for (_cmd = &__start___cmd; _cmd < &__stop___cmd; \
104+
_cmd = (const struct cmd *)((char *)_cmd + cmd_size))
105+
106+
107+
static void __usage_cmd(const struct cmd *cmd, char *indent, bool full)
103108
{
104109
const char *start, *lend, *end;
105110

@@ -115,8 +120,8 @@ static void __usage_cmd(struct cmd *cmd, char *indent, bool full)
115120
printf("dev <devname> ");
116121
break;
117122
}
118-
if (cmd->section)
119-
printf("%s ", cmd->section);
123+
if (cmd->parent && cmd->parent->name)
124+
printf("%s ", cmd->parent->name);
120125
printf("%s", cmd->name);
121126
if (cmd->args)
122127
printf(" %s", cmd->args);
@@ -156,17 +161,26 @@ static const char *argv0;
156161

157162
static void usage(bool full)
158163
{
159-
struct cmd *cmd;
164+
const struct cmd *section, *cmd;
160165

161166
printf("Usage:\t%s [options] command\n", argv0);
162167
usage_options();
163168
printf("\t--version\tshow version (%s)\n", iw_version);
164169
printf("Commands:\n");
165-
for (cmd = &__start___cmd; cmd < &__stop___cmd;
166-
cmd = (struct cmd *)((char *)cmd + cmd_size)) {
167-
if (!cmd->handler || cmd->hidden)
170+
for_each_cmd(section) {
171+
if (section->parent)
168172
continue;
169-
__usage_cmd(cmd, "\t", full);
173+
174+
if (section->handler && !section->hidden)
175+
__usage_cmd(section, "\t", full);
176+
177+
for_each_cmd(cmd) {
178+
if (section != cmd->parent)
179+
continue;
180+
if (!cmd->handler || cmd->hidden)
181+
continue;
182+
__usage_cmd(cmd, "\t", full);
183+
}
170184
}
171185
printf("\nYou can omit the 'phy' or 'dev' if "
172186
"the identification is unique,\n"
@@ -186,7 +200,7 @@ static int print_help(struct nl80211_state *state,
186200
TOPLEVEL(help, NULL, 0, 0, CIB_NONE, print_help,
187201
"Print usage for each command.");
188202

189-
static void usage_cmd(struct cmd *cmd)
203+
static void usage_cmd(const struct cmd *cmd)
190204
{
191205
printf("Usage:\t%s [options] ", argv0);
192206
__usage_cmd(cmd, "", true);
@@ -238,9 +252,9 @@ static int ack_handler(struct nl_msg *msg, void *arg)
238252
}
239253

240254
static int __handle_cmd(struct nl80211_state *state, enum id_input idby,
241-
int argc, char **argv, struct cmd **cmdout)
255+
int argc, char **argv, const struct cmd **cmdout)
242256
{
243-
struct cmd *cmd, *match = NULL;
257+
const struct cmd *cmd, *match = NULL, *sectcmd;
244258
struct nl_cb *cb;
245259
struct nl_msg *msg;
246260
int devidx = 0;
@@ -285,44 +299,61 @@ static int __handle_cmd(struct nl80211_state *state, enum id_input idby,
285299
if (devidx < 0)
286300
return -errno;
287301

288-
section = command = *argv;
302+
section = *argv;
289303
argc--;
290304
argv++;
291305

292-
for (cmd = &__start___cmd; cmd < &__stop___cmd;
293-
cmd = (struct cmd *)((char *)cmd + cmd_size)) {
294-
if (!cmd->handler)
306+
for_each_cmd(sectcmd) {
307+
if (sectcmd->parent)
295308
continue;
296-
if (cmd->idby != command_idby)
309+
/* ok ... bit of a hack for the dupe 'info' section */
310+
if (match && sectcmd->idby != command_idby)
297311
continue;
298-
if (cmd->section) {
299-
if (strcmp(cmd->section, section))
312+
if (strcmp(sectcmd->name, section) == 0)
313+
match = sectcmd;
314+
}
315+
316+
sectcmd = match;
317+
match = NULL;
318+
if (!sectcmd)
319+
return 1;
320+
321+
if (argc > 0) {
322+
command = *argv;
323+
324+
for_each_cmd(cmd) {
325+
if (!cmd->handler)
300326
continue;
301-
/* this is a bit icky ... */
302-
if (command == section) {
303-
if (argc <= 0) {
304-
if (match)
305-
break;
306-
return 1;
307-
}
308-
command = *argv;
309-
argc--;
310-
argv++;
311-
}
312-
} else if (section != command)
313-
continue;
314-
if (strcmp(cmd->name, command))
315-
continue;
316-
if (argc && !cmd->args)
317-
continue;
327+
if (cmd->parent != sectcmd)
328+
continue;
329+
if (cmd->idby != command_idby)
330+
continue;
331+
if (strcmp(cmd->name, command))
332+
continue;
333+
if (argc > 1 && !cmd->args)
334+
continue;
335+
match = cmd;
336+
break;
337+
}
318338

319-
match = cmd;
339+
if (match) {
340+
argc--;
341+
argv++;
342+
}
320343
}
321344

322-
cmd = match;
323-
324-
if (!cmd)
325-
return 1;
345+
if (match)
346+
cmd = match;
347+
else {
348+
/* Use the section itself, if possible. */
349+
cmd = sectcmd;
350+
if (argc && !cmd->args)
351+
return 1;
352+
if (cmd->idby != command_idby)
353+
return 1;
354+
if (!cmd->handler)
355+
return 1;
356+
}
326357

327358
if (cmdout)
328359
*cmdout = cmd;
@@ -396,11 +427,10 @@ int main(int argc, char **argv)
396427
{
397428
struct nl80211_state nlstate;
398429
int err;
399-
struct cmd *cmd = NULL;
430+
const struct cmd *cmd = NULL;
400431

401432
/* calculate command size including padding */
402-
cmd_size = abs((long)&__cmd_NULL_NULL_1_CIB_NONE_0
403-
- (long)&__cmd_NULL_NULL_0_CIB_NONE_0);
433+
cmd_size = abs((long)&__section_set - (long)&__section_get);
404434
/* strip off self */
405435
argc--;
406436
argv0 = *argv++;

iw.h

+30-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ enum id_input {
3535
};
3636

3737
struct cmd {
38-
const char *section;
3938
const char *name;
4039
const char *args;
4140
const char *help;
@@ -52,6 +51,7 @@ struct cmd {
5251
struct nl_cb *cb,
5352
struct nl_msg *msg,
5453
int argc, char **argv);
54+
const struct cmd *parent;
5555
};
5656

5757
#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0]))
@@ -60,7 +60,6 @@ struct cmd {
6060
static const struct cmd \
6161
__cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
6262
__attribute__((used)) __attribute__((section("__cmd"))) = { \
63-
.section = (_section), \
6463
.name = (_name), \
6564
.args = (_args), \
6665
.cmd = (_nlcmd), \
@@ -69,15 +68,34 @@ struct cmd {
6968
.idby = (_idby), \
7069
.handler = (_handler), \
7170
.help = (_help), \
71+
.parent = _section, \
7272
}
7373
#define COMMAND(section, name, args, cmd, flags, idby, handler, help) \
74-
__COMMAND(#section, name, #name, args, cmd, flags, 0, idby, handler, help)
74+
__COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help)
7575
#define HIDDEN(section, name, args, cmd, flags, idby, handler) \
76-
__COMMAND(#section, name, #name, args, cmd, flags, 1, idby, handler, NULL)
77-
#define TOPLEVEL(name, args, cmd, flags, idby, handler, help) \
78-
__COMMAND(NULL, name, #name, args, cmd, flags, 0, idby, handler, help)
79-
extern struct cmd __start___cmd;
80-
extern struct cmd __stop___cmd;
76+
__COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 1, idby, handler, NULL)
77+
78+
#define TOPLEVEL(_name, _args, _nlcmd, _flags, _idby, _handler, _help) \
79+
const struct cmd \
80+
__section ## _ ## _name \
81+
__attribute__((used)) __attribute__((section("__cmd"))) = { \
82+
.name = (#_name), \
83+
.args = (_args), \
84+
.cmd = (_nlcmd), \
85+
.nl_msg_flags = (_flags), \
86+
.idby = (_idby), \
87+
.handler = (_handler), \
88+
.help = (_help), \
89+
}
90+
#define SECTION(_name) \
91+
const struct cmd __section ## _ ## _name \
92+
__attribute__((used)) __attribute__((section("__cmd"))) = { \
93+
.name = (#_name), \
94+
.hidden = 1, \
95+
}
96+
97+
#define DECLARE_SECTION(_name) \
98+
extern const struct cmd __section ## _ ## _name;
8199

82100
extern const char iw_version[];
83101

@@ -125,4 +143,8 @@ enum print_ie_type {
125143
void print_ies(unsigned char *ie, int ielen, bool unknown,
126144
enum print_ie_type ptype);
127145

146+
147+
DECLARE_SECTION(set);
148+
DECLARE_SECTION(get);
149+
128150
#endif /* __IW_H */

link.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ static int handle_scan_for_link(struct nl80211_state *state,
105105
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, link_bss_handler, &lr);
106106
return 0;
107107
}
108-
HIDDEN(link, get_bss, NULL, NL80211_CMD_GET_SCAN, NLM_F_DUMP,
109-
CIB_NETDEV, handle_scan_for_link);
110108

111109
static int print_link_sta(struct nl_msg *msg, void *arg)
112110
{
@@ -213,8 +211,6 @@ static int handle_link_sta(struct nl80211_state *state,
213211
nla_put_failure:
214212
return -ENOBUFS;
215213
}
216-
HIDDEN(link, get_sta, "", NL80211_CMD_GET_STATION, 0,
217-
CIB_NETDEV, handle_link_sta);
218214

219215
static int handle_link(struct nl80211_state *state, struct nl_cb *cb,
220216
struct nl_msg *msg, int argc, char **argv)
@@ -255,3 +251,7 @@ static int handle_link(struct nl80211_state *state, struct nl_cb *cb,
255251
}
256252
TOPLEVEL(link, NULL, 0, 0, CIB_NETDEV, handle_link,
257253
"Print information about the current link, if any.");
254+
HIDDEN(link, get_sta, "", NL80211_CMD_GET_STATION, 0,
255+
CIB_NETDEV, handle_link_sta);
256+
HIDDEN(link, get_bss, NULL, NL80211_CMD_GET_SCAN, NLM_F_DUMP,
257+
CIB_NETDEV, handle_scan_for_link);

mpath.c

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "nl80211.h"
1212
#include "iw.h"
1313

14+
SECTION(mpath);
15+
1416
enum plink_state {
1517
LISTEN,
1618
OPN_SNT,

reg.c

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "nl80211.h"
1313
#include "iw.h"
1414

15+
SECTION(reg);
16+
1517
#define MHZ_TO_KHZ(freq) ((freq) * 1000)
1618
#define KHZ_TO_MHZ(freq) ((freq) / 1000)
1719
#define DBI_TO_MBI(gain) ((gain) * 100)

scan.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ static int handle_scan(struct nl80211_state *state,
108108
nlmsg_free(freqs);
109109
return err;
110110
}
111-
COMMAND(scan, trigger, "[freq <freq>*] [ssid <ssid>*|passive]",
112-
NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan,
113-
"Trigger a scan on the given frequencies with probing for the given\n"
114-
"SSIDs (or wildcard if not given) unless passive scanning is requested.");
115111

116112
static void tab_on_first(bool *first)
117113
{
@@ -877,10 +873,6 @@ static int handle_scan_dump(struct nl80211_state *state,
877873
&scan_params);
878874
return 0;
879875
}
880-
COMMAND(scan, dump, "[-u]",
881-
NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump,
882-
"Dump the current scan results. If -u is specified, print unknown\n"
883-
"data in scan results.");
884876

885877
static int handle_scan_combined(struct nl80211_state *state,
886878
struct nl_cb *cb,
@@ -959,3 +951,11 @@ TOPLEVEL(scan, "[-u] [freq <freq>*] [ssid <ssid>*|passive]", 0, 0,
959951
"Scan on the given frequencies and probe for the given SSIDs\n"
960952
"(or wildcard if not given) unless passive scanning is requested.\n"
961953
"If -u is specified print unknown data in the scan results.");
954+
COMMAND(scan, dump, "[-u]",
955+
NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump,
956+
"Dump the current scan results. If -u is specified, print unknown\n"
957+
"data in scan results.");
958+
COMMAND(scan, trigger, "[freq <freq>*] [ssid <ssid>*|passive]",
959+
NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan,
960+
"Trigger a scan on the given frequencies with probing for the given\n"
961+
"SSIDs (or wildcard if not given) unless passive scanning is requested.");

0 commit comments

Comments
 (0)