1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
/*
* Definitions and functions for nl80211 based routines.
*/
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <netinet/ether.h>
#include <stdbool.h>
/*
* Use local copy of nl80211.h rather than the one shipped with the distro in
* /usr/include/linux. There are different versions, local one may be out of date.
*/
#include "nl80211.h"
#define BIT(x) (1ULL<<(x)) /* from iw:iw.h */
/* Set to 1 to enable callback debugging */
#define IW_NL_CB_DEBUG 0
/**
* struct msg_attribute - attributes to nla_put into the message
* @type: type of the attribute
* @len: attribute length
* @data: pointer to data area of length @len
*/
struct msg_attribute {
int type,
len;
const void *data;
};
/**
* struct cmd - stolen and modified from iw:iw.h
* @cmd: nl80211 command to send via GeNetlink
* @sk: netlink socket to be used for this command
* @flags: flags to set in the GeNetlink message
* @handler: netlink callback handler
* @handler_arg: argument for @handler
* @msg_args: additional attributes to pass into message
* @msg_args_len: number of elements in @msg_args
*/
struct cmd {
enum nl80211_commands cmd;
struct nl_sock *sk;
int flags;
int (*handler)(struct nl_msg *msg, void *arg);
void *handler_arg;
struct msg_attribute *msg_args;
uint8_t msg_args_len;
};
extern int handle_cmd(struct cmd *cmd);
/**
* iw_nl80211_ifstat - interface statistics
* @phy: PHY index
* @ifindex: ifindex of receiving interface
* @wdev: wireless device index
* @iftype: interface mode (access point ...)
*
* @freq: frequency in MHz
* @chan_width: channel width
* @chan_type: channel type
* @freq_ctr1: center frequency #1
* @freq_ctr2: center frequency #2
*/
struct iw_nl80211_ifstat {
uint32_t phy,
ifindex,
wdev,
iftype;
char ssid[64];
uint32_t freq;
int chan_width,
chan_type,
freq_ctr1,
freq_ctr2;
};
extern void iw_nl80211_getifstat(struct iw_nl80211_ifstat *is);
/**
* struct iw_nl80211_survey_data - channel survey data
* @freq: channel frequency (only filled in if it is in use)
* @noise: channel noise in dBm (0 means invalid data)
*
* @active: amount of time that the radio was on
* @busy: amount of the time the primary channel was sensed busy
* @ext_busy: amount of time the extension channel was sensed busy
* @rx: amount of time the radio spent receiving data
* @tx: amount of time the radio spent transmitting data
* @scan: time the radio spent for scan
*/
struct iw_nl80211_survey {
uint32_t freq;
int8_t noise;
struct time_data_in_milliseconds {
uint64_t active,
busy,
ext_busy,
rx,
tx,
scan;
} time;
};
extern void iw_nl80211_get_survey(struct iw_nl80211_survey *sd);
/* struct iw_nl80211_linkstat - aggregate link statistics
* @status: association status (%nl80211_bss_status)
* @bssid: station MAC address
* @inactive_time: inactivity in msec
* @connected_time: time since last connecting in sec
* @beacon_loss: count of time beacon loss was detected
* @rx_bytes/packets: byte/packet counter for RX direction
* @rx_drop_misc: packets dropped for unspecified reasons
* @tx_bytes/packets: byte/packet counter for TX direction
* @tx_retries: TX retry counter
* @tx_failed: TX failure counter
* @expected_thru: expected throughput in kB/s
* @beacon_int: beacon interval in Time Units of 1024usec
* @dtim_period: DTIM period for beaconing
* @beacon_avg_sig: average beacon signal (in dBm)
* @beacons: number of beacons received
* @beacon_loss: count of times beacon loss was detected
* @signal: signal strength in dBm (0 if not present)
* @signal_avg: average signal strength in dBm
* @bss_signal: signal strength of BSS probe in dBm (or 0)
* @bss_signal_qual: unitless signal strength of BSS probe, 0..100
* @tx_bitrate: string describing current TX bitrate
* @rx_bitrate: string describing current RX bitrate
* @cts_protection: whether CTS protection is set
* @long_preamble: whether using long or short preamble
* @short_slot_time: whether short slots are enabled
* @wme: Wireless Multimedia Extensions / Wi-Fi Multimedia
* @mfp: Management Frame Protection
* @tdls: Tunneled Direct Link Setup
* @survey: channel survey data (where present)
*/
struct iw_nl80211_linkstat {
uint32_t status;
struct ether_addr bssid;
/*
* Station details (not always filled in):
*/
uint32_t inactive_time,
connected_time,
rx_bytes,
rx_packets;
uint64_t rx_drop_misc;
uint16_t beacon_int;
uint8_t dtim_period,
beacon_avg_sig;
uint64_t beacons;
uint32_t beacon_loss;
uint32_t tx_bytes,
tx_packets,
tx_retries,
tx_failed;
uint32_t expected_thru;
int8_t signal,
signal_avg;
int8_t bss_signal;
uint8_t bss_signal_qual;
char tx_bitrate[100],
rx_bitrate[100];
bool cts_protection:1,
long_preamble:1,
short_slot_time:1,
wme:1,
mfp:1,
tdls:1;
/*
* Channel survey data (requires suitable card, e.g. ath9k).
*/
struct iw_nl80211_survey survey;
};
extern void iw_nl80211_get_linkstat(struct iw_nl80211_linkstat *ls);
extern void iw_cache_update(struct iw_nl80211_linkstat *ls);
/* Indicate whether @ls contains usable channel survey data */
static inline bool iw_nl80211_have_survey_data(struct iw_nl80211_linkstat *ls)
{
return ls->survey.freq != 0 && ls->survey.noise != 0;
}
/**
* struct iw_nl80211_reg - regulatory domain information
* @region: regulatory DFS region (%nl80211_dfs_regions or -1)
* @country: two-character country code
*/
struct iw_nl80211_reg {
int region;
char country[3];
};
extern void iw_nl80211_getreg(struct iw_nl80211_reg *ir);
extern void print_ssid_escaped(char *buf, const size_t buflen,
const uint8_t *data, const size_t datalen);
/*
* Multicast event handling (taken from iw:event.c and iw:scan.c)
*/
/**
* struct wait_event - wait for arrival of a specified message
* @cmds: array of GeNetlink commands (>0) to match
* @n_cmds: length of @cmds
* @cmd: matched element of @cmds (if message arrived), else 0
*/
struct wait_event {
const uint32_t *cmds;
uint8_t n_cmds;
uint32_t cmd;
};
extern struct nl_sock *alloc_nl_mcast_sk(const char *grp);
/*
* utils.c
*/
extern bool ether_addr_is_zero(const struct ether_addr *ea);
/*
* (Ge)Netlink and nl80211 Internals
*/
// stolen from iw:station.c
enum plink_state {
LISTEN,
OPN_SNT,
OPN_RCVD,
CNF_RCVD,
ESTAB,
HOLDING,
BLOCKED
};
/* Predefined handlers, stolen from iw:iw.c */
static inline int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
void *arg)
{
int *ret = arg;
*ret = err->error;
return NL_STOP;
}
static inline int finish_handler(struct nl_msg *msg, void *arg)
{
int *ret = arg;
*ret = 0;
return NL_SKIP;
}
static inline int ack_handler(struct nl_msg *msg, void *arg)
{
int *ret = arg;
*ret = 0;
return NL_STOP;
}
static inline int no_seq_check(struct nl_msg *msg, void *arg)
{
return NL_OK;
}
|