1 : /*
2 : * Wireless Tools
3 : *
4 : * Jean II - HPLB 97->99 - HPL 99->04
5 : *
6 : * Common header for the Wireless Extension library...
7 : *
8 : * This file is released under the GPL license.
9 : * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
10 : */
11 :
12 : #ifndef IWLIB_H
13 : #define IWLIB_H
14 :
15 : /*#include "CHANGELOG.h"*/
16 :
17 : /***************************** INCLUDES *****************************/
18 :
19 : /* Standard headers */
20 : #include <sys/types.h>
21 : #include <sys/ioctl.h>
22 : #include <stdio.h>
23 : #include <math.h>
24 : #include <errno.h>
25 : #include <fcntl.h>
26 : #include <ctype.h>
27 : #include <stdlib.h>
28 : #include <string.h>
29 : #include <unistd.h>
30 : #include <netdb.h> /* gethostbyname, getnetbyname */
31 : #include <net/ethernet.h> /* struct ether_addr */
32 : #include <sys/time.h> /* struct timeval */
33 : #include <unistd.h>
34 :
35 : /* This is our header selection. Try to hide the mess and the misery :-(
36 : * Don't look, you would go blind ;-) */
37 :
38 : #ifndef LINUX_VERSION_CODE
39 : #include <linux/version.h>
40 : #endif
41 :
42 : /* Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1
43 : * Kernel headers 2.2.X + Glibc 2.2 - Slackware 8.0 */
44 : #if defined(__GLIBC__) \
45 : && __GLIBC__ == 2 \
46 : && __GLIBC_MINOR__ >= 2 \
47 : && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
48 : #define HEADERS_GENERIC
49 :
50 : /* Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0
51 : * Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1 */
52 : #elif defined(__GLIBC__) \
53 : && __GLIBC__ == 2 \
54 : && __GLIBC_MINOR__ == 1 \
55 : && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
56 : #define HEADERS_GENERIC
57 : #define HEADERS_KERNEL
58 :
59 : /* Unsupported combination */
60 : #else
61 : #error "Your kernel/libc combination is not supported"
62 : #endif
63 :
64 : #ifdef HEADERS_GENERIC
65 : /* Proposed by Dr. Michael Rietz <rietz@mail.amps.de>, 27.3.2 */
66 : #include <net/if_arp.h> /* For ARPHRD_ETHER */
67 : #include <sys/socket.h> /* For AF_INET & struct sockaddr */
68 : #include <netinet/in.h> /* For struct sockaddr_in */
69 : #include <netinet/if_ether.h>
70 : #endif /* HEADERS_GENERIC */
71 :
72 : /* Fixup to be able to include kernel includes in userspace.
73 : * Basically, kill the sparse annotations... Jean II */
74 : #ifndef __user
75 : #define __user
76 : #endif
77 :
78 : #include <linux/types.h> /* for "caddr_t" et al */
79 :
80 : #ifdef HEADERS_KERNEL
81 : /* Traditionally we have used kernel headers, included in wireless.h */
82 : #include <linux/socket.h> /* for "struct sockaddr" et al */
83 : #include <linux/if.h> /* for IFNAMSIZ and co... */
84 : #else /* !HEADERS_KERNEL */
85 : /* Glibc systems headers are supposedly less problematic than kernel ones */
86 : #include <sys/socket.h> /* for "struct sockaddr" et al */
87 : #include <net/if.h> /* for IFNAMSIZ and co... */
88 : #endif /* !HEADERS_KERNEL */
89 :
90 : /* Private copy of Wireless extensions (in this directoty) */
91 : #include "wireless.h"
92 :
93 : /* Make gcc understant that when we say inline, we mean it.
94 : * I really hate when the compiler is trying to be more clever than me,
95 : * because in this case gcc is not able to figure out functions with a
96 : * single call site, so not only I have to tag those functions inline
97 : * by hand, but then it refuse to inline them properly.
98 : * Total saving for iwevent : 150B = 0.7%.
99 : * Fortunately, in gcc 3.4, they now automatically inline static functions
100 : * with a single call site. Hurrah !
101 : * Jean II */
102 : #undef IW_GCC_HAS_BROKEN_INLINE
103 : #if __GNUC__ == 3
104 : #if __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4
105 : #define IW_GCC_HAS_BROKEN_INLINE 1
106 : #endif /* __GNUC_MINOR__ */
107 : #endif /* __GNUC__ */
108 : /* However, gcc 4.0 has introduce a new "feature", when compiling with
109 : * '-Os', it does not want to inline iw_ether_cmp() and friends.
110 : * So, we need to fix inline again !
111 : * Jean II */
112 : #if __GNUC__ == 4
113 : #define IW_GCC_HAS_BROKEN_INLINE 1
114 : #endif /* __GNUC__ */
115 : /* Now, really fix the inline */
116 : #ifdef IW_GCC_HAS_BROKEN_INLINE
117 : #ifdef inline
118 : #undef inline
119 : #endif /* inline */
120 : #define inline inline __attribute__((always_inline))
121 : #endif /* IW_GCC_HAS_BROKEN_INLINE */
122 :
123 : #ifdef __cplusplus
124 : extern "C" {
125 : #endif
126 :
127 : /****************************** DEBUG ******************************/
128 :
129 :
130 : /************************ CONSTANTS & MACROS ************************/
131 :
132 : /* Various versions information */
133 : /* Recommended Wireless Extension version */
134 : #define WE_VERSION 20
135 : /* Maximum forward compatibility built in this version of WT */
136 : #define WE_MAX_VERSION 21
137 : /* Version of Wireless Tools */
138 : #define WT_VERSION 28
139 :
140 : /* Paths */
141 : #define PROC_NET_WIRELESS "/proc/net/wireless"
142 : #define PROC_NET_DEV "/proc/net/dev"
143 :
144 : /* Some usefull constants */
145 : #define KILO 1e3
146 : #define MEGA 1e6
147 : #define GIGA 1e9
148 : /* For doing log10/exp10 without libm */
149 : #define LOG10_MAGIC 1.25892541179
150 :
151 : /* Backward compatibility for network headers */
152 : #ifndef ARPHRD_IEEE80211
153 : #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
154 : #endif /* ARPHRD_IEEE80211 */
155 :
156 : /****************************** TYPES ******************************/
157 :
158 : /* Shortcuts */
159 : typedef struct iw_statistics iwstats;
160 : typedef struct iw_range iwrange;
161 : typedef struct iw_param iwparam;
162 : typedef struct iw_freq iwfreq;
163 : typedef struct iw_quality iwqual;
164 : typedef struct iw_priv_args iwprivargs;
165 : typedef struct sockaddr sockaddr;
166 :
167 : /* Structure for storing all wireless information for each device
168 : * This is a cut down version of the one above, containing only
169 : * the things *truly* needed to configure a card.
170 : * Don't add other junk, I'll remove it... */
171 : typedef struct wireless_config
172 : {
173 : char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
174 : int has_nwid;
175 : iwparam nwid; /* Network ID */
176 : int has_freq;
177 : double freq; /* Frequency/channel */
178 : int freq_flags;
179 : int has_key;
180 : unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
181 : int key_size; /* Number of bytes */
182 : int key_flags; /* Various flags */
183 : int has_essid;
184 : int essid_on;
185 : char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
186 : int has_mode;
187 : int mode; /* Operation mode */
188 : } wireless_config;
189 :
190 : /* Structure for storing all wireless information for each device
191 : * This is pretty exhaustive... */
192 : typedef struct wireless_info
193 : {
194 : struct wireless_config b; /* Basic information */
195 :
196 : int has_sens;
197 : iwparam sens; /* sensitivity */
198 : int has_nickname;
199 : char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */
200 : int has_ap_addr;
201 : sockaddr ap_addr; /* Access point address */
202 : int has_bitrate;
203 : iwparam bitrate; /* Bit rate in bps */
204 : int has_rts;
205 : iwparam rts; /* RTS threshold in bytes */
206 : int has_frag;
207 : iwparam frag; /* Fragmentation threshold in bytes */
208 : int has_power;
209 : iwparam power; /* Power management parameters */
210 : int has_txpower;
211 : iwparam txpower; /* Transmit Power in dBm */
212 : int has_retry;
213 : iwparam retry; /* Retry limit or lifetime */
214 :
215 : /* Stats */
216 : iwstats stats;
217 : int has_stats;
218 : iwrange range;
219 : int has_range;
220 :
221 : /* Auth params for WPA/802.1x/802.11i */
222 : int auth_key_mgmt;
223 : int has_auth_key_mgmt;
224 : int auth_cipher_pairwise;
225 : int has_auth_cipher_pairwise;
226 : int auth_cipher_group;
227 : int has_auth_cipher_group;
228 : } wireless_info;
229 :
230 : /* Structure for storing an entry of a wireless scan.
231 : * This is only a subset of all possible information, the flexible
232 : * structure of scan results make it impossible to capture all
233 : * information in such a static structure. */
234 : typedef struct wireless_scan
235 : {
236 : /* Linked list */
237 : struct wireless_scan * next;
238 :
239 : /* Cell identifiaction */
240 : int has_ap_addr;
241 : sockaddr ap_addr; /* Access point address */
242 :
243 : /* Other information */
244 : struct wireless_config b; /* Basic information */
245 : iwstats stats; /* Signal strength */
246 : int has_stats;
247 : } wireless_scan;
248 :
249 : /*
250 : * Context used for non-blocking scan.
251 : */
252 : typedef struct wireless_scan_head
253 : {
254 : wireless_scan * result; /* Result of the scan */
255 : int retry; /* Retry level */
256 : } wireless_scan_head;
257 :
258 : /* Structure used for parsing event streams, such as Wireless Events
259 : * and scan results */
260 : typedef struct stream_descr
261 : {
262 : char * end; /* End of the stream */
263 : char * current; /* Current event in stream of events */
264 : char * value; /* Current value in event */
265 : } stream_descr;
266 :
267 : /* Prototype for handling display of each single interface on the
268 : * system - see iw_enum_devices() */
269 : typedef int (*iw_enum_handler)(int skfd,
270 : char * ifname,
271 : char * args[],
272 : int count);
273 :
274 : /**************************** PROTOTYPES ****************************/
275 : /*
276 : * All the functions in iwcommon.c
277 : */
278 :
279 : /* ---------------------- SOCKET SUBROUTINES -----------------------*/
280 : int
281 : iw_sockets_open(void);
282 : void
283 : iw_enum_devices(int skfd,
284 : iw_enum_handler fn,
285 : char * args[],
286 : int count);
287 : /* --------------------- WIRELESS SUBROUTINES ----------------------*/
288 : int
289 : iw_get_kernel_we_version(void);
290 : int
291 : iw_print_version_info(const char * toolname);
292 : int
293 : iw_get_range_info(int skfd,
294 : const char * ifname,
295 : iwrange * range);
296 : int
297 : iw_get_priv_info(int skfd,
298 : const char * ifname,
299 : iwprivargs ** ppriv);
300 : int
301 : iw_get_basic_config(int skfd,
302 : const char * ifname,
303 : wireless_config * info);
304 : int
305 : iw_set_basic_config(int skfd,
306 : const char * ifname,
307 : wireless_config * info);
308 : /* --------------------- PROTOCOL SUBROUTINES --------------------- */
309 : int
310 : iw_protocol_compare(const char * protocol1,
311 : const char * protocol2);
312 : /* -------------------- FREQUENCY SUBROUTINES --------------------- */
313 : void
314 : iw_float2freq(double in,
315 : iwfreq * out);
316 : double
317 : iw_freq2float(const iwfreq * in);
318 : void
319 : iw_print_freq_value(char * buffer,
320 : int buflen,
321 : double freq);
322 : void
323 : iw_print_freq(char * buffer,
324 : int buflen,
325 : double freq,
326 : int channel,
327 : int freq_flags);
328 : int
329 : iw_freq_to_channel(double freq,
330 : const struct iw_range * range);
331 : int
332 : iw_channel_to_freq(int channel,
333 : double * pfreq,
334 : const struct iw_range * range);
335 : void
336 : iw_print_bitrate(char * buffer,
337 : int buflen,
338 : int bitrate);
339 : /* ---------------------- POWER SUBROUTINES ----------------------- */
340 : int
341 : iw_dbm2mwatt(int in);
342 : int
343 : iw_mwatt2dbm(int in);
344 : void
345 : iw_print_txpower(char * buffer,
346 : int buflen,
347 : struct iw_param * txpower);
348 : /* -------------------- STATISTICS SUBROUTINES -------------------- */
349 : int
350 : iw_get_stats(int skfd,
351 : const char * ifname,
352 : iwstats * stats,
353 : const iwrange * range,
354 : int has_range);
355 : void
356 : iw_print_stats(char * buffer,
357 : int buflen,
358 : const iwqual * qual,
359 : const iwrange * range,
360 : int has_range);
361 : /* --------------------- ENCODING SUBROUTINES --------------------- */
362 : void
363 : iw_print_key(char * buffer,
364 : int buflen,
365 : const unsigned char * key,
366 : int key_size,
367 : int key_flags);
368 : int
369 : iw_in_key(const char * input,
370 : unsigned char * key);
371 : int
372 : iw_in_key_full(int skfd,
373 : const char * ifname,
374 : const char * input,
375 : unsigned char * key,
376 : __u16 * flags);
377 : /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
378 : void
379 : iw_print_pm_value(char * buffer,
380 : int buflen,
381 : int value,
382 : int flags);
383 : void
384 : iw_print_pm_mode(char * buffer,
385 : int buflen,
386 : int flags);
387 : /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
388 : void
389 : iw_print_retry_value(char * buffer,
390 : int buflen,
391 : int value,
392 : int flags);
393 : /* ----------------------- TIME SUBROUTINES ----------------------- */
394 : void
395 : iw_print_timeval(char * buffer,
396 : int buflen,
397 : const struct timeval * time,
398 : const struct timezone * tz);
399 : /* --------------------- ADDRESS SUBROUTINES ---------------------- */
400 : int
401 : iw_check_mac_addr_type(int skfd,
402 : const char * ifname);
403 : int
404 : iw_check_if_addr_type(int skfd,
405 : const char * ifname);
406 : #if 0
407 : int
408 : iw_check_addr_type(int skfd,
409 : const char * ifname);
410 : #endif
411 : #if 0
412 : int
413 : iw_get_mac_addr(int skfd,
414 : const char * name,
415 : struct ether_addr * eth,
416 : unsigned short * ptype);
417 : #endif
418 : char *
419 : iw_mac_ntop(const unsigned char * mac,
420 : int maclen,
421 : char * buf,
422 : int buflen);
423 : void
424 : iw_ether_ntop(const struct ether_addr * eth,
425 : char * buf);
426 : char *
427 : iw_sawap_ntop(const struct sockaddr * sap,
428 : char * buf);
429 : int
430 : iw_mac_aton(const char * orig,
431 : unsigned char * mac,
432 : int macmax);
433 : int
434 : iw_ether_aton(const char* bufp, struct ether_addr* eth);
435 : int
436 : iw_in_inet(char *bufp, struct sockaddr *sap);
437 : int
438 : iw_in_addr(int skfd,
439 : const char * ifname,
440 : char * bufp,
441 : struct sockaddr * sap);
442 : /* ----------------------- MISC SUBROUTINES ------------------------ */
443 : int
444 : iw_get_priv_size(int args);
445 :
446 : /* ---------------------- EVENT SUBROUTINES ---------------------- */
447 : void
448 : iw_init_event_stream(struct stream_descr * stream,
449 : char * data,
450 : int len);
451 : int
452 : iw_extract_event_stream(struct stream_descr * stream,
453 : struct iw_event * iwe,
454 : int we_version);
455 : /* --------------------- SCANNING SUBROUTINES --------------------- */
456 : int
457 : iw_process_scan(int skfd,
458 : char * ifname,
459 : int we_version,
460 : wireless_scan_head * context);
461 : int
462 : iw_scan(int skfd,
463 : char * ifname,
464 : int we_version,
465 : wireless_scan_head * context);
466 :
467 : /**************************** VARIABLES ****************************/
468 :
469 : /* Modes as human readable strings */
470 : extern const char * const iw_operation_mode[];
471 : #define IW_NUM_OPER_MODE 7
472 :
473 : /************************* INLINE FUNTIONS *************************/
474 : /*
475 : * Functions that are so simple that it's more efficient inlining them
476 : */
477 :
478 : /*
479 : * Note : I've defined wrapper for the ioctl request so that
480 : * it will be easier to migrate to other kernel API if needed
481 : */
482 :
483 : /*------------------------------------------------------------------*/
484 : /*
485 : * Wrapper to push some Wireless Parameter in the driver
486 : */
487 : static inline int
488 : iw_set_ext(int skfd, /* Socket to the kernel */
489 : const char * ifname, /* Device name */
490 : int request, /* WE ID */
491 : struct iwreq * pwrq) /* Fixed part of the request */
492 : {
493 : /* Set device name */
494 : strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
495 : /* Do the request */
496 : return(ioctl(skfd, request, pwrq));
497 : }
498 :
499 : /*------------------------------------------------------------------*/
500 : /*
501 : * Wrapper to extract some Wireless Parameter out of the driver
502 : */
503 : static inline int
504 : iw_get_ext(int skfd, /* Socket to the kernel */
505 : const char * ifname, /* Device name */
506 : int request, /* WE ID */
507 : struct iwreq * pwrq) /* Fixed part of the request */
508 : {
509 : /* Set device name */
510 3 : strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
511 : /* Do the request */
512 3 : return(ioctl(skfd, request, pwrq));
513 : }
514 :
515 : /*------------------------------------------------------------------*/
516 : /*
517 : * Close the socket used for ioctl.
518 : */
519 : static inline void
520 : iw_sockets_close(int skfd)
521 : {
522 1 : close(skfd);
523 : }
524 :
525 : /*------------------------------------------------------------------*/
526 : /*
527 : * Display an Ethernet Socket Address in readable format.
528 : */
529 : static inline char *
530 : iw_saether_ntop(const struct sockaddr *sap, char* bufp)
531 : {
532 : iw_ether_ntop((const struct ether_addr *) sap->sa_data, bufp);
533 : return bufp;
534 : }
535 : /*------------------------------------------------------------------*/
536 : /*
537 : * Input an Ethernet Socket Address and convert to binary.
538 : */
539 : static inline int
540 : iw_saether_aton(const char *bufp, struct sockaddr *sap)
541 : {
542 : sap->sa_family = ARPHRD_ETHER;
543 : return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data);
544 : }
545 :
546 : /*------------------------------------------------------------------*/
547 : /*
548 : * Create an Ethernet broadcast address
549 : */
550 : static inline void
551 : iw_broad_ether(struct sockaddr *sap)
552 : {
553 : sap->sa_family = ARPHRD_ETHER;
554 : memset((char *) sap->sa_data, 0xFF, ETH_ALEN);
555 : }
556 :
557 : /*------------------------------------------------------------------*/
558 : /*
559 : * Create an Ethernet NULL address
560 : */
561 : static inline void
562 : iw_null_ether(struct sockaddr *sap)
563 : {
564 : sap->sa_family = ARPHRD_ETHER;
565 : memset((char *) sap->sa_data, 0x00, ETH_ALEN);
566 : }
567 :
568 : /*------------------------------------------------------------------*/
569 : /*
570 : * Compare two ethernet addresses
571 : */
572 : static inline int
573 : iw_ether_cmp(const struct ether_addr* eth1, const struct ether_addr* eth2)
574 : {
575 : return memcmp(eth1, eth2, sizeof(*eth1));
576 : }
577 :
578 : #ifdef __cplusplus
579 : }
580 : #endif
581 :
582 : #endif /* IWLIB_H */
|