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>
23 int chantype
; /* for older kernel */
26 static int get_cf1(const struct chanmode
*chanmode
, unsigned long freq
)
28 unsigned int cf1
= freq
, j
;
29 unsigned int vht80
[] = { 5180, 5260, 5500, 5580, 5660, 5745 };
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)
39 if (j
== ARRAY_SIZE(vht80
))
45 cf1
= freq
+ chanmode
->freq1_diff
;
52 static int join_ibss(struct nl80211_state
*state
,
54 int argc
, char **argv
,
58 unsigned char abssid
[6];
59 unsigned char rates
[NL80211_MAX_SUPP_RATES
];
61 char *value
= NULL
, *sptr
= NULL
;
66 const struct chanmode
*chanmode_selected
= NULL
;
67 static const struct chanmode chanmode
[] = {
69 .width
= NL80211_CHAN_WIDTH_20
,
71 .chantype
= NL80211_CHAN_HT20
},
73 .width
= NL80211_CHAN_WIDTH_40
,
75 .chantype
= NL80211_CHAN_HT40PLUS
},
77 .width
= NL80211_CHAN_WIDTH_40
,
79 .chantype
= NL80211_CHAN_HT40MINUS
},
81 .width
= NL80211_CHAN_WIDTH_20_NOHT
,
83 .chantype
= NL80211_CHAN_NO_HT
},
85 .width
= NL80211_CHAN_WIDTH_5
,
89 .width
= NL80211_CHAN_WIDTH_10
,
93 .width
= NL80211_CHAN_WIDTH_80
,
102 NLA_PUT(msg
, NL80211_ATTR_SSID
, strlen(argv
[0]), argv
[0]);
107 freq
= strtoul(argv
[0], &end
, 10);
111 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
116 for (i
= 0; i
< ARRAY_SIZE(chanmode
); i
++) {
117 if (strcasecmp(chanmode
[i
].name
, argv
[0]) == 0) {
118 chanmode_selected
= &chanmode
[i
];
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
,
126 get_cf1(chanmode_selected
, freq
));
127 if (chanmode_selected
->chantype
!= -1)
129 NL80211_ATTR_WIPHY_CHANNEL_TYPE
,
130 chanmode_selected
->chantype
);
138 if (argc
&& strcmp(argv
[0], "fixed-freq") == 0) {
139 NLA_PUT_FLAG(msg
, NL80211_ATTR_FREQ_FIXED
);
145 if (mac_addr_a2n(abssid
, argv
[0]) == 0) {
146 NLA_PUT(msg
, NL80211_ATTR_MAC
, 6, abssid
);
152 if (argc
> 1 && strcmp(argv
[0], "beacon-interval") == 0) {
155 bintval
= strtoul(argv
[0], &end
, 10);
158 NLA_PUT_U32(msg
, NL80211_ATTR_BEACON_INTERVAL
, bintval
);
164 if (argc
> 1 && strcmp(argv
[0], "basic-rates") == 0) {
168 value
= strtok_r(argv
[0], ",", &sptr
);
170 while (value
&& n_rates
< NL80211_MAX_SUPP_RATES
) {
171 rate
= strtod(value
, &end
);
172 rates
[n_rates
] = rate
* 2;
174 /* filter out suspicious values */
175 if (*end
!= '\0' || !rates
[n_rates
] ||
176 rate
*2 != rates
[n_rates
])
180 value
= strtok_r(NULL
, ",", &sptr
);
183 NLA_PUT(msg
, NL80211_ATTR_BSS_BASIC_RATES
, n_rates
, rates
);
190 if (argc
> 1 && strcmp(argv
[0], "mcast-rate") == 0) {
194 rate
= strtod(argv
[0], &end
);
198 NLA_PUT_U32(msg
, NL80211_ATTR_MCAST_RATE
, (int)(rate
* 10));
206 if (strcmp(*argv
, "key") != 0 && strcmp(*argv
, "keys") != 0)
212 return parse_keys(msg
, argv
, argc
);
217 static int leave_ibss(struct nl80211_state
*state
,
219 int argc
, char **argv
,
224 COMMAND(ibss
, leave
, NULL
,
225 NL80211_CMD_LEAVE_IBSS
, 0, CIB_NETDEV
, leave_ibss
,
226 "Leave the current IBSS cell.");
228 "<SSID> <freq in MHz> [HT20|HT40+|HT40-|NOHT|5MHz|10MHz|80MHz] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]"
229 " [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] "
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"
236 "if it has higher TSF and the same SSID. If an IBSS is created, create\n"
237 "it with the specified basic-rates, multicast-rate and beacon-interval.");