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>
17 static int handle_name(struct nl80211_state
*state
,
19 int argc
, char **argv
,
25 NLA_PUT_STRING(msg
, NL80211_ATTR_WIPHY_NAME
, *argv
);
31 COMMAND(set
, name
, "<new name>", NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_name
,
32 "Rename this wireless device.");
34 static int handle_freqs(struct nl_msg
*msg
, int argc
, char **argv
)
40 { .name
= "20", .val
= NL80211_CHAN_WIDTH_20
, },
41 { .name
= "40", .val
= NL80211_CHAN_WIDTH_40
, },
42 { .name
= "80", .val
= NL80211_CHAN_WIDTH_80
, },
43 { .name
= "80+80", .val
= NL80211_CHAN_WIDTH_80P80
, },
44 { .name
= "160", .val
= NL80211_CHAN_WIDTH_160
, },
47 int i
, bwval
= NL80211_CHAN_WIDTH_20_NOHT
;
53 for (i
= 0; i
< ARRAY_SIZE(bwmap
); i
++) {
54 if (strcasecmp(bwmap
[i
].name
, argv
[0]) == 0) {
60 if (bwval
== NL80211_CHAN_WIDTH_20_NOHT
)
63 NLA_PUT_U32(msg
, NL80211_ATTR_CHANNEL_WIDTH
, bwval
);
71 freq
= strtoul(argv
[1], &end
, 10);
74 NLA_PUT_U32(msg
, NL80211_ATTR_CENTER_FREQ1
, freq
);
82 freq
= strtoul(argv
[2], &end
, 10);
85 NLA_PUT_U32(msg
, NL80211_ATTR_CENTER_FREQ2
, freq
);
92 static int handle_freqchan(struct nl_msg
*msg
, bool chan
,
93 int argc
, char **argv
)
100 { .name
= "HT20", .val
= NL80211_CHAN_HT20
, },
101 { .name
= "HT40+", .val
= NL80211_CHAN_HT40PLUS
, },
102 { .name
= "HT40-", .val
= NL80211_CHAN_HT40MINUS
, },
104 unsigned int htval
= NL80211_CHAN_NO_HT
;
108 if (!argc
|| argc
> 4)
113 freq
= strtoul(argv
[0], &end
, 10);
118 enum nl80211_band band
;
119 band
= freq
<= 14 ? NL80211_BAND_2GHZ
: NL80211_BAND_5GHZ
;
120 freq
= ieee80211_channel_to_frequency(freq
, band
);
123 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
126 return handle_freqs(msg
, argc
- 1, argv
+ 1);
127 } else if (argc
== 2) {
128 for (i
= 0; i
< ARRAY_SIZE(htmap
); i
++) {
129 if (strcasecmp(htmap
[i
].name
, argv
[1]) == 0) {
130 htval
= htmap
[i
].val
;
134 if (htval
== NL80211_CHAN_NO_HT
)
135 return handle_freqs(msg
, argc
- 1, argv
+ 1);
138 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_CHANNEL_TYPE
, htval
);
145 static int handle_freq(struct nl80211_state
*state
, struct nl_msg
*msg
,
146 int argc
, char **argv
,
149 return handle_freqchan(msg
, false, argc
, argv
);
151 COMMAND(set
, freq
, "<freq> [HT20|HT40+|HT40-]",
152 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_freq
,
153 "Set frequency/channel the hardware is using, including HT\n"
155 COMMAND(set
, freq
, "<freq> [HT20|HT40+|HT40-]\n"
156 "<control freq> [20|40|80|80+80|160] [<center freq 1>] [<center freq 2>]",
157 NL80211_CMD_SET_WIPHY
, 0, CIB_NETDEV
, handle_freq
, NULL
);
159 static int handle_chan(struct nl80211_state
*state
, struct nl_msg
*msg
,
160 int argc
, char **argv
,
163 return handle_freqchan(msg
, true, argc
, argv
);
165 COMMAND(set
, channel
, "<channel> [HT20|HT40+|HT40-]",
166 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_chan
, NULL
);
167 COMMAND(set
, channel
, "<channel> [HT20|HT40+|HT40-]",
168 NL80211_CMD_SET_WIPHY
, 0, CIB_NETDEV
, handle_chan
, NULL
);
170 static int handle_fragmentation(struct nl80211_state
*state
,
172 int argc
, char **argv
,
180 if (strcmp("off", argv
[0]) == 0)
187 frag
= strtoul(argv
[0], &end
, 10);
192 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FRAG_THRESHOLD
, frag
);
198 COMMAND(set
, frag
, "<fragmentation threshold|off>",
199 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_fragmentation
,
200 "Set fragmentation threshold.");
202 static int handle_rts(struct nl80211_state
*state
,
204 int argc
, char **argv
,
212 if (strcmp("off", argv
[0]) == 0)
219 rts
= strtoul(argv
[0], &end
, 10);
224 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_RTS_THRESHOLD
, rts
);
230 COMMAND(set
, rts
, "<rts threshold|off>",
231 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_rts
,
232 "Set rts threshold.");
234 static int handle_retry(struct nl80211_state
*state
,
236 int argc
, char **argv
, enum id_input id
)
238 unsigned int retry_short
= 0, retry_long
= 0;
239 bool have_retry_s
= false, have_retry_l
= false;
245 } parser_state
= S_NONE
;
247 if (!argc
|| (argc
!= 2 && argc
!= 4))
250 for (i
= 0; i
< argc
; i
++) {
254 if (strcmp(argv
[i
], "short") == 0) {
257 parser_state
= S_SHORT
;
259 } else if (strcmp(argv
[i
], "long") == 0) {
262 parser_state
= S_LONG
;
265 tmpul
= strtoul(argv
[i
], &end
, 10);
268 if (!tmpul
|| tmpul
> 255)
270 switch (parser_state
) {
283 if (!have_retry_s
&& !have_retry_l
)
286 NLA_PUT_U8(msg
, NL80211_ATTR_WIPHY_RETRY_SHORT
, retry_short
);
288 NLA_PUT_U8(msg
, NL80211_ATTR_WIPHY_RETRY_LONG
, retry_long
);
294 COMMAND(set
, retry
, "[short <limit>] [long <limit>]",
295 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_retry
,
298 #ifndef NETNS_RUN_DIR
299 #define NETNS_RUN_DIR "/var/run/netns"
301 static int netns_get_fd(const char *name
)
303 char pathbuf
[MAXPATHLEN
];
304 const char *path
, *ptr
;
307 ptr
= strchr(name
, '/');
309 snprintf(pathbuf
, sizeof(pathbuf
), "%s/%s",
310 NETNS_RUN_DIR
, name
);
313 return open(path
, O_RDONLY
);
316 static int handle_netns(struct nl80211_state
*state
,
318 int argc
, char **argv
,
324 if (argc
< 1 || !*argv
[0])
328 NLA_PUT_U32(msg
, NL80211_ATTR_PID
,
329 strtoul(argv
[0], &end
, 10));
331 printf("Invalid parameter: pid(%s)\n", argv
[0]);
337 if (argc
!= 2 || strcmp(argv
[0], "name"))
340 if ((fd
= netns_get_fd(argv
[1])) >= 0) {
341 NLA_PUT_U32(msg
, NL80211_ATTR_NETNS_FD
, fd
);
344 printf("Invalid parameter: nsname(%s)\n", argv
[0]);
352 COMMAND(set
, netns
, "{ <pid> | name <nsname> }",
353 NL80211_CMD_SET_WIPHY_NETNS
, 0, CIB_PHY
, handle_netns
,
354 "Put this wireless device into a different network namespace:\n"
355 " <pid> - change network namespace by process id\n"
356 " <nsname> - change network namespace by name from "NETNS_RUN_DIR
"\n"
357 " or by absolute path (man ip-netns)\n");
359 static int handle_coverage(struct nl80211_state
*state
,
361 int argc
, char **argv
,
365 unsigned int coverage
;
372 coverage
= strtoul(argv
[0], &end
, 10);
379 NLA_PUT_U8(msg
, NL80211_ATTR_WIPHY_COVERAGE_CLASS
, coverage
);
385 COMMAND(set
, coverage
, "<coverage class>",
386 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_coverage
,
387 "Set coverage class (1 for every 3 usec of air propagation time).\n"
388 "Valid values: 0 - 255.");
390 static int handle_distance(struct nl80211_state
*state
,
392 int argc
, char **argv
,
401 if (strcmp("auto", argv
[0]) == 0) {
402 NLA_PUT_FLAG(msg
, NL80211_ATTR_WIPHY_DYN_ACK
);
405 unsigned int distance
, coverage
;
407 distance
= strtoul(argv
[0], &end
, 10);
413 * Divide double the distance by the speed of light
414 * in m/usec (300) to get round-trip time in microseconds
415 * and then divide the result by three to get coverage class
416 * as specified in IEEE 802.11-2007 table 7-27.
417 * Values are rounded upwards.
419 coverage
= (distance
+ 449) / 450;
423 NLA_PUT_U8(msg
, NL80211_ATTR_WIPHY_COVERAGE_CLASS
, coverage
);
430 COMMAND(set
, distance
, "<auto|distance>",
431 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_distance
,
432 "Enable ACK timeout estimation algorithm (dynack) or set appropriate\n"
433 "coverage class for given link distance in meters.\n"
434 "To disable dynack set valid value for coverage class.\n"
435 "Valid values: 0 - 114750");
437 static int handle_txpower(struct nl80211_state
*state
,
439 int argc
, char **argv
,
442 enum nl80211_tx_power_setting type
;
445 /* get the required args */
446 if (argc
!= 1 && argc
!= 2)
449 if (!strcmp(argv
[0], "auto"))
450 type
= NL80211_TX_POWER_AUTOMATIC
;
451 else if (!strcmp(argv
[0], "fixed"))
452 type
= NL80211_TX_POWER_FIXED
;
453 else if (!strcmp(argv
[0], "limit"))
454 type
= NL80211_TX_POWER_LIMITED
;
456 printf("Invalid parameter: %s\n", argv
[0]);
460 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_TX_POWER_SETTING
, type
);
462 if (type
!= NL80211_TX_POWER_AUTOMATIC
) {
465 printf("Missing TX power level argument.\n");
469 mbm
= strtol(argv
[1], &endptr
, 10);
472 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_TX_POWER_LEVEL
, mbm
);
473 } else if (argc
!= 1)
481 COMMAND(set
, txpower
, "<auto|fixed|limit> [<tx power in mBm>]",
482 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_txpower
,
483 "Specify transmit power level and setting type.");
484 COMMAND(set
, txpower
, "<auto|fixed|limit> [<tx power in mBm>]",
485 NL80211_CMD_SET_WIPHY
, 0, CIB_NETDEV
, handle_txpower
,
486 "Specify transmit power level and setting type.");
488 static int handle_antenna(struct nl80211_state
*state
,
490 int argc
, char **argv
,
494 uint32_t tx_ant
= 0, rx_ant
= 0;
496 if (argc
== 1 && strcmp(argv
[0], "all") == 0) {
499 } else if (argc
== 1) {
500 tx_ant
= rx_ant
= strtoul(argv
[0], &end
, 0);
504 else if (argc
== 2) {
505 tx_ant
= strtoul(argv
[0], &end
, 0);
508 rx_ant
= strtoul(argv
[1], &end
, 0);
514 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_ANTENNA_TX
, tx_ant
);
515 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_ANTENNA_RX
, rx_ant
);
522 COMMAND(set
, antenna
, "<bitmap> | all | <tx bitmap> <rx bitmap>",
523 NL80211_CMD_SET_WIPHY
, 0, CIB_PHY
, handle_antenna
,
524 "Set a bitmap of allowed antennas to use for TX and RX.\n"
525 "The driver may reject antenna configurations it cannot support.");