4 * Jean II - HPLB 97->99 - HPL 99->07
6 * Common header for the Wireless Extension library...
8 * This file is released under the GPL license.
9 * Copyright (c) 1997-2007 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 ;-)
37 * Note : compatibility with *old* distributions has been removed,
38 * you will need Glibc 2.2 and older to compile (which means
39 * Mandrake 8.0, Debian 2.3, RH 7.1 or older).
42 /* Set of headers proposed by Dr. Michael Rietz <rietz@mail.amps.de>, 27.3.2 */
43 #include <net/if_arp.h> /* For ARPHRD_ETHER */
44 #include <sys/socket.h> /* For AF_INET & struct sockaddr */
45 #include <netinet/in.h> /* For struct sockaddr_in */
46 #include <netinet/if_ether.h>
48 /* Fixup to be able to include kernel includes in userspace.
49 * Basically, kill the sparse annotations... Jean II */
54 #include <linux/types.h> /* for "caddr_t" et al */
56 /* Glibc systems headers are supposedly less problematic than kernel ones */
57 #include <sys/socket.h> /* for "struct sockaddr" et al */
58 #include <net/if.h> /* for IFNAMSIZ and co... */
60 /* Private copy of Wireless extensions (in this directoty) */
63 /* Make gcc understant that when we say inline, we mean it.
64 * I really hate when the compiler is trying to be more clever than me,
65 * because in this case gcc is not able to figure out functions with a
66 * single call site, so not only I have to tag those functions inline
67 * by hand, but then it refuse to inline them properly.
68 * Total saving for iwevent : 150B = 0.7%.
69 * Fortunately, in gcc 3.4, they now automatically inline static functions
70 * with a single call site. Hurrah !
72 #undef IW_GCC_HAS_BROKEN_INLINE
74 #if __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4
75 #define IW_GCC_HAS_BROKEN_INLINE 1
76 #endif /* __GNUC_MINOR__ */
78 /* However, gcc 4.0 has introduce a new "feature", when compiling with
79 * '-Os', it does not want to inline iw_ether_cmp() and friends.
80 * So, we need to fix inline again !
83 #define IW_GCC_HAS_BROKEN_INLINE 1
85 /* Now, really fix the inline */
86 #ifdef IW_GCC_HAS_BROKEN_INLINE
90 #define inline inline __attribute__((always_inline))
91 #endif /* IW_GCC_HAS_BROKEN_INLINE */
97 /****************************** DEBUG ******************************/
101 /************************ CONSTANTS & MACROS ************************/
103 /* Various versions information */
104 /* Recommended Wireless Extension version */
105 #define WE_VERSION 21
106 /* Maximum forward compatibility built in this version of WT */
107 #define WE_MAX_VERSION 22
108 /* Version of Wireless Tools */
109 #define WT_VERSION 29
112 #define PROC_NET_WIRELESS "/proc/net/wireless"
113 #define PROC_NET_DEV "/proc/net/dev"
115 /* Some usefull constants */
119 /* For doing log10/exp10 without libm */
120 #define LOG10_MAGIC 1.25892541179
122 /* Backward compatibility for network headers */
123 #ifndef ARPHRD_IEEE80211
124 #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
125 #endif /* ARPHRD_IEEE80211 */
127 #ifndef IW_EV_LCP_PK_LEN
128 /* Size of the Event prefix when packed in stream */
129 #define IW_EV_LCP_PK_LEN (4)
130 /* Size of the various events when packed in stream */
131 #define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
132 #define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32))
133 #define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
134 #define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
135 #define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
136 #define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
137 #define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4)
141 __u16 len; /* Real lenght of this stuff */
142 __u16 cmd; /* Wireless IOCTL */
143 union iwreq_data u; /* IOCTL fixed payload */
144 } __attribute__ ((packed));
147 void __user *pointer; /* Pointer to the data (in user space) */
148 __u16 length; /* number of fields or size in bytes */
149 __u16 flags; /* Optional params */
150 } __attribute__ ((packed));
152 #define IW_EV_LCP_PK2_LEN (sizeof(struct iw_pk_event) - sizeof(union iwreq_data))
153 #define IW_EV_POINT_PK2_LEN (IW_EV_LCP_PK2_LEN + sizeof(struct iw_pk_point) - IW_EV_POINT_OFF)
155 #endif /* IW_EV_LCP_PK_LEN */
157 /****************************** TYPES ******************************/
160 typedef struct iw_statistics iwstats;
161 typedef struct iw_range iwrange;
162 typedef struct iw_param iwparam;
163 typedef struct iw_freq iwfreq;
164 typedef struct iw_quality iwqual;
165 typedef struct iw_priv_args iwprivargs;
166 typedef struct sockaddr sockaddr;
168 /* Structure for storing all wireless information for each device
169 * This is a cut down version of the one above, containing only
170 * the things *truly* needed to configure a card.
171 * Don't add other junk, I'll remove it... */
172 typedef struct wireless_config
174 char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
176 iwparam nwid; /* Network ID */
178 double freq; /* Frequency/channel */
181 unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
182 int key_size; /* Number of bytes */
183 int key_flags; /* Various flags */
186 char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
188 int mode; /* Operation mode */
191 /* Structure for storing all wireless information for each device
192 * This is pretty exhaustive... */
193 typedef struct wireless_info
195 struct wireless_config b; /* Basic information */
198 iwparam sens; /* sensitivity */
200 char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */
202 sockaddr ap_addr; /* Access point address */
204 iwparam bitrate; /* Bit rate in bps */
206 iwparam rts; /* RTS threshold in bytes */
208 iwparam frag; /* Fragmentation threshold in bytes */
210 iwparam power; /* Power management parameters */
212 iwparam txpower; /* Transmit Power in dBm */
214 iwparam retry; /* Retry limit or lifetime */
222 /* Auth params for WPA/802.1x/802.11i */
224 int has_auth_key_mgmt;
225 int auth_cipher_pairwise;
226 int has_auth_cipher_pairwise;
227 int auth_cipher_group;
228 int has_auth_cipher_group;
231 /* Structure for storing an entry of a wireless scan.
232 * This is only a subset of all possible information, the flexible
233 * structure of scan results make it impossible to capture all
234 * information in such a static structure. */
235 typedef struct wireless_scan
238 struct wireless_scan * next;
240 /* Cell identifiaction */
242 sockaddr ap_addr; /* Access point address */
244 /* Other information */
245 struct wireless_config b; /* Basic information */
246 iwstats stats; /* Signal strength */
248 iwparam maxbitrate; /* Max bit rate in bps */
253 * Context used for non-blocking scan.
255 typedef struct wireless_scan_head
257 wireless_scan * result; /* Result of the scan */
258 int retry; /* Retry level */
259 } wireless_scan_head;
261 /* Structure used for parsing event streams, such as Wireless Events
262 * and scan results */
263 typedef struct stream_descr
265 char * end; /* End of the stream */
266 char * current; /* Current event in stream of events */
267 char * value; /* Current value in event */
270 /* Prototype for handling display of each single interface on the
271 * system - see iw_enum_devices() */
272 typedef int (*iw_enum_handler)(int skfd,
277 /* Describe a modulation */
278 typedef struct iw_modul_descr
280 unsigned int mask; /* Modulation bitmask */
281 char cmd[8]; /* Short name */
282 char * verbose; /* Verbose description */
285 /**************************** PROTOTYPES ****************************/
287 * All the functions in iwcommon.c
290 /* ---------------------- SOCKET SUBROUTINES -----------------------*/
292 iw_sockets_open(void);
294 iw_enum_devices(int skfd,
298 /* --------------------- WIRELESS SUBROUTINES ----------------------*/
300 iw_get_kernel_we_version(void);
302 iw_print_version_info(const char * toolname);
304 iw_get_range_info(int skfd,
308 iw_get_priv_info(int skfd,
310 iwprivargs ** ppriv);
312 iw_get_basic_config(int skfd,
314 wireless_config * info);
316 iw_set_basic_config(int skfd,
318 wireless_config * info);
319 /* --------------------- PROTOCOL SUBROUTINES --------------------- */
321 iw_protocol_compare(const char * protocol1,
322 const char * protocol2);
323 /* -------------------- FREQUENCY SUBROUTINES --------------------- */
325 iw_float2freq(double in,
328 iw_freq2float(const iwfreq * in);
330 iw_print_freq_value(char * buffer,
334 iw_print_freq(char * buffer,
340 iw_freq_to_channel(double freq,
341 const struct iw_range * range);
343 iw_channel_to_freq(int channel,
345 const struct iw_range * range);
347 iw_print_bitrate(char * buffer,
350 /* ---------------------- POWER SUBROUTINES ----------------------- */
352 iw_dbm2mwatt(int in);
354 iw_mwatt2dbm(int in);
356 iw_print_txpower(char * buffer,
358 struct iw_param * txpower);
359 /* -------------------- STATISTICS SUBROUTINES -------------------- */
361 iw_get_stats(int skfd,
364 const iwrange * range,
367 iw_print_stats(char * buffer,
370 const iwrange * range,
372 /* --------------------- ENCODING SUBROUTINES --------------------- */
374 iw_print_key(char * buffer,
376 const unsigned char * key,
380 iw_in_key(const char * input,
381 unsigned char * key);
383 iw_in_key_full(int skfd,
388 /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
390 iw_print_pm_value(char * buffer,
396 iw_print_pm_mode(char * buffer,
399 /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
401 iw_print_retry_value(char * buffer,
406 /* ----------------------- TIME SUBROUTINES ----------------------- */
408 iw_print_timeval(char * buffer,
410 const struct timeval * time,
411 const struct timezone * tz);
412 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
414 iw_check_mac_addr_type(int skfd,
415 const char * ifname);
417 iw_check_if_addr_type(int skfd,
418 const char * ifname);
421 iw_check_addr_type(int skfd,
422 const char * ifname);
426 iw_get_mac_addr(int skfd,
428 struct ether_addr * eth,
429 unsigned short * ptype);
432 iw_mac_ntop(const unsigned char * mac,
437 iw_ether_ntop(const struct ether_addr * eth,
440 iw_sawap_ntop(const struct sockaddr * sap,
443 iw_mac_aton(const char * orig,
447 iw_ether_aton(const char* bufp, struct ether_addr* eth);
449 iw_in_inet(char *bufp, struct sockaddr *sap);
454 struct sockaddr * sap);
455 /* ----------------------- MISC SUBROUTINES ------------------------ */
457 iw_get_priv_size(int args);
459 /* ---------------------- EVENT SUBROUTINES ---------------------- */
461 iw_init_event_stream(struct stream_descr * stream,
465 iw_extract_event_stream(struct stream_descr * stream,
466 struct iw_event * iwe,
468 /* --------------------- SCANNING SUBROUTINES --------------------- */
470 iw_process_scan(int skfd,
473 wireless_scan_head * context);
478 wireless_scan_head * context);
480 /**************************** VARIABLES ****************************/
482 /* Modes as human readable strings */
483 extern const char * const iw_operation_mode[];
484 #define IW_NUM_OPER_MODE 7
485 #define IW_NUM_OPER_MODE_EXT 8
487 /* Modulations as human readable strings */
488 extern const struct iw_modul_descr iw_modul_list[];
489 #define IW_SIZE_MODUL_LIST 16
491 /************************* INLINE FUNTIONS *************************/
493 * Functions that are so simple that it's more efficient inlining them
497 * Note : I've defined wrapper for the ioctl request so that
498 * it will be easier to migrate to other kernel API if needed
501 /*------------------------------------------------------------------*/
503 * Wrapper to push some Wireless Parameter in the driver
506 iw_set_ext(int skfd, /* Socket to the kernel */
507 const char * ifname, /* Device name */
508 int request, /* WE ID */
509 struct iwreq * pwrq) /* Fixed part of the request */
511 /* Set device name */
512 strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
514 return(ioctl(skfd, request, pwrq));
517 /*------------------------------------------------------------------*/
519 * Wrapper to extract some Wireless Parameter out of the driver
522 iw_get_ext(int skfd, /* Socket to the kernel */
523 const char * ifname, /* Device name */
524 int request, /* WE ID */
525 struct iwreq * pwrq) /* Fixed part of the request */
527 /* Set device name */
528 strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
530 return(ioctl(skfd, request, pwrq));
533 /*------------------------------------------------------------------*/
535 * Close the socket used for ioctl.
538 iw_sockets_close(int skfd)
543 /*------------------------------------------------------------------*/
545 * Display an Ethernet Socket Address in readable format.
548 iw_saether_ntop(const struct sockaddr *sap, char* bufp)
550 iw_ether_ntop((const struct ether_addr *) sap->sa_data, bufp);
553 /*------------------------------------------------------------------*/
555 * Input an Ethernet Socket Address and convert to binary.
558 iw_saether_aton(const char *bufp, struct sockaddr *sap)
560 sap->sa_family = ARPHRD_ETHER;
561 return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data);
564 /*------------------------------------------------------------------*/
566 * Create an Ethernet broadcast address
569 iw_broad_ether(struct sockaddr *sap)
571 sap->sa_family = ARPHRD_ETHER;
572 memset((char *) sap->sa_data, 0xFF, ETH_ALEN);
575 /*------------------------------------------------------------------*/
577 * Create an Ethernet NULL address
580 iw_null_ether(struct sockaddr *sap)
582 sap->sa_family = ARPHRD_ETHER;
583 memset((char *) sap->sa_data, 0x00, ETH_ALEN);
586 /*------------------------------------------------------------------*/
588 * Compare two ethernet addresses
591 iw_ether_cmp(const struct ether_addr* eth1, const struct ether_addr* eth2)
593 return memcmp(eth1, eth2, sizeof(*eth1));