mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-26 15:02:50 +02:00
lib/libiw: add libiw from wireless tools v29, and wrapper to scan wlan networks
Origin commit data
------------------
Branch: ni/coolstream
Commit: 9a40a9f740
Author: [CST] Focus <focus.cst@gmail.com>
Date: 2013-11-01 (Fri, 01 Nov 2013)
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
6
lib/libiw/Makefile.am
Normal file
6
lib/libiw/Makefile.am
Normal file
@@ -0,0 +1,6 @@
|
||||
noinst_LIBRARIES = libiw.a
|
||||
|
||||
AM_CXXFLAGS = -I$(top_builddir) -fno-rtti -fno-exceptions
|
||||
|
||||
libiw_a_SOURCES = iwlib.c iwscan.cpp
|
||||
|
3214
lib/libiw/iwlib.c
Normal file
3214
lib/libiw/iwlib.c
Normal file
File diff suppressed because it is too large
Load Diff
600
lib/libiw/iwlib.h
Normal file
600
lib/libiw/iwlib.h
Normal file
@@ -0,0 +1,600 @@
|
||||
/*
|
||||
* 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 <jt@hpl.hp.com>
|
||||
*/
|
||||
|
||||
#ifndef IWLIB_H
|
||||
#define IWLIB_H
|
||||
|
||||
/*#include "CHANGELOG.h"*/
|
||||
|
||||
/***************************** INCLUDES *****************************/
|
||||
|
||||
/* Standard headers */
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h> /* gethostbyname, getnetbyname */
|
||||
#include <net/ethernet.h> /* struct ether_addr */
|
||||
#include <sys/time.h> /* struct timeval */
|
||||
#include <unistd.h>
|
||||
|
||||
/* 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 <rietz@mail.amps.de>, 27.3.2 */
|
||||
#include <net/if_arp.h> /* For ARPHRD_ETHER */
|
||||
#include <sys/socket.h> /* For AF_INET & struct sockaddr */
|
||||
#include <netinet/in.h> /* For struct sockaddr_in */
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
/* Fixup to be able to include kernel includes in userspace.
|
||||
* Basically, kill the sparse annotations... Jean II */
|
||||
#ifndef __user
|
||||
#define __user
|
||||
#endif
|
||||
|
||||
#include <linux/types.h> /* for "caddr_t" et al */
|
||||
|
||||
/* Glibc systems headers are supposedly less problematic than kernel ones */
|
||||
#include <sys/socket.h> /* for "struct sockaddr" et al */
|
||||
#include <net/if.h> /* 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 */
|
294
lib/libiw/iwscan.cpp
Normal file
294
lib/libiw/iwscan.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
Copyright (C) 2013 CoolStream International Ltd
|
||||
|
||||
Based on iwlist.c, Copyright (c) 1997-2007 Jean Tourrilhes <jt@hpl.hp.com>
|
||||
|
||||
License: GPLv2
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation;
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
extern "C" {
|
||||
#include "iwlib.h" /* Header */
|
||||
}
|
||||
|
||||
#include <config.h>
|
||||
#include "iwscan.h"
|
||||
|
||||
static void device_up(std::string dev)
|
||||
{
|
||||
int sockfd;
|
||||
struct ifreq ifr;
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (sockfd < 0) {
|
||||
perror("socket");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof ifr);
|
||||
|
||||
strncpy(ifr.ifr_name, dev.c_str(), IFNAMSIZ);
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
|
||||
perror("SIOCGIFFLAGS");
|
||||
|
||||
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
|
||||
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
|
||||
perror("SIOCSIFFLAGS");
|
||||
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
bool get_wlan_list(std::string dev, std::vector<wlan_network> &networks)
|
||||
{
|
||||
int skfd;
|
||||
struct iwreq wrq;
|
||||
unsigned char * buffer = NULL; /* Results */
|
||||
int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
|
||||
struct iw_range range;
|
||||
int has_range;
|
||||
struct timeval tv; /* Select timeout */
|
||||
int timeout = 15000000; /* 15s */
|
||||
const char * ifname = dev.c_str();
|
||||
|
||||
networks.clear();
|
||||
device_up(dev);
|
||||
|
||||
if((skfd = iw_sockets_open()) < 0)
|
||||
{
|
||||
perror("socket");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get range stuff */
|
||||
has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
|
||||
|
||||
/* Check if the interface could support scanning. */
|
||||
if((!has_range) || (range.we_version_compiled < 14))
|
||||
{
|
||||
fprintf(stderr, "%-8.16s Interface doesn't support scanning.\n\n",
|
||||
ifname);
|
||||
goto _return;
|
||||
}
|
||||
|
||||
/* Init timeout value -> 250ms between set and first get */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 250000;
|
||||
|
||||
wrq.u.data.pointer = NULL;
|
||||
wrq.u.data.flags = 0;
|
||||
wrq.u.data.length = 0;
|
||||
|
||||
/* Initiate Scanning */
|
||||
if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
|
||||
{
|
||||
if(errno != EPERM)
|
||||
{
|
||||
fprintf(stderr, "%-8.16s Interface doesn't support scanning : %s\n\n",
|
||||
ifname, strerror(errno));
|
||||
goto _return;
|
||||
}
|
||||
/* If we don't have the permission to initiate the scan, we may
|
||||
* still have permission to read left-over results.
|
||||
* But, don't wait !!! */
|
||||
tv.tv_usec = 0;
|
||||
}
|
||||
timeout -= tv.tv_usec;
|
||||
|
||||
/* Forever */
|
||||
while(1)
|
||||
{
|
||||
fd_set rfds; /* File descriptors for select */
|
||||
int last_fd; /* Last fd */
|
||||
int ret;
|
||||
|
||||
/* Guess what ? We must re-generate rfds each time */
|
||||
FD_ZERO(&rfds);
|
||||
last_fd = -1;
|
||||
|
||||
/* In here, add the rtnetlink fd in the list */
|
||||
|
||||
/* Wait until something happens */
|
||||
ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
|
||||
|
||||
/* Check if there was an error */
|
||||
if(ret < 0)
|
||||
{
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
fprintf(stderr, "Unhandled signal - exiting...\n");
|
||||
goto _return;
|
||||
}
|
||||
|
||||
/* Check if there was a timeout */
|
||||
if(ret == 0)
|
||||
{
|
||||
unsigned char * newbuf;
|
||||
|
||||
realloc:
|
||||
/* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
|
||||
newbuf = (unsigned char *) realloc(buffer, buflen);
|
||||
if(newbuf == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
|
||||
goto _return;
|
||||
}
|
||||
buffer = newbuf;
|
||||
|
||||
/* Try to read the results */
|
||||
wrq.u.data.pointer = buffer;
|
||||
wrq.u.data.flags = 0;
|
||||
wrq.u.data.length = buflen;
|
||||
if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
|
||||
{
|
||||
/* Check if buffer was too small (WE-17 only) */
|
||||
if((errno == E2BIG) && (range.we_version_compiled > 16))
|
||||
{
|
||||
/* Some driver may return very large scan results, either
|
||||
* because there are many cells, or because they have many
|
||||
* large elements in cells (like IWEVCUSTOM). Most will
|
||||
* only need the regular sized buffer. We now use a dynamic
|
||||
* allocation of the buffer to satisfy everybody. Of course,
|
||||
* as we don't know in advance the size of the array, we try
|
||||
* various increasing sizes. Jean II */
|
||||
|
||||
/* Check if the driver gave us any hints. */
|
||||
if(wrq.u.data.length > buflen)
|
||||
buflen = wrq.u.data.length;
|
||||
else
|
||||
buflen *= 2;
|
||||
|
||||
/* Try again */
|
||||
goto realloc;
|
||||
}
|
||||
|
||||
/* Check if results not available yet */
|
||||
if(errno == EAGAIN)
|
||||
{
|
||||
/* Restart timer for only 100ms*/
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000;
|
||||
timeout -= tv.tv_usec;
|
||||
if(timeout > 0)
|
||||
continue; /* Try again later */
|
||||
}
|
||||
|
||||
/* Bad error */
|
||||
fprintf(stderr, "%-8.16s Failed to read scan data : %s\n\n",
|
||||
ifname, strerror(errno));
|
||||
goto _return;
|
||||
}
|
||||
else
|
||||
/* We have the results, go to process them */
|
||||
break;
|
||||
}
|
||||
|
||||
/* In here, check if event and event type
|
||||
* if scan event, read results. All errors bad & no reset timeout */
|
||||
}
|
||||
|
||||
if(wrq.u.data.length)
|
||||
{
|
||||
struct iw_event iwe;
|
||||
struct iw_event * event = &iwe;
|
||||
struct stream_descr stream;
|
||||
int ret;
|
||||
|
||||
printf("%-8.16s Scan completed :\n", ifname);
|
||||
iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
|
||||
int count = -1;
|
||||
while(1)
|
||||
{
|
||||
wlan_network network;
|
||||
/* Extract an event and print it */
|
||||
ret = iw_extract_event_stream(&stream, &iwe,
|
||||
range.we_version_compiled);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
switch(event->cmd) {
|
||||
case SIOCGIWESSID:
|
||||
{
|
||||
char essid[IW_ESSID_MAX_SIZE+1];
|
||||
memset(essid, '\0', sizeof(essid));
|
||||
if((event->u.essid.pointer) && (event->u.essid.length))
|
||||
memcpy(essid, event->u.essid.pointer, event->u.essid.length);
|
||||
if(event->u.essid.flags)
|
||||
{
|
||||
printf(" ESSID:\"%s\"\n", essid);
|
||||
network.ssid = essid;
|
||||
}
|
||||
else {
|
||||
printf(" ESSID:off/any/hidden\n");
|
||||
network.ssid = "(hidden)";
|
||||
}
|
||||
count++;
|
||||
networks.push_back(network);
|
||||
}
|
||||
|
||||
break;
|
||||
case SIOCGIWFREQ:
|
||||
{
|
||||
double freq; /* Frequency/channel */
|
||||
int channel = -1; /* Converted to channel */
|
||||
char buf[128];
|
||||
freq = iw_freq2float(&(event->u.freq));
|
||||
/* Convert to channel if possible */
|
||||
if(has_range)
|
||||
channel = iw_freq_to_channel(freq, &range);
|
||||
iw_print_freq(buf, sizeof(buf),
|
||||
freq, channel, event->u.freq.flags);
|
||||
#if 0
|
||||
if ((channel < 0) && (freq < KILO))
|
||||
channel = freq;
|
||||
#endif
|
||||
printf(" %s\n", buf);
|
||||
networks[count].channel = buf;
|
||||
}
|
||||
break;
|
||||
case IWEVQUAL:
|
||||
{
|
||||
char buf[128];
|
||||
iw_print_stats(buf, sizeof(buf),
|
||||
&event->u.qual, &range, has_range);
|
||||
printf(" %s\n", buf);
|
||||
networks[count].qual = buf;
|
||||
std::size_t found = networks[count].qual.find_first_of(' ');
|
||||
if (found != std::string::npos)
|
||||
networks[count].qual = networks[count].qual.substr(0, found);
|
||||
}
|
||||
break;
|
||||
case SIOCGIWENCODE:
|
||||
if(event->u.data.flags & IW_ENCODE_DISABLED)
|
||||
networks[count].encrypted = 0;
|
||||
else
|
||||
networks[count].encrypted = 1;
|
||||
|
||||
printf(" Encryption key:%s\n", networks[count].encrypted ? "on" : "off");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
printf("%-8.16s No scan results\n\n", ifname);
|
||||
|
||||
_return:
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
iw_sockets_close(skfd);
|
||||
|
||||
return !networks.empty();
|
||||
}
|
36
lib/libiw/iwscan.h
Normal file
36
lib/libiw/iwscan.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (C) 2013 CoolStream International Ltd
|
||||
|
||||
License: GPLv2
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation;
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _IWSCAN_H_
|
||||
#define _IWSCAN_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct wlan_network
|
||||
{
|
||||
std::string ssid;
|
||||
int encrypted;
|
||||
std::string channel;
|
||||
std::string qual;
|
||||
wlan_network(): encrypted(0) {}
|
||||
};
|
||||
|
||||
bool get_wlan_list(std::string dev, std::vector<wlan_network> &networks);
|
||||
#endif
|
1120
lib/libiw/wireless.h
Normal file
1120
lib/libiw/wireless.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user