1 | /* |
2 | * Wireless Tools |
3 | * |
4 | * Jean II - HPLB 97->99 - HPL 99->09 |
5 | * |
6 | * Common header for the Wireless Extension library... |
7 | * |
8 | * This file is released under the GPL license. |
9 | * Copyright (c) 1997-2009 Jean Tourrilhes <jt@hpl.hp.com> |
10 | */ |
11 | |
12 | #ifndef IWLIB_H |
13 | #define IWLIB_H |
14 | |
15 | /***************************** INCLUDES *****************************/ |
16 | |
17 | /* Standard headers */ |
18 | #include <sys/types.h> |
19 | #include <sys/ioctl.h> |
20 | #include <stdio.h> |
21 | #include <math.h> |
22 | #include <errno.h> |
23 | #include <fcntl.h> |
24 | #include <ctype.h> |
25 | #include <stdlib.h> |
26 | #include <string.h> |
27 | #include <unistd.h> |
28 | #include <netdb.h> /* gethostbyname, getnetbyname */ |
29 | #include <net/ethernet.h> /* struct ether_addr */ |
30 | #include <sys/time.h> /* struct timeval */ |
31 | #include <unistd.h> |
32 | |
33 | /* This is our header selection. Try to hide the mess and the misery :-( |
34 | * Don't look, you would go blind ;-) |
35 | * Note : compatibility with *old* distributions has been removed, |
36 | * you will need Glibc 2.2 and older to compile (which means |
37 | * Mandrake 8.0, Debian 2.3, RH 7.1 or older). |
38 | */ |
39 | |
40 | /* Set of headers proposed by Dr. Michael Rietz <rietz@mail.amps.de>, 27.3.2 */ |
41 | #include <net/if_arp.h> /* For ARPHRD_ETHER */ |
42 | #include <sys/socket.h> /* For AF_INET & struct sockaddr */ |
43 | #include <netinet/in.h> /* For struct sockaddr_in */ |
44 | #include <netinet/if_ether.h> |
45 | |
46 | /* Fixup to be able to include kernel includes in userspace. |
47 | * Basically, kill the sparse annotations... Jean II */ |
48 | #ifndef __user |
49 | #define __user |
50 | #endif |
51 | |
52 | #include <linux/types.h> /* for "caddr_t" et al */ |
53 | |
54 | /* Glibc systems headers are supposedly less problematic than kernel ones */ |
55 | #include <sys/socket.h> /* for "struct sockaddr" et al */ |
56 | #include <net/if.h> /* for IFNAMSIZ and co... */ |
57 | |
58 | /* Private copy of Wireless extensions (in this directoty) */ |
59 | #include "wireless.h" |
60 | |
61 | #ifdef __cplusplus |
62 | extern "C" { |
63 | #endif |
64 | |
65 | /************************ CONSTANTS & MACROS ************************/ |
66 | |
67 | /* Various versions information */ |
68 | /* Recommended Wireless Extension version */ |
69 | #define WE_VERSION 22 |
70 | /* Maximum forward compatibility built in this version of WT */ |
71 | #define WE_MAX_VERSION 22 |
72 | /* Version of Wireless Tools */ |
73 | #define WT_VERSION 30 |
74 | |
75 | /****************************** TYPES ******************************/ |
76 | |
77 | /* Shortcuts */ |
78 | typedef struct iw_statistics iwstats; |
79 | typedef struct iw_range iwrange; |
80 | typedef struct iw_param iwparam; |
81 | typedef struct iw_freq iwfreq; |
82 | typedef struct iw_quality iwqual; |
83 | typedef struct iw_priv_args iwprivargs; |
84 | typedef struct sockaddr sockaddr; |
85 | |
86 | /* Structure for storing all wireless information for each device |
87 | * This is a cut down version of the one above, containing only |
88 | * the things *truly* needed to configure a card. |
89 | * Don't add other junk, I'll remove it... */ |
90 | typedef struct wireless_config |
91 | { |
92 | char name[IFNAMSIZ + 1]; /* Wireless/protocol name */ |
93 | int has_nwid; |
94 | iwparam nwid; /* Network ID */ |
95 | int has_freq; |
96 | double freq; /* Frequency/channel */ |
97 | int freq_flags; |
98 | int has_key; |
99 | unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */ |
100 | int key_size; /* Number of bytes */ |
101 | int key_flags; /* Various flags */ |
102 | int has_essid; |
103 | int essid_on; |
104 | char essid[IW_ESSID_MAX_SIZE + 2]; /* ESSID (extended network) */ |
105 | int essid_len; |
106 | int has_mode; |
107 | int mode; /* Operation mode */ |
108 | } wireless_config; |
109 | |
110 | /* Structure for storing all wireless information for each device |
111 | * This is pretty exhaustive... */ |
112 | typedef struct wireless_info |
113 | { |
114 | struct wireless_config b; /* Basic information */ |
115 | |
116 | int has_sens; |
117 | iwparam sens; /* sensitivity */ |
118 | int has_nickname; |
119 | char nickname[IW_ESSID_MAX_SIZE + 2]; /* NickName */ |
120 | int has_ap_addr; |
121 | sockaddr ap_addr; /* Access point address */ |
122 | int has_bitrate; |
123 | iwparam bitrate; /* Bit rate in bps */ |
124 | int has_rts; |
125 | iwparam rts; /* RTS threshold in bytes */ |
126 | int has_frag; |
127 | iwparam frag; /* Fragmentation threshold in bytes */ |
128 | int has_power; |
129 | iwparam power; /* Power management parameters */ |
130 | int has_txpower; |
131 | iwparam txpower; /* Transmit Power in dBm */ |
132 | int has_retry; |
133 | iwparam retry; /* Retry limit or lifetime */ |
134 | |
135 | /* Stats */ |
136 | iwstats stats; |
137 | int has_stats; |
138 | iwrange range; |
139 | int has_range; |
140 | |
141 | /* Auth params for WPA/802.1x/802.11i */ |
142 | int auth_key_mgmt; |
143 | int has_auth_key_mgmt; |
144 | int auth_cipher_pairwise; |
145 | int has_auth_cipher_pairwise; |
146 | int auth_cipher_group; |
147 | int has_auth_cipher_group; |
148 | } wireless_info; |
149 | |
150 | /* Structure for storing an entry of a wireless scan. |
151 | * This is only a subset of all possible information, the flexible |
152 | * structure of scan results make it impossible to capture all |
153 | * information in such a static structure. */ |
154 | typedef struct wireless_scan |
155 | { |
156 | /* Linked list */ |
157 | struct wireless_scan * next; |
158 | |
159 | /* Cell identifiaction */ |
160 | int has_ap_addr; |
161 | sockaddr ap_addr; /* Access point address */ |
162 | |
163 | /* Other information */ |
164 | struct wireless_config b; /* Basic information */ |
165 | iwstats stats; /* Signal strength */ |
166 | int has_stats; |
167 | iwparam maxbitrate; /* Max bit rate in bps */ |
168 | int has_maxbitrate; |
169 | } wireless_scan; |
170 | |
171 | /* |
172 | * Context used for non-blocking scan. |
173 | */ |
174 | typedef struct wireless_scan_head |
175 | { |
176 | wireless_scan * result; /* Result of the scan */ |
177 | int retry; /* Retry level */ |
178 | } wireless_scan_head; |
179 | |
180 | /* Structure used for parsing event streams, such as Wireless Events |
181 | * and scan results */ |
182 | typedef struct stream_descr |
183 | { |
184 | char * end; /* End of the stream */ |
185 | char * current; /* Current event in stream of events */ |
186 | char * value; /* Current value in event */ |
187 | } stream_descr; |
188 | |
189 | /* Prototype for handling display of each single interface on the |
190 | * system - see iw_enum_devices() */ |
191 | typedef int (*iw_enum_handler)(int skfd, |
192 | char * ifname, |
193 | char * args[], |
194 | int count); |
195 | |
196 | /* Describe a modulation */ |
197 | typedef struct iw_modul_descr |
198 | { |
199 | unsigned int mask; /* Modulation bitmask */ |
200 | char cmd[8]; /* Short name */ |
201 | char * verbose; /* Verbose description */ |
202 | } iw_modul_descr; |
203 | |
204 | /**************************** PROTOTYPES ****************************/ |
205 | /* |
206 | * All the functions in iwlib.c |
207 | */ |
208 | |
209 | /* ---------------------- SOCKET SUBROUTINES -----------------------*/ |
210 | int |
211 | iw_sockets_open(void); |
212 | void |
213 | iw_enum_devices(int skfd, |
214 | iw_enum_handler fn, |
215 | char * args[], |
216 | int count); |
217 | /* --------------------- WIRELESS SUBROUTINES ----------------------*/ |
218 | int |
219 | iw_get_kernel_we_version(void); |
220 | int |
221 | iw_print_version_info(const char * toolname); |
222 | int |
223 | iw_get_range_info(int skfd, |
224 | const char * ifname, |
225 | iwrange * range); |
226 | int |
227 | iw_get_priv_info(int skfd, |
228 | const char * ifname, |
229 | iwprivargs ** ppriv); |
230 | int |
231 | iw_get_basic_config(int skfd, |
232 | const char * ifname, |
233 | wireless_config * info); |
234 | int |
235 | iw_set_basic_config(int skfd, |
236 | const char * ifname, |
237 | wireless_config * info); |
238 | /* --------------------- PROTOCOL SUBROUTINES --------------------- */ |
239 | int |
240 | iw_protocol_compare(const char * protocol1, |
241 | const char * protocol2); |
242 | /* ---------------------- ESSID SUBROUTINES ---------------------- */ |
243 | void |
244 | iw_essid_escape(char * dest, |
245 | const char * src, |
246 | const int slen); |
247 | int |
248 | iw_essid_unescape(char * dest, |
249 | const char * src); |
250 | /* -------------------- FREQUENCY SUBROUTINES --------------------- */ |
251 | void |
252 | iw_float2freq(double in, |
253 | iwfreq * out); |
254 | double |
255 | iw_freq2float(const iwfreq * in); |
256 | void |
257 | iw_print_freq_value(char * buffer, |
258 | int buflen, |
259 | double freq); |
260 | void |
261 | iw_print_freq(char * buffer, |
262 | int buflen, |
263 | double freq, |
264 | int channel, |
265 | int freq_flags); |
266 | int |
267 | iw_freq_to_channel(double freq, |
268 | const struct iw_range * range); |
269 | int |
270 | iw_channel_to_freq(int channel, |
271 | double * pfreq, |
272 | const struct iw_range * range); |
273 | void |
274 | iw_print_bitrate(char * buffer, |
275 | int buflen, |
276 | int bitrate); |
277 | /* ---------------------- POWER SUBROUTINES ----------------------- */ |
278 | int |
279 | iw_dbm2mwatt(int in); |
280 | int |
281 | iw_mwatt2dbm(int in); |
282 | void |
283 | iw_print_txpower(char * buffer, |
284 | int buflen, |
285 | struct iw_param * txpower); |
286 | /* -------------------- STATISTICS SUBROUTINES -------------------- */ |
287 | int |
288 | iw_get_stats(int skfd, |
289 | const char * ifname, |
290 | iwstats * stats, |
291 | const iwrange * range, |
292 | int has_range); |
293 | void |
294 | iw_print_stats(char * buffer, |
295 | int buflen, |
296 | const iwqual * qual, |
297 | const iwrange * range, |
298 | int has_range); |
299 | /* --------------------- ENCODING SUBROUTINES --------------------- */ |
300 | void |
301 | iw_print_key(char * buffer, |
302 | int buflen, |
303 | const unsigned char * key, |
304 | int key_size, |
305 | int key_flags); |
306 | int |
307 | iw_in_key(const char * input, |
308 | unsigned char * key); |
309 | int |
310 | iw_in_key_full(int skfd, |
311 | const char * ifname, |
312 | const char * input, |
313 | unsigned char * key, |
314 | __u16 * flags); |
315 | /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */ |
316 | void |
317 | iw_print_pm_value(char * buffer, |
318 | int buflen, |
319 | int value, |
320 | int flags, |
321 | int we_version); |
322 | void |
323 | iw_print_pm_mode(char * buffer, |
324 | int buflen, |
325 | int flags); |
326 | /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */ |
327 | void |
328 | iw_print_retry_value(char * buffer, |
329 | int buflen, |
330 | int value, |
331 | int flags, |
332 | int we_version); |
333 | /* ----------------------- TIME SUBROUTINES ----------------------- */ |
334 | void |
335 | iw_print_timeval(char * buffer, |
336 | int buflen, |
337 | const struct timeval * time, |
338 | const struct timezone * tz); |
339 | /* --------------------- ADDRESS SUBROUTINES ---------------------- */ |
340 | int |
341 | iw_check_mac_addr_type(int skfd, |
342 | const char * ifname); |
343 | int |
344 | iw_check_if_addr_type(int skfd, |
345 | const char * ifname); |
346 | char * |
347 | iw_mac_ntop(const unsigned char * mac, |
348 | int maclen, |
349 | char * buf, |
350 | int buflen); |
351 | void |
352 | iw_ether_ntop(const struct ether_addr * eth, |
353 | char * buf); |
354 | char * |
355 | iw_sawap_ntop(const struct sockaddr * sap, |
356 | char * buf); |
357 | int |
358 | iw_mac_aton(const char * orig, |
359 | unsigned char * mac, |
360 | int macmax); |
361 | int |
362 | iw_ether_aton(const char* bufp, struct ether_addr* eth); |
363 | int |
364 | iw_in_inet(char *bufp, struct sockaddr *sap); |
365 | int |
366 | iw_in_addr(int skfd, |
367 | const char * ifname, |
368 | char * bufp, |
369 | struct sockaddr * sap); |
370 | /* ----------------------- MISC SUBROUTINES ------------------------ */ |
371 | int |
372 | iw_get_priv_size(int args); |
373 | |
374 | /* ---------------------- EVENT SUBROUTINES ---------------------- */ |
375 | void |
376 | iw_init_event_stream(struct stream_descr * stream, |
377 | char * data, |
378 | int len); |
379 | int |
380 | (struct stream_descr * stream, |
381 | struct iw_event * iwe, |
382 | int we_version); |
383 | /* --------------------- SCANNING SUBROUTINES --------------------- */ |
384 | int |
385 | iw_process_scan(int skfd, |
386 | char * ifname, |
387 | int we_version, |
388 | wireless_scan_head * context); |
389 | int |
390 | iw_scan(int skfd, |
391 | char * ifname, |
392 | int we_version, |
393 | wireless_scan_head * context); |
394 | |
395 | /**************************** VARIABLES ****************************/ |
396 | |
397 | /* Modes as human readable strings */ |
398 | extern const char * const iw_operation_mode[]; |
399 | #define IW_NUM_OPER_MODE 7 |
400 | #define IW_NUM_OPER_MODE_EXT 8 |
401 | |
402 | /* Modulations as human readable strings */ |
403 | extern const struct iw_modul_descr iw_modul_list[]; |
404 | #define IW_SIZE_MODUL_LIST 16 |
405 | |
406 | /************************* INLINE FUNTIONS *************************/ |
407 | /* |
408 | * Functions that are so simple that it's more efficient inlining them |
409 | * Most inline are private because gcc is fussy about inline... |
410 | */ |
411 | |
412 | /* |
413 | * Note : I've defined wrapper for the ioctl request so that |
414 | * it will be easier to migrate to other kernel API if needed |
415 | */ |
416 | |
417 | /*------------------------------------------------------------------*/ |
418 | /* |
419 | * Wrapper to push some Wireless Parameter in the driver |
420 | */ |
421 | static inline __attribute__((always_inline)) int |
422 | iw_set_ext(int skfd, /* Socket to the kernel */ |
423 | const char * ifname, /* Device name */ |
424 | int request, /* WE ID */ |
425 | struct iwreq * pwrq) /* Fixed part of the request */ |
426 | { |
427 | /* Set device name */ |
428 | strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); |
429 | /* Do the request */ |
430 | return(ioctl(skfd, request, pwrq)); |
431 | } |
432 | |
433 | /*------------------------------------------------------------------*/ |
434 | /* |
435 | * Wrapper to extract some Wireless Parameter out of the driver |
436 | */ |
437 | static inline __attribute__((always_inline)) int |
438 | iw_get_ext(int skfd, /* Socket to the kernel */ |
439 | const char * ifname, /* Device name */ |
440 | int request, /* WE ID */ |
441 | struct iwreq * pwrq) /* Fixed part of the request */ |
442 | { |
443 | /* Set device name */ |
444 | strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); |
445 | /* Do the request */ |
446 | return(ioctl(skfd, request, pwrq)); |
447 | } |
448 | |
449 | /*------------------------------------------------------------------*/ |
450 | /* |
451 | * Close the socket used for ioctl. |
452 | */ |
453 | static inline void |
454 | iw_sockets_close(int skfd) |
455 | { |
456 | close(skfd); |
457 | } |
458 | |
459 | #ifdef __cplusplus |
460 | } |
461 | #endif |
462 | |
463 | #endif /* IWLIB_H */ |
464 | |