]> git.ipfire.org Git - thirdparty/iw.git/blob - ibss.c
add new commands
[thirdparty/iw.git] / ibss.c
1 #include <errno.h>
2 #include <string.h>
3 #include <strings.h>
4
5 #include "nl80211.h"
6 #include "iw.h"
7
8 SECTION(ibss);
9
10 static int join_ibss(struct nl80211_state *state,
11 struct nl_msg *msg,
12 int argc, char **argv,
13 enum id_input id)
14 {
15 char *end;
16 unsigned char abssid[6];
17 unsigned char rates[NL80211_MAX_SUPP_RATES];
18 int n_rates = 0;
19 char *value = NULL, *sptr = NULL;
20 float rate;
21 int bintval;
22 unsigned int i;
23 unsigned long freq;
24 const struct chanmode *chanmode_selected = NULL;
25 static const struct chanmode chanmode[] = {
26 { .name = "HT20",
27 .width = NL80211_CHAN_WIDTH_20,
28 .freq1_diff = 0,
29 .chantype = NL80211_CHAN_HT20 },
30 { .name = "HT40+",
31 .width = NL80211_CHAN_WIDTH_40,
32 .freq1_diff = 10,
33 .chantype = NL80211_CHAN_HT40PLUS },
34 { .name = "HT40-",
35 .width = NL80211_CHAN_WIDTH_40,
36 .freq1_diff = -10,
37 .chantype = NL80211_CHAN_HT40MINUS },
38 { .name = "NOHT",
39 .width = NL80211_CHAN_WIDTH_20_NOHT,
40 .freq1_diff = 0,
41 .chantype = NL80211_CHAN_NO_HT },
42 { .name = "5MHz",
43 .width = NL80211_CHAN_WIDTH_5,
44 .freq1_diff = 0,
45 .chantype = -1 },
46 { .name = "10MHz",
47 .width = NL80211_CHAN_WIDTH_10,
48 .freq1_diff = 0,
49 .chantype = -1 },
50 { .name = "80MHz",
51 .width = NL80211_CHAN_WIDTH_80,
52 .freq1_diff = 0,
53 .chantype = -1 },
54 };
55
56 if (argc < 2)
57 return 1;
58
59 /* SSID */
60 NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
61 argv++;
62 argc--;
63
64 /* freq */
65 freq = strtoul(argv[0], &end, 10);
66 if (*end != '\0')
67 return 1;
68
69 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
70 argv++;
71 argc--;
72
73 if (argc) {
74 for (i = 0; i < ARRAY_SIZE(chanmode); i++) {
75 if (strcasecmp(chanmode[i].name, argv[0]) == 0) {
76 chanmode_selected = &chanmode[i];
77 break;
78 }
79 }
80 if (chanmode_selected) {
81 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
82 chanmode_selected->width);
83 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1,
84 get_cf1(chanmode_selected, freq));
85 if (chanmode_selected->chantype != -1)
86 NLA_PUT_U32(msg,
87 NL80211_ATTR_WIPHY_CHANNEL_TYPE,
88 chanmode_selected->chantype);
89
90 argv++;
91 argc--;
92 }
93
94 }
95
96 if (argc && strcmp(argv[0], "fixed-freq") == 0) {
97 NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED);
98 argv++;
99 argc--;
100 }
101
102 if (argc) {
103 if (mac_addr_a2n(abssid, argv[0]) == 0) {
104 NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
105 argv++;
106 argc--;
107 }
108 }
109
110 if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) {
111 argv++;
112 argc--;
113 bintval = strtoul(argv[0], &end, 10);
114 if (*end != '\0')
115 return 1;
116 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval);
117 argv++;
118 argc--;
119 }
120
121 /* basic rates */
122 if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
123 argv++;
124 argc--;
125
126 value = strtok_r(argv[0], ",", &sptr);
127
128 while (value && n_rates < NL80211_MAX_SUPP_RATES) {
129 rate = strtod(value, &end);
130 rates[n_rates] = rate * 2;
131
132 /* filter out suspicious values */
133 if (*end != '\0' || !rates[n_rates] ||
134 rate*2 != rates[n_rates])
135 return 1;
136
137 n_rates++;
138 value = strtok_r(NULL, ",", &sptr);
139 }
140
141 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates);
142
143 argv++;
144 argc--;
145 }
146
147 /* multicast rate */
148 if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) {
149 argv++;
150 argc--;
151
152 rate = strtod(argv[0], &end);
153 if (*end != '\0')
154 return 1;
155
156 NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10));
157 argv++;
158 argc--;
159 }
160
161 if (!argc)
162 return 0;
163
164 if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
165 return 1;
166
167 argv++;
168 argc--;
169
170 return parse_keys(msg, argv, argc);
171 nla_put_failure:
172 return -ENOSPC;
173 }
174
175 static int leave_ibss(struct nl80211_state *state,
176 struct nl_msg *msg,
177 int argc, char **argv,
178 enum id_input id)
179 {
180 return 0;
181 }
182 COMMAND(ibss, leave, NULL,
183 NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
184 "Leave the current IBSS cell.");
185 COMMAND(ibss, join,
186 "<SSID> <freq in MHz> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]"
187 " [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] "
188 "[key d:0:abcde]",
189 NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss,
190 "Join the IBSS cell with the given SSID, if it doesn't exist create\n"
191 "it on the given frequency. When fixed frequency is requested, don't\n"
192 "join/create a cell on a different frequency. When a fixed BSSID is\n"
193 "requested use that BSSID and do not adopt another cell's BSSID even\n"
194 "if it has higher TSF and the same SSID. If an IBSS is created, create\n"
195 "it with the specified basic-rates, multicast-rate and beacon-interval.");