/* * Wireless Tools * * Jean II - HPLB 97->99 - HPL 99->07 * * Common header for the Wireless Extension library... * * This file is released under the GPL license. * Copyright (c) 1997-2007 Jean Tourrilhes */ #ifndef IWLIB_H #define IWLIB_H /*#include "CHANGELOG.h"*/ /***************************** INCLUDES *****************************/ /* Standard headers */ #include #include #include #include #include #include #include #include #include #include #include /* gethostbyname, getnetbyname */ #include /* struct ether_addr */ #include /* struct timeval */ #include /* This is our header selection. Try to hide the mess and the misery :-( * Don't look, you would go blind ;-) * Note : compatibility with *old* distributions has been removed, * you will need Glibc 2.2 and older to compile (which means * Mandrake 8.0, Debian 2.3, RH 7.1 or older). */ /* Set of headers proposed by Dr. Michael Rietz , 27.3.2 */ #include /* For ARPHRD_ETHER */ #include /* For AF_INET & struct sockaddr */ #include /* For struct sockaddr_in */ #include /* Fixup to be able to include kernel includes in userspace. * Basically, kill the sparse annotations... Jean II */ #ifndef __user #define __user #endif #include /* for "caddr_t" et al */ /* Glibc systems headers are supposedly less problematic than kernel ones */ #include /* for "struct sockaddr" et al */ #include /* for IFNAMSIZ and co... */ /* Private copy of Wireless extensions (in this directoty) */ #include "wireless.h" /* Make gcc understant that when we say inline, we mean it. * I really hate when the compiler is trying to be more clever than me, * because in this case gcc is not able to figure out functions with a * single call site, so not only I have to tag those functions inline * by hand, but then it refuse to inline them properly. * Total saving for iwevent : 150B = 0.7%. * Fortunately, in gcc 3.4, they now automatically inline static functions * with a single call site. Hurrah ! * Jean II */ #undef IW_GCC_HAS_BROKEN_INLINE #if __GNUC__ == 3 #if __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4 #define IW_GCC_HAS_BROKEN_INLINE 1 #endif /* __GNUC_MINOR__ */ #endif /* __GNUC__ */ /* However, gcc 4.0 has introduce a new "feature", when compiling with * '-Os', it does not want to inline iw_ether_cmp() and friends. * So, we need to fix inline again ! * Jean II */ #if __GNUC__ == 4 #define IW_GCC_HAS_BROKEN_INLINE 1 #endif /* __GNUC__ */ /* Now, really fix the inline */ #ifdef IW_GCC_HAS_BROKEN_INLINE #ifdef inline #undef inline #endif /* inline */ #define inline inline __attribute__((always_inline)) #endif /* IW_GCC_HAS_BROKEN_INLINE */ #ifdef __cplusplus extern "C" { #endif /****************************** DEBUG ******************************/ //#define DEBUG 1 /************************ CONSTANTS & MACROS ************************/ /* Various versions information */ /* Recommended Wireless Extension version */ #define WE_VERSION 21 /* Maximum forward compatibility built in this version of WT */ #define WE_MAX_VERSION 22 /* Version of Wireless Tools */ #define WT_VERSION 29 /* Paths */ #define PROC_NET_WIRELESS "/proc/net/wireless" #define PROC_NET_DEV "/proc/net/dev" /* Some usefull constants */ #define KILO 1e3 #define MEGA 1e6 #define GIGA 1e9 /* For doing log10/exp10 without libm */ #define LOG10_MAGIC 1.25892541179 /* Backward compatibility for network headers */ #ifndef ARPHRD_IEEE80211 #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #endif /* ARPHRD_IEEE80211 */ #ifndef IW_EV_LCP_PK_LEN /* Size of the Event prefix when packed in stream */ #define IW_EV_LCP_PK_LEN (4) /* Size of the various events when packed in stream */ #define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ) #define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32)) #define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq)) #define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param)) #define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr)) #define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality)) #define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4) struct iw_pk_event { __u16 len; /* Real lenght of this stuff */ __u16 cmd; /* Wireless IOCTL */ union iwreq_data u; /* IOCTL fixed payload */ } __attribute__ ((packed)); struct iw_pk_point { void __user *pointer; /* Pointer to the data (in user space) */ __u16 length; /* number of fields or size in bytes */ __u16 flags; /* Optional params */ } __attribute__ ((packed)); #define IW_EV_LCP_PK2_LEN (sizeof(struct iw_pk_event) - sizeof(union iwreq_data)) #define IW_EV_POINT_PK2_LEN (IW_EV_LCP_PK2_LEN + sizeof(struct iw_pk_point) - IW_EV_POINT_OFF) #endif /* IW_EV_LCP_PK_LEN */ /****************************** TYPES ******************************/ /* Shortcuts */ typedef struct iw_statistics iwstats; typedef struct iw_range iwrange; typedef struct iw_param iwparam; typedef struct iw_freq iwfreq; typedef struct iw_quality iwqual; typedef struct iw_priv_args iwprivargs; typedef struct sockaddr sockaddr; /* Structure for storing all wireless information for each device * This is a cut down version of the one above, containing only * the things *truly* needed to configure a card. * Don't add other junk, I'll remove it... */ typedef struct wireless_config { char name[IFNAMSIZ + 1]; /* Wireless/protocol name */ int has_nwid; iwparam nwid; /* Network ID */ int has_freq; double freq; /* Frequency/channel */ int freq_flags; int has_key; unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */ int key_size; /* Number of bytes */ int key_flags; /* Various flags */ int has_essid; int essid_on; char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */ int has_mode; int mode; /* Operation mode */ } wireless_config; /* Structure for storing all wireless information for each device * This is pretty exhaustive... */ typedef struct wireless_info { struct wireless_config b; /* Basic information */ int has_sens; iwparam sens; /* sensitivity */ int has_nickname; char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */ int has_ap_addr; sockaddr ap_addr; /* Access point address */ int has_bitrate; iwparam bitrate; /* Bit rate in bps */ int has_rts; iwparam rts; /* RTS threshold in bytes */ int has_frag; iwparam frag; /* Fragmentation threshold in bytes */ int has_power; iwparam power; /* Power management parameters */ int has_txpower; iwparam txpower; /* Transmit Power in dBm */ int has_retry; iwparam retry; /* Retry limit or lifetime */ /* Stats */ iwstats stats; int has_stats; iwrange range; int has_range; /* Auth params for WPA/802.1x/802.11i */ int auth_key_mgmt; int has_auth_key_mgmt; int auth_cipher_pairwise; int has_auth_cipher_pairwise; int auth_cipher_group; int has_auth_cipher_group; } wireless_info; /* Structure for storing an entry of a wireless scan. * This is only a subset of all possible information, the flexible * structure of scan results make it impossible to capture all * information in such a static structure. */ typedef struct wireless_scan { /* Linked list */ struct wireless_scan * next; /* Cell identifiaction */ int has_ap_addr; sockaddr ap_addr; /* Access point address */ /* Other information */ struct wireless_config b; /* Basic information */ iwstats stats; /* Signal strength */ int has_stats; iwparam maxbitrate; /* Max bit rate in bps */ int has_maxbitrate; } wireless_scan; /* * Context used for non-blocking scan. */ typedef struct wireless_scan_head { wireless_scan * result; /* Result of the scan */ int retry; /* Retry level */ } wireless_scan_head; /* Structure used for parsing event streams, such as Wireless Events * and scan results */ typedef struct stream_descr { char * end; /* End of the stream */ char * current; /* Current event in stream of events */ char * value; /* Current value in event */ } stream_descr; /* Prototype for handling display of each single interface on the * system - see iw_enum_devices() */ typedef int (*iw_enum_handler)(int skfd, char * ifname, char * args[], int count); /* Describe a modulation */ typedef struct iw_modul_descr { unsigned int mask; /* Modulation bitmask */ char cmd[8]; /* Short name */ char * verbose; /* Verbose description */ } iw_modul_descr; /**************************** PROTOTYPES ****************************/ /* * All the functions in iwcommon.c */ /* ---------------------- SOCKET SUBROUTINES -----------------------*/ int iw_sockets_open(void); void iw_enum_devices(int skfd, iw_enum_handler fn, char * args[], int count); /* --------------------- WIRELESS SUBROUTINES ----------------------*/ int iw_get_kernel_we_version(void); int iw_print_version_info(const char * toolname); int iw_get_range_info(int skfd, const char * ifname, iwrange * range); int iw_get_priv_info(int skfd, const char * ifname, iwprivargs ** ppriv); int iw_get_basic_config(int skfd, const char * ifname, wireless_config * info); int iw_set_basic_config(int skfd, const char * ifname, wireless_config * info); /* --------------------- PROTOCOL SUBROUTINES --------------------- */ int iw_protocol_compare(const char * protocol1, const char * protocol2); /* -------------------- FREQUENCY SUBROUTINES --------------------- */ void iw_float2freq(double in, iwfreq * out); double iw_freq2float(const iwfreq * in); void iw_print_freq_value(char * buffer, int buflen, double freq); void iw_print_freq(char * buffer, int buflen, double freq, int channel, int freq_flags); int iw_freq_to_channel(double freq, const struct iw_range * range); int iw_channel_to_freq(int channel, double * pfreq, const struct iw_range * range); void iw_print_bitrate(char * buffer, int buflen, int bitrate); /* ---------------------- POWER SUBROUTINES ----------------------- */ int iw_dbm2mwatt(int in); int iw_mwatt2dbm(int in); void iw_print_txpower(char * buffer, int buflen, struct iw_param * txpower); /* -------------------- STATISTICS SUBROUTINES -------------------- */ int iw_get_stats(int skfd, const char * ifname, iwstats * stats, const iwrange * range, int has_range); void iw_print_stats(char * buffer, int buflen, const iwqual * qual, const iwrange * range, int has_range); /* --------------------- ENCODING SUBROUTINES --------------------- */ void iw_print_key(char * buffer, int buflen, const unsigned char * key, int key_size, int key_flags); int iw_in_key(const char * input, unsigned char * key); int iw_in_key_full(int skfd, const char * ifname, const char * input, unsigned char * key, __u16 * flags); /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */ void iw_print_pm_value(char * buffer, int buflen, int value, int flags, int we_version); void iw_print_pm_mode(char * buffer, int buflen, int flags); /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */ void iw_print_retry_value(char * buffer, int buflen, int value, int flags, int we_version); /* ----------------------- TIME SUBROUTINES ----------------------- */ void iw_print_timeval(char * buffer, int buflen, const struct timeval * time, const struct timezone * tz); /* --------------------- ADDRESS SUBROUTINES ---------------------- */ int iw_check_mac_addr_type(int skfd, const char * ifname); int iw_check_if_addr_type(int skfd, const char * ifname); #if 0 int iw_check_addr_type(int skfd, const char * ifname); #endif #if 0 int iw_get_mac_addr(int skfd, const char * name, struct ether_addr * eth, unsigned short * ptype); #endif char * iw_mac_ntop(const unsigned char * mac, int maclen, char * buf, int buflen); void iw_ether_ntop(const struct ether_addr * eth, char * buf); char * iw_sawap_ntop(const struct sockaddr * sap, char * buf); int iw_mac_aton(const char * orig, unsigned char * mac, int macmax); int iw_ether_aton(const char* bufp, struct ether_addr* eth); int iw_in_inet(char *bufp, struct sockaddr *sap); int iw_in_addr(int skfd, const char * ifname, char * bufp, struct sockaddr * sap); /* ----------------------- MISC SUBROUTINES ------------------------ */ int iw_get_priv_size(int args); /* ---------------------- EVENT SUBROUTINES ---------------------- */ void iw_init_event_stream(struct stream_descr * stream, char * data, int len); int iw_extract_event_stream(struct stream_descr * stream, struct iw_event * iwe, int we_version); /* --------------------- SCANNING SUBROUTINES --------------------- */ int iw_process_scan(int skfd, char * ifname, int we_version, wireless_scan_head * context); int iw_scan(int skfd, char * ifname, int we_version, wireless_scan_head * context); /**************************** VARIABLES ****************************/ /* Modes as human readable strings */ extern const char * const iw_operation_mode[]; #define IW_NUM_OPER_MODE 7 #define IW_NUM_OPER_MODE_EXT 8 /* Modulations as human readable strings */ extern const struct iw_modul_descr iw_modul_list[]; #define IW_SIZE_MODUL_LIST 16 /************************* INLINE FUNTIONS *************************/ /* * Functions that are so simple that it's more efficient inlining them */ /* * Note : I've defined wrapper for the ioctl request so that * it will be easier to migrate to other kernel API if needed */ /*------------------------------------------------------------------*/ /* * Wrapper to push some Wireless Parameter in the driver */ static inline int iw_set_ext(int skfd, /* Socket to the kernel */ const char * ifname, /* Device name */ int request, /* WE ID */ struct iwreq * pwrq) /* Fixed part of the request */ { /* Set device name */ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); /* Do the request */ return(ioctl(skfd, request, pwrq)); } /*------------------------------------------------------------------*/ /* * Wrapper to extract some Wireless Parameter out of the driver */ static inline int iw_get_ext(int skfd, /* Socket to the kernel */ const char * ifname, /* Device name */ int request, /* WE ID */ struct iwreq * pwrq) /* Fixed part of the request */ { /* Set device name */ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); /* Do the request */ return(ioctl(skfd, request, pwrq)); } /*------------------------------------------------------------------*/ /* * Close the socket used for ioctl. */ static inline void iw_sockets_close(int skfd) { close(skfd); } /*------------------------------------------------------------------*/ /* * Display an Ethernet Socket Address in readable format. */ static inline char * iw_saether_ntop(const struct sockaddr *sap, char* bufp) { iw_ether_ntop((const struct ether_addr *) sap->sa_data, bufp); return bufp; } /*------------------------------------------------------------------*/ /* * Input an Ethernet Socket Address and convert to binary. */ static inline int iw_saether_aton(const char *bufp, struct sockaddr *sap) { sap->sa_family = ARPHRD_ETHER; return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data); } /*------------------------------------------------------------------*/ /* * Create an Ethernet broadcast address */ static inline void iw_broad_ether(struct sockaddr *sap) { sap->sa_family = ARPHRD_ETHER; memset((char *) sap->sa_data, 0xFF, ETH_ALEN); } /*------------------------------------------------------------------*/ /* * Create an Ethernet NULL address */ static inline void iw_null_ether(struct sockaddr *sap) { sap->sa_family = ARPHRD_ETHER; memset((char *) sap->sa_data, 0x00, ETH_ALEN); } /*------------------------------------------------------------------*/ /* * Compare two ethernet addresses */ static inline int iw_ether_cmp(const struct ether_addr* eth1, const struct ether_addr* eth2) { return memcmp(eth1, eth2, sizeof(*eth1)); } #ifdef __cplusplus } #endif #endif /* IWLIB_H */