]>
git.ipfire.org Git - thirdparty/iw.git/blob - iw.c
2 * nl80211 userspace tool
4 * Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net>
11 #include <sys/types.h>
16 #include <netlink/genl/genl.h>
17 #include <netlink/genl/family.h>
18 #include <netlink/genl/ctrl.h>
19 #include <netlink/msg.h>
20 #include <netlink/attr.h>
21 #include <linux/nl80211.h>
28 static int nl80211_init(struct nl80211_state
*state
)
32 state
->nl_handle
= nl_handle_alloc();
33 if (!state
->nl_handle
) {
34 fprintf(stderr
, "Failed to allocate netlink handle.\n");
38 if (genl_connect(state
->nl_handle
)) {
39 fprintf(stderr
, "Failed to connect to generic netlink.\n");
41 goto out_handle_destroy
;
44 state
->nl_cache
= genl_ctrl_alloc_cache(state
->nl_handle
);
45 if (!state
->nl_cache
) {
46 fprintf(stderr
, "Failed to allocate generic netlink cache.\n");
48 goto out_handle_destroy
;
51 state
->nl80211
= genl_ctrl_search_by_name(state
->nl_cache
, "nl80211");
52 if (!state
->nl80211
) {
53 fprintf(stderr
, "nl80211 not found.\n");
61 nl_cache_free(state
->nl_cache
);
63 nl_handle_destroy(state
->nl_handle
);
67 static void nl80211_cleanup(struct nl80211_state
*state
)
69 genl_family_put(state
->nl80211
);
70 nl_cache_free(state
->nl_cache
);
71 nl_handle_destroy(state
->nl_handle
);
74 __COMMAND(NULL
, NULL
, NULL
, 0, 0, CIB_NONE
, NULL
);
75 __COMMAND(NULL
, NULL
, NULL
, 1, 0, CIB_NONE
, NULL
);
79 static void usage(const char *argv0
)
83 fprintf(stderr
, "Usage:\t%s [options] command\n", argv0
);
84 fprintf(stderr
, "Options:\n");
85 fprintf(stderr
, "\t--debug\t\tenable netlink debugging\n");
86 fprintf(stderr
, "\t--version\tshow version\n");
87 fprintf(stderr
, "Commands:\n");
88 for (cmd
= &__start___cmd
; cmd
< &__stop___cmd
;
89 cmd
= (struct cmd
*)((char *)cmd
+ cmd_size
)) {
94 fprintf(stderr
, "\t");
97 if (cmd
->idby
== CIB_PHY
)
98 fprintf(stderr
, "\tphy <phyname> ");
101 if (cmd
->idby
== CIB_NETDEV
)
102 fprintf(stderr
, "\tdev <devname> ");
104 fprintf(stderr
, "%s ", cmd
->section
);
105 fprintf(stderr
, "%s", cmd
->name
);
107 fprintf(stderr
, " %s", cmd
->args
);
108 fprintf(stderr
, "\n");
114 static void version(void)
116 printf("iw version " IW_VERSION
"\n");
119 static int phy_lookup(char *name
)
124 snprintf(buf
, sizeof(buf
), "/sys/class/ieee80211/%s/index", name
);
126 fd
= open(buf
, O_RDONLY
);
127 pos
= read(fd
, buf
, sizeof(buf
) - 1);
134 static int error_handler(struct sockaddr_nl
*nla
, struct nlmsgerr
*err
,
142 static int finish_handler(struct nl_msg
*msg
, void *arg
)
147 static int ack_handler(struct nl_msg
*msg
, void *arg
)
154 static int handle_cmd(struct nl80211_state
*state
,
155 enum command_identify_by idby
,
156 int argc
, char **argv
)
159 struct nl_cb
*cb
= NULL
;
163 const char *command
, *section
;
165 if (argc
<= 1 && idby
!= CIB_NONE
)
170 devidx
= phy_lookup(*argv
);
175 devidx
= if_nametoindex(*argv
);
183 section
= command
= *argv
;
187 for (cmd
= &__start___cmd
; cmd
< &__stop___cmd
;
188 cmd
= (struct cmd
*)((char *)cmd
+ cmd_size
)) {
191 if (cmd
->idby
!= idby
)
194 if (strcmp(cmd
->section
, section
))
196 /* this is a bit icky ... */
197 if (command
== section
) {
204 } else if (section
!= command
)
206 if (strcmp(cmd
->name
, command
))
208 if (argc
&& !cmd
->args
)
213 if (cmd
== &__stop___cmd
)
218 fprintf(stderr
, "failed to allocate netlink message\n");
222 cb
= nl_cb_alloc(debug
? NL_CB_DEBUG
: NL_CB_DEFAULT
);
224 fprintf(stderr
, "failed to allocate netlink callbacks\n");
229 genlmsg_put(msg
, 0, 0, genl_family_get_id(state
->nl80211
), 0,
230 cmd
->nl_msg_flags
, cmd
->cmd
, 0);
234 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY
, devidx
);
237 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, devidx
);
243 err
= cmd
->handler(cb
, msg
, argc
, argv
);
247 err
= nl_send_auto_complete(state
->nl_handle
, msg
);
251 nl_cb_err(cb
, NL_CB_CUSTOM
, error_handler
, &err
);
252 nl_cb_set(cb
, NL_CB_FINISH
, NL_CB_CUSTOM
, finish_handler
, NULL
);
253 nl_cb_set(cb
, NL_CB_ACK
, NL_CB_CUSTOM
, ack_handler
, &err
);
255 nl_recvmsgs(state
->nl_handle
, cb
);
262 fprintf(stderr
, "building message failed\n");
266 int main(int argc
, char **argv
)
268 struct nl80211_state nlstate
;
272 cmd_size
= abs((long)&__cmd_NULL1CIB_NONE
- (long)&__cmd_NULL0CIB_NONE
);
277 if (argc
> 0 && strcmp(*argv
, "--debug") == 0) {
283 if (argc
> 0 && strcmp(*argv
, "--version") == 0) {
288 if (argc
== 0 || strcmp(*argv
, "help") == 0) {
293 err
= nl80211_init(&nlstate
);
297 if (strcmp(*argv
, "dev") == 0) {
300 err
= handle_cmd(&nlstate
, CIB_NETDEV
, argc
, argv
);
301 } else if (strcmp(*argv
, "phy") == 0) {
304 err
= handle_cmd(&nlstate
, CIB_PHY
, argc
, argv
);
306 err
= handle_cmd(&nlstate
, CIB_NONE
, argc
, argv
);
311 fprintf(stderr
, "command failed: %s (%d)\n", strerror(-err
), err
);
313 nl80211_cleanup(&nlstate
);