4 * Jean II - HPLB 97->99 - HPL 99->04
6 * Common header for the Wireless Extension library...
8 * This file is released under the GPL license.
9 * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
15 /*#include "CHANGELOG.h"*/
17 /***************************** INCLUDES *****************************/
19 /* Standard headers */
20 #include <sys/types.h>
21 #include <sys/ioctl.h>
30 #include <netdb.h> /* gethostbyname, getnetbyname */
31 #include <net/ethernet.h> /* struct ether_addr */
32 #include <sys/time.h> /* struct timeval */
35 /* This is our header selection. Try to hide the mess and the misery :-(
36 * Don't look, you would go blind ;-) */
38 #ifndef LINUX_VERSION_CODE
39 #include <linux/version.h>
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__) \
46 && __GLIBC_MINOR__ >= 2 \
47 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
48 #define HEADERS_GENERIC
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__) \
54 && __GLIBC_MINOR__ == 1 \
55 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
56 #define HEADERS_GENERIC
57 #define HEADERS_KERNEL
59 /* Unsupported combination */
61 #error "Your kernel/libc combination is not supported"
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 */
72 /* Fixup to be able to include kernel includes in userspace.
73 * Basically, kill the sparse annotations... Jean II */
78 #include <linux/types.h> /* for "caddr_t" et al */
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 */
90 /* Private copy of Wireless extensions (in this directoty) */
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 !
102 #undef IW_GCC_HAS_BROKEN_INLINE
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 !
113 #define IW_GCC_HAS_BROKEN_INLINE 1
114 #endif /* __GNUC__ */
115 /* Now, really fix the inline */
116 #ifdef IW_GCC_HAS_BROKEN_INLINE
120 #define inline inline __attribute__((always_inline))
121 #endif /* IW_GCC_HAS_BROKEN_INLINE */
127 /****************************** DEBUG ******************************/
130 /************************ CONSTANTS & MACROS ************************/
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
141 #define PROC_NET_WIRELESS "/proc/net/wireless"
142 #define PROC_NET_DEV "/proc/net/dev"
144 /* Some usefull constants */
148 /* For doing log10/exp10 without libm */
149 #define LOG10_MAGIC 1.25892541179
151 /* Backward compatibility for network headers */
152 #ifndef ARPHRD_IEEE80211
153 #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
154 #endif /* ARPHRD_IEEE80211 */
156 /****************************** TYPES ******************************/
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;
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
173 char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
175 iwparam nwid; /* Network ID */
177 double freq; /* Frequency/channel */
180 unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
181 int key_size; /* Number of bytes */
182 int key_flags; /* Various flags */
185 char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
187 int mode; /* Operation mode */
190 /* Structure for storing all wireless information for each device
191 * This is pretty exhaustive... */
192 typedef struct wireless_info
194 struct wireless_config b; /* Basic information */
197 iwparam sens; /* sensitivity */
199 char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */
201 sockaddr ap_addr; /* Access point address */
203 iwparam bitrate; /* Bit rate in bps */
205 iwparam rts; /* RTS threshold in bytes */
207 iwparam frag; /* Fragmentation threshold in bytes */
209 iwparam power; /* Power management parameters */
211 iwparam txpower; /* Transmit Power in dBm */
213 iwparam retry; /* Retry limit or lifetime */
221 /* Auth params for WPA/802.1x/802.11i */
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;
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
237 struct wireless_scan * next;
239 /* Cell identifiaction */
241 sockaddr ap_addr; /* Access point address */
243 /* Other information */
244 struct wireless_config b; /* Basic information */
245 iwstats stats; /* Signal strength */
250 * Context used for non-blocking scan.
252 typedef struct wireless_scan_head
254 wireless_scan * result; /* Result of the scan */
255 int retry; /* Retry level */
256 } wireless_scan_head;
258 /* Structure used for parsing event streams, such as Wireless Events
259 * and scan results */
260 typedef struct stream_descr
262 char * end; /* End of the stream */
263 char * current; /* Current event in stream of events */
264 char * value; /* Current value in event */
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,
274 /**************************** PROTOTYPES ****************************/
276 * All the functions in iwcommon.c
279 /* ---------------------- SOCKET SUBROUTINES -----------------------*/
281 iw_sockets_open(void);
283 iw_enum_devices(int skfd,
287 /* --------------------- WIRELESS SUBROUTINES ----------------------*/
289 iw_get_kernel_we_version(void);
291 iw_print_version_info(const char * toolname);
293 iw_get_range_info(int skfd,
297 iw_get_priv_info(int skfd,
299 iwprivargs ** ppriv);
301 iw_get_basic_config(int skfd,
303 wireless_config * info);
305 iw_set_basic_config(int skfd,
307 wireless_config * info);
308 /* --------------------- PROTOCOL SUBROUTINES --------------------- */
310 iw_protocol_compare(const char * protocol1,
311 const char * protocol2);
312 /* -------------------- FREQUENCY SUBROUTINES --------------------- */
314 iw_float2freq(double in,
317 iw_freq2float(const iwfreq * in);
319 iw_print_freq_value(char * buffer,
323 iw_print_freq(char * buffer,
329 iw_freq_to_channel(double freq,
330 const struct iw_range * range);
332 iw_channel_to_freq(int channel,
334 const struct iw_range * range);
336 iw_print_bitrate(char * buffer,
339 /* ---------------------- POWER SUBROUTINES ----------------------- */
341 iw_dbm2mwatt(int in);
343 iw_mwatt2dbm(int in);
345 iw_print_txpower(char * buffer,
347 struct iw_param * txpower);
348 /* -------------------- STATISTICS SUBROUTINES -------------------- */
350 iw_get_stats(int skfd,
353 const iwrange * range,
356 iw_print_stats(char * buffer,
359 const iwrange * range,
361 /* --------------------- ENCODING SUBROUTINES --------------------- */
363 iw_print_key(char * buffer,
365 const unsigned char * key,
369 iw_in_key(const char * input,
370 unsigned char * key);
372 iw_in_key_full(int skfd,
377 /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
379 iw_print_pm_value(char * buffer,
384 iw_print_pm_mode(char * buffer,
387 /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
389 iw_print_retry_value(char * buffer,
393 /* ----------------------- TIME SUBROUTINES ----------------------- */
395 iw_print_timeval(char * buffer,
397 const struct timeval * time,
398 const struct timezone * tz);
399 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
401 iw_check_mac_addr_type(int skfd,
402 const char * ifname);
404 iw_check_if_addr_type(int skfd,
405 const char * ifname);
408 iw_check_addr_type(int skfd,
409 const char * ifname);
413 iw_get_mac_addr(int skfd,
415 struct ether_addr * eth,
416 unsigned short * ptype);
419 iw_mac_ntop(const unsigned char * mac,
424 iw_ether_ntop(const struct ether_addr * eth,
427 iw_sawap_ntop(const struct sockaddr * sap,
430 iw_mac_aton(const char * orig,
434 iw_ether_aton(const char* bufp, struct ether_addr* eth);
436 iw_in_inet(char *bufp, struct sockaddr *sap);
441 struct sockaddr * sap);
442 /* ----------------------- MISC SUBROUTINES ------------------------ */
444 iw_get_priv_size(int args);
446 /* ---------------------- EVENT SUBROUTINES ---------------------- */
448 iw_init_event_stream(struct stream_descr * stream,
452 iw_extract_event_stream(struct stream_descr * stream,
453 struct iw_event * iwe,
455 /* --------------------- SCANNING SUBROUTINES --------------------- */
457 iw_process_scan(int skfd,
460 wireless_scan_head * context);
465 wireless_scan_head * context);
467 /**************************** VARIABLES ****************************/
469 /* Modes as human readable strings */
470 extern const char * const iw_operation_mode[];
471 #define IW_NUM_OPER_MODE 7
473 /************************* INLINE FUNTIONS *************************/
475 * Functions that are so simple that it's more efficient inlining them
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
483 /*------------------------------------------------------------------*/
485 * Wrapper to push some Wireless Parameter in the driver
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 */
493 /* Set device name */
494 strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
496 return(ioctl(skfd, request, pwrq));
499 /*------------------------------------------------------------------*/
501 * Wrapper to extract some Wireless Parameter out of the driver
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 */
509 /* Set device name */
510 strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
512 return(ioctl(skfd, request, pwrq));
515 /*------------------------------------------------------------------*/
517 * Close the socket used for ioctl.
520 iw_sockets_close(int skfd)
525 /*------------------------------------------------------------------*/
527 * Display an Ethernet Socket Address in readable format.
530 iw_saether_ntop(const struct sockaddr *sap, char* bufp)
532 iw_ether_ntop((const struct ether_addr *) sap->sa_data, bufp);
535 /*------------------------------------------------------------------*/
537 * Input an Ethernet Socket Address and convert to binary.
540 iw_saether_aton(const char *bufp, struct sockaddr *sap)
542 sap->sa_family = ARPHRD_ETHER;
543 return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data);
546 /*------------------------------------------------------------------*/
548 * Create an Ethernet broadcast address
551 iw_broad_ether(struct sockaddr *sap)
553 sap->sa_family = ARPHRD_ETHER;
554 memset((char *) sap->sa_data, 0xFF, ETH_ALEN);
557 /*------------------------------------------------------------------*/
559 * Create an Ethernet NULL address
562 iw_null_ether(struct sockaddr *sap)
564 sap->sa_family = ARPHRD_ETHER;
565 memset((char *) sap->sa_data, 0x00, ETH_ALEN);
568 /*------------------------------------------------------------------*/
570 * Compare two ethernet addresses
573 iw_ether_cmp(const struct ether_addr* eth1, const struct ether_addr* eth2)
575 return memcmp(eth1, eth2, sizeof(*eth1));