]> git.ipfire.org Git - thirdparty/iw.git/blame - ibss.c
ibss: use correct "MHz" instead of "MHZ"
[thirdparty/iw.git] / ibss.c
CommitLineData
b893686f
JB
1#ifndef _POSIX_SOURCE
2#define _POSIX_SOURCE
3#endif
edea4d14 4#include <errno.h>
b893686f 5#include <string.h>
135cb523 6#include <strings.h>
edea4d14
JB
7
8#include <netlink/genl/genl.h>
9#include <netlink/genl/family.h>
10#include <netlink/genl/ctrl.h>
11#include <netlink/msg.h>
12#include <netlink/attr.h>
13
14#include "nl80211.h"
15#include "iw.h"
16
4698bfc2
JB
17SECTION(ibss);
18
faeef830
JD
19struct chanmode {
20 const char *name;
21 unsigned int width;
22 int freq1_diff;
23 int chantype; /* for older kernel */
24};
25
26static int get_cf1(const struct chanmode *chanmode, unsigned long freq)
27{
28 int cf1 = freq, j;
29 int vht80[] = { 5180, 5260, 5500, 5580, 5660, 5745 };
30
31 switch (chanmode->width) {
32 case NL80211_CHAN_WIDTH_80:
33 /* setup center_freq1 */
34 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
35 if (freq >= vht80[j] && freq < vht80[j] + 80)
36 break;
37 }
38
39 if (j == ARRAY_SIZE(vht80))
40 break;
41
42 cf1 = vht80[j] + 30;
43 break;
44 default:
45 cf1 = freq + chanmode->freq1_diff;
46 break;
47 }
48
49 return cf1;
50}
51
edea4d14 52static int join_ibss(struct nl80211_state *state,
edea4d14 53 struct nl_msg *msg,
05514f95
JB
54 int argc, char **argv,
55 enum id_input id)
edea4d14 56{
95940df3 57 char *end;
edea4d14 58 unsigned char abssid[6];
6a24bb22
TP
59 unsigned char rates[NL80211_MAX_SUPP_RATES];
60 int n_rates = 0;
61 char *value = NULL, *sptr = NULL;
62 float rate;
ec46ba52 63 int bintval;
135cb523 64 int i;
85da7703 65 unsigned long freq;
faeef830
JD
66 const struct chanmode *chanmode_selected = NULL;
67 static const struct chanmode chanmode[] = {
85da7703
SW
68 { .name = "HT20",
69 .width = NL80211_CHAN_WIDTH_20,
70 .freq1_diff = 0,
71 .chantype = NL80211_CHAN_HT20 },
72 { .name = "HT40+",
73 .width = NL80211_CHAN_WIDTH_40,
74 .freq1_diff = 10,
75 .chantype = NL80211_CHAN_HT40PLUS },
76 { .name = "HT40-",
77 .width = NL80211_CHAN_WIDTH_40,
78 .freq1_diff = -10,
79 .chantype = NL80211_CHAN_HT40MINUS },
80 { .name = "NOHT",
81 .width = NL80211_CHAN_WIDTH_20_NOHT,
82 .freq1_diff = 0,
83 .chantype = NL80211_CHAN_NO_HT },
7187aada 84 { .name = "5MHz",
85da7703
SW
85 .width = NL80211_CHAN_WIDTH_5,
86 .freq1_diff = 0,
87 .chantype = -1 },
7187aada 88 { .name = "10MHz",
85da7703
SW
89 .width = NL80211_CHAN_WIDTH_10,
90 .freq1_diff = 0,
91 .chantype = -1 },
7187aada 92 { .name = "80MHz",
faeef830
JD
93 .width = NL80211_CHAN_WIDTH_80,
94 .freq1_diff = 0,
95 .chantype = -1 },
135cb523 96 };
edea4d14 97
95940df3
JB
98 if (argc < 2)
99 return 1;
edea4d14 100
95940df3
JB
101 /* SSID */
102 NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
edea4d14
JB
103 argv++;
104 argc--;
105
95940df3 106 /* freq */
85da7703 107 freq = strtoul(argv[0], &end, 10);
95940df3
JB
108 if (*end != '\0')
109 return 1;
85da7703
SW
110
111 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
95940df3
JB
112 argv++;
113 argc--;
edea4d14 114
135cb523 115 if (argc) {
85da7703
SW
116 for (i = 0; i < ARRAY_SIZE(chanmode); i++) {
117 if (strcasecmp(chanmode[i].name, argv[0]) == 0) {
118 chanmode_selected = &chanmode[i];
135cb523
SW
119 break;
120 }
121 }
85da7703
SW
122 if (chanmode_selected) {
123 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
124 chanmode_selected->width);
125 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1,
faeef830 126 get_cf1(chanmode_selected, freq));
85da7703
SW
127 if (chanmode_selected->chantype != -1)
128 NLA_PUT_U32(msg,
129 NL80211_ATTR_WIPHY_CHANNEL_TYPE,
130 chanmode_selected->chantype);
131
135cb523
SW
132 argv++;
133 argc--;
134 }
135
136 }
137
95940df3
JB
138 if (argc && strcmp(argv[0], "fixed-freq") == 0) {
139 NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED);
140 argv++;
141 argc--;
edea4d14
JB
142 }
143
95940df3 144 if (argc) {
51e9bd80
JB
145 if (mac_addr_a2n(abssid, argv[0]) == 0) {
146 NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
147 argv++;
148 argc--;
149 }
edea4d14
JB
150 }
151
ec46ba52
BR
152 if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) {
153 argv++;
154 argc--;
155 bintval = strtoul(argv[0], &end, 10);
156 if (*end != '\0')
157 return 1;
158 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval);
159 argv++;
160 argc--;
161 }
162
6a24bb22
TP
163 /* basic rates */
164 if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
165 argv++;
166 argc--;
167
168 value = strtok_r(argv[0], ",", &sptr);
169
170 while (value && n_rates < NL80211_MAX_SUPP_RATES) {
171 rate = strtod(value, &end);
172 rates[n_rates] = rate * 2;
173
174 /* filter out suspicious values */
175 if (*end != '\0' || !rates[n_rates] ||
176 rate*2 != rates[n_rates])
177 return 1;
178
179 n_rates++;
180 value = strtok_r(NULL, ",", &sptr);
181 }
182
183 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates);
184
185 argv++;
186 argc--;
187 }
188
506b442b
FF
189 /* multicast rate */
190 if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) {
191 argv++;
192 argc--;
193
194 rate = strtod(argv[0], &end);
195 if (*end != '\0')
196 return 1;
197
e399be8c 198 NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10));
506b442b
FF
199 argv++;
200 argc--;
201 }
202
1e03690e
JB
203 if (!argc)
204 return 0;
edea4d14 205
1e03690e
JB
206 if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
207 return 1;
ded1f078 208
1e03690e
JB
209 argv++;
210 argc--;
51e9bd80 211
1e03690e 212 return parse_keys(msg, argv, argc);
edea4d14
JB
213 nla_put_failure:
214 return -ENOSPC;
215}
216
217static int leave_ibss(struct nl80211_state *state,
edea4d14 218 struct nl_msg *msg,
05514f95
JB
219 int argc, char **argv,
220 enum id_input id)
edea4d14
JB
221{
222 return 0;
223}
224COMMAND(ibss, leave, NULL,
806bad30
JB
225 NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
226 "Leave the current IBSS cell.");
6a24bb22 227COMMAND(ibss, join,
7187aada 228 "<SSID> <freq in MHz> [HT20|HT40+|HT40-|NOHT|5MHz|10MHz|80MHz] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]"
506b442b
FF
229 " [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] "
230 "[key d:0:abcde]",
806bad30
JB
231 NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss,
232 "Join the IBSS cell with the given SSID, if it doesn't exist create\n"
233 "it on the given frequency. When fixed frequency is requested, don't\n"
234 "join/create a cell on a different frequency. When a fixed BSSID is\n"
235 "requested use that BSSID and do not adopt another cell's BSSID even\n"
ec46ba52 236 "if it has higher TSF and the same SSID. If an IBSS is created, create\n"
506b442b 237 "it with the specified basic-rates, multicast-rate and beacon-interval.");