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