2 * nl80211 userspace tool
4 * Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net>
11 #include <sys/types.h>
16 #include <linux/netlink.h>
18 #include <netlink/genl/genl.h>
19 #include <netlink/genl/family.h>
20 #include <netlink/genl/ctrl.h>
21 #include <netlink/msg.h>
22 #include <netlink/attr.h>
27 /* libnl 1.x compatibility code */
28 #if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30)
29 static inline struct nl_handle
*nl_socket_alloc(void)
31 return nl_handle_alloc();
34 static inline void nl_socket_free(struct nl_sock
*h
)
39 static inline int nl_socket_set_buffer_size(struct nl_sock
*sk
,
42 return nl_set_buffer_size(sk
, rxbuf
, txbuf
);
44 #endif /* CONFIG_LIBNL20 && CONFIG_LIBNL30 */
48 static int nl80211_init(struct nl80211_state
*state
)
52 state
->nl_sock
= nl_socket_alloc();
53 if (!state
->nl_sock
) {
54 fprintf(stderr
, "Failed to allocate netlink socket.\n");
58 if (genl_connect(state
->nl_sock
)) {
59 fprintf(stderr
, "Failed to connect to generic netlink.\n");
61 goto out_handle_destroy
;
64 nl_socket_set_buffer_size(state
->nl_sock
, 8192, 8192);
66 /* try to set NETLINK_EXT_ACK to 1, ignoring errors */
68 setsockopt(nl_socket_get_fd(state
->nl_sock
), SOL_NETLINK
,
69 NETLINK_EXT_ACK
, &err
, sizeof(err
));
71 state
->nl80211_id
= genl_ctrl_resolve(state
->nl_sock
, "nl80211");
72 if (state
->nl80211_id
< 0) {
73 fprintf(stderr
, "nl80211 not found.\n");
75 goto out_handle_destroy
;
81 nl_socket_free(state
->nl_sock
);
85 static void nl80211_cleanup(struct nl80211_state
*state
)
87 nl_socket_free(state
->nl_sock
);
92 extern struct cmd
*__start___cmd
[];
93 extern struct cmd
*__stop___cmd
;
95 #define for_each_cmd(_cmd, i) \
96 for (i = 0; i < &__stop___cmd - __start___cmd; i++) \
97 if ((_cmd = __start___cmd[i]))
100 static void __usage_cmd(const struct cmd
*cmd
, char *indent
, bool full
)
102 const char *start
, *lend
, *end
;
104 printf("%s", indent
);
110 printf("phy <phyname> ");
113 printf("dev <devname> ");
116 printf("wdev <idx> ");
119 if (cmd
->parent
&& cmd
->parent
->name
)
120 printf("%s ", cmd
->parent
->name
);
121 printf("%s", cmd
->name
);
124 /* print line by line */
126 end
= strchr(start
, '\0');
129 lend
= strchr(start
, '\n');
132 if (start
!= cmd
->args
) {
138 printf("phy <phyname> ");
141 printf("dev <devname> ");
144 printf("wdev <idx> ");
147 if (cmd
->parent
&& cmd
->parent
->name
)
148 printf("%s ", cmd
->parent
->name
);
149 printf("%s ", cmd
->name
);
151 printf("%.*s\n", (int)(lend
- start
), start
);
153 } while (end
!= lend
);
157 if (!full
|| !cmd
->help
)
166 /* print line by line */
168 end
= strchr(start
, '\0');
170 lend
= strchr(start
, '\n');
173 printf("%s", indent
);
174 printf("%.*s\n", (int)(lend
- start
), start
);
176 } while (end
!= lend
);
181 static void usage_options(void)
183 printf("Options:\n");
184 printf("\t--debug\t\tenable netlink debugging\n");
187 static const char *argv0
;
189 static void usage(int argc
, char **argv
)
191 const struct cmd
*section
, *cmd
;
192 bool full
= argc
>= 0;
193 const char *sect_filt
= NULL
;
194 const char *cmd_filt
= NULL
;
203 printf("Usage:\t%s [options] command\n", argv0
);
205 printf("\t--version\tshow version (%s)\n", iw_version
);
206 printf("Commands:\n");
207 for_each_cmd(section
, i
) {
211 if (sect_filt
&& strcmp(section
->name
, sect_filt
))
214 if (section
->handler
&& !section
->hidden
)
215 __usage_cmd(section
, "\t", full
);
217 for_each_cmd(cmd
, j
) {
218 if (section
!= cmd
->parent
)
220 if (!cmd
->handler
|| cmd
->hidden
)
222 if (cmd_filt
&& strcmp(cmd
->name
, cmd_filt
))
224 __usage_cmd(cmd
, "\t", full
);
227 printf("\nCommands that use the netdev ('dev') can also be given the\n"
228 "'wdev' instead to identify the device.\n");
229 printf("\nYou can omit the 'phy' or 'dev' if "
230 "the identification is unique,\n"
231 "e.g. \"iw wlan0 info\" or \"iw phy0 info\". "
232 "(Don't when scripting.)\n\n"
233 "Do NOT screenscrape this tool, we don't "
234 "consider its output stable.\n\n");
237 static int print_help(struct nl80211_state
*state
,
239 int argc
, char **argv
,
244 TOPLEVEL(help
, "[command]", 0, 0, CIB_NONE
, print_help
,
245 "Print usage for all or a specific command, e.g.\n"
246 "\"help wowlan\" or \"help wowlan enable\".");
248 static void usage_cmd(const struct cmd
*cmd
)
250 printf("Usage:\t%s [options] ", argv0
);
251 __usage_cmd(cmd
, "", true);
255 static void version(void)
257 printf("iw version %s\n", iw_version
);
260 static int phy_lookup(char *name
)
265 snprintf(buf
, sizeof(buf
), "/sys/class/ieee80211/%s/index", name
);
267 fd
= open(buf
, O_RDONLY
);
270 pos
= read(fd
, buf
, sizeof(buf
) - 1);
280 static int error_handler(struct sockaddr_nl
*nla
, struct nlmsgerr
*err
,
283 struct nlmsghdr
*nlh
= (struct nlmsghdr
*)err
- 1;
284 int len
= nlh
->nlmsg_len
;
285 struct nlattr
*attrs
;
286 struct nlattr
*tb
[NLMSGERR_ATTR_MAX
+ 1];
288 int ack_len
= sizeof(*nlh
) + sizeof(int) + sizeof(*nlh
);
290 if (err
->error
> 0) {
292 * This is illegal, per netlink(7), but not impossible (think
293 * "vendor commands"). Callers really expect negative error
294 * codes, so make that happen.
297 "ERROR: received positive netlink error code %d\n",
304 if (!(nlh
->nlmsg_flags
& NLM_F_ACK_TLVS
))
307 if (!(nlh
->nlmsg_flags
& NLM_F_CAPPED
))
308 ack_len
+= err
->msg
.nlmsg_len
- sizeof(*nlh
);
313 attrs
= (void *)((unsigned char *)nlh
+ ack_len
);
316 nla_parse(tb
, NLMSGERR_ATTR_MAX
, attrs
, len
, NULL
);
317 if (tb
[NLMSGERR_ATTR_MSG
]) {
318 len
= strnlen((char *)nla_data(tb
[NLMSGERR_ATTR_MSG
]),
319 nla_len(tb
[NLMSGERR_ATTR_MSG
]));
320 fprintf(stderr
, "kernel reports: %*s\n", len
,
321 (char *)nla_data(tb
[NLMSGERR_ATTR_MSG
]));
327 static int finish_handler(struct nl_msg
*msg
, void *arg
)
334 static int ack_handler(struct nl_msg
*msg
, void *arg
)
341 static int (*registered_handler
)(struct nl_msg
*, void *);
342 static void *registered_handler_data
;
344 void register_handler(int (*handler
)(struct nl_msg
*, void *), void *data
)
346 registered_handler
= handler
;
347 registered_handler_data
= data
;
350 int valid_handler(struct nl_msg
*msg
, void *arg
)
352 if (registered_handler
)
353 return registered_handler(msg
, registered_handler_data
);
358 static int __handle_cmd(struct nl80211_state
*state
, enum id_input idby
,
359 int argc
, char **argv
, const struct cmd
**cmdout
)
361 const struct cmd
*cmd
, *match
= NULL
, *sectcmd
;
365 signed long long devidx
= 0;
367 const char *command
, *section
;
369 enum command_identify_by command_idby
= CIB_NONE
;
371 if (argc
<= 1 && idby
!= II_NONE
)
379 command_idby
= CIB_PHY
;
380 devidx
= strtoul(*argv
+ 4, &tmp
, 0);
387 command_idby
= CIB_PHY
;
388 devidx
= phy_lookup(*argv
);
393 command_idby
= CIB_NETDEV
;
394 devidx
= if_nametoindex(*argv
);
401 command_idby
= CIB_WDEV
;
402 devidx
= strtoll(*argv
, &tmp
, 0);
418 for_each_cmd(sectcmd
, i
) {
421 /* ok ... bit of a hack for the dupe 'info' section */
422 if (match
&& sectcmd
->idby
!= command_idby
)
424 if (strcmp(sectcmd
->name
, section
) == 0)
436 for_each_cmd(cmd
, i
) {
439 if (cmd
->parent
!= sectcmd
)
442 * ignore mismatch id by, but allow WDEV
445 if (cmd
->idby
!= command_idby
&&
446 !(cmd
->idby
== CIB_NETDEV
&&
447 command_idby
== CIB_WDEV
))
449 if (strcmp(cmd
->name
, command
))
451 if (argc
> 1 && !cmd
->args
)
466 /* Use the section itself, if possible. */
468 if (argc
&& !cmd
->args
)
470 if (cmd
->idby
!= command_idby
&&
471 !(cmd
->idby
== CIB_NETDEV
&& command_idby
== CIB_WDEV
))
478 cmd
= cmd
->selector(argc
, argv
);
489 return cmd
->handler(state
, NULL
, argc
, argv
, idby
);
494 fprintf(stderr
, "failed to allocate netlink message\n");
498 cb
= nl_cb_alloc(iw_debug
? NL_CB_DEBUG
: NL_CB_DEFAULT
);
499 s_cb
= nl_cb_alloc(iw_debug
? NL_CB_DEBUG
: NL_CB_DEFAULT
);
501 fprintf(stderr
, "failed to allocate netlink callbacks\n");
506 genlmsg_put(msg
, 0, 0, state
->nl80211_id
, 0,
507 cmd
->nl_msg_flags
, cmd
->cmd
, 0);
509 switch (command_idby
) {
511 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY
, devidx
);
514 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, devidx
);
517 NLA_PUT_U64(msg
, NL80211_ATTR_WDEV
, devidx
);
523 err
= cmd
->handler(state
, msg
, argc
, argv
, idby
);
527 nl_socket_set_cb(state
->nl_sock
, s_cb
);
529 err
= nl_send_auto_complete(state
->nl_sock
, msg
);
535 nl_cb_err(cb
, NL_CB_CUSTOM
, error_handler
, &err
);
536 nl_cb_set(cb
, NL_CB_FINISH
, NL_CB_CUSTOM
, finish_handler
, &err
);
537 nl_cb_set(cb
, NL_CB_ACK
, NL_CB_CUSTOM
, ack_handler
, &err
);
538 nl_cb_set(cb
, NL_CB_VALID
, NL_CB_CUSTOM
, valid_handler
, NULL
);
541 nl_recvmsgs(state
->nl_sock
, cb
);
548 fprintf(stderr
, "building message failed\n");
552 int handle_cmd(struct nl80211_state
*state
, enum id_input idby
,
553 int argc
, char **argv
)
555 return __handle_cmd(state
, idby
, argc
, argv
, NULL
);
559 * Unfortunately, I don't know how densely the linker packs the struct cmd.
560 * For example, if you have a 72-byte struct cmd, the linker will pad each
561 * out to 96 bytes before putting them together in the section. There must
562 * be some algorithm, but I haven't found it yet.
564 * We used to calculate this by taking the (abs value of) the difference
565 * between __section_get and __section_set, but if LTO is enabled then this
566 * stops working because the entries of the "__cmd" section get rearranged
567 * freely by the compiler/linker.
569 * Fix this by using yet another "__sizer" section that only contains these
570 * two entries - then the (abs value of) the difference between them will
571 * be how they get packed and that can be used to iterate the __cmd section
574 static struct cmd sizer1
__attribute__((section("__sizer"))) = {};
575 static struct cmd sizer2
__attribute__((section("__sizer"))) = {};
577 int main(int argc
, char **argv
)
579 struct nl80211_state nlstate
;
581 const struct cmd
*cmd
= NULL
;
583 /* calculate command size including padding */
584 cmd_size
= labs((long)&sizer2
- (long)&sizer1
);
589 if (argc
> 0 && strcmp(*argv
, "--debug") == 0) {
595 if (argc
> 0 && strcmp(*argv
, "--version") == 0) {
600 /* need to treat "help" command specially so it works w/o nl80211 */
601 if (argc
== 0 || strcmp(*argv
, "help") == 0) {
602 usage(argc
- 1, argv
+ 1);
606 err
= nl80211_init(&nlstate
);
610 if (strcmp(*argv
, "dev") == 0 && argc
> 1) {
613 err
= __handle_cmd(&nlstate
, II_NETDEV
, argc
, argv
, &cmd
);
614 } else if (strncmp(*argv
, "phy", 3) == 0 && argc
> 1) {
615 if (strlen(*argv
) == 3) {
618 err
= __handle_cmd(&nlstate
, II_PHY_NAME
, argc
, argv
, &cmd
);
619 } else if (*(*argv
+ 3) == '#')
620 err
= __handle_cmd(&nlstate
, II_PHY_IDX
, argc
, argv
, &cmd
);
623 } else if (strcmp(*argv
, "wdev") == 0 && argc
> 1) {
626 err
= __handle_cmd(&nlstate
, II_WDEV
, argc
, argv
, &cmd
);
632 if ((idx
= if_nametoindex(argv
[0])) != 0)
634 else if ((idx
= phy_lookup(argv
[0])) >= 0)
636 err
= __handle_cmd(&nlstate
, idby
, argc
, argv
, &cmd
);
639 if (err
== HANDLER_RET_USAGE
) {
644 } else if (err
== HANDLER_RET_DONE
) {
647 fprintf(stderr
, "command failed: %s (%d)\n", strerror(-err
), err
);
649 nl80211_cleanup(&nlstate
);