--- /dev/null
+/*
+ * Wireless Tools
+ *
+ * Jean II - HPLB 97->99 - HPL 99->01
+ *
+ * The changelog...
+ *
+ * This file is released under the GPL license.
+ */
+
+/* --------------------------- HISTORY --------------------------- */
+/*
+ * wireless 16 : (Jean Tourrilhes)
+ * -----------
+ * o iwconfig, iwpriv & iwspy
+ *
+ * wireless 17 : (Justin Seger)
+ * -----------
+ * o Compile under glibc fix
+ * o merge iwpriv in iwconfig
+ * o Add Wavelan roaming support
+ * o Update man page of iwconfig
+ *
+ * wireless 18 :
+ * -----------
+ * (From Andreas Neuhaus <andy@fasta.fh-dortmund.de>)
+ * o Many fix to remove "core dumps" in iwconfig
+ * o Remove useless headers in iwconfig
+ * o CHAR wide private ioctl
+ * (From Jean Tourrilhes)
+ * o Create iwcommon.h and iwcommon.c
+ * o Separate iwpriv again for user interface issues
+ * The folllowing didn't make sense and crashed :
+ * iwconfig eth0 priv sethisto 12 15 nwid 100
+ * o iwspy no longer depend on net-tools-1.2.0
+ * o Reorganisation of the code, cleanup
+ * o Add ESSID stuff in iwconfig
+ * o Add display of level & noise in dBm (stats in iwconfig)
+ * o Update man page of iwconfig and iwpriv
+ * o Add xwireless (didn't check if it compiles)
+ * (From Dean W. Gehnert <deang@tpi.com>)
+ * o Minor fixes
+ * (Jan Rafaj <rafaj@cedric.vabo.cz>)
+ * o Cosmetic changes (sensitivity relative, freq list)
+ * o Frequency computation on double
+ * o Compile clean on libc5
+ * (From Jean Tourrilhes)
+ * o Move listing of frequencies to iwspy
+ * o Add AP address stuff in iwconfig
+ * o Add AP list stuff in iwspy
+ *
+ * wireless 19 :
+ * -----------
+ * (From Jean Tourrilhes)
+ * o Allow for sensitivity in dBm (if < 0) [iwconfig]
+ * o Formatting changes in displaying ap address in [iwconfig]
+ * o Slightly improved man pages and usage display
+ * o Add channel number for each frequency in list [iwspy]
+ * o Add nickname... [iwconfig]
+ * o Add "port" private ioctl shortcut [iwpriv]
+ * o If signal level = 0, no range or dBms [iwconfig]
+ * o I think I now got set/get char strings right in [iwpriv]
+ * (From Thomas Ekstrom <tomeck@thelogic.com>)
+ * o Fix a very obscure bug in [iwspy]
+ *
+ * wireless 20 :
+ * -----------
+ * (From Jean Tourrilhes)
+ * o Remove all #ifdef WIRELESS ugliness, but add a #error :
+ * we require Wireless Extensions 9 or nothing ! [all]
+ * o Switch to new 'nwid' definition (specific -> iw_param) [iwconfig]
+ * o Rewriten totally the encryption support [iwconfig]
+ * - Multiple keys, through key index
+ * - Flexible/multiple key size, and remove 64bits upper limit
+ * - Open/Restricted modes
+ * - Enter keys as ASCII strings
+ * o List key sizes supported and all keys in [iwspy]
+ * o Mode of operation support (ad-hoc, managed...) [iwconfig]
+ * o Use '=' to indicate fixed instead of ugly '(f)' [iwconfig]
+ * o Ability to disable RTS & frag (off), now the right way [iwconfig]
+ * o Auto as an input modifier for bitrate [iwconfig]
+ * o Power Management support [iwconfig]
+ * - set timeout or period and its value
+ * - Reception mode (unicast/multicast/all)
+ * o Updated man pages with all that ;-)
+ *
+ * wireless 21 :
+ * -----------
+ * (from Alan McReynolds <alan_mcreynolds@hpl.hp.com>)
+ * o Use proper macros for compilation directives [Makefile]
+ * (From Jean Tourrilhes)
+ * o Put licensing info everywhere (almost). Yes, it's GPL !
+ * o Document the use of /etc/pcmcia/wireless.opts
+ * o Add min/max modifiers to power management parameters [iwconfig]
+ * -> requested by Lee Keyser-Allen for the Spectrum24 driver
+ * o Optionally output a second power management parameter [iwconfig]
+ * ---
+ * o Common subroutines to display stats & power saving info [iwcommon]
+ * o Display all power management info, capability and values [iwspy]
+ * ---
+ * o Optional index for ESSID (for Aironet driver) [iwcommon]
+ * o IW_ENCODE_NOKEY for write only keys [iwconfig/iwspy]
+ * o Common subrouting to print encoding keys [iwspy]
+ * ---
+ * o Transmit Power stuff (dBm + mW) [iwconfig/iwspy]
+ * o Cleaner formatting algorithm when displaying params [iwconfig]
+ * ---
+ * o Fix get_range_info() and use it everywhere - Should fix core dumps.
+ * o Catch WE version differences between tools and driver and
+ * warn user. Thanks to Tobias Ringstrom for the tip... [iwcommon]
+ * o Add Retry limit and lifetime support. [iwconfig/iwlist]
+ * o Display "Cell:" instead of "Access Point:" in ad-hoc mode [iwconfig]
+ * o Header fix for glibc2.2 by Ross G. Miller <Ross_Miller@baylor.edu>
+ * o Move header selection flags in Makefile [iwcommon/Makefile]
+ * o Spin-off iwlist.c from iwspy.c. iwspy is now much smaller
+ * After moving this bit of code all over the place, from iwpriv
+ * to iwconfig to iwspy, it now has a home of its own... [iwspy/iwlist]
+ * o Wrote quick'n'dirty iwgetid.
+ * o Remove output of second power management parameter [iwconfig]
+ * Please use iwlist, I don't want to bloat iwconfig
+ * ---
+ * o Fix bug in display ints - "Allen Miu" <aklmiu@mit.edu> [iwpriv]
+ *
+ * wireless 22 :
+ * -----------
+ * (From Jim Kaba <jkaba@sarnoff.com>)
+ * o Fix socket_open to not open all types of sockets [iwcommon]
+ * (From Michael Tokarev <mjt@tls.msk.ru>)
+ * o Rewrite main (top level) + command line parsing of [iwlist]
+ * (From Jean Tourrilhes)
+ * o Set commands should return proper success flag [iwspy/iwpriv]
+ * requested by Michael Tokarev
+ * ---
+ * (From Torgeir Hansen <torgeir@trenger.ro>)
+ * o Replace "strcpy(wrq.ifr_name," with strncpy to avoid buffer
+ * overflows. This is OK because the kernel use strncmp...
+ * ---
+ * o Move operation_mode in iwcommon and add NUM_OPER_MODE [iwconfig]
+ * o print_stats, print_key, ... use char * instead if FILE * [iwcommon]
+ * o Add `iw_' prefix to avoid namespace pollution [iwcommon]
+ * o Add iw_get_basic_config() and iw_set_basic_config() [iwcommon]
+ * o Move iw_getstats from iwconfig to iwcommon [iwcommon]
+ * o Move changelog to CHANGELOG.h [iwcommon]
+ * o Rename iwcommon.* into iwlib.* [iwcommon->iwlib]
+ * o Compile iwlib. as a dynamic or static library [Makefile]
+ * o Allow the tools to be compiled with the dynamic library [Makefile]
+ * --- Update to Wireless Extension 12 ---
+ * o Show typical/average quality in iwspy [iwspy]
+ * o Get Wireless Stats through ioctl instead of /proc [iwlib]
+ *
+ */
+
+/* ----------------------------- TODO ----------------------------- */
+/*
+ * One day, maybe...
+ *
+ * iwconfig :
+ * --------
+ * Make disable a per encryption key modifier if some hardware
+ * requires it.
+ *
+ * iwpriv :
+ * ------
+ * Remove 'port' and 'roam' cruft now that we have mode in iwconfig
+ *
+ * iwspy :
+ * -----
+ * -
+ *
+ * Doc & man pages :
+ * ---------------
+ * Update main doc.
+ *
+ * Other :
+ * -----
+ * What about some graphical tools ?
+ */
#
# Targets to build
+STATIC=libiw.a
+DYNAMIC=libiw.so.22
PROGS= iwconfig iwlist iwpriv iwspy iwgetid
+# Composition of the library :
+OBJS = iwlib.o
+
+# Define if tools should be built using static or dynamic version of the lib
+IWLIBS=$(OBJS)
+#IWLIBS=-liw
+
# Installation directory. By default, go in local.
# Distributions should probably use /usr/sbin, but they probably know better...
INSTALL_DIR= /usr/local/sbin
+INSTALL_LIB= /usr/local/lib
+INSTALL_INC= /usr/local/include
# This is our header selection. Try to hide the mess and the misery :-(
# Please choose *only one* of the define...
-# Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0 */
+# Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1
#HEADERS= -DGLIBC22_HEADERS
# Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH 5
CFLAGS=-O2 -Wall $(HEADERS) $(WE_HEADER)
-LIBS=-lm
+LIBS=$(IWLIBS) -lm
-all:: $(PROGS)
+all:: $(STATIC) $(DYNAMIC) $(PROGS)
.c.o:
$(CC) $(CFLAGS) -c $<
-iwconfig: iwconfig.o iwcommon.o
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+iwconfig: iwconfig.o $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $< $(LIBS)
-iwlist: iwlist.o iwcommon.o
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+iwlist: iwlist.o $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $< $(LIBS)
-iwpriv: iwpriv.o iwcommon.o
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+iwpriv: iwpriv.o $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $< $(LIBS)
-iwspy: iwspy.o iwcommon.o
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+iwspy: iwspy.o $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $< $(LIBS)
iwgetid: iwgetid.o
$(CC) $(CFLAGS) -o $@ $^
+# Compilation of the dynamic library
+libiw.so.22: $(OBJS)
+ $(CC) -O2 -shared -o $@ -Wl,-soname,$@ -lm -lc $^
+
+# Compilation of the static library
+libiw.a: $(OBJS)
+ $(RM) $@
+ ar cru $@ $^
+ ranlib $@
+
# So crude but so effective ;-)
install::
cp $(PROGS) $(INSTALL_DIR)
+ cp $(STATIC) $(DYNAMIC) $(INSTALL_LIB)
+ echo "Don't forget to fix you /etc/ld.so.conf and run ldconfig."
+ cp iwlib.h $(INSTALL_INC)
clean::
$(RM_CMD)
realclean::
$(RM_CMD)
- $(RM) $(PROGS)
+ $(RM) $(STATIC) $(DYNAMIC) $(PROGS)
depend::
makedepend -s "# DO NOT DELETE" -- $(INCLUDES) -- $(SRCS)
+++ /dev/null
-/*
- * Wireless Tools
- *
- * Jean II - HPLB 97->99 - HPL 99->00
- *
- * Common header for the wireless tools...
- *
- * This file is released under the GPL license.
- */
-
-#ifndef IWCOMMON_H
-#define IWCOMMON_H
-
-/************************** DOCUMENTATION **************************/
-/*
- * None ? Todo...
- */
-
-/* --------------------------- HISTORY --------------------------- */
-/*
- * wireless 16 : (Jean Tourrilhes)
- * -----------
- * o iwconfig, iwpriv & iwspy
- *
- * wireless 17 : (Justin Seger)
- * -----------
- * o Compile under glibc fix
- * o merge iwpriv in iwconfig
- * o Add Wavelan roaming support
- * o Update man page of iwconfig
- *
- * wireless 18 :
- * -----------
- * (From Andreas Neuhaus <andy@fasta.fh-dortmund.de>)
- * o Many fix to remove "core dumps" in iwconfig
- * o Remove useless headers in iwconfig
- * o CHAR wide private ioctl
- * (From Jean Tourrilhes)
- * o Create iwcommon.h and iwcommon.c
- * o Separate iwpriv again for user interface issues
- * The folllowing didn't make sense and crashed :
- * iwconfig eth0 priv sethisto 12 15 nwid 100
- * o iwspy no longer depend on net-tools-1.2.0
- * o Reorganisation of the code, cleanup
- * o Add ESSID stuff in iwconfig
- * o Add display of level & noise in dBm (stats in iwconfig)
- * o Update man page of iwconfig and iwpriv
- * o Add xwireless (didn't check if it compiles)
- * (From Dean W. Gehnert <deang@tpi.com>)
- * o Minor fixes
- * (Jan Rafaj <rafaj@cedric.vabo.cz>)
- * o Cosmetic changes (sensitivity relative, freq list)
- * o Frequency computation on double
- * o Compile clean on libc5
- * (From Jean Tourrilhes)
- * o Move listing of frequencies to iwspy
- * o Add AP address stuff in iwconfig
- * o Add AP list stuff in iwspy
- *
- * wireless 19 :
- * -----------
- * (From Jean Tourrilhes)
- * o Allow for sensitivity in dBm (if < 0) [iwconfig]
- * o Formatting changes in displaying ap address in [iwconfig]
- * o Slightly improved man pages and usage display
- * o Add channel number for each frequency in list [iwspy]
- * o Add nickname... [iwconfig]
- * o Add "port" private ioctl shortcut [iwpriv]
- * o If signal level = 0, no range or dBms [iwconfig]
- * o I think I now got set/get char strings right in [iwpriv]
- * (From Thomas Ekstrom <tomeck@thelogic.com>)
- * o Fix a very obscure bug in [iwspy]
- *
- * wireless 20 :
- * -----------
- * (From Jean Tourrilhes)
- * o Remove all #ifdef WIRELESS ugliness, but add a #error :
- * we require Wireless Extensions 9 or nothing ! [all]
- * o Switch to new 'nwid' definition (specific -> iw_param) [iwconfig]
- * o Rewriten totally the encryption support [iwconfig]
- * - Multiple keys, through key index
- * - Flexible/multiple key size, and remove 64bits upper limit
- * - Open/Restricted modes
- * - Enter keys as ASCII strings
- * o List key sizes supported and all keys in [iwspy]
- * o Mode of operation support (ad-hoc, managed...) [iwconfig]
- * o Use '=' to indicate fixed instead of ugly '(f)' [iwconfig]
- * o Ability to disable RTS & frag (off), now the right way [iwconfig]
- * o Auto as an input modifier for bitrate [iwconfig]
- * o Power Management support [iwconfig]
- * - set timeout or period and its value
- * - Reception mode (unicast/multicast/all)
- * o Updated man pages with all that ;-)
- *
- * wireless 21 :
- * -----------
- * (from Alan McReynolds <alan_mcreynolds@hpl.hp.com>)
- * o Use proper macros for compilation directives [Makefile]
- * (From Jean Tourrilhes)
- * o Put licensing info everywhere (almost). Yes, it's GPL !
- * o Document the use of /etc/pcmcia/wireless.opts
- * o Add min/max modifiers to power management parameters [iwconfig]
- * -> requested by Lee Keyser-Allen for the Spectrum24 driver
- * o Optionally output a second power management parameter [iwconfig]
- * ---
- * o Common subroutines to display stats & power saving info [iwcommon]
- * o Display all power management info, capability and values [iwspy]
- * ---
- * o Optional index for ESSID (for Aironet driver) [iwcommon]
- * o IW_ENCODE_NOKEY for write only keys [iwconfig/iwspy]
- * o Common subrouting to print encoding keys [iwspy]
- * ---
- * o Transmit Power stuff (dBm + mW) [iwconfig/iwspy]
- * o Cleaner formatting algorithm when displaying params [iwconfig]
- * ---
- * o Fix get_range_info() and use it everywhere - Should fix core dumps.
- * o Catch WE version differences between tools and driver and
- * warn user. Thanks to Tobias Ringstrom for the tip... [iwcommon]
- * o Add Retry limit and lifetime support. [iwconfig/iwlist]
- * o Display "Cell:" instead of "Access Point:" in ad-hoc mode [iwconfig]
- * o Header fix for glibc2.2 by Ross G. Miller <Ross_Miller@baylor.edu>
- * o Move header selection flags in Makefile [iwcommon/Makefile]
- * o Spin-off iwlist.c from iwspy.c. iwspy is now much smaller
- * After moving this bit of code all over the place, from iwpriv
- * to iwconfig to iwspy, it now has a home of its own... [iwspy/iwlist]
- * o Wrote quick'n'dirty iwgetid.
- * o Remove output of second power management parameter [iwconfig]
- * Please use iwlist, I don't want to bloat iwconfig
- * ---
- * o Fix bug in display ints - "Allen Miu" <aklmiu@mit.edu> [iwpriv]
- */
-
-/* ----------------------------- TODO ----------------------------- */
-/*
- * One day, maybe...
- *
- * iwconfig :
- * --------
- * Make disable a per encryption key modifier if some hardware
- * requires it.
- *
- * iwpriv :
- * ------
- * Remove 'port' and 'roam' cruft now that we have mode in iwconfig
- *
- * iwspy :
- * -----
- * -
- *
- * Doc & man pages :
- * ---------------
- * Update main doc.
- *
- * Other :
- * -----
- * What about some graphical tools ?
- */
-
-/***************************** 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 */
-
-/* This is our header selection. Try to hide the mess and the misery :-(
- * The selection has been moved in the Makefile, here we have only
- * the ugly part. Don't look, you would go blind ;-) */
-
-#ifdef KLUDGE_HEADERS
-#include <socketbits.h>
-#endif /* KLUDGE_HEADERS */
-
-#if defined(KLUDGE_HEADERS) || defined(GLIBC_HEADERS)
-#include <linux/if_arp.h> /* For ARPHRD_ETHER */
-#include <linux/socket.h> /* For AF_INET & struct sockaddr */
-#include <linux/in.h> /* For struct sockaddr_in */
-#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
-
-#ifdef GLIBC22_HEADERS
-/* Added by Ross G. Miller <Ross_Miller@baylor.edu>, 3/28/01 */
-#include <linux/if_arp.h> /* For ARPHRD_ETHER */
-#include <linux/socket.h> /* For AF_INET & struct sockaddr */
-#include <sys/socket.h>
-#endif /* GLIBC22_HEADERS */
-
-#ifdef LIBC5_HEADERS
-#include <sys/socket.h> /* For AF_INET & struct sockaddr & socket() */
-#include <linux/if_arp.h> /* For ARPHRD_ETHER */
-#include <linux/in.h> /* For struct sockaddr_in */
-#endif /* LIBC5_HEADERS */
-
-#ifdef PRIVATE_WE_HEADER
-/* Private copy of Wireless extensions */
-#include "wireless.h"
-#else /* PRIVATE_WE_HEADER */
-/* System wide Wireless extensions */
-#include <linux/wireless.h>
-#endif /* PRIVATE_WE_HEADER */
-
-#if WIRELESS_EXT < 9
-#error "Wireless Extension v9 or newer required :-(\
-Use Wireless Tools v19 or update your kernel headers"
-#endif
-#if WIRELESS_EXT < 11
-#warning "Wireless Extension v11 recommended...\
-You may update your kernel and/or system headers to get the new features..."
-#endif
-
-/****************************** DEBUG ******************************/
-
-
-/************************ CONSTANTS & MACROS ************************/
-
-/* Some usefull constants */
-#define KILO 1e3
-#define MEGA 1e6
-#define GIGA 1e9
-
-/* Backward compatibility for Wireless Extension 9 */
-#ifndef IW_POWER_MODIFIER
-#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
-#define IW_POWER_MIN 0x0001 /* Value is a minimum */
-#define IW_POWER_MAX 0x0002 /* Value is a maximum */
-#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-#endif IW_POWER_MODIFIER
-
-#ifndef IW_ENCODE_NOKEY
-#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not here */
-#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
-#endif IW_ENCODE_NOKEY
-
-/****************************** 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 */
-typedef struct wireless_info
-{
- char name[IFNAMSIZ]; /* Wireless/protocol name */
- int has_nwid;
- iwparam nwid; /* Network ID */
- int has_freq;
- float freq; /* Frequency/channel */
- int has_sens;
- iwparam sens; /* sensitivity */
- 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_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_mode;
- int mode; /* Operation mode */
- 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;
-} wireless_info;
-
-/**************************** PROTOTYPES ****************************/
-/*
- * All the functions in iwcommon.c
- */
-/* ---------------------- SOCKET SUBROUTINES -----------------------*/
-int
- sockets_open(void);
-/* --------------------- WIRELESS SUBROUTINES ----------------------*/
-int
- get_range_info(int skfd,
- char * ifname,
- iwrange * range);
-int
- get_priv_info(int skfd,
- char * ifname,
- iwprivargs * priv);
-/* -------------------- FREQUENCY SUBROUTINES --------------------- */
-void
- float2freq(double in,
- iwfreq * out);
-double
- freq2float(iwfreq * in);
-/* ---------------------- POWER SUBROUTINES ----------------------- */
-int
- dbm2mwatt(int in);
-int
- mwatt2dbm(int in);
-/* -------------------- STATISTICS SUBROUTINES -------------------- */
-void
- print_stats(FILE * stream,
- iwqual * qual,
- iwrange * range,
- int has_range);
-/* --------------------- ENCODING SUBROUTINES --------------------- */
-void
- print_key(FILE * stream,
- unsigned char * key,
- int key_size,
- int key_flags);
-/* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
-void
- print_pm_value(FILE * stream,
- int value,
- int flags);
-void
- print_pm_mode(FILE * stream,
- int flags);
-/* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
-#if WIRELESS_EXT > 10
-void
- print_retry_value(FILE * stream,
- int value,
- int flags);
-#endif
-/* --------------------- ADDRESS SUBROUTINES ---------------------- */
-int
- check_addr_type(int skfd,
- char * ifname);
-char *
- pr_ether(unsigned char *ptr);
-int
- in_ether(char *bufp, struct sockaddr *sap);
-int
- in_inet(char *bufp, struct sockaddr *sap);
-int
- in_addr(int skfd,
- char * ifname,
- char * bufp,
- struct sockaddr *sap);
-/* ----------------------- MISC SUBROUTINES ------------------------ */
-int
- byte_size(int args);
-
-/**************************** VARIABLES ****************************/
-
-#endif /* IWCOMMON_H */
* This file is released under the GPL license.
*/
-#include "iwcommon.h" /* Header */
-
-/**************************** VARIABLES ****************************/
-char * operation_mode[] = { "Auto",
- "Ad-Hoc",
- "Managed",
- "Master",
- "Repeater",
- "Secondary" };
+#include "iwlib.h" /* Header */
/************************* MISC SUBROUTINES **************************/
/*------------------------------------------------------------------*/
/*
- * Read /proc/net/wireless to get the latest statistics
- */
-static int
-iw_getstats(char * ifname,
- iwstats * stats)
-{
- FILE * f=fopen("/proc/net/wireless","r");
- char buf[256];
- char * bp;
- int t;
- if(f==NULL)
- return -1;
- /* Loop on all devices */
- while(fgets(buf,255,f))
- {
- bp=buf;
- while(*bp&&isspace(*bp))
- bp++;
- /* Is it the good device ? */
- if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
- {
- /* Skip ethX: */
- bp=strchr(bp,':');
- bp++;
- /* -- status -- */
- bp = strtok(bp, " ");
- sscanf(bp, "%X", &t);
- stats->status = (unsigned short) t;
- /* -- link quality -- */
- bp = strtok(NULL, " ");
- if(strchr(bp,'.') != NULL)
- stats->qual.updated |= 1;
- sscanf(bp, "%d", &t);
- stats->qual.qual = (unsigned char) t;
- /* -- signal level -- */
- bp = strtok(NULL, " ");
- if(strchr(bp,'.') != NULL)
- stats->qual.updated |= 2;
- sscanf(bp, "%d", &t);
- stats->qual.level = (unsigned char) t;
- /* -- noise level -- */
- bp = strtok(NULL, " ");
- if(strchr(bp,'.') != NULL)
- stats->qual.updated += 4;
- sscanf(bp, "%d", &t);
- stats->qual.noise = (unsigned char) t;
- /* -- discarded packets -- */
- bp = strtok(NULL, " ");
- sscanf(bp, "%d", &stats->discard.nwid);
- bp = strtok(NULL, " ");
- sscanf(bp, "%d", &stats->discard.code);
- bp = strtok(NULL, " ");
- sscanf(bp, "%d", &stats->discard.misc);
- fclose(f);
- return 0;
- }
- }
- fclose(f);
- return -1;
-}
-
-/*------------------------------------------------------------------*/
-/*
* Get wireless informations & config from the device driver
* We will call all the classical wireless ioctl on the driver through
* the socket to know what is supported and to get the settings...
memset((char *) info, 0, sizeof(struct wireless_info));
/* Get wireless name */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
/* If no wireless name : no wireless extensions */
return(-1);
strcpy(info->name, wrq.u.name);
/* Get ranges */
- if(get_range_info(skfd, ifname, &(info->range)) >= 0)
+ if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
info->has_range = 1;
/* Get network ID */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
{
info->has_nwid = 1;
}
/* Get frequency / channel */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWFREQ, &wrq) >= 0)
{
info->has_freq = 1;
- info->freq = freq2float(&(wrq.u.freq));
+ info->freq = iw_freq2float(&(wrq.u.freq));
}
/* Get sensitivity */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWSENS, &wrq) >= 0)
{
info->has_sens = 1;
}
/* Get encryption information */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) info->key;
wrq.u.data.length = 0;
wrq.u.data.flags = 0;
}
/* Get ESSID */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.essid.pointer = (caddr_t) info->essid;
wrq.u.essid.length = 0;
wrq.u.essid.flags = 0;
}
/* Get AP address */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWAP, &wrq) >= 0)
{
info->has_ap_addr = 1;
}
/* Get NickName */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.essid.pointer = (caddr_t) info->nickname;
wrq.u.essid.length = 0;
wrq.u.essid.flags = 0;
info->has_nickname = 1;
/* Get bit rate */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWRATE, &wrq) >= 0)
{
info->has_bitrate = 1;
}
/* Get RTS threshold */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWRTS, &wrq) >= 0)
{
info->has_rts = 1;
}
/* Get fragmentation threshold */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWFRAG, &wrq) >= 0)
{
info->has_frag = 1;
}
/* Get operation mode */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWMODE, &wrq) >= 0)
{
- if((wrq.u.mode < 6) && (wrq.u.mode >= 0))
+ if((wrq.u.mode < IW_NUM_OPER_MODE) && (wrq.u.mode >= 0))
info->has_mode = 1;
info->mode = wrq.u.mode;
}
/* Get Power Management settings */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.power.flags = 0;
if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
{
#if WIRELESS_EXT > 9
/* Get Transmit Power */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWTXPOW, &wrq) >= 0)
{
info->has_txpower = 1;
#if WIRELESS_EXT > 10
/* Get retry limit/lifetime */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
{
info->has_retry = 1;
#endif /* WIRELESS_EXT > 10 */
/* Get stats */
- if(iw_getstats(ifname, &(info->stats)) >= 0)
+ if(iw_get_stats(skfd, ifname, &(info->stats)) >= 0)
{
info->has_stats = 1;
}
display_info(struct wireless_info * info,
char * ifname)
{
+ char buffer[128]; /* Temporary buffer */
+
/* One token is more of less 5 character, 14 tokens per line */
int tokens = 3; /* For name */
printf("ESSID:\"%s\" ", info->essid);
}
else
- printf("ESSID:off ");
+ printf("ESSID:off/any ");
}
/* Display NickName (station name), if any */
/* Display Network ID */
if(info->has_nwid)
{
- /* Note : should display right number of digit according to info
+ /* Note : should display proper number of digit according to info
* in range structure */
if(info->nwid.disabled)
printf("NWID:off/any ");
/* Display the current mode of operation */
if(info->has_mode)
{
- printf("Mode:%s ", operation_mode[info->mode]);
+ printf("Mode:%s ", iw_operation_mode[info->mode]);
tokens +=3;
}
printf("Cell:");
else
printf("Access Point:");
- printf(" %s", pr_ether(info->ap_addr.sa_data));
+ printf(" %s", iw_pr_ether(buffer, info->ap_addr.sa_data));
}
/* Display the currently used/set bit-rate */
/* Convert everything to dBm */
if(info->txpower.flags & IW_TXPOW_MWATT)
- dbm = mwatt2dbm(info->txpower.value);
+ dbm = iw_mwatt2dbm(info->txpower.value);
else
dbm = info->txpower.value;
{
/* Let's check the value and its type */
if(info->retry.flags & IW_RETRY_TYPE)
- print_retry_value(stdout, info->retry.value, info->retry.flags);
+ {
+ iw_print_retry_value(buffer,
+ info->retry.value, info->retry.flags);
+ printf("%s", buffer);
+ }
/* Let's check if nothing (simply on) */
if(info->retry.flags == IW_RETRY_ON)
else
{
/* Display the key */
- print_key(stdout, info->key, info->key_size, info->key_flags);
+ iw_print_key(buffer, info->key, info->key_size, info->key_flags);
+ printf("%s", buffer);
/* Other info... */
if((info->key_flags & IW_ENCODE_INDEX) > 1)
{
/* Let's check the value and its type */
if(info->power.flags & IW_POWER_TYPE)
- print_pm_value(stdout, info->power.value, info->power.flags);
+ {
+ iw_print_pm_value(buffer, info->power.value, info->power.flags);
+ printf("%s", buffer);
+ }
/* Let's check the mode */
- print_pm_mode(stdout, info->power.flags);
+ iw_print_pm_mode(buffer, info->power.flags);
+ printf("%s", buffer);
/* Let's check if nothing (simply on) */
if(info->power.flags == IW_POWER_ON)
if(info->has_stats)
{
info->stats.qual.updated = 0x0; /* Not that reliable, disable */
- printf("Link ");
- print_stats(stdout, &info->stats.qual, &info->range, info->has_range);
+ iw_print_stats(buffer, &info->stats.qual, &info->range, info->has_range);
+ printf("Link %s\n", buffer);
+#if WIRELESS_EXT > 11
+ printf(" Rx invalid nwid:%d Rx invalid crypt:%d Rx invalid frag:%d\n Tx excessive retries:%d Invalid misc:%d Missed beacon:%d\n",
+ info->stats.discard.nwid,
+ info->stats.discard.code,
+ info->stats.discard.fragment,
+ info->stats.discard.retries,
+ info->stats.discard.misc,
+ info->stats.miss.beacon);
+#else /* WIRELESS_EXT > 11 */
printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n",
info->stats.discard.nwid,
info->stats.discard.code,
info->stats.discard.misc);
+#endif /* WIRELESS_EXT > 11 */
}
printf("\n");
fprintf(stderr, "SIOCGIWNWID: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.nwid.disabled = 0;
}
else
if(index(args[i], 'M')) freq *= MEGA;
if(index(args[i], 'k')) freq *= KILO;
- float2freq(freq, &(wrq.u.freq));
+ iw_float2freq(freq, &(wrq.u.freq));
if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
{
fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.data.flags &= ~IW_ENCODE_DISABLED; /* Enable */
}
else
}
else
{
- /* Second case : has hexadecimal digits */
- p = buff = malloc(strlen(args[i]) + 1);
+ /* Second case : as hexadecimal digits */
+ buff = malloc(strlen(args[i]) + 1);
+ if(buff == NULL)
+ {
+ fprintf(stderr, "Setting key : Malloc failed (string too long ?)\n");
+ return(-1);
+ }
strcpy(buff, args[i]);
p = strtok(buff, "-:;.,");
- while(p != (char *) NULL)
+ while((p != (char *) NULL) && (k < IW_ENCODING_TOKEN_MAX))
{
if(sscanf(p, "%2X", &temp) != 1)
{
fprintf(stderr, "SIOCGIWESSID: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.essid.flags = 1;
}
else
+ /* Check the size of what the user passed us to avoid
+ * buffer overflows */
if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
{
fprintf(stderr, "ESSID too long (max %d): ``%s''\n",
int temp;
wrq.u.essid.flags = 1;
- strcpy(essid, args[i]);
+ strcpy(essid, args[i]); /* Size checked, all clear */
/* Check for ESSID index */
if(((i+1) < count) &&
iw_usage();
/* Check if we have valid address types */
- if(check_addr_type(skfd, ifname) < 0)
+ if(iw_check_addr_type(skfd, ifname) < 0)
{
fprintf(stderr, "%-8.8s Interface doesn't support MAC & IP addresses\n", ifname);
return(-1);
}
/* Get the address */
- if(in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
+ if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
iw_usage();
if(ioctl(skfd, SIOCSIWAP, &wrq) < 0)
fprintf(stderr, "SIOCGIWRATE: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.bitrate.fixed = 1;
}
else /* Should be a numeric value */
fprintf(stderr, "SIOCGIWRTS: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.rts.fixed = 1;
}
else /* Should be a numeric value */
fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.frag.fixed = 1;
}
else /* Should be a numeric value */
if(sscanf(args[i], "%d", &k) != 1)
{
k = 0;
- while(k < 6 && strncasecmp(args[i], operation_mode[k], 3))
+ while((k < IW_NUM_OPER_MODE) &&
+ strncasecmp(args[i], iw_operation_mode[k], 3))
k++;
}
- if((k > 5) || (k < 0))
+ if((k >= IW_NUM_OPER_MODE) || (k < 0))
iw_usage();
wrq.u.mode = k;
fprintf(stderr, "SIOCGIWPOWER: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.power.disabled = 0;
}
else
iw_usage();
/* Extract range info */
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
memset(&range, 0, sizeof(range));
/* Prepare the request */
fprintf(stderr, "SIOCGIWTXPOW: %s\n", strerror(errno));
return(-1);
}
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.txpower.fixed = 1;
}
else /* Should be a numeric value */
/* Convert */
if(!ismwatt && (range.txpower_capa & IW_TXPOW_MWATT))
{
- power = dbm2mwatt(power);
+ power = iw_dbm2mwatt(power);
wrq.u.data.flags = IW_TXPOW_MWATT;
}
if(ismwatt && !(range.txpower_capa & IW_TXPOW_MWATT))
- power = mwatt2dbm(power);
+ power = iw_mwatt2dbm(power);
wrq.u.bitrate.value = power;
/* Check for an additional argument */
int goterr = 0;
/* Create a channel to the NET kernel. */
- if((skfd = sockets_open()) < 0)
+ if((skfd = iw_sockets_open()) < 0)
{
perror("socket");
exit(-1);
* This file is released under the GPL license.
*/
-#include "iwcommon.h" /* Header */
+#include "iwlib.h" /* Header */
#define FORMAT_DEFAULT 0 /* Nice looking display for the user */
#define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
int j;
/* Get ESSID */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.essid.pointer = (caddr_t) essid;
wrq.u.essid.length = 0;
wrq.u.essid.flags = 0;
struct iwreq wrq;
/* Get network ID */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
return(-1);
* Display an Ethernet address in readable format.
*/
char *
-pr_ether(unsigned char *ptr)
+pr_ether(char * buffer,
+ unsigned char *ptr)
{
- static char buff[64];
-
- sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
- (ptr[0] & 0xFF), (ptr[1] & 0xFF), (ptr[2] & 0xFF),
- (ptr[3] & 0xFF), (ptr[4] & 0xFF), (ptr[5] & 0xFF)
+ sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (ptr[0] & 0xFF), (ptr[1] & 0xFF), (ptr[2] & 0xFF),
+ (ptr[3] & 0xFF), (ptr[4] & 0xFF), (ptr[5] & 0xFF)
);
- return(buff);
+ return(buffer);
}
/*------------------------------------------------------------------*/
int format)
{
struct iwreq wrq;
+ char buffer[64];
/* Get network ID */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)
return(-1);
/* Print */
printf("%-8.8s Access Point: %s\n", ifname,
- pr_ether(wrq.u.ap_addr.sa_data));
+ pr_ether(buffer, wrq.u.ap_addr.sa_data));
return(0);
}
/*
* Wireless Tools
*
- * Jean II - HPLB 97->99 - HPL 99->00
+ * Jean II - HPLB 97->99 - HPL 99->01
*
* Common subroutines to all the wireless tools...
*
* This file is released under the GPL license.
*/
-#include "iwcommon.h" /* Header */
+#include "iwlib.h" /* Header */
+
+/**************************** VARIABLES ****************************/
+
+const char * iw_operation_mode[] = { "Auto",
+ "Ad-Hoc",
+ "Managed",
+ "Master",
+ "Repeater",
+ "Secondary" };
/************************ SOCKET SUBROUTINES *************************/
* will allow us to talk to the driver.
*/
int
-sockets_open(void)
+iw_sockets_open(void)
{
- int ipx_sock = -1; /* IPX socket */
- int ax25_sock = -1; /* AX.25 socket */
- int inet_sock = -1; /* INET socket */
- int ddp_sock = -1; /* Appletalk DDP socket */
-
- inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
- ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
- ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
- ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
- /*
- * Now pick any (exisiting) useful socket family for generic queries
- */
- if(inet_sock!=-1)
- return inet_sock;
- if(ipx_sock!=-1)
- return ipx_sock;
- if(ax25_sock!=-1)
- return ax25_sock;
- /*
- * If this is -1 we have no known network layers and its time to jump.
- */
-
- return ddp_sock;
+ int ipx_sock = -1; /* IPX socket */
+ int ax25_sock = -1; /* AX.25 socket */
+ int inet_sock = -1; /* INET socket */
+ int ddp_sock = -1; /* Appletalk DDP socket */
+
+ /*
+ * Now pick any (exisiting) useful socket family for generic queries
+ * Note : don't open all the socket, only returns when one matches,
+ * all protocols might not be valid.
+ * Workaround by Jim Kaba <jkaba@sarnoff.com>
+ * Note : in 99% of the case, we will just open the inet_sock.
+ * The remaining 1% case are not fully correct...
+ */
+ inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
+ if(inet_sock!=-1)
+ return inet_sock;
+ ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
+ if(ipx_sock!=-1)
+ return ipx_sock;
+ ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
+ if(ax25_sock!=-1)
+ return ax25_sock;
+ ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
+ /*
+ * If this is -1 we have no known network layers and its time to jump.
+ */
+ return ddp_sock;
}
/*********************** WIRELESS SUBROUTINES ************************/
* Get the range information out of the driver
*/
int
-get_range_info(int skfd,
- char * ifname,
- iwrange * range)
+iw_get_range_info(int skfd,
+ char * ifname,
+ iwrange * range)
{
struct iwreq wrq;
char buffer[sizeof(iwrange) * 2]; /* Large enough */
/* Cleanup */
memset(buffer, 0, sizeof(range));
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) buffer;
wrq.u.data.length = 0;
wrq.u.data.flags = 0;
* Get information about what private ioctls are supported by the driver
*/
int
-get_priv_info(int skfd,
- char * ifname,
- iwprivargs * priv)
+iw_get_priv_info(int skfd,
+ char * ifname,
+ iwprivargs * priv)
{
struct iwreq wrq;
/* Ask the driver */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) priv;
wrq.u.data.length = 0;
wrq.u.data.flags = 0;
return(wrq.u.data.length);
}
+/*------------------------------------------------------------------*/
+/*
+ * Get essential wireless config from the device driver
+ * We will call all the classical wireless ioctl on the driver through
+ * the socket to know what is supported and to get the settings...
+ * Note : compare to the version in iwconfig, we extract only
+ * what's *really* needed to configure a device...
+ */
+int
+iw_get_basic_config(int skfd,
+ char * ifname,
+ wireless_config * info)
+{
+ struct iwreq wrq;
+
+ memset((char *) info, 0, sizeof(struct wireless_config));
+
+ /* Get wireless name */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
+ /* If no wireless name : no wireless extensions */
+ return(-1);
+ else
+ strcpy(info->name, wrq.u.name);
+
+ /* Get network ID */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
+ {
+ info->has_nwid = 1;
+ memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
+ }
+
+ /* Get frequency / channel */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(skfd, SIOCGIWFREQ, &wrq) >= 0)
+ {
+ info->has_freq = 1;
+ info->freq = iw_freq2float(&(wrq.u.freq));
+ }
+
+ /* Get encryption information */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ wrq.u.data.pointer = (caddr_t) info->key;
+ wrq.u.data.length = 0;
+ wrq.u.data.flags = 0;
+ if(ioctl(skfd, SIOCGIWENCODE, &wrq) >= 0)
+ {
+ info->has_key = 1;
+ info->key_size = wrq.u.data.length;
+ info->key_flags = wrq.u.data.flags;
+ }
+
+ /* Get ESSID */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ wrq.u.essid.pointer = (caddr_t) info->essid;
+ wrq.u.essid.length = 0;
+ wrq.u.essid.flags = 0;
+ if(ioctl(skfd, SIOCGIWESSID, &wrq) >= 0)
+ {
+ info->has_essid = 1;
+ info->essid_on = wrq.u.data.flags;
+ }
+
+ /* Get operation mode */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(skfd, SIOCGIWMODE, &wrq) >= 0)
+ {
+ if((wrq.u.mode < 6) && (wrq.u.mode >= 0))
+ info->has_mode = 1;
+ info->mode = wrq.u.mode;
+ }
+
+ return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Set essential wireless config in the device driver
+ * We will call all the classical wireless ioctl on the driver through
+ * the socket to know what is supported and to set the settings...
+ * We support only the restricted set as above...
+ */
+int
+iw_set_basic_config(int skfd,
+ char * ifname,
+ wireless_config * info)
+{
+ struct iwreq wrq;
+ int ret = 0;
+
+ /* Get wireless name (check if interface is valid) */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
+ /* If no wireless name : no wireless extensions */
+ return(-2);
+
+ /* Set Network ID, if available (this is for non-802.11 cards) */
+ if(info->has_nwid)
+ {
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ memcpy(&(wrq.u.nwid), &(info->nwid), sizeof(iwparam));
+ wrq.u.nwid.fixed = 1; /* Hum... When in Rome... */
+
+ if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
+ {
+ fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
+ ret = -1;
+ }
+ }
+
+ /* Set frequency / channel */
+ if(info->has_freq)
+ {
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ iw_float2freq(info->freq, &(wrq.u.freq));
+
+ if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
+ {
+ fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
+ ret = -1;
+ }
+ }
+
+ /* Set encryption information */
+ if(info->has_key)
+ {
+ int flags = info->key_flags;
+
+ /* Check if there is a key index */
+ if((flags & IW_ENCODE_INDEX) > 0)
+ {
+ /* Set the index */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ wrq.u.data.pointer = (caddr_t) NULL;
+ wrq.u.data.flags = flags & (IW_ENCODE_INDEX);
+ wrq.u.data.length = 0;
+
+ if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
+ {
+ fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
+ errno, strerror(errno));
+ ret = -1;
+ }
+ }
+
+ /* Mask out index to minimise probability of reject when setting key */
+ flags = flags & (~IW_ENCODE_INDEX);
+
+ /* Set the key itself (set current key in this case) */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ wrq.u.data.pointer = (caddr_t) info->key;
+ wrq.u.data.length = info->key_size;
+ wrq.u.data.flags = flags;
+
+ if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
+ {
+ fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
+ errno, strerror(errno));
+ ret = -1;
+ }
+ }
+
+ /* Set ESSID (extended network), if available */
+ if(info->has_essid)
+ {
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ wrq.u.essid.pointer = (caddr_t) info->essid;
+ wrq.u.essid.length = strlen(info->essid) + 1;
+ wrq.u.data.flags = info->essid_on;
+
+ if(ioctl(skfd, SIOCSIWESSID, &wrq) < 0)
+ {
+ fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
+ ret = -1;
+ }
+ }
+
+ /* Set the current mode of operation */
+ if(info->has_mode)
+ {
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ wrq.u.mode = info->mode;
+
+ if(ioctl(skfd, SIOCSIWMODE, &wrq) < 0)
+ {
+ fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
+ ret = -1;
+ }
+ }
+
+ return(ret);
+}
+
/********************** FREQUENCY SUBROUTINES ***********************/
/*------------------------------------------------------------------*/
* this custom format instead.
*/
void
-float2freq(double in,
- iwfreq * out)
+iw_float2freq(double in,
+ iwfreq * out)
{
out->e = (short) (floor(log10(in)));
if(out->e > 8)
* Convert our internal representation of frequencies to a floating point.
*/
double
-freq2float(iwfreq * in)
+iw_freq2float(iwfreq * in)
{
return ((double) in->m) * pow(10,in->e);
}
* Convert a value in dBm to a value in milliWatt.
*/
int
-dbm2mwatt(int in)
+iw_dbm2mwatt(int in)
{
return((int) (floor(pow(10.0, (((double) in) / 10.0)))));
}
* Convert a value in milliWatt to a value in dBm.
*/
int
-mwatt2dbm(int in)
+iw_mwatt2dbm(int in)
{
return((int) (ceil(10.0 * log10((double) in))));
}
/*------------------------------------------------------------------*/
/*
+ * Read /proc/net/wireless to get the latest statistics
+ */
+int
+iw_get_stats(int skfd,
+ char * ifname,
+ iwstats * stats)
+{
+#if WIRELESS_EXT > 11
+ struct iwreq wrq;
+ wrq.u.data.pointer = (caddr_t) stats;
+ wrq.u.data.length = 0;
+ wrq.u.data.flags = 1; /* Clear updated flag */
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(skfd, SIOCGIWSTATS, &wrq) < 0)
+ return(-1);
+
+ return(0);
+#else /* WIRELESS_EXT > 11 */
+ FILE * f=fopen("/proc/net/wireless","r");
+ char buf[256];
+ char * bp;
+ int t;
+ if(f==NULL)
+ return -1;
+ /* Loop on all devices */
+ while(fgets(buf,255,f))
+ {
+ bp=buf;
+ while(*bp&&isspace(*bp))
+ bp++;
+ /* Is it the good device ? */
+ if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
+ {
+ /* Skip ethX: */
+ bp=strchr(bp,':');
+ bp++;
+ /* -- status -- */
+ bp = strtok(bp, " ");
+ sscanf(bp, "%X", &t);
+ stats->status = (unsigned short) t;
+ /* -- link quality -- */
+ bp = strtok(NULL, " ");
+ if(strchr(bp,'.') != NULL)
+ stats->qual.updated |= 1;
+ sscanf(bp, "%d", &t);
+ stats->qual.qual = (unsigned char) t;
+ /* -- signal level -- */
+ bp = strtok(NULL, " ");
+ if(strchr(bp,'.') != NULL)
+ stats->qual.updated |= 2;
+ sscanf(bp, "%d", &t);
+ stats->qual.level = (unsigned char) t;
+ /* -- noise level -- */
+ bp = strtok(NULL, " ");
+ if(strchr(bp,'.') != NULL)
+ stats->qual.updated += 4;
+ sscanf(bp, "%d", &t);
+ stats->qual.noise = (unsigned char) t;
+ /* -- discarded packets -- */
+ bp = strtok(NULL, " ");
+ sscanf(bp, "%d", &stats->discard.nwid);
+ bp = strtok(NULL, " ");
+ sscanf(bp, "%d", &stats->discard.code);
+ bp = strtok(NULL, " ");
+ sscanf(bp, "%d", &stats->discard.misc);
+ fclose(f);
+ return 0;
+ }
+ }
+ fclose(f);
+ return -1;
+#endif /* WIRELESS_EXT > 11 */
+}
+
+/*------------------------------------------------------------------*/
+/*
* Output the link statistics, taking care of formating
*/
void
-print_stats(FILE * stream,
- iwqual * qual,
- iwrange * range,
- int has_range)
+iw_print_stats(char * buffer,
+ iwqual * qual,
+ iwrange * range,
+ int has_range)
{
/* Just do it */
if(has_range && (qual->level != 0))
if(qual->level > range->max_qual.level)
{
/* Statistics are in dBm (absolute power measurement) */
- fprintf(stream,
- "Quality:%d/%d Signal level:%d dBm Noise level:%d dBm%s\n",
+ sprintf(buffer,
+ "Quality:%d/%d Signal level:%d dBm Noise level:%d dBm%s",
qual->qual, range->max_qual.qual,
qual->level - 0x100, qual->noise - 0x100,
(qual->updated & 0x7) ? " (updated)" : "");
else
{
/* Statistics are relative values (0 -> max) */
- fprintf(stream,
- "Quality:%d/%d Signal level:%d/%d Noise level:%d/%d%s\n",
+ sprintf(buffer,
+ "Quality:%d/%d Signal level:%d/%d Noise level:%d/%d%s",
qual->qual, range->max_qual.qual,
qual->level, range->max_qual.level,
qual->noise, range->max_qual.noise,
else
{
/* We can't read the range, so we don't know... */
- fprintf(stream, "Quality:%d Signal level:%d Noise level:%d%s\n",
+ sprintf(buffer, "Quality:%d Signal level:%d Noise level:%d%s",
qual->qual, qual->level, qual->noise,
(qual->updated & 0x7) ? " (updated)" : "");
}
* Output the encoding key, with a nice formating
*/
void
-print_key(FILE * stream,
- unsigned char * key,
- int key_size,
- int key_flags)
+iw_print_key(char * buffer,
+ unsigned char * key,
+ int key_size,
+ int key_flags)
{
int i;
if(key_flags & IW_ENCODE_NOKEY)
{
/* Nope : print dummy */
- printf("**");
+ strcpy(buffer, "**");
+ buffer +=2;
for(i = 1; i < key_size; i++)
{
if((i & 0x1) == 0)
- printf("-");
- printf("**");
+ strcpy(buffer++, "-");
+ strcpy(buffer, "**");
+ buffer +=2;
}
}
else
{
/* Yes : print the key */
- printf("%.2X", key[0]);
+ sprintf(buffer, "%.2X", key[0]);
+ buffer +=2;
for(i = 1; i < key_size; i++)
{
if((i & 0x1) == 0)
- printf("-");
- printf("%.2X", key[i]);
+ strcpy(buffer++, "-");
+ sprintf(buffer, "%.2X", key[i]);
+ buffer +=2;
}
}
}
* Output a power management value with all attributes...
*/
void
-print_pm_value(FILE * stream,
- int value,
- int flags)
+iw_print_pm_value(char * buffer,
+ int value,
+ int flags)
{
/* Modifiers */
if(flags & IW_POWER_MIN)
- fprintf(stream, " min");
+ {
+ strcpy(buffer, " min");
+ buffer += 4;
+ }
if(flags & IW_POWER_MAX)
- fprintf(stream, " max");
+ {
+ strcpy(buffer, " max");
+ buffer += 4;
+ }
/* Type */
if(flags & IW_POWER_TIMEOUT)
- fprintf(stream, " timeout:");
+ {
+ strcpy(buffer, " timeout:");
+ buffer += 9;
+ }
else
- fprintf(stream, " period:");
+ {
+ strcpy(buffer, " period:");
+ buffer += 8;
+ }
/* Display value without units */
if(flags & IW_POWER_RELATIVE)
- fprintf(stream, "%g ", ((double) value) / MEGA);
+ sprintf(buffer, "%g ", ((double) value) / MEGA);
else
{
/* Display value with units */
if(value >= (int) MEGA)
- fprintf(stream, "%gs ", ((double) value) / MEGA);
+ sprintf(buffer, "%gs ", ((double) value) / MEGA);
else
if(value >= (int) KILO)
- fprintf(stream, "%gms ", ((double) value) / KILO);
+ sprintf(buffer, "%gms ", ((double) value) / KILO);
else
- fprintf(stream, "%dus ", value);
+ sprintf(buffer, "%dus ", value);
}
}
* Output a power management mode
*/
void
-print_pm_mode(FILE * stream,
- int flags)
+iw_print_pm_mode(char * buffer,
+ int flags)
{
/* Print the proper mode... */
switch(flags & IW_POWER_MODE)
{
case IW_POWER_UNICAST_R:
- fprintf(stream, " mode:Unicast only received");
+ strcpy(buffer, " mode:Unicast only received");
break;
case IW_POWER_MULTICAST_R:
- fprintf(stream, " mode:Multicast only received");
+ strcpy(buffer, " mode:Multicast only received");
break;
case IW_POWER_ALL_R:
- fprintf(stream, " mode:All packets received");
+ strcpy(buffer, " mode:All packets received");
break;
case IW_POWER_FORCE_S:
- fprintf(stream, " mode:Force sending");
+ strcpy(buffer, " mode:Force sending");
break;
case IW_POWER_REPEATER:
- fprintf(stream, " mode:Repeat multicasts");
+ strcpy(buffer, " mode:Repeat multicasts");
break;
default:
}
* Output a retry value with all attributes...
*/
void
-print_retry_value(FILE * stream,
- int value,
- int flags)
+iw_print_retry_value(char * buffer,
+ int value,
+ int flags)
{
/* Modifiers */
if(flags & IW_RETRY_MIN)
- fprintf(stream, " min");
+ {
+ strcpy(buffer, " min");
+ buffer += 4;
+ }
if(flags & IW_RETRY_MAX)
- fprintf(stream, " max");
+ {
+ strcpy(buffer, " max");
+ buffer += 4;
+ }
/* Type lifetime of limit */
if(flags & IW_RETRY_LIFETIME)
{
- fprintf(stream, " lifetime:");
+ strcpy(buffer, " lifetime:");
+ buffer += 10;
/* Display value without units */
if(flags & IW_POWER_RELATIVE)
- fprintf(stream, "%g", ((double) value) / MEGA);
+ sprintf(buffer, "%g", ((double) value) / MEGA);
else
{
/* Display value with units */
if(value >= (int) MEGA)
- fprintf(stream, "%gs", ((double) value) / MEGA);
+ sprintf(buffer, "%gs", ((double) value) / MEGA);
else
if(value >= (int) KILO)
- fprintf(stream, "%gms", ((double) value) / KILO);
+ sprintf(buffer, "%gms", ((double) value) / KILO);
else
- fprintf(stream, "%dus", value);
+ sprintf(buffer, "%dus", value);
}
}
else
- fprintf(stream, " limit:%d", value);
+ sprintf(buffer, " limit:%d", value);
}
#endif /* WIRELESS_EXT > 10 */
* Check if interface support the right address types...
*/
int
-check_addr_type(int skfd,
- char * ifname)
+iw_check_addr_type(int skfd,
+ char * ifname)
{
struct ifreq ifr;
/* Get the type of interface address */
- strcpy(ifr.ifr_name, ifname);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if((ioctl(skfd, SIOCGIFADDR, &ifr) < 0) ||
(ifr.ifr_addr.sa_family != AF_INET))
{
#endif
/* Get the type of hardware address */
- strcpy(ifr.ifr_name, ifname);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if((ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) ||
(ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER))
{
* Display an Ethernet address in readable format.
*/
char *
-pr_ether(unsigned char *ptr)
+iw_pr_ether(char * buffer,
+ unsigned char * ptr)
{
- static char buff[64];
-
- sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
- (ptr[0] & 0xFF), (ptr[1] & 0xFF), (ptr[2] & 0xFF),
- (ptr[3] & 0xFF), (ptr[4] & 0xFF), (ptr[5] & 0xFF)
+ sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (ptr[0] & 0xFF), (ptr[1] & 0xFF), (ptr[2] & 0xFF),
+ (ptr[3] & 0xFF), (ptr[4] & 0xFF), (ptr[5] & 0xFF)
);
- return(buff);
+ return(buffer);
}
/*------------------------------------------------------------------*/
* Input an Ethernet address and convert to binary.
*/
int
-in_ether(char *bufp, struct sockaddr *sap)
+iw_in_ether(char *bufp, struct sockaddr *sap)
{
unsigned char *ptr;
char c, *orig;
* Input an Internet address and convert to binary.
*/
int
-in_inet(char *bufp, struct sockaddr *sap)
+iw_in_inet(char *bufp, struct sockaddr *sap)
{
struct hostent *hp;
struct netent *np;
* Input an address and convert to binary.
*/
int
-in_addr(int skfd,
- char * ifname,
- char * bufp,
- struct sockaddr *sap)
+iw_in_addr(int skfd,
+ char * ifname,
+ char * bufp,
+ struct sockaddr *sap)
{
/* Check if it is a hardware or IP address */
if(index(bufp, ':') == NULL)
struct arpreq arp_query;
/* Read interface address */
- if(in_inet(bufp, &if_address) < 0)
+ if(iw_in_inet(bufp, &if_address) < 0)
{
fprintf(stderr, "Invalid interface address %s\n", bufp);
return(-1);
arp_query.arp_flags = 0;
/* The following restrict the search to the interface only */
/* For old kernels which complain, just comment it... */
- strcpy(arp_query.arp_dev, ifname);
+ strncpy(arp_query.arp_dev, ifname, IFNAMSIZ);
if((ioctl(skfd, SIOCGARP, &arp_query) < 0) ||
!(arp_query.arp_flags & ATF_COM))
{
}
else /* If it's an hardware address */
/* Get the hardware address */
- if(in_ether(bufp, sap) < 0)
+ if(iw_in_ether(bufp, sap) < 0)
{
fprintf(stderr, "Invalid hardware address %s\n", bufp);
return(-1);
/*
*/
int
-byte_size(int args)
+iw_byte_size(int args)
{
int ret = args & IW_PRIV_SIZE_MASK;
--- /dev/null
+/*
+ * Wireless Tools
+ *
+ * Jean II - HPLB 97->99 - HPL 99->01
+ *
+ * Common header for the Wireless Extension library...
+ *
+ * This file is released under the GPL license.
+ */
+
+#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 */
+
+/* This is our header selection. Try to hide the mess and the misery :-(
+ * The selection has been moved in the Makefile, here we have only
+ * the ugly part. Don't look, you would go blind ;-) */
+
+#ifdef KLUDGE_HEADERS
+#include <socketbits.h>
+#endif /* KLUDGE_HEADERS */
+
+#if defined(KLUDGE_HEADERS) || defined(GLIBC_HEADERS)
+#include <linux/if_arp.h> /* For ARPHRD_ETHER */
+#include <linux/socket.h> /* For AF_INET & struct sockaddr */
+#include <linux/in.h> /* For struct sockaddr_in */
+#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
+
+#ifdef GLIBC22_HEADERS
+/* Added by Ross G. Miller <Ross_Miller@baylor.edu>, 3/28/01 */
+#include <linux/if_arp.h> /* For ARPHRD_ETHER */
+#include <linux/socket.h> /* For AF_INET & struct sockaddr */
+#include <sys/socket.h>
+#endif /* GLIBC22_HEADERS */
+
+#ifdef LIBC5_HEADERS
+#include <sys/socket.h> /* For AF_INET & struct sockaddr & socket() */
+#include <linux/if_arp.h> /* For ARPHRD_ETHER */
+#include <linux/in.h> /* For struct sockaddr_in */
+#endif /* LIBC5_HEADERS */
+
+#ifdef PRIVATE_WE_HEADER
+/* Private copy of Wireless extensions */
+#include "wireless.h"
+#else /* PRIVATE_WE_HEADER */
+/* System wide Wireless extensions */
+#include <linux/wireless.h>
+#endif /* PRIVATE_WE_HEADER */
+
+#if WIRELESS_EXT < 9
+#error "Wireless Extension v9 or newer required :-(\
+Use Wireless Tools v19 or update your kernel headers"
+#endif
+#if WIRELESS_EXT < 11
+#warning "Wireless Extension v11 recommended...\
+You may update your kernel and/or system headers to get the new features..."
+#endif
+
+/****************************** DEBUG ******************************/
+
+
+/************************ CONSTANTS & MACROS ************************/
+
+/* Some usefull constants */
+#define KILO 1e3
+#define MEGA 1e6
+#define GIGA 1e9
+
+/* Backward compatibility for Wireless Extension 9 */
+#ifndef IW_POWER_MODIFIER
+#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
+#define IW_POWER_MIN 0x0001 /* Value is a minimum */
+#define IW_POWER_MAX 0x0002 /* Value is a maximum */
+#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
+#endif IW_POWER_MODIFIER
+
+#ifndef IW_ENCODE_NOKEY
+#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not here */
+#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
+#endif IW_ENCODE_NOKEY
+
+/****************************** 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 pretty exhaustive... */
+typedef struct wireless_info
+{
+ char name[IFNAMSIZ]; /* Wireless/protocol name */
+ int has_nwid;
+ iwparam nwid; /* Network ID */
+ int has_freq;
+ float freq; /* Frequency/channel */
+ int has_sens;
+ iwparam sens; /* sensitivity */
+ 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_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_mode;
+ int mode; /* Operation mode */
+ 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;
+} wireless_info;
+
+/* 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]; /* Wireless/protocol name */
+ int has_nwid;
+ iwparam nwid; /* Network ID */
+ int has_freq;
+ float freq; /* Frequency/channel */
+ 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;
+
+/**************************** PROTOTYPES ****************************/
+/*
+ * All the functions in iwcommon.c
+ */
+/* ---------------------- SOCKET SUBROUTINES -----------------------*/
+int
+ iw_sockets_open(void);
+/* --------------------- WIRELESS SUBROUTINES ----------------------*/
+int
+ iw_get_range_info(int skfd,
+ char * ifname,
+ iwrange * range);
+int
+ iw_get_priv_info(int skfd,
+ char * ifname,
+ iwprivargs * priv);
+int
+ iw_get_basic_config(int skfd,
+ char * ifname,
+ wireless_config * info);
+int
+ iw_set_basic_config(int skfd,
+ char * ifname,
+ wireless_config * info);
+/* -------------------- FREQUENCY SUBROUTINES --------------------- */
+void
+ iw_float2freq(double in,
+ iwfreq * out);
+double
+ iw_freq2float(iwfreq * in);
+/* ---------------------- POWER SUBROUTINES ----------------------- */
+int
+ iw_dbm2mwatt(int in);
+int
+ iw_mwatt2dbm(int in);
+/* -------------------- STATISTICS SUBROUTINES -------------------- */
+int
+ iw_get_stats(int skfd,
+ char * ifname,
+ iwstats * stats);
+void
+ iw_print_stats(char * buffer,
+ iwqual * qual,
+ iwrange * range,
+ int has_range);
+/* --------------------- ENCODING SUBROUTINES --------------------- */
+void
+ iw_print_key(char * buffer,
+ unsigned char * key,
+ int key_size,
+ int key_flags);
+/* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
+void
+ iw_print_pm_value(char * buffer,
+ int value,
+ int flags);
+void
+ iw_print_pm_mode(char * buffer,
+ int flags);
+/* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
+#if WIRELESS_EXT > 10
+void
+ iw_print_retry_value(char * buffer,
+ int value,
+ int flags);
+#endif
+/* --------------------- ADDRESS SUBROUTINES ---------------------- */
+int
+ iw_check_addr_type(int skfd,
+ char * ifname);
+char *
+ iw_pr_ether(char *buffer, unsigned char *ptr);
+int
+ iw_in_ether(char *bufp, struct sockaddr *sap);
+int
+ iw_in_inet(char *bufp, struct sockaddr *sap);
+int
+ iw_in_addr(int skfd,
+ char * ifname,
+ char * bufp,
+ struct sockaddr * sap);
+/* ----------------------- MISC SUBROUTINES ------------------------ */
+int
+ iw_byte_size(int args);
+
+/**************************** VARIABLES ****************************/
+
+extern const char * iw_operation_mode[];
+#define IW_NUM_OPER_MODE 6
+
+#endif /* IWLIB_H */
* This file is released under the GPL license.
*/
-#include "iwcommon.h" /* Header */
+#include "iwlib.h" /* Header */
/*********************** FREQUENCIES/CHANNELS ***********************/
struct iw_range range;
int k;
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no frequency information.\n\n",
ifname);
else
for(k = 0; k < range.num_frequency; k++)
{
printf("\t Channel %.2d : ", range.freq[k].i);
- freq = freq2float(&(range.freq[k]));
+ freq = iw_freq2float(&(range.freq[k]));
if(freq >= GIGA)
printf("%g GHz\n", freq / GIGA);
else
}
}
-/*------------------------------------------------------------------*/
-/*
- * Get frequency info on all devices and print it on the screen
- */
-static void
-print_freq_devices(int skfd)
-{
- char buff[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i;
-
- /* Get list of active devices */
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
- {
- fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
- return;
- }
- ifr = ifc.ifc_req;
-
- /* Print them */
- for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_freq_info(skfd, ifr->ifr_name);
-}
-
/************************ ACCESS POINT LIST ************************/
/*------------------------------------------------------------------*/
*/
static void
print_ap_info(int skfd,
- char * ifname)
+ char * ifname)
{
struct iwreq wrq;
char buffer[(sizeof(struct iw_quality) +
sizeof(struct sockaddr)) * IW_MAX_AP];
+ char temp[128];
struct sockaddr * hwa;
struct iw_quality * qual;
iwrange range;
qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
/* Check if we have valid address types */
- if(check_addr_type(skfd, ifname) < 0)
+ if(iw_check_addr_type(skfd, ifname) < 0)
{
fprintf(stderr, "%-8.8s Interface doesn't support MAC & IP addresses\n\n", ifname);
return;
}
/* Get range info if we can */
- if(get_range_info(skfd, ifname, &(range)) >= 0)
+ if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
has_range = 1;
/* Display it */
if(has_qual)
{
/* Print stats for this address */
- printf(" %s : ", pr_ether(hwa[i].sa_data));
- print_stats(stdout, &qual[i], &range, has_range);
+ printf(" %s : ", iw_pr_ether(temp, hwa[i].sa_data));
+ iw_print_stats(temp, &qual[i], &range, has_range);
+ printf("%s\n", temp);
}
else
/* Only print the address */
- printf(" %s\n", pr_ether(hwa[i].sa_data));
+ printf(" %s\n", iw_pr_ether(temp, hwa[i].sa_data));
}
printf("\n");
}
-/*------------------------------------------------------------------*/
-/*
- * Get list of AP on all devices and print it on the screen
- */
-static void
-print_ap_devices(int skfd)
-{
- char buff[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i;
-
- /* Get list of active devices */
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
- {
- fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
- return;
- }
- ifr = ifc.ifc_req;
-
- /* Print them */
- for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_ap_info(skfd, ifr->ifr_name);
-}
-
/***************************** BITRATES *****************************/
/*------------------------------------------------------------------*/
int k;
/* Extract range info */
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no bit-rate information.\n\n",
ifname);
else
}
}
-/*------------------------------------------------------------------*/
-/*
- * Get bit-rate info on all devices and print it on the screen
- */
-static void
-print_bitrate_devices(int skfd)
-{
- char buff[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i;
-
- /* Get list of active devices */
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
- {
- fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
- return;
- }
- ifr = ifc.ifc_req;
-
- /* Print them */
- for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_bitrate_info(skfd, ifr->ifr_name);
-}
-
/************************* ENCRYPTION KEYS *************************/
/*------------------------------------------------------------------*/
struct iw_range range;
unsigned char key[IW_ENCODING_TOKEN_MAX];
int k;
+ char buffer[128];
/* Extract range info */
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no encryption keys information.\n\n",
ifname);
else
printf("%d keys available :\n", range.max_encoding_tokens);
for(k = 1; k <= range.max_encoding_tokens; k++)
{
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) key;
wrq.u.data.length = 0;
wrq.u.data.flags = k;
else
{
/* Display the key */
- printf("\t\t[%d]: ", k);
- print_key(stdout, key, wrq.u.data.length, wrq.u.data.flags);
+ iw_print_key(buffer, key, wrq.u.data.length, wrq.u.data.flags);
+ printf("\t\t[%d]: %s", k, buffer);
/* Other info... */
printf(" (%d bits)", wrq.u.data.length * 8);
}
}
/* Print current key and mode */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) key;
wrq.u.data.length = 0;
wrq.u.data.flags = 0; /* Set index to zero to get current */
}
}
-/*------------------------------------------------------------------*/
-/*
- * Get encryption info on all devices and print it on the screen
- */
-static void
-print_keys_devices(int skfd)
-{
- char buff[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i;
-
- /* Get list of active devices */
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
- {
- fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
- return;
- }
- ifr = ifc.ifc_req;
-
- /* Print them */
- for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_keys_info(skfd, ifr->ifr_name);
-}
-
/************************* POWER MANAGEMENT *************************/
/*------------------------------------------------------------------*/
get_pm_value(int skfd,
char * ifname,
struct iwreq * pwrq,
- int flags)
+ int flags,
+ char * buffer)
{
/* Get Another Power Management value */
- strcpy(pwrq->ifr_name, ifname);
+ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
pwrq->u.power.flags = flags;
if(ioctl(skfd, SIOCGIWPOWER, pwrq) >= 0)
{
/* Let's check the value and its type */
if(pwrq->u.power.flags & IW_POWER_TYPE)
{
- printf("\n ");
- print_pm_value(stdout, pwrq->u.power.value, pwrq->u.power.flags);
+ iw_print_pm_value(buffer, pwrq->u.power.value, pwrq->u.power.flags);
+ printf("\n %s", buffer);
}
}
return(pwrq->u.power.flags);
{
struct iwreq wrq;
struct iw_range range;
+ char buffer[128];
/* Extract range info */
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no power management information.\n\n",
ifname);
else
else
printf("Fixed period ; ");
/* Print the range */
- print_pm_value(stdout, range.min_pmp, flags | IW_POWER_MIN);
- printf("\n ");
- print_pm_value(stdout, range.max_pmp, flags | IW_POWER_MAX);
- printf("\n ");
+ iw_print_pm_value(buffer, range.min_pmp, flags | IW_POWER_MIN);
+ printf("%s\n ", buffer);
+ iw_print_pm_value(buffer, range.max_pmp, flags | IW_POWER_MAX);
+ printf("%s\n ", buffer);
}
/* Display min/max timeout availables */
else
printf("Fixed timeout ; ");
/* Print the range */
- print_pm_value(stdout, range.min_pmt, flags | IW_POWER_MIN);
- printf("\n ");
- print_pm_value(stdout, range.max_pmt, flags | IW_POWER_MAX);
- printf("\n ");
+ iw_print_pm_value(buffer, range.min_pmt, flags | IW_POWER_MIN);
+ printf("%s\n ", buffer);
+ iw_print_pm_value(buffer, range.max_pmt, flags | IW_POWER_MAX);
+ printf("%s\n ", buffer);
}
#endif /* WIRELESS_EXT > 9 */
/* Get current Power Management settings */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.power.flags = 0;
if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
{
int pm_mask = 0;
/* Let's check the mode */
- printf("Current");
- print_pm_mode(stdout, flags);
+ iw_print_pm_mode(buffer, flags);
+ printf("Current%s", buffer);
/* Let's check if nothing (simply on) */
if((flags & IW_POWER_MODE) == IW_POWER_ON)
/* Let's check the value and its type */
if(wrq.u.power.flags & IW_POWER_TYPE)
- print_pm_value(stdout, wrq.u.power.value, wrq.u.power.flags);
+ {
+ iw_print_pm_value(buffer,
+ wrq.u.power.value, wrq.u.power.flags);
+ printf("%s", buffer);
+ }
/* If we have been returned a MIN value, ask for the MAX */
if(flags & IW_POWER_MIN)
pm_mask = IW_POWER_MIN;
/* If we have something to ask for... */
if(pm_mask)
- get_pm_value(skfd, ifname, &wrq, pm_mask);
+ get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
#if WIRELESS_EXT > 9
/* And if we have both a period and a timeout, ask the other */
if(pm_mask)
{
int base_mask = pm_mask;
- flags = get_pm_value(skfd, ifname, &wrq, pm_mask);
+ flags = get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
pm_mask = 0;
/* If we have been returned a MIN value, ask for the MAX */
pm_mask = IW_POWER_MIN | base_mask;
/* If we have something to ask for... */
if(pm_mask)
- get_pm_value(skfd, ifname, &wrq, pm_mask);
+ get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
}
#endif /* WIRELESS_EXT > 9 */
}
}
}
-/*------------------------------------------------------------------*/
-/*
- * Get Power Management info on all devices and print it on the screen
- */
-static void
-print_pm_devices(int skfd)
-{
- char buff[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i;
-
- /* Get list of active devices */
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
- {
- fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
- return;
- }
- ifr = ifc.ifc_req;
-
- /* Print them */
- for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_pm_info(skfd, ifr->ifr_name);
-}
-
/************************** TRANSMIT POWER **************************/
/*------------------------------------------------------------------*/
#if WIRELESS_EXT > 9
/* Extract range info */
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no transmit-power information.\n\n",
ifname);
else
{
if(range.txpower_capa & IW_TXPOW_MWATT)
{
- dbm = mwatt2dbm(range.txpower[k]);
+ dbm = iw_mwatt2dbm(range.txpower[k]);
mwatt = range.txpower[k];
}
else
{
dbm = range.txpower[k];
- mwatt = dbm2mwatt(range.txpower[k]);
+ mwatt = iw_dbm2mwatt(range.txpower[k]);
}
printf("\t %d dBm \t(%d mW)\n", dbm, mwatt);
}
#endif /* WIRELESS_EXT > 9 */
}
-/*------------------------------------------------------------------*/
-/*
- * Get tx-power info on all devices and print it on the screen
- */
-static void
-print_txpower_devices(int skfd)
-{
- char buff[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i;
-
- /* Get list of active devices */
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
- {
- fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
- return;
- }
- ifr = ifc.ifc_req;
-
- /* Print them */
- for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_txpower_info(skfd, ifr->ifr_name);
-}
-
/*********************** RETRY LIMIT/LIFETIME ***********************/
#if WIRELESS_EXT > 10
get_retry_value(int skfd,
char * ifname,
struct iwreq * pwrq,
- int flags)
+ int flags,
+ char * buffer)
{
/* Get Another retry value */
- strcpy(pwrq->ifr_name, ifname);
+ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
pwrq->u.retry.flags = flags;
if(ioctl(skfd, SIOCGIWRETRY, pwrq) >= 0)
{
/* Let's check the value and its type */
if(pwrq->u.retry.flags & IW_RETRY_TYPE)
{
- printf("\n ");
- print_retry_value(stdout, pwrq->u.retry.value, pwrq->u.retry.flags);
+ iw_print_retry_value(buffer,
+ pwrq->u.retry.value, pwrq->u.retry.flags);
+ printf("%s\n ", buffer);
}
}
return(pwrq->u.retry.flags);
*/
static void
print_retry_info(int skfd,
- char * ifname)
+ char * ifname)
{
struct iwreq wrq;
struct iw_range range;
+ char buffer[128];
/* Extract range info */
- if(get_range_info(skfd, ifname, &range) < 0)
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no retry limit/lifetime information.\n\n",
ifname);
else
else
printf("Fixed limit ; ");
/* Print the range */
- print_retry_value(stdout, range.min_retry, flags | IW_RETRY_MIN);
- printf("\n ");
- print_retry_value(stdout, range.max_retry, flags | IW_RETRY_MAX);
- printf("\n ");
+ iw_print_retry_value(buffer, range.min_retry, flags | IW_RETRY_MIN);
+ printf("%s\n ", buffer);
+ iw_print_retry_value(buffer, range.max_retry, flags | IW_RETRY_MAX);
+ printf("%s\n ", buffer);
}
/* Display min/max lifetime availables */
else
printf("Fixed lifetime ; ");
/* Print the range */
- print_retry_value(stdout, range.min_r_time, flags | IW_RETRY_MIN);
- printf("\n ");
- print_retry_value(stdout, range.max_r_time, flags | IW_RETRY_MAX);
- printf("\n ");
+ iw_print_retry_value(buffer, range.min_r_time, flags | IW_RETRY_MIN);
+ printf("%s\n ", buffer);
+ iw_print_retry_value(buffer, range.max_r_time, flags | IW_RETRY_MAX);
+ printf("%s\n ", buffer);
}
/* Get current retry settings */
- strcpy(wrq.ifr_name, ifname);
+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.retry.flags = 0;
if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
{
/* Let's check the value and its type */
if(wrq.u.retry.flags & IW_RETRY_TYPE)
- print_retry_value(stdout, wrq.u.retry.value, wrq.u.retry.flags);
+ {
+ iw_print_retry_value(buffer,
+ wrq.u.retry.value, wrq.u.retry.flags);
+ printf("%s", buffer);
+ }
/* If we have been returned a MIN value, ask for the MAX */
if(flags & IW_RETRY_MIN)
retry_mask = IW_RETRY_MIN;
/* If we have something to ask for... */
if(retry_mask)
- get_retry_value(skfd, ifname, &wrq, retry_mask);
+ get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
/* And if we have both a period and a timeout, ask the other */
retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
if(retry_mask)
{
int base_mask = retry_mask;
- flags = get_retry_value(skfd, ifname, &wrq, retry_mask);
+ flags = get_retry_value(skfd, ifname, &wrq, retry_mask,
+ buffer);
retry_mask = 0;
/* If we have been returned a MIN value, ask for the MAX */
retry_mask = IW_RETRY_MIN | base_mask;
/* If we have something to ask for... */
if(retry_mask)
- get_retry_value(skfd, ifname, &wrq, retry_mask);
+ get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
}
}
}
}
}
+#endif /* WIRELESS_EXT > 10 */
+
+/************************* COMMON UTILITIES *************************/
+/*
+ * This section was written by Michael Tokarev <mjt@tls.msk.ru>
+ */
+
/*------------------------------------------------------------------*/
/*
- * Get retry info on all devices and print it on the screen
+ * Enumerate devices and call specified routine
*/
static void
-print_retry_devices(int skfd)
+enum_devices(int skfd, void (*fn)(int skfd, char *ifname))
{
char buff[1024];
struct ifconf ifc;
/* Print them */
for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
- print_retry_info(skfd, ifr->ifr_name);
+ (*fn)(skfd, ifr->ifr_name);
+}
+
+/* command list */
+typedef struct iwlist_entry {
+ const char *cmd;
+ void (*fn)(int skfd, char *ifname);
+} iwlist_cmd;
+
+static const struct iwlist_entry iwlist_cmds[] = {
+ { "frequency", print_freq_info },
+ { "channel", print_freq_info },
+ { "ap", print_ap_info },
+ { "accesspoints", print_ap_info },
+ { "bitrate", print_bitrate_info },
+ { "rate", print_bitrate_info },
+ { "encription", print_keys_info },
+ { "key", print_keys_info },
+ { "power", print_pm_info },
+ { "txpower", print_txpower_info },
+#if WIRELESS_EXT > 10
+ { "retry", print_retry_info },
+#endif
+ { NULL, 0 },
+};
+
+/* Display help */
+static void usage(FILE *f)
+{
+ int i;
+ for(i = 0; iwlist_cmds[i].cmd != NULL; ++i)
+ fprintf(f, "%s [interface] %s\n",
+ i ? " " :
+ "Usage: iwlist",
+ iwlist_cmds[i].cmd);
}
-#endif /* WIRELESS_EXT > 10 */
/******************************* MAIN ********************************/
char ** argv)
{
int skfd = -1; /* generic raw socket desc. */
+ char *dev; /* device name */
+ char *cmd; /* command */
+ int i;
- /* Create a channel to the NET kernel. */
- if((skfd = sockets_open()) < 0)
- {
- perror("socket");
- exit(-1);
- }
-
- /* Help */
- if((argc == 1) || (argc > 3) ||
- (!strncmp(argv[1], "-h", 9)) || (!strcmp(argv[1], "--help")))
- {
- fprintf(stderr, "Usage: iwlist [interface] freq\n");
- fprintf(stderr, " [interface] ap\n");
- fprintf(stderr, " [interface] bitrate\n");
- fprintf(stderr, " [interface] keys\n");
- fprintf(stderr, " [interface] power\n");
- fprintf(stderr, " [interface] txpower\n");
- fprintf(stderr, " [interface] retries\n");
- close(skfd);
- exit(0);
- }
-
- /* Frequency list */
- if((!strncmp(argv[1], "freq", 4)) ||
- (!strncmp(argv[1], "channel", 7)))
- {
- print_freq_devices(skfd);
- close(skfd);
- exit(0);
- }
-
- /* Access Point list */
- if(!strcasecmp(argv[1], "ap"))
- {
- print_ap_devices(skfd);
- close(skfd);
- exit(0);
- }
-
- /* Bit-rate list */
- if((!strncmp(argv[1], "bit", 3)) ||
- (!strcmp(argv[1], "rate")))
- {
- print_bitrate_devices(skfd);
- close(skfd);
- exit(0);
- }
-
- /* Encryption key list */
- if((!strncmp(argv[1], "enc", 3)) ||
- (!strncmp(argv[1], "key", 3)))
- {
- print_keys_devices(skfd);
- close(skfd);
- exit(0);
- }
-
- /* Power Management list */
- if(!strncmp(argv[1], "power", 3))
- {
- print_pm_devices(skfd);
- close(skfd);
- exit(0);
- }
-
- /* Transmit Power list */
- if(!strncmp(argv[1], "txpower", 3))
- {
- print_txpower_devices(skfd);
- close(skfd);
- exit(0);
- }
-
-#if WIRELESS_EXT > 10
- /* Retry limit/lifetime */
- if(!strncmp(argv[1], "retry", 4))
- {
- print_retry_devices(skfd);
- close(skfd);
- exit(0);
- }
-#endif
-
- /* Special cases take two... */
- /* Frequency list */
- if((!strncmp(argv[2], "freq", 4)) ||
- (!strncmp(argv[2], "channel", 7)))
- {
- print_freq_info(skfd, argv[1]);
- close(skfd);
- exit(0);
- }
-
- /* Access Point list */
- if(!strcasecmp(argv[2], "ap"))
+ if(argc == 1 || argc > 3)
{
- print_ap_info(skfd, argv[1]);
- close(skfd);
- exit(0);
+ usage(stderr);
+ return 1;
}
-
- /* Bit-rate list */
- if((!strncmp(argv[2], "bit", 3)) ||
- (!strcmp(argv[2], "rate")))
+ if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
{
- print_bitrate_info(skfd, argv[1]);
- close(skfd);
- exit(0);
+ usage(stdout);
+ return 0;
}
-
- /* Encryption key list */
- if((!strncmp(argv[2], "enc", 3)) ||
- (!strncmp(argv[2], "key", 3)))
+ if (argc == 2)
{
- print_keys_info(skfd, argv[1]);
- close(skfd);
- exit(0);
+ cmd = argv[1];
+ dev = NULL;
}
-
- /* Power Management list */
- if(!strncmp(argv[2], "power", 3))
+ else
{
- print_pm_info(skfd, argv[1]);
- close(skfd);
- exit(0);
- }
+ cmd = argv[2];
+ dev = argv[1];
+ }
+
+ /* find a command */
+ {
+ int found = -1, ambig = 0;
+ int len = strlen(cmd);
+ for(i = 0; iwlist_cmds[i].cmd != NULL; ++i)
+ {
+ if (strncasecmp(iwlist_cmds[i].cmd, cmd, len) != 0)
+ continue;
+ if (len == strlen(iwlist_cmds[i].cmd)) /* exact match */
+ {
+ found = i;
+ ambig = 0;
+ break;
+ }
+ if (found < 0)
+ found = i;
+ else if (iwlist_cmds[i].fn != iwlist_cmds[found].fn)
+ ambig = 1;
+ }
+ if (found < 0)
+ {
+ fprintf(stderr, "iwlist: unknown command `%s'\n", cmd);
+ return 1;
+ }
+ if (ambig)
+ {
+ fprintf(stderr, "iwlist: command `%s' is ambiguous\n", cmd);
+ return 1;
+ }
+ i = found;
+ }
- /* Transmit Power list */
- if(!strncmp(argv[2], "txpower", 3))
+ /* Create a channel to the NET kernel. */
+ if((skfd = iw_sockets_open()) < 0)
{
- print_txpower_info(skfd, argv[1]);
- close(skfd);
- exit(0);
+ perror("socket");
+ return -1;
}
-#if WIRELESS_EXT > 10
- /* Retry limit/lifetime */
- if(!strncmp(argv[2], "retry", 4))
- {
- print_retry_info(skfd, argv[1]);
- close(skfd);
- exit(0);
- }
-#endif
+ /* do the actual work */
+ if (dev)
+ (*iwlist_cmds[i].fn)(skfd, dev);
+ else
+ enum_devices(skfd, iwlist_cmds[i].fn);
/* Close the socket. */
close(skfd);
- return(1);
+ return 0;
}
* This file is released under the GPL license.
*/
-#include "iwcommon.h" /* Header */
+#include "iwlib.h" /* Header */
/************************* MISC SUBROUTINES **************************/
fprintf(stderr, "Usage: iwpriv interface [private-command [private-arguments]]\n");
fprintf(stderr, " interface [roam {on|off}]\n");
fprintf(stderr, " interface [port {ad-hoc|managed|N}]\n");
- exit(1);
}
/************************ GENERIC FUNCTIONS *************************/
int k;
iwprivargs priv[16];
int n;
- char * argtype[] = { " ", "byte", "char", "", "int", "float" };
+ char * argtype[] = { " ", "byte", "char", "", "int ", "float" };
/* Read the private ioctls */
- n = get_priv_info(skfd, ifname, priv);
+ n = iw_get_priv_info(skfd, ifname, priv);
/* Is there any ? */
if(n <= 0)
int number;
/* Read the private ioctls */
- number = get_priv_info(skfd, ifname, priv);
+ number = iw_get_priv_info(skfd, ifname, priv);
/* Is there any ? */
if(number <= 0)
strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
- (byte_size(priv[k].set_args) < IFNAMSIZ))
+ (iw_byte_size(priv[k].set_args) < IFNAMSIZ))
memcpy(wrq.u.name, buffer, IFNAMSIZ);
else
{
printf("%-8.8s %s:", ifname, priv[k].name);
if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
- (byte_size(priv[k].get_args) < IFNAMSIZ))
+ (iw_byte_size(priv[k].get_args) < IFNAMSIZ))
{
memcpy(buffer, wrq.u.name, IFNAMSIZ);
n = priv[k].get_args & IW_PRIV_SIZE_MASK;
change roam states */
/* Read the private ioctls */
- number = get_priv_info(skfd, ifname, priv);
+ number = iw_get_priv_info(skfd, ifname, priv);
/* Is there any ? */
if(number <= 0)
}
if(count != 1)
- iw_usage();
+ {
+ iw_usage();
+ return(-1);
+ }
if(!strcasecmp(args[i], "on"))
{
if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
{
fprintf(stderr, "Roaming support is broken.\n");
- exit(0);
+ return(-1);
}
}
- i++;
- return(i);
+ return(0);
}
/*------------------------------------------------------------------*/
char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
/* Read the private ioctls */
- number = get_priv_info(skfd, ifname, priv);
+ number = iw_get_priv_info(skfd, ifname, priv);
/* Is there any ? */
if(number <= 0)
}
if(count != 1)
- iw_usage();
+ {
+ iw_usage();
+ return(-1);
+ }
/* Read it */
/* As a string... */
else
/* ...or as an integer */
if(sscanf(args[i], "%d", (int *) &ptype) != 1)
- iw_usage();
+ {
+ iw_usage();
+ return(-1);
+ }
k = -1;
while((++k < number) && strcmp(priv[k].name, "sport_type") &&
if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
{
fprintf(stderr, "Invalid port type (or setting not allowed)\n");
- exit(0);
+ return(-1);
}
- i++;
- return(i);
+ return(0);
}
/******************************* MAIN ********************************/
int goterr = 0;
/* Create a channel to the NET kernel. */
- if((skfd = sockets_open()) < 0)
+ if((skfd = iw_sockets_open()) < 0)
{
perror("socket");
- exit(-1);
+ return(-1);
}
/* No argument : show the list of all device + info */
{
print_priv_devices(skfd);
close(skfd);
- exit(0);
+ return(0);
}
/* Special cases take one... */
{
iw_usage();
close(skfd);
- exit(0);
+ return(0);
}
/* The device name must be the first argument */
{
print_priv_info(skfd, argv[1]);
close(skfd);
- exit(0);
+ return(0);
}
/* Special cases take two... */
{
goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);
close(skfd);
- exit(0);
+ return(goterr);
}
/* Port type */
{
goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);
close(skfd);
- exit(0);
+ return(goterr);
}
/* Otherwise, it's a private ioctl */
/* Close the socket. */
close(skfd);
- return(1);
+ return(goterr);
}
* This file is released under the GPL license.
*/
-#include "iwcommon.h" /* Header */
+#include "iwlib.h" /* Header */
/************************* DISPLAY ROUTINES **************************/
struct iwreq wrq;
char buffer[(sizeof(struct iw_quality) +
sizeof(struct sockaddr)) * IW_MAX_SPY];
+ char temp[128];
struct sockaddr hwa[IW_MAX_SPY];
struct iw_quality qual[IW_MAX_SPY];
iwrange range;
/* Check if we have valid address types */
- if(check_addr_type(skfd, ifname) < 0)
+ if(iw_check_addr_type(skfd, ifname) < 0)
{
fprintf(stderr, "%-8.8s Interface doesn't support MAC & IP addresses\n\n", ifname);
return;
}
/* Get range info if we can */
- if(get_range_info(skfd, ifname, &(range)) >= 0)
+ if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
has_range = 1;
/* Display it */
for(i = 0; i < n; i++)
{
/* Print stats for each address */
- printf(" %s : ", pr_ether(hwa[i].sa_data));
- print_stats(stdout, &qual[i], &range, has_range);
+ printf(" %s : ", iw_pr_ether(temp, hwa[i].sa_data));
+ iw_print_stats(temp, &qual[i], &range, has_range);
+ printf("%s\n", temp);
}
+#if WIRELESS_EXT > 11
+ if((n > 0) && (has_range))
+ {
+ iw_print_stats(temp, &range.avg_qual, &range, has_range);
+ printf(" typical/average : %s\n", temp);
+ }
+#endif /* WIRELESS_EXT > 11 */
+
printf("\n");
}
nbr = 0; /* Number of args readen so far */
/* Check if we have valid address types */
- if(check_addr_type(skfd, ifname) < 0)
+ if(iw_check_addr_type(skfd, ifname) < 0)
{
fprintf(stderr, "%-8.8s Interface doesn't support MAC & IP addresses\n", ifname);
return(-1);
/* Read other args on command line */
while((i < count) && (nbr < IW_MAX_SPY))
{
- if(in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
+ if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
continue;
nbr++;
}
if((nbr == 0) && strcmp(args[0], "off"))
{
fprintf(stderr, "No valid addresses found : exiting...\n");
- exit(0);
+ return(-1);
}
/* Check if there is some remaining arguments */
int goterr = 0;
/* Create a channel to the NET kernel. */
- if((skfd = sockets_open()) < 0)
+ if((skfd = iw_sockets_open()) < 0)
{
perror("socket");
- exit(-1);
+ return(-1);
}
/* No argument : show the list of all device + info */
{
print_spy_devices(skfd);
close(skfd);
- exit(0);
+ return(0);
}
/* Special cases take one... */
(!strcmp(argv[1], "--help")))
{
fprintf(stderr, "Usage: iwspy interface [+] [MAC address] [IP address]\n");
- fprintf(stderr, " interface [freq]\n");
- fprintf(stderr, " interface [ap]\n");
close(skfd);
- exit(0);
+ return(0);
}
/* The device name must be the first argument */
{
print_spy_info(skfd, argv[1]);
close(skfd);
- exit(0);
+ return(0);
}
/* Otherwise, it's a list of address to set in the spy list */
/* Close the socket. */
close(skfd);
- return(1);
+ return(goterr);
}
--- /dev/null
+/*
+ * macaddr
+ *
+ * Program to return the MAC address of an Ethernet
+ * adapter. This was written to help configure the
+ * adapter based on the MAC address rather than the
+ * name.
+ *
+ * Version 1.0 Eric Dittman 2001-10-19
+ *
+ * This is released unther the GPL license.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/in.h>
+#include <linux/socket.h>
+#include <linux/if.h>
+
+int main(int argc, char** argv) {
+
+ int devsock;
+ struct ifreq ifbuffer;
+ int i;
+
+ if (argc != 2) {
+ printf("Usage: macaddr interface\n");
+ exit(1);
+ }
+
+ devsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (devsock == -1) {
+ printf("Failed opening socket\n");
+ exit (1);
+ }
+
+ memset(&ifbuffer, 0, sizeof(ifbuffer));
+ strcpy(ifbuffer.ifr_name, argv[1]);
+ if (ioctl(devsock, SIOCGIFHWADDR, &ifbuffer) == -1) {
+ printf("There is no MACADDR for %s\n", argv[1]);
+ exit(1);
+ }
+ close (devsock);
+
+ for (i = 0; i < IFHWADDRLEN; i++)
+ printf("%02X", (unsigned char) ifbuffer.ifr_ifru.ifru_hwaddr.sa_data[i]);
+ printf("\n");
+
+ exit(0);
+
+}
--- /dev/null
+/*
+ * This file define a set of standard wireless extensions
+ *
+ * Version : 11 28.3.01
+ *
+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ */
+
+#ifndef _LINUX_WIRELESS_H
+#define _LINUX_WIRELESS_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Basically, the wireless extensions are for now a set of standard ioctl
+ * call + /proc/net/wireless
+ *
+ * The entry /proc/net/wireless give statistics and information on the
+ * driver.
+ * This is better than having each driver having its entry because
+ * its centralised and we may remove the driver module safely.
+ *
+ * Ioctl are used to configure the driver and issue commands. This is
+ * better than command line options of insmod because we may want to
+ * change dynamically (while the driver is running) some parameters.
+ *
+ * The ioctl mechanimsm are copied from standard devices ioctl.
+ * We have the list of command plus a structure descibing the
+ * data exchanged...
+ * Note that to add these ioctl, I was obliged to modify :
+ * net/core/dev.c (two place + add include)
+ * net/ipv4/af_inet.c (one place + add include)
+ *
+ * /proc/net/wireless is a copy of /proc/net/dev.
+ * We have a structure for data passed from the driver to /proc/net/wireless
+ * Too add this, I've modified :
+ * net/core/dev.c (two other places)
+ * include/linux/netdevice.h (one place)
+ * include/linux/proc_fs.h (one place)
+ *
+ * Do not add here things that are redundant with other mechanisms
+ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
+ * wireless specific.
+ *
+ * These wireless extensions are not magic : each driver has to provide
+ * support for them...
+ *
+ * IMPORTANT NOTE : As everything in the kernel, this is very much a
+ * work in progress. Contact me if you have ideas of improvements...
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <linux/types.h> /* for "caddr_t" et al */
+#include <linux/socket.h> /* for "struct sockaddr" et al */
+#include <linux/if.h> /* for IFNAMSIZ and co... */
+
+/**************************** CONSTANTS ****************************/
+
+/* --------------------------- VERSION --------------------------- */
+/*
+ * This constant is used to know the availability of the wireless
+ * extensions and to know which version of wireless extensions it is
+ * (there is some stuff that will be added in the future...)
+ * I just plan to increment with each new version.
+ */
+#define WIRELESS_EXT 11
+
+/*
+ * Changes :
+ *
+ * V2 to V3
+ * --------
+ * Alan Cox start some incompatibles changes. I've integrated a bit more.
+ * - Encryption renamed to Encode to avoid US regulation problems
+ * - Frequency changed from float to struct to avoid problems on old 386
+ *
+ * V3 to V4
+ * --------
+ * - Add sensitivity
+ *
+ * V4 to V5
+ * --------
+ * - Missing encoding definitions in range
+ * - Access points stuff
+ *
+ * V5 to V6
+ * --------
+ * - 802.11 support (ESSID ioctls)
+ *
+ * V6 to V7
+ * --------
+ * - define IW_ESSID_MAX_SIZE and IW_MAX_AP
+ *
+ * V7 to V8
+ * --------
+ * - Changed my e-mail address
+ * - More 802.11 support (nickname, rate, rts, frag)
+ * - List index in frequencies
+ *
+ * V8 to V9
+ * --------
+ * - Support for 'mode of operation' (ad-hoc, managed...)
+ * - Support for unicast and multicast power saving
+ * - Change encoding to support larger tokens (>64 bits)
+ * - Updated iw_params (disable, flags) and use it for NWID
+ * - Extracted iw_point from iwreq for clarity
+ *
+ * V9 to V10
+ * ---------
+ * - Add PM capability to range structure
+ * - Add PM modifier : MAX/MIN/RELATIVE
+ * - Add encoding option : IW_ENCODE_NOKEY
+ * - Add TxPower ioctls (work like TxRate)
+ *
+ * V10 to V11
+ * ----------
+ * - Add WE version in range (help backward/forward compatibility)
+ * - Add retry ioctls (work like PM)
+ */
+
+/* -------------------------- IOCTL LIST -------------------------- */
+
+/* Basic operations */
+#define SIOCSIWNAME 0x8B00 /* Unused */
+#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
+#define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
+#define SIOCGIWNWID 0x8B03 /* get network id */
+#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
+#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
+#define SIOCSIWMODE 0x8B06 /* set operation mode */
+#define SIOCGIWMODE 0x8B07 /* get operation mode */
+#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */
+#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */
+
+/* Informative stuff */
+#define SIOCSIWRANGE 0x8B0A /* Unused */
+#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */
+#define SIOCSIWPRIV 0x8B0C /* Unused */
+#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
+
+/* Mobile IP support */
+#define SIOCSIWSPY 0x8B10 /* set spy addresses */
+#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
+
+/* Access Point manipulation */
+#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
+#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
+#define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
+
+/* 802.11 specific support */
+#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
+#define SIOCGIWESSID 0x8B1B /* get ESSID */
+#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */
+#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
+/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
+ * within the 'iwreq' structure, so we need to use the 'data' member to
+ * point to a string in user space, like it is done for RANGE...
+ * The "flags" member indicate if the ESSID is active or not (promiscuous).
+ */
+
+/* Other parameters usefull in 802.11 and some other devices */
+#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
+#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */
+#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */
+#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */
+#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */
+#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */
+#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */
+#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */
+#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */
+#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */
+
+/* Encoding stuff (scrambling, hardware security, WEP...) */
+#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */
+#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */
+/* Power saving stuff (power management, unicast and multicast) */
+#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
+#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
+
+/* ------------------------- IOCTL STUFF ------------------------- */
+
+/* The first and the last (range) */
+#define SIOCIWFIRST 0x8B00
+#define SIOCIWLAST 0x8B30
+
+/* Even : get (world access), odd : set (root access) */
+#define IW_IS_SET(cmd) (!((cmd) & 0x1))
+#define IW_IS_GET(cmd) ((cmd) & 0x1)
+
+/* ------------------------- PRIVATE INFO ------------------------- */
+/*
+ * The following is used with SIOCGIWPRIV. It allow a driver to define
+ * the interface (name, type of data) for its private ioctl.
+ * Privates ioctl are SIOCDEVPRIVATE -> SIOCDEVPRIVATE + 0xF
+ */
+
+#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */
+#define IW_PRIV_TYPE_NONE 0x0000
+#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
+#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
+#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
+#define IW_PRIV_TYPE_FLOAT 0x5000
+
+#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */
+
+#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */
+
+/*
+ * Note : if the number of args is fixed and the size < 16 octets,
+ * instead of passing a pointer we will put args in the iwreq struct...
+ */
+
+/* ----------------------- OTHER CONSTANTS ----------------------- */
+
+/* Maximum frequencies in the range struct */
+#define IW_MAX_FREQUENCIES 16
+/* Note : if you have something like 80 frequencies,
+ * don't increase this constant and don't fill the frequency list.
+ * The user will be able to set by channel anyway... */
+
+/* Maximum bit rates in the range struct */
+#define IW_MAX_BITRATES 8
+
+/* Maximum tx powers in the range struct */
+#define IW_MAX_TXPOWER 8
+
+/* Maximum of address that you may set with SPY */
+#define IW_MAX_SPY 8
+
+/* Maximum of address that you may get in the
+ list of access points in range */
+#define IW_MAX_AP 8
+
+/* Maximum size of the ESSID and NICKN strings */
+#define IW_ESSID_MAX_SIZE 32
+
+/* Modes of operation */
+#define IW_MODE_AUTO 0 /* Let the driver decides */
+#define IW_MODE_ADHOC 1 /* Single cell network */
+#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */
+#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
+#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
+#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
+
+/* Maximum number of size of encoding token available
+ * they are listed in the range structure */
+#define IW_MAX_ENCODING_SIZES 8
+
+/* Maximum size of the encoding token in bytes */
+#define IW_ENCODING_TOKEN_MAX 32 /* 256 bits (for now) */
+
+/* Flags for encoding (along with the token) */
+#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
+#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
+#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
+#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
+#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
+#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
+#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
+#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
+
+/* Power management flags available (along with the value, if any) */
+#define IW_POWER_ON 0x0000 /* No details... */
+#define IW_POWER_TYPE 0xF000 /* Type of parameter */
+#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */
+#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */
+#define IW_POWER_MODE 0x0F00 /* Power Management mode */
+#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */
+#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */
+#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */
+#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */
+#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */
+#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
+#define IW_POWER_MIN 0x0001 /* Value is a minimum */
+#define IW_POWER_MAX 0x0002 /* Value is a maximum */
+#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
+
+/* Transmit Power flags available */
+#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
+#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
+
+/* Retry limits and lifetime flags available */
+#define IW_RETRY_ON 0x0000 /* No details... */
+#define IW_RETRY_TYPE 0xF000 /* Type of parameter */
+#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
+#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
+#define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */
+#define IW_RETRY_MIN 0x0001 /* Value is a minimum */
+#define IW_RETRY_MAX 0x0002 /* Value is a maximum */
+#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
+
+/****************************** TYPES ******************************/
+
+/* --------------------------- SUBTYPES --------------------------- */
+/*
+ * Generic format for most parameters that fit in an int
+ */
+struct iw_param
+{
+ __s32 value; /* The value of the parameter itself */
+ __u8 fixed; /* Hardware should not use auto select */
+ __u8 disabled; /* Disable the feature */
+ __u16 flags; /* Various specifc flags (if any) */
+};
+
+/*
+ * For all data larger than 16 octets, we need to use a
+ * pointer to memory alocated in user space.
+ */
+struct iw_point
+{
+ caddr_t pointer; /* Pointer to the data (in user space) */
+ __u16 length; /* number of fields or size in bytes */
+ __u16 flags; /* Optional params */
+};
+
+/*
+ * A frequency
+ * For numbers lower than 10^9, we encode the number in 'm' and
+ * set 'e' to 0
+ * For number greater than 10^9, we divide it by the lowest power
+ * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
+ * The power of 10 is in 'e', the result of the division is in 'm'.
+ */
+struct iw_freq
+{
+ __u32 m; /* Mantissa */
+ __u16 e; /* Exponent */
+ __u8 i; /* List index (when in range struct) */
+};
+
+/*
+ * Quality of the link
+ */
+struct iw_quality
+{
+ __u8 qual; /* link quality (%retries, SNR or better...) */
+ __u8 level; /* signal level */
+ __u8 noise; /* noise level */
+ __u8 updated; /* Flags to know if updated */
+};
+
+/*
+ * Packet discarded in the wireless adapter due to
+ * "wireless" specific problems...
+ */
+struct iw_discarded
+{
+ __u32 nwid; /* Wrong nwid */
+ __u32 code; /* Unable to code/decode */
+ __u32 misc; /* Others cases */
+};
+
+/* ------------------------ WIRELESS STATS ------------------------ */
+/*
+ * Wireless statistics (used for /proc/net/wireless)
+ */
+struct iw_statistics
+{
+ __u16 status; /* Status
+ * - device dependent for now */
+
+ struct iw_quality qual; /* Quality of the link
+ * (instant/mean/max) */
+ struct iw_discarded discard; /* Packet discarded counts */
+};
+
+/* ------------------------ IOCTL REQUEST ------------------------ */
+/*
+ * The structure to exchange data for ioctl.
+ * This structure is the same as 'struct ifreq', but (re)defined for
+ * convenience...
+ *
+ * Note that it should fit on the same memory footprint !
+ * You should check this when increasing the above structures (16 octets)
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ */
+struct iwreq
+{
+ union
+ {
+ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
+ } ifr_ifrn;
+
+ /* Data part */
+ union
+ {
+ /* Config - generic */
+ char name[IFNAMSIZ];
+ /* Name : used to verify the presence of wireless extensions.
+ * Name of the protocol/provider... */
+
+ struct iw_point essid; /* Extended network name */
+ struct iw_param nwid; /* network id (or domain - the cell) */
+ struct iw_freq freq; /* frequency or channel :
+ * 0-1000 = channel
+ * > 1000 = frequency in Hz */
+
+ struct iw_param sens; /* signal level threshold */
+ struct iw_param bitrate; /* default bit rate */
+ struct iw_param txpower; /* default transmit power */
+ struct iw_param rts; /* RTS threshold threshold */
+ struct iw_param frag; /* Fragmentation threshold */
+ __u32 mode; /* Operation mode */
+ struct iw_param retry; /* Retry limits & lifetime */
+
+ struct iw_point encoding; /* Encoding stuff : tokens */
+ struct iw_param power; /* PM duration/timeout */
+
+ struct sockaddr ap_addr; /* Access point address */
+
+ struct iw_point data; /* Other large parameters */
+ } u;
+};
+
+/* -------------------------- IOCTL DATA -------------------------- */
+/*
+ * For those ioctl which want to exchange mode data that what could
+ * fit in the above structure...
+ */
+
+/*
+ * Range of parameters
+ */
+
+struct iw_range
+{
+ /* Informative stuff (to choose between different interface) */
+ __u32 throughput; /* To give an idea... */
+ /* In theory this value should be the maximum benchmarked
+ * TCP/IP throughput, because with most of these devices the
+ * bit rate is meaningless (overhead an co) to estimate how
+ * fast the connection will go and pick the fastest one.
+ * I suggest people to play with Netperf or any benchmark...
+ */
+
+ /* NWID (or domain id) */
+ __u32 min_nwid; /* Minimal NWID we are able to set */
+ __u32 max_nwid; /* Maximal NWID we are able to set */
+
+ /* Frequency */
+ __u16 num_channels; /* Number of channels [0; num - 1] */
+ __u8 num_frequency; /* Number of entry in the list */
+ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
+ /* Note : this frequency list doesn't need to fit channel numbers */
+
+ /* signal level threshold range */
+ __s32 sensitivity;
+
+ /* Quality of link & SNR stuff */
+ struct iw_quality max_qual; /* Quality of the link */
+
+ /* Rates */
+ __u8 num_bitrates; /* Number of entries in the list */
+ __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */
+
+ /* RTS threshold */
+ __s32 min_rts; /* Minimal RTS threshold */
+ __s32 max_rts; /* Maximal RTS threshold */
+
+ /* Frag threshold */
+ __s32 min_frag; /* Minimal frag threshold */
+ __s32 max_frag; /* Maximal frag threshold */
+
+ /* Power Management duration & timeout */
+ __s32 min_pmp; /* Minimal PM period */
+ __s32 max_pmp; /* Maximal PM period */
+ __s32 min_pmt; /* Minimal PM timeout */
+ __s32 max_pmt; /* Maximal PM timeout */
+ __u16 pmp_flags; /* How to decode max/min PM period */
+ __u16 pmt_flags; /* How to decode max/min PM timeout */
+ __u16 pm_capa; /* What PM options are supported */
+
+ /* Encoder stuff */
+ __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */
+ __u8 num_encoding_sizes; /* Number of entry in the list */
+ __u8 max_encoding_tokens; /* Max number of tokens */
+
+ /* Transmit power */
+ __u16 txpower_capa; /* What options are supported */
+ __u8 num_txpower; /* Number of entries in the list */
+ __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */
+
+ /* Wireless Extension version info */
+ __u8 we_version_compiled; /* Must be WIRELESS_EXT */
+ __u8 we_version_source; /* Last update of source */
+
+ /* Retry limits and lifetime */
+ __u16 retry_capa; /* What retry options are supported */
+ __u16 retry_flags; /* How to decode max/min retry limit */
+ __u16 r_time_flags; /* How to decode max/min retry life */
+ __s32 min_retry; /* Minimal number of retries */
+ __s32 max_retry; /* Maximal number of retries */
+ __s32 min_r_time; /* Minimal retry lifetime */
+ __s32 max_r_time; /* Maximal retry lifetime */
+};
+
+/*
+ * Private ioctl interface information
+ */
+
+struct iw_priv_args
+{
+ __u32 cmd; /* Number of the ioctl to issue */
+ __u16 set_args; /* Type and number of args */
+ __u16 get_args; /* Type and number of args */
+ char name[IFNAMSIZ]; /* Name of the extension */
+};
+
+#endif /* _LINUX_WIRELESS_H */
/*
* This file define a set of standard wireless extensions
*
- * Version : 11 28.3.01
+ * Version : 12 5.10.01
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
*/
* (there is some stuff that will be added in the future...)
* I just plan to increment with each new version.
*/
-#define WIRELESS_EXT 11
+#define WIRELESS_EXT 12
/*
* Changes :
* ----------
* - Add WE version in range (help backward/forward compatibility)
* - Add retry ioctls (work like PM)
+ *
+ * V11 to V12
+ * ----------
+ * - Add SIOCSIWSTATS to get /proc/net/wireless programatically
+ * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
+ * - Add new statistics (frag, retry, beacon)
+ * - Add average quality (for user space calibration)
*/
/* -------------------------- IOCTL LIST -------------------------- */
#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */
#define SIOCSIWPRIV 0x8B0C /* Unused */
#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
+#define SIOCSIWSTATS 0x8B0E /* Unused */
+#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
/* Mobile IP support */
#define SIOCSIWSPY 0x8B10 /* set spy addresses */
* The "flags" member indicate if the ESSID is active or not (promiscuous).
*/
-/* Other parameters usefull in 802.11 and some other devices */
+/* Other parameters useful in 802.11 and some other devices */
#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */
#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */
#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
+/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
+
+/* These 16 ioctl are wireless device private.
+ * Each driver is free to use them for whatever purpose it chooses,
+ * however the driver *must* export the description of those ioctls
+ * with SIOCGIWPRIV and *must* use arguments as defined below.
+ * If you don't follow those rules, DaveM is going to hate you (reason :
+ * it make mixed 32/64bit operation impossible).
+ */
+#define SIOCIWFIRSTPRIV 0x8BE0
+#define SIOCIWLASTPRIV 0x8BFF
+/* Previously, we were using SIOCDEVPRIVATE, but we know have our
+ * separate range because of collisions with other tools such as
+ * 'mii-tool'.
+ * We now have 32 commands, so a bit more space ;-).
+ * Also, all 'odd' commands are only usable by root and don't return the
+ * content of ifr/iwr to user (but you are not obliged to use the set/get
+ * convention, just use every other two command).
+ * And I repeat : you are not obliged to use them with iwspy, but you
+ * must be compliant with it.
+ */
+
/* ------------------------- IOCTL STUFF ------------------------- */
/* The first and the last (range) */
#define SIOCIWFIRST 0x8B00
-#define SIOCIWLAST 0x8B30
+#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
/* Even : get (world access), odd : set (root access) */
#define IW_IS_SET(cmd) (!((cmd) & 0x1))
/*
* The following is used with SIOCGIWPRIV. It allow a driver to define
* the interface (name, type of data) for its private ioctl.
- * Privates ioctl are SIOCDEVPRIVATE -> SIOCDEVPRIVATE + 0xF
+ * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV
*/
#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */
/*
* For all data larger than 16 octets, we need to use a
- * pointer to memory alocated in user space.
+ * pointer to memory allocated in user space.
*/
struct iw_point
{
*/
struct iw_quality
{
- __u8 qual; /* link quality (%retries, SNR or better...) */
- __u8 level; /* signal level */
- __u8 noise; /* noise level */
+ __u8 qual; /* link quality (%retries, SNR,
+ %missed beacons or better...) */
+ __u8 level; /* signal level (dBm) */
+ __u8 noise; /* noise level (dBm) */
__u8 updated; /* Flags to know if updated */
};
/*
* Packet discarded in the wireless adapter due to
* "wireless" specific problems...
+ * Note : the list of counter and statistics in net_device_stats
+ * is already pretty exhaustive, and you should use that first.
+ * This is only additional stats...
*/
struct iw_discarded
{
- __u32 nwid; /* Wrong nwid */
- __u32 code; /* Unable to code/decode */
+ __u32 nwid; /* Rx : Wrong nwid/essid */
+ __u32 code; /* Rx : Unable to code/decode (WEP) */
+ __u32 fragment; /* Rx : Can't perform MAC reassembly */
+ __u32 retries; /* Tx : Max MAC retries num reached */
__u32 misc; /* Others cases */
};
+/*
+ * Packet/Time period missed in the wireless adapter due to
+ * "wireless" specific problems...
+ */
+struct iw_missed
+{
+ __u32 beacon; /* Missed beacons/superframe */
+};
+
/* ------------------------ WIRELESS STATS ------------------------ */
/*
* Wireless statistics (used for /proc/net/wireless)
struct iw_quality qual; /* Quality of the link
* (instant/mean/max) */
struct iw_discarded discard; /* Packet discarded counts */
+ struct iw_missed miss; /* Packet missed counts */
};
/* ------------------------ IOCTL REQUEST ------------------------ */
__s32 max_retry; /* Maximal number of retries */
__s32 min_r_time; /* Minimal retry lifetime */
__s32 max_r_time; /* Maximal retry lifetime */
+
+ /* Average quality of link & SNR */
+ struct iw_quality avg_qual; /* Quality of the link */
+ /* This should contain the average/typical values of the quality
+ * indicator. This should be the threshold between a "good" and
+ * a "bad" link (example : monitor going from green to orange).
+ * Currently, user space apps like quality monitors don't have any
+ * way to calibrate the measurement. With this, they can split
+ * the range between 0 and max_qual in different quality level
+ * (using a geometric subdivision centered on the average).
+ * I expect that people doing the user space apps will feedback
+ * us on which value we need to put in each driver...
+ */
};
/*