Professional Documents
Culture Documents
\
|
+
=
=
1
) (
) ( ) (
100
1
1
k
i
k
i
i Weight
i Weight i Tab
; k = Number of applied values (2)
If the reported value of Y differentiates more than a given threshold from the current Y value, then the
current value will be reported, see (3). The mathematical model of this first algorithm (2), describing
the transition between given SNR values to a cost into STP, is roughly estimated through experiments.
Report if: 35
) (
) ( ) (
100 >
reported Y
current Y reported Y
(3)
The value at position i = 1 in Weight
i
, points at the most recent registered value at Tab
i
.
1
2
3
18
19
Master Thesis Project 2004-12-08 21(52)
Allan Nadhmi Faraj
The SNR value does usually vary between 0-36, which gives us that Y s variation giving these
boundaries does vary between 100-2. The lower the cost we have on a link indicates that the SNR
value for that link is higher, which means that a good link will give us a low cost. If a link goes down
an SNR value of zero is registered.
6.2 Additional algorithm 2
nd
algorithm
Another way of calculating the output Y was performed (i.e. 2
nd
algorithm) and experimental data was
obtained. It is based upon the theories of Shannons formula of a channel capacity. Since the SNR
values in our case vary between 0-36, a relationship is obtained using (4).
) 10 1 ( log
10
2
SNR
bB a STP + + = (4)
A bad SNR indicates a cost of 100, while a good SNR indicates a cost of two. That is the requirements
that I have set, just as the first algorithm (2).
) 10 1 ( log 1
100
100 100
)) 10 1 ( log 1 (
100
) 10 1 ( log
100
) 10 1 ( log 100 0
) 10 1 ( log 0 36
100 100 0
10
max
2
10
max
2
10
max
2
10
max
2
10
max
2
SNR
SNR SNR
SNR
SNR
bB a
B B B
b
bB bB
bB a STP SNR
bB a bB a STP SNR
+
= =
+
=
+
=
+ + =
+ + = = =
= + = = =
Inserting these values (i.e. a and b) into (4) will give us the relationship between a given SNR value to
a cost into STP.
+
+
+
+
+
+
= + + =
)) 10 1 ( log 1 (
) 10 1 ( log 1
100
100
) 10 1 ( log
)) 10 1 ( log 1 (
100
) 10 1 ( log 1
100
100
) 10 1 ( log
10
2
10
max
2
10
2
10
max
2
10
max
2
10
2
SNR
SNR
SNR
SNR SNR
SNR
bB a STP
Master Thesis Project 2004-12-08 22(52)
Allan Nadhmi Faraj
=
|
|
|
|
.
|
\
|
=
|
|
|
.
|
\
|
|
|
|
.
|
\
|
+
+
=
=
=
36
) (
) ( ) (
;
) 10 1 ( log 1
) 10 1 ( log 1
1 100
max
1
1
10
max
2
10
2
2
SNR
i Weight
i Weight i Tab
SNR
Y
k
i
k
i
SNR
SNR
|
|
|
.
|
\
|
|
|
|
.
|
\
|
+
+
=
|
|
|
.
|
\
|
|
|
|
.
|
\
|
+
+
|
|
|
.
|
\
|
+
+
) 10 1 ( log 1
) 10 1 ( log 1
1 100
) 10 1 ( log 1
) 10 1 ( log 1
1 100
) 10 1 ( log 1
) 10 1 ( log 1
100 100
10
max
2
10
2
10
max
2
10
2
10
max
2
10
2
SNR
SNR
SNR
SNR
SNR
SNR
STP
This gives us a new output, Y
2
as shown in (5).
(5)
Experiments as described in the previous chapter where made on both of the algorithms, and
experimental data was obtained. As can be seen from the results in the next chapter, we get a
significant improvement of the networks performance when using the path cost algorithms as
compared to without (i.e. default case). For obtaining and analyzing the data, I need to use the wireless
tools package embedded in the PX30 operating system as mentioned earlier. Since Iwlist is used to
display some information from the wireless network, I therefore modified the Iwlist source code
(written in C) to gather the necessary data in real-time. The new and modified Iwlist, suitably called
Iw_own was developed to do this. Iw_own gathers the data that is to be used, makes some calculations
and inserts the proper cost to the available protocol using either (2) or (5).
Master Thesis Project 2004-12-08 23(52)
Allan Nadhmi Faraj
7 Results and evaluations
On the experiments that have been run, the first algorithm works better than the second. It provides a
high increased performance of the wireless network. This does not mean that the first algorithm is the
best choice to use in all kind of wireless networks. The gains from using these path cost estimation
algorithms do of course depend on the wireless networks that are being set up. In short the obtained
results depend on the emplacement of the five nodes, and changes in the environment. The two
algorithms will be run under the impact of node movement to evaluate their performances under
dynamic topology changes.
As mentioned in chapter five seven different combinations were tried out when moving the
antennas around. We could therefore construct a mobile network by moving the antennas around
instead of moving the actual PX30s. The packet loss values presented in these tables below are the
average values of the packet loss from a node to another of each combination.
7.1 Results with the 1
st
algorithm
The packet loss values presented in these tables below are the average values of the packet loss from a
node to another of each combination. Figure 7.1 shows the average packet loss between each given
nodes when using the first algorithm as compared to without.
Node-2-node 1 2 13 14 15
Average Packet loss, default settings 52% 26% 49% 61%
Average Packet loss using 1
st
algorithm 16% 5% 14% 26%
Table 7.1 Average Packet loss statistics
Experiment with the 1st algorithm
52%
26%
49%
61%
16%
5%
14%
26%
0%
10%
20%
30%
40%
50%
60%
70%
1--> 2 1--> 3 1--> 4 1--> 5
Node-2-Node
P
a
c
k
e
t
l
o
s
s
Average Packet loss, default settings Average Packet loss using 1st algorithm
Figure 7.1 Average packet loss when using the first algorithm as compared to without
Master Thesis Project 2004-12-08 24(52)
Allan Nadhmi Faraj
7.2 Results with the 2
nd
algorithm
The packet loss values presented in this table below are the average values of the packet loss from a
node to another of each combination. The average packet loss when using the second algorithm
(additional algorithm) as compared to without is shown in Figure 7.2.
Node-2-node 12 13 14 15
Average Packet loss, default settings 28% 26% 24% 32%
Average Packet loss, using 2
nd
algorithm 14% 22% 17% 13%
Table 7.2 Average Packet loss statistics
Experiment with the 2nd algorithm
28%
26%
24%
32%
14%
22%
17%
13%
0%
5%
10%
15%
20%
25%
30%
35%
1--> 2 1--> 3 1--> 4 1--> 5
Node-2-Node
P
a
c
k
e
t
l
o
s
s
Average Packet loss, default settings Average Packet loss, using 2nd algorithm
Figure 7.2 Average packet loss when using the first algorithm as compared to without
Master Thesis Project 2004-12-08 25(52)
Allan Nadhmi Faraj
8 Conclusions
8.1 Discussion of the obtained results
Experiments have verified that Quality of Service, from a performance perspective, is needed in
wireless networks. This does however not mean that it is always the best choice depending on what the
network will be used for. Changes due to surrounding circumstances in a mobile network make the
current state information imprecise, which makes the idea of adding QoS to a real challenge. That is
why the focus on routing in wireless networks is only on best effort data traffic, and not about finding
the best optimized/shortest-path route to a destination.
The path cost algorithms presented in this paper does improve the networks reliability and
performance. It does so by choosing the best route based on the Quality of Service constraint among
the possible routes that is computed in the Spanning Tree Protocol. On all experiments that have been
run, the first algorithm works better than the second. The obtained results do of course depend on
changes in the environment as mentioned, and the emplacement of the nodes.
Nodes far away but still within transmitting range to a node are considered as valid, despite the
poor connection. Most of the present routing protocols use the shortest hops path, and by doing so
the good quality links may not be used. The revised algorithm may thus improve the chance that a
better bandwidth route is found between two adjacent nodes.
8.2 Future work
There are several issues that could be subject to further studies. These are just some of them:
An approach is to complement the Spanning Tree Protocol with an Ethernet protocol that uses
the Wireless Distribution System to gather values from other bridges and therefore set a path
cost to them.
Investigate the relationship between given SNR values to a path cost by studying the
behaviour of the packet loss in different scenarios. This is accomplished by study the SNR
values and the packet loss between different n-hop neighbours to each other.
Study the advantages of using the Rapid Spanning Tree Protocol (RSTP; IEEE 802.1W) with
the presented path cost algorithms.
Master Thesis Project 2004-12-08 26(52)
Allan Nadhmi Faraj
9 References
A URL for the reference is provided wherever possible. While all URLs provided below were valid
(and tested) in Aug 2004, URLs can become out of date.
[1] Ad hoc On-Demand Distance Vector (AODV) Routing, http://www.ietf.org/rfc/rfc3561.txt
[2] By Bob OHara and Al Petrick, IEEE 802.11 Handbook A Designers Companion, The
Institute of Electrical and Electronics Engineers, New York, ISBN 0-7381-1855-9.
[3] Cisco Systems
http://www.cisco.com
[4] HostAp driver
http://hostap.epitest.fi/
[5] IEEE, Institute of Electrical and Electronic Engineers
http://www.ieee.org
[6] Internet Engineering Task Force
http://www.ietf.org
[7] James F. Kurose and Keith W. Ross, Computer Networking A Top-Down Approach Featuring
the Internet 2
nd
edition, Addison Wesley Publishing Company, Massachusetts, ISBN 0-201-
97699-4.
[8] Mobile Ad hoc Networking (MANET) Routing Protocol Performance Issues and Evaluation
Considerations, http://www.ietf.org/rfc/rfc2501.txt
[9] Optimized Link State Routing Protocol (OLSR),
http://www.ietf.org/rfc/rfc3626.txt
[10] Part 3: Media Access Control (MAC) Bridges ANSI/IEEE 802.1D,
http://standards.ieee.org./getieee802/
[11] Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY)
Specifications, http://standards.ieee.org/getieee802/802.11.html
[12] Possio AB
http://www.possio.com
[13] Radia Perlman, Interconnections 2
nd
edition Bridges, Routers, Switches, and Internetworking
Protocols, Addison Wesley Publishing Company, Massachusetts, ISBN 0-201-63448-1.
[14] Rich Seifert, The Switch Book, Wiley Computer Publishing, New York, ISBN 0-471-34586-5.
[15] Sean Odom and Hanson Nottingham, CISCO Switching Black Book, the Coriolis Group,
Arizona, ISBN 1-57610-706-X
[16] Wi-Fi Planet
http://www.wi-fiplanet.com/
Master Thesis Project 2004-12-08 27(52)
Allan Nadhmi Faraj
APPENDIX A PX30 pictures
7
A.1 Front picture with shell
A.2 Front picture without shell
A.3 Rear picture
7
http://linuxdevices.com/articles/AT7459336271.html
Master Thesis Project 2004-12-08 28(52)
Allan Nadhmi Faraj
APPENDIX B Manual Reference
8
Page for Iwlist
NAME
iwlist - Get wireless statistics from specific nodes
SYNOPSIS
iwlist interface freq
iwlist interface ap
iwlist interface scan
iwlist interface rate
iwlist interface key
iwlist interface power
iwlist interface txpower
iwlist interface retry
iwlist --help
iwlist --version
DESCRIPTION
Iwlist is used to display some large chunk of information from a wireless network interface that is not displayed
by iwconfig. This is typically list of parameters.
PARAMETERS
Freq/channel
Give the list of available frequencies in the device and the number of defined channels. Please note that usually
the driver returns the total number of channels and only the frequencies available in the present locale, so there is
no one to one mapping between frequencies displayed and channel numbers.
Ap/access point
Give the list of Access Points in range, and optionally the quality of link to them. This feature is obsolete and
now deprecated in favour of scanning support (below), and it will disappear in the future.
Scan [ning]
Give the list of Access Points and Ad-Hoc cells in range, and optionally a whole bunch of information about
them (ESSID, Quality, Frequency, Mode...). The type of information returned depends on what the card support.
Triggering scanning is a privileged operation (root only) and normal users can only read left-over scan results.
By default, the way scanning is done (the scope of the scan) will be impacted by the current setting of the driver.
Also, this command is supposed to take extra arguments to control the scanning behaviour, but this is currently
not implemented.
Rate/bit [rate]
List the bit-rates supported by the device.
Key/enc [ryption]
List the encryption key sizes supported and display all the encryption keys available in the device.
Power
List the various Power Management attributes and modes of the device.
Txpower
List the various Transmit Power available on the device.
Retry
List the transmit retry limits and retry lifetime on the device.
--Version
Display the version of the tools, as well as the recommended and current Wireless Extensions version for the tool
and the various wireless interfaces.
8
http://leaf.sourceforge.net/devel/jnilo/manpages/iwlist.html
Master Thesis Project 2004-12-08 29(52)
Allan Nadhmi Faraj
APPENDIX C Iw_own source code
/*
* Wireless Tools
* Comments in Swedish
*/
#include "iwlib.h"
#include <stdlib.h> /* Header */
#include <ctype.h> /* Header */
#include <sys/time.h>
#include <unistd.h> /* Header */
#include <math.h> /* Header */
#define Antal 20 /* Antal Signalbrus vrden som ska memoreras */
int vikt[Antal]={100,90,81,73,65,59,53,48,43,38,34,31,28,25,22,20,18,16,15,13};
#define Max_WDS 20 /* Antal WDS lnkar som vi kan ha som max */
#define Procent 35 /* Grns fr path cost */
int Tab[Max_WDS][Antal]; /* Reserverad minne fr memorerade vrde */
int TabCount[Max_WDS]; /* Antal vrden som r riktiga eller gller i minnet Tab*/
int Reported[Max_WDS]; /* Sista vrdet som har rapporterats till STP fr varje WDS lnk */
char WDS[Max_WDS][20]; /* Reserverad minne fr alla mac adresser fr WDS lnkarna, som text */
char WDS_text[Max_WDS][20]; /* Reserverad minne fr Namn p alla WDS lnkar t.ex. Wlan0Wds0 */
/*********************** FREQUENCIES/CHANNELS ***********************/
/*------------------------------------------------------------------*/
/*
* Print the number of channels and available frequency for the device
*/
static int
print_freq_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_range range;
double freq;
int k;
int channel;
char buffer[128]; /* Temporary buffer */
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Get list of frequencies / channels */
if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no frequency information.\n\n",
ifname);
else
{
if(range.num_frequency > 0)
{
printf("%-8.8s %d channels in total; available frequencies :\n",
Master Thesis Project 2004-12-08 30(52)
Allan Nadhmi Faraj
ifname, range.num_channels);
/* Print them all */
for(k = 0; k < range.num_frequency; k++)
{
printf(" Channel %.2d : ", range.freq[k].i);
freq = iw_freq2float(&(range.freq[k]));
if(freq >= GIGA)
printf("%g GHz\n", freq / GIGA);
else
if(freq >= MEGA)
printf("%g MHz\n", freq / MEGA);
else
printf("%g kHz\n", freq / KILO);
}
}
else
printf("%-8.8s %d channels\n",
ifname, range.num_channels);
/* Get current frequency / channel and display it */
if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
{
freq = iw_freq2float(&(wrq.u.freq));
iw_print_freq(buffer, freq);
channel = iw_freq_to_channel(freq, &range);
if(channel >= 0)
printf(" Current %s (channel %.2d)\n\n", buffer, channel);
else
printf(" Current %s\n\n", buffer);
}
}
return(0);
}
/************************ ACCESS POINT LIST ************************/
/*
* Note : now that we have scanning support, this is depracted and
* won't survive long. Actually, next version it's out !
*/
/*------------------------------------------------------------------*/
/*
* Display the list of ap addresses and the associated stats
* Exactly the same as the spy list, only with different IOCTL and messages
*/
/*
* FD_print_ap_info r funktionen som hette print_ap_info i iwlist.c
* Funktionen tar reda p information om ntet och skriver ut p skrmen
* Sttet att skriva p skrmen r anpassad till vrt behov
*/
static int
FD_print_ap_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
static struct iwreq wrq;
Master Thesis Project 2004-12-08 31(52)
Allan Nadhmi Faraj
static char buffer[(sizeof(struct iw_quality) +
sizeof(struct sockaddr)) * IW_MAX_AP];
static char temp[128];
static struct sockaddr * hwa;
static struct iw_quality * qual;
static iwrange range;
static int has_range = 0;
static int has_qual = 0;
static int n;
static int i,j;
int w;
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Collect stats */
wrq.u.data.pointer = (caddr_t) buffer;
wrq.u.data.length = IW_MAX_AP;
wrq.u.data.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0)
{
fprintf(stderr, "%-8.8s Interface doesn't have a list of Peers/Access-Points\n\n", ifname);
return(-1);
}
/* Number of addresses */
n = wrq.u.data.length;
has_qual = wrq.u.data.flags;
/* The two lists */
hwa = (struct sockaddr *) buffer;
qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
/* Check if we have valid mac address type */
if(iw_check_mac_addr_type(skfd, ifname) < 0)
{
fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n\n", ifname);
return(-2);
}
/* Get range info if we can */
if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
has_range = 1;
/* Display it
if(n == 0)
printf("%-8.8s No Peers/Access-Point in range\n", ifname);
else
printf("%-8.8s Peers/Access-Points in range:\n", ifname);
*/
/*
* Skiftar vrden i Tab listan fr varje WDS lnk
* sedan nollstller frsta vrdet i Tab listan
*/
for (i=0 ; i < Max_WDS ; ++i) {
for (j=Antal-1 ; j > 0 ; --j)
Tab[i][j] = Tab[i][j-1];
Master Thesis Project 2004-12-08 32(52)
Allan Nadhmi Faraj
Tab[i][0] = 0;
}
/*
* Lser och memorerar nytt signalbrus vrden fr alla lnkar
* och skriver information p skrmen om det behvs.
*/
for(i = 0; i < n; i++) {
if(has_qual) {
/* Skriver statusen fr den hr adressen p skrmen */
printf(" %s : %d - %d = %d\n", iw_pr_ether(temp, hwa[i].sa_data),
qual[i].level - 0x100, qual[i].noise - 0x100,
qual[i].level-qual[i].noise);
/*
* Frsker hitta samma Mac adress i WDS listan,
* skriver informationen p skrmen
* och memorerar vrdet fr respektive WDS lnk i Tab
*/
for (j = 0 ; j < Max_WDS ; ++j){
if (!strcmp (WDS[j], iw_pr_ether(temp, hwa[i].sa_data))){ /* Samma Mac-adress? */
printf ("%d) ",j);
if (qual[i].updated & 0x7) /* Uppdateras lnken? */
Tab[j][0] = qual[i].level-qual[i].noise; /* Memorera signalbrus vrdet som i
frsta positionen i Tab */
else
Tab[j][0] = 0; /* Annars memoreras 0 som
indikerar att uppdatering inte skett */
if (++TabCount[j] >= Antal) --TabCount[j]; /* Antal gllande vrde i Tab kas
med 1 */
printf ("Styrka=%d Reported=%d (%x)\n", /* Skriver p skrmen information
om signalbrus vrdet, */
Tab[j][0], Reported[j], /* Senaste rapporterade vrde i STP, indikator fr
uppdatering fr WDS lnk */
((qual[i].updated&0x7)?1:0));
for (w=0 ; w<Antal-1 ;++w) /* Skriver alla memorerade vrden i Tab fr
respektive WDS lnk */
printf ("%d,",Tab[j][w]);
printf ("%d\n",Tab[j][Antal-1]);
for (w=0 ; w<Antal-1 ;++w) /* Skriver alla memorerade vrden i Tab mult med
respektive vikt */
printf ("%d,",Tab[j][w]*vikt[w]); /* fr respektive WDS lnk */
printf ("%d\n",Tab[j][Antal-1]*vikt[Antal-1]);
j = Max_WDS; /* Avsluta skning efter samma Mac-adress i WDS listan, till nsta
Mac-adress */
}
}
}
else {
/* Only print the address */
printf(" %s\n", iw_pr_ether(temp, hwa[i].sa_data));
return (-1);
}
}
Master Thesis Project 2004-12-08 33(52)
Allan Nadhmi Faraj
printf("____________________________________\n"); /* Markera slutet av utskrift */
return(0);
}
/*
* Sm till stora bokstver
*/
void
Upper (char *s)
{
for ( ; *s != '\0' ; ++s)
*s = toupper (*s);
}
/*
* print_ap_info anropas frn main funktionen
* FD_print_ap_info anropas hrifrn.
*
* print_ap_info och FD_print_ap_info har samma argumenter.
*
* print_ap_info initierar vrde i reserverade minne
* och initierar WDS listan.
*
*/
static int
print_ap_info( int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
char temp[128];
char W_temp[128];
int i,j;
double sum,vikt_sum;
FILE *WDS_list; /* Pekare till filen WDS list*/
/*
* Nollstllning av alla variabler
*/
for (j=0 ; j<Max_WDS ; ++j){
WDS[j][0] = '\0';
WDS_text[j][0] = '\0';
Reported[j] = 0;
for (i=0 ; i<Antal ; ++i) Tab[j][i] = 0;
TabCount[j] = 0;
}
sprintf (temp, "/proc/net/hostap/%s/wds", ifname); /* Namn med skvg till WDS list */
printf ("WDS file = %s\n", temp); /* Skriver ovanstende p skrmen */
WDS_list = fopen (temp, "r"); /* ppnar WDS listan fr lsning */
if (!WDS_list){ /* Om filen inte ppnas, ge felmeddelande och avsluta */
printf ("Can't find WDS list!\n");
return 0;
}
for (j=0 ; !feof (WDS_list) && j<Max_WDS ; ++j) /* Lsa innehllet av WDS listan till slutet av
filen */
{
Master Thesis Project 2004-12-08 34(52)
Allan Nadhmi Faraj
temp[0]= '\0';
fscanf (WDS_list, "%s %s\n", W_temp, temp); /* Lsa Namnet p WDS lnken samt Mac
adressen */
Upper (temp); /* ndra namnet till stora bokstver */
if (temp[0]!= '\0') /* Om lyckad */
{
strcpy (WDS_text[j], W_temp); /* Kopierar namn till WDS_text i minnet vi
har reserverat */
strcpy (WDS[j], temp); /* Kopierar Mac adressen till WDS i minnet
som vi har reserverat */
printf ("WDS_list #%d: %s temp=\"%s\"\n", j, W_temp, temp); /* Skriver namn och
Mac adressen p skrmen */
}
}
fclose (WDS_list); /* Stnger igen filen */
/*
* "Gra jobbet" tills programmet stoppas
*/
for ( ; ; )
{
j = FD_print_ap_info (skfd, ifname, args, count); /* Verkliga anropet till print_ap_info */
if (j != 0) return j; /* Avsluta om ngot blev fel i FD_print_ap_info */
/*
* Gr igenom Tab listan som nu r uppdaterade
* och avgr om det ska rapporteras ett nytt vrde till STP
*/
for (j = 0 ; j<Max_WDS && WDS[j][0]!='\0'; ++j)
{
sum = 0;
for (i = 0 ; i < TabCount[j] ; ++i) /* Summerar alla memorerade vrden fr lnken
multiplicerad med vikten */
sum = sum + Tab[j][i] * vikt[i];
vikt_sum = 0;
for (i = 0 ; i < TabCount[j] ; ++i) /* Ta reda p totala vikten */
vikt_sum += vikt[i];
sum = 100 / (sum / vikt_sum +1); /* Matematiska uttrycket fr frsta algoritmen*/
/* Matematiska uttrycket fr den andra metoden
*
* sum = 100*(1.0 - (1.0 - log10(1.0 + pow(10.0, sum/vikt_sum/10.0)) /log10(2.0)) / (1.0 -
log10(1.0 + pow(10.0, 3.6)) /log10(2.0)));
*/
/*
* Behvs det rapporteras?
*/
if ((Reported[j] == 0) ||
(Reported[j] != 0 && abs(100*(Reported[j]-sum)/Reported[j]) > Procent))
{
/* r det inte samma vrde som redan r inrapporterad? */
if (Reported[j] != sum){
Reported[j] = sum; /* Memorera vrdet som kommer att
rapporteras */
Master Thesis Project 2004-12-08 35(52)
Allan Nadhmi Faraj
printf ("*** Report to STP : %s,%s : %d\n", WDS_text[j], WDS[j],
Reported[j]);
printf ("*** %s %d\n", WDS_text[j], Reported[j]);
/* Gra klart fr anrop till STP */
sprintf (temp, "brctl setpathcost br0 %s %d\n", WDS_text[j],
Reported[j]);
printf ("%s",temp);
/* Anropet till brctl fr rapportering till STP */
system (temp);
}
}
}
usleep(3e6); /* Vnta i tre sekunder innan nsta lsning av ntet */
}
return 0;
}
/***************************** BITRATES *****************************/
/*------------------------------------------------------------------*/
/*
* Print the number of available bitrates for the device
*/
static int
print_bitrate_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_range range;
int k;
char buffer[128];
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Extract range info */
if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no bit-rate information.\n\n",
ifname);
else
{
if((range.num_bitrates > 0) && (range.num_bitrates <= IW_MAX_BITRATES))
{
printf("%-8.8s %d available bit-rates :\n",
ifname, range.num_bitrates);
/* Print them all */
for(k = 0; k < range.num_bitrates; k++)
{
iw_print_bitrate(buffer, range.bitrate[k]);
/* Maybe this should be %10s */
printf("\t %s\n", buffer);
}
}
else
printf("%-8.8s No bit-rates ? Please update driver...\n", ifname);
Master Thesis Project 2004-12-08 36(52)
Allan Nadhmi Faraj
/* Get current bit rate */
if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
{
iw_print_bitrate(buffer, wrq.u.bitrate.value);
printf(" Current Bit Rate%c%s\n\n",
(wrq.u.bitrate.fixed ? '=' : ':'), buffer);
}
}
return(0);
}
/************************* ENCRYPTION KEYS *************************/
/*------------------------------------------------------------------*/
/*
* Print the number of available encryption key for the device
*/
static int
print_keys_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_range range;
unsigned char key[IW_ENCODING_TOKEN_MAX];
int k;
char buffer[128];
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Extract range info */
if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no encryption keys information.\n\n",
ifname);
else
{
printf("%-8.8s ", ifname);
/* Print key sizes */
if((range.num_encoding_sizes > 0) &&
(range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
{
printf("%d key sizes : %d", range.num_encoding_sizes,
range.encoding_size[0] * 8);
/* Print them all */
for(k = 1; k < range.num_encoding_sizes; k++)
printf(", %d", range.encoding_size[k] * 8);
printf("bits\n ");
}
/* Print the keys and associate mode */
printf("%d keys available :\n", range.max_encoding_tokens);
for(k = 1; k <= range.max_encoding_tokens; k++)
{
wrq.u.data.pointer = (caddr_t) key;
wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
wrq.u.data.flags = k;
if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
Master Thesis Project 2004-12-08 37(52)
Allan Nadhmi Faraj
{
fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
break;
}
if((wrq.u.data.flags & IW_ENCODE_DISABLED) ||
(wrq.u.data.length == 0))
printf("\t\t[%d]: off\n", k);
else
{
/* Display the key */
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);
printf("\n");
}
}
/* Print current key and mode */
wrq.u.data.pointer = (caddr_t) key;
wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
wrq.u.data.flags = 0; /* Set index to zero to get current */
if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
{
fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
return(-1);
}
printf(" Current Transmit Key: [%d]\n",
wrq.u.data.flags & IW_ENCODE_INDEX);
if(wrq.u.data.flags & IW_ENCODE_RESTRICTED)
printf(" Security mode:restricted\n");
if(wrq.u.data.flags & IW_ENCODE_OPEN)
printf(" Security mode:open\n");
printf("\n\n");
}
return(0);
}
/************************* POWER MANAGEMENT *************************/
/*------------------------------------------------------------------*/
/*
* Print Power Management info for each device
*/
static inline int
get_pm_value(int skfd,
char * ifname,
struct iwreq * pwrq,
int flags,
char * buffer)
{
/* Get Another Power Management value */
pwrq->u.power.flags = flags;
if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, pwrq) >= 0)
{
/* Let's check the value and its type */
if(pwrq->u.power.flags & IW_POWER_TYPE)
{
Master Thesis Project 2004-12-08 38(52)
Allan Nadhmi Faraj
iw_print_pm_value(buffer, pwrq->u.power.value, pwrq->u.power.flags);
printf("\n %s", buffer);
}
}
return(pwrq->u.power.flags);
}
/*------------------------------------------------------------------*/
/*
* Print Power Management info for each device
*/
static int
print_pm_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_range range;
char buffer[128];
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Extract range info */
if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no power management information.\n\n",
ifname);
else
{
printf("%-8.8s ", ifname);
#if WIRELESS_EXT > 9
/* Display modes availables */
if(range.pm_capa & IW_POWER_MODE)
{
printf("Supported modes :\n ");
if(range.pm_capa & (IW_POWER_UNICAST_R | IW_POWER_MULTICAST_R))
printf("\t\to Receive all packets (unicast & multicast)\n ");
if(range.pm_capa & IW_POWER_UNICAST_R)
printf("\t\to Receive Unicast only (discard multicast)\n ");
if(range.pm_capa & IW_POWER_MULTICAST_R)
printf("\t\to Receive Multicast only (discard unicast)\n ");
if(range.pm_capa & IW_POWER_FORCE_S)
printf("\t\to Force sending using Power Management\n ");
if(range.pm_capa & IW_POWER_REPEATER)
printf("\t\to Repeat multicast\n ");
}
/* Display min/max period availables */
if(range.pmp_flags & IW_POWER_PERIOD)
{
int flags = (range.pmp_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
/* Display if auto or fixed */
if(range.pmp_flags & IW_POWER_MIN)
printf("Auto period ; ");
else
printf("Fixed period ; ");
/* Print the range */
iw_print_pm_value(buffer, range.min_pmp, flags | IW_POWER_MIN);
printf("%s\n ", buffer);
Master Thesis Project 2004-12-08 39(52)
Allan Nadhmi Faraj
iw_print_pm_value(buffer, range.max_pmp, flags | IW_POWER_MAX);
printf("%s\n ", buffer);
}
/* Display min/max timeout availables */
if(range.pmt_flags & IW_POWER_TIMEOUT)
{
int flags = (range.pmt_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
/* Display if auto or fixed */
if(range.pmt_flags & IW_POWER_MIN)
printf("Auto timeout ; ");
else
printf("Fixed timeout ; ");
/* Print the range */
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 */
wrq.u.power.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
{
int flags = wrq.u.power.flags;
/* Is it disabled ? */
if(wrq.u.power.disabled)
printf("Current mode:off\n ");
else
{
int pm_mask = 0;
/* Let's check the mode */
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)
printf("mode:on");
printf("\n ");
/* Let's check the value and its type */
if(wrq.u.power.flags & IW_POWER_TYPE)
{
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_MAX;
/* If we have been returned a MAX value, ask for the MIN */
if(flags & IW_POWER_MAX)
pm_mask = IW_POWER_MIN;
/* If we have something to ask for... */
Master Thesis Project 2004-12-08 40(52)
Allan Nadhmi Faraj
if(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 */
pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
IW_POWER_TYPE));
if(pm_mask)
{
int base_mask = 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 */
if(flags & IW_POWER_MIN)
pm_mask = IW_POWER_MAX | base_mask;
/* If we have been returned a MAX value, ask for the MIN */
if(flags & IW_POWER_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, buffer);
}
#endif /* WIRELESS_EXT > 9 */
}
}
printf("\n");
}
return(0);
}
/************************** TRANSMIT POWER **************************/
/*------------------------------------------------------------------*/
/*
* Print the number of available transmit powers for the device
*/
static int
print_txpower_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_range range;
int dbm;
int mwatt;
int k;
/* Avoid "Unused parameter" warning */
args = args; count = count;
#if WIRELESS_EXT > 9
/* Extract range info */
if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no transmit-power information.\n\n",
ifname);
else
{
Master Thesis Project 2004-12-08 41(52)
Allan Nadhmi Faraj
if((range.num_txpower <= 0) || (range.num_txpower > IW_MAX_TXPOWER))
printf("%-8.8s No transmit-powers ? Please update driver...\n\n", ifname);
else
{
printf("%-8.8s %d available transmit-powers :\n",
ifname, range.num_txpower);
/* Print them all */
for(k = 0; k < range.num_txpower; k++)
{
if(range.txpower_capa & IW_TXPOW_MWATT)
{
dbm = iw_mwatt2dbm(range.txpower[k]);
mwatt = range.txpower[k];
}
else
{
dbm = range.txpower[k];
mwatt = iw_dbm2mwatt(range.txpower[k]);
}
printf("\t %d dBm \t(%d mW)\n", dbm, mwatt);
}
/* Get current Transmit Power */
if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
{
printf(" Current Tx-Power");
/* Disabled ? */
if(wrq.u.txpower.disabled)
printf(":off\n\n");
else
{
/* Fixed ? */
if(wrq.u.txpower.fixed)
printf("=");
else
printf(":");
if(wrq.u.txpower.flags & IW_TXPOW_MWATT)
{
dbm = iw_mwatt2dbm(wrq.u.txpower.value);
mwatt = wrq.u.txpower.value;
}
else
{
dbm = wrq.u.txpower.value;
mwatt = iw_dbm2mwatt(wrq.u.txpower.value);
}
printf("%d dBm \t(%d mW)\n\n", dbm, mwatt);
}
}
}
}
#endif /* WIRELESS_EXT > 9 */
return(0);
}
/*********************** RETRY LIMIT/LIFETIME ***********************/
#if WIRELESS_EXT > 10
/*------------------------------------------------------------------*/
Master Thesis Project 2004-12-08 42(52)
Allan Nadhmi Faraj
/*
* Print one retry value
*/
static inline int
get_retry_value(int skfd,
char * ifname,
struct iwreq * pwrq,
int flags,
char * buffer)
{
/* Get Another retry value */
pwrq->u.retry.flags = flags;
if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, pwrq) >= 0)
{
/* Let's check the value and its type */
if(pwrq->u.retry.flags & IW_RETRY_TYPE)
{
iw_print_retry_value(buffer,
pwrq->u.retry.value, pwrq->u.retry.flags);
printf("%s\n ", buffer);
}
}
return(pwrq->u.retry.flags);
}
/*------------------------------------------------------------------*/
/*
* Print Retry info for each device
*/
static int
print_retry_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_range range;
char buffer[128];
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Extract range info */
if(iw_get_range_info(skfd, ifname, &range) < 0)
fprintf(stderr, "%-8.8s no retry limit/lifetime information.\n\n",
ifname);
else
{
printf("%-8.8s ", ifname);
/* Display min/max limit availables */
if(range.retry_flags & IW_RETRY_LIMIT)
{
int flags = (range.retry_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
/* Display if auto or fixed */
if(range.retry_flags & IW_RETRY_MIN)
printf("Auto limit ; ");
else
printf("Fixed limit ; ");
Master Thesis Project 2004-12-08 43(52)
Allan Nadhmi Faraj
/* Print the range */
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 */
if(range.r_time_flags & IW_RETRY_LIFETIME)
{
int flags = (range.r_time_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
/* Display if auto or fixed */
if(range.r_time_flags & IW_RETRY_MIN)
printf("Auto lifetime ; ");
else
printf("Fixed lifetime ; ");
/* Print the range */
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 */
wrq.u.retry.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
{
int flags = wrq.u.retry.flags;
/* Is it disabled ? */
if(wrq.u.retry.disabled)
printf("Current mode:off\n ");
else
{
int retry_mask = 0;
/* Let's check the mode */
printf("Current mode:on\n ");
/* Let's check the value and its type */
if(wrq.u.retry.flags & IW_RETRY_TYPE)
{
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_MAX;
/* If we have been returned a MAX value, ask for the MIN */
if(flags & IW_RETRY_MAX)
retry_mask = IW_RETRY_MIN;
/* If we have something to ask for... */
if(retry_mask)
get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
/* And if we have both a period and a timeout, ask the other */
Master Thesis Project 2004-12-08 44(52)
Allan Nadhmi Faraj
retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
IW_RETRY_TYPE));
if(retry_mask)
{
int base_mask = 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 */
if(flags & IW_RETRY_MIN)
retry_mask = IW_RETRY_MAX | base_mask;
/* If we have been returned a MAX value, ask for the MIN */
if(flags & IW_RETRY_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, buffer);
}
}
}
printf("\n");
}
return(0);
}
#endif /* WIRELESS_EXT > 10 */
/***************************** SCANNING *****************************/
/*
* This one behave quite differently from the others
*/
#if WIRELESS_EXT > 13
/*------------------------------------------------------------------*/
/*
* Print one element from the scanning results
*/
static inline int
print_scanning_token(struct iw_event * event, /* Extracted token */
int ap_num, /* AP number */
struct iw_range * iwrange, /* Range info */
int has_range)
{
char buffer[128]; /* Temporary buffer */
/* Now, let's decode the event */
switch(event->cmd)
{
case SIOCGIWAP:
printf(" Cell %02d - Address: %s\n", ap_num,
iw_pr_ether(buffer, event->u.ap_addr.sa_data));
ap_num++;
break;
case SIOCGIWNWID:
if(event->u.nwid.disabled)
printf(" NWID:off/any\n");
else
printf(" NWID:%X\n", event->u.nwid.value);
break;
Master Thesis Project 2004-12-08 45(52)
Allan Nadhmi Faraj
case SIOCGIWFREQ:
{
double freq; /* Frequency/channel */
freq = iw_freq2float(&(event->u.freq));
iw_print_freq(buffer, freq);
printf(" %s\n", buffer);
}
break;
case SIOCGIWMODE:
printf(" Mode:%s\n",
iw_operation_mode[event->u.mode]);
break;
case SIOCGIWNAME:
printf(" Protocol:%-1.16s\n", event->u.name);
break;
case SIOCGIWESSID:
{
char essid[IW_ESSID_MAX_SIZE+1];
if((event->u.essid.pointer) && (event->u.essid.length))
memcpy(essid, event->u.essid.pointer, event->u.essid.length);
essid[event->u.essid.length] = '\0';
if(event->u.essid.flags)
{
/* Does it have an ESSID index ? */
if((event->u.essid.flags & IW_ENCODE_INDEX) > 1)
printf(" ESSID:\"%s\" [%d]\n", essid,
(event->u.essid.flags & IW_ENCODE_INDEX));
else
printf(" ESSID:\"%s\"\n", essid);
}
else
printf(" ESSID:off/any\n");
}
break;
case SIOCGIWENCODE:
{
unsigned char key[IW_ENCODING_TOKEN_MAX];
if(event->u.data.pointer)
memcpy(key, event->u.essid.pointer, event->u.data.length);
else
event->u.data.flags |= IW_ENCODE_NOKEY;
printf(" Encryption key:");
if(event->u.data.flags & IW_ENCODE_DISABLED)
printf("off\n");
else
{
/* Display the key */
iw_print_key(buffer, key, event->u.data.length,
event->u.data.flags);
printf("%s", buffer);
/* Other info... */
if((event->u.data.flags & IW_ENCODE_INDEX) > 1)
printf(" [%d]", event->u.data.flags & IW_ENCODE_INDEX);
if(event->u.data.flags & IW_ENCODE_RESTRICTED)
printf(" Security mode:restricted");
if(event->u.data.flags & IW_ENCODE_OPEN)
printf(" Security mode:open");
printf("\n");
Master Thesis Project 2004-12-08 46(52)
Allan Nadhmi Faraj
}
}
break;
case SIOCGIWRATE:
iw_print_bitrate(buffer, event->u.bitrate.value);
printf(" Bit Rate:%s\n", buffer);
break;
case IWEVQUAL:
{
event->u.qual.updated = 0x0; /* Not that reliable, disable */
iw_print_stats(buffer, &event->u.qual, iwrange, has_range);
printf(" %s\n", buffer);
break;
}
#if WIRELESS_EXT > 14
case IWEVCUSTOM:
{
char custom[IW_CUSTOM_MAX+1];
if((event->u.data.pointer) && (event->u.data.length))
memcpy(custom, event->u.data.pointer, event->u.data.length);
custom[event->u.data.length] = '\0';
printf(" Extra:%s\n", custom);
}
break;
#endif /* WIRELESS_EXT > 14 */
default:
printf(" (Unknown Wireless Token 0x%04X)\n",
event->cmd);
} /* switch(event->cmd) */
/* May have changed */
return(ap_num);
}
/*------------------------------------------------------------------*/
/*
* Perform a scanning on one device
*/
static int
print_scanning_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
unsigned char buffer[IW_SCAN_MAX_DATA]; /* Results */
struct timeval tv; /* Select timeout */
int timeout = 5000000; /* 5s */
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Init timeout value -> 250ms*/
tv.tv_sec = 0;
tv.tv_usec = 250000;
/*
* Here we should look at the command line args and set the IW_SCAN_ flags
* properly
Master Thesis Project 2004-12-08 47(52)
Allan Nadhmi Faraj
*/
wrq.u.param.flags = IW_SCAN_DEFAULT;
wrq.u.param.value = 0; /* Later */
/* Initiate Scanning */
if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
{
if(errno != EPERM)
{
fprintf(stderr, "%-8.8s Interface doesn't support scanning : %s\n\n",
ifname, strerror(errno));
return(-1);
}
/* If we don't have the permission to initiate the scan, we may
* still have permission to read left-over results.
* But, don't wait !!! */
#if 0
/* Not cool, it display for non wireless interfaces... */
fprintf(stderr, "%-8.8s (Could not trigger scanning, just reading left-over results)\n", ifname);
#endif
tv.tv_usec = 0;
}
timeout -= tv.tv_usec;
/* Forever */
while(1)
{
fd_set rfds; /* File descriptors for select */
int last_fd; /* Last fd */
int ret;
/* Guess what ? We must re-generate rfds each time */
FD_ZERO(&rfds);
last_fd = -1;
/* In here, add the rtnetlink fd in the list */
/* Wait until something happens */
ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
/* Check if there was an error */
if(ret < 0)
{
if(errno == EAGAIN || errno == EINTR)
continue;
fprintf(stderr, "Unhandled signal - exiting...\n");
return(-1);
}
/* Check if there was a timeout */
if(ret == 0)
{
/* Try to read the results */
wrq.u.data.pointer = buffer;
wrq.u.data.flags = 0;
wrq.u.data.length = sizeof(buffer);
if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
{
/* Check if results not available yet */
Master Thesis Project 2004-12-08 48(52)
Allan Nadhmi Faraj
if(errno == EAGAIN)
{
/* Restart timer for only 100ms*/
tv.tv_sec = 0;
tv.tv_usec = 100000;
timeout -= tv.tv_usec;
if(timeout > 0)
continue; /* Try again later */
}
/* Bad error */
fprintf(stderr, "%-8.8s Failed to read scan data : %s\n\n",
ifname, strerror(errno));
return(-2);
}
else
/* We have the results, go to process them */
break;
}
/* In here, check if event and event type
* if scan event, read results. All errors bad & no reset timeout */
}
if(wrq.u.data.length)
{
struct iw_event iwe;
struct stream_descr stream;
int ap_num = 1;
int ret;
struct iw_range range;
int has_range;
#if 0
/* Debugging code. In theory useless, because it's debugged ;-) */
int i;
printf("Scan result [%02X", buffer[0]);
for(i = 1; i < wrq.u.data.length; i++)
printf(":%02X", buffer[i]);
printf("]\n");
#endif
has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
printf("%-8.8s Scan completed :\n", ifname);
iw_init_event_stream(&stream, buffer, wrq.u.data.length);
do
{
/* Extract an event and print it */
ret = iw_extract_event_stream(&stream, &iwe);
if(ret > 0)
ap_num = print_scanning_token(&iwe, ap_num, &range, has_range);
}
while(ret > 0);
printf("\n");
}
else
printf("%-8.8s No scan results\n", ifname);
return(0);
}
#endif /* WIRELESS_EXT > 13 */
Master Thesis Project 2004-12-08 49(52)
Allan Nadhmi Faraj
/************************* COMMON UTILITIES *************************/
/*
* This section was written by Michael Tokarev <mjt@tls.msk.ru>
* But modified by me ;-)
*/
/* command list */
typedef struct iwlist_entry {
const char *cmd;
iw_enum_handler fn;
int min_count;
int max_count;
} iwlist_cmd;
static const struct iwlist_entry iwlist_cmds[] = {
{ "frequency", print_freq_info, 0, 0 },
{ "channel", print_freq_info, 0, 0 },
{ "ap", print_ap_info, 0, 0 },
{ "accesspoints", print_ap_info, 0, 0 },
{ "peers", print_ap_info, 0, 0 },
{ "bitrate", print_bitrate_info, 0, 0 },
{ "rate", print_bitrate_info, 0, 0 },
{ "encryption", print_keys_info, 0, 0 },
{ "key", print_keys_info, 0, 0 },
{ "power", print_pm_info, 0, 0 },
{ "txpower", print_txpower_info, 0, 0 },
#if WIRELESS_EXT > 10
{ "retry", print_retry_info, 0, 0 },
#endif
#if WIRELESS_EXT > 13
{ "scanning", print_scanning_info, 0, 5 },
#endif
{ NULL, NULL, 0, 0 },
};
/*------------------------------------------------------------------*/
/*
* Find the most appropriate command matching the command line
*/
static inline const iwlist_cmd *
find_command(const char * cmd)
{
const iwlist_cmd * found = NULL;
int ambig = 0;
unsigned int len = strlen(cmd);
int i;
/* Go through all commands */
for(i = 0; iwlist_cmds[i].cmd != NULL; ++i)
{
/* No match -> next one */
if(strncasecmp(iwlist_cmds[i].cmd, cmd, len) != 0)
continue;
/* Exact match -> perfect */
if(len == strlen(iwlist_cmds[i].cmd))
return &iwlist_cmds[i];
Master Thesis Project 2004-12-08 50(52)
Allan Nadhmi Faraj
/* Partial match */
if(found == NULL)
/* First time */
found = &iwlist_cmds[i];
else
/* Another time */
if (iwlist_cmds[i].fn != found->fn)
ambig = 1;
}
if(found == NULL)
{
fprintf(stderr, "iwlist: unknown command `%s'\n", cmd);
return NULL;
}
if(ambig)
{
fprintf(stderr, "iwlist: command `%s' is ambiguous\n", cmd);
return NULL;
}
return found;
}
/*------------------------------------------------------------------*/
/*
* Display help
*/
static void iw_usage(int status)
{
FILE* f = status ? stderr : stdout;
int i;
fprintf(f, "Usage: iwlist [interface] %s\n", iwlist_cmds[0].cmd);
for(i = 1; iwlist_cmds[i].cmd != NULL; ++i)
fprintf(f, " [interface] %s\n", iwlist_cmds[i].cmd);
exit(status);
}
/******************************* MAIN ********************************/
/*------------------------------------------------------------------*/
/*
* The main !
*/
int
main(int argc,
char ** argv)
{
int skfd; /* generic raw socket desc. */
char *dev; /* device name */
char *cmd; /* command */
char **args; /* Command arguments */
int count; /* Number of arguments */
const iwlist_cmd *iwcmd;
if(argc == 1 || argc > 3)
iw_usage(1);
Master Thesis Project 2004-12-08 51(52)
Allan Nadhmi Faraj
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
iw_usage(0);
/* This is also handled slightly differently */
if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))
return(iw_print_version_info("iwlist"));
if (argc == 2)
{
cmd = argv[1];
dev = NULL;
args = NULL;
count = 0;
}
else
{
cmd = argv[2];
dev = argv[1];
args = argv + 3;
count = argc - 3;
}
/* find a command */
iwcmd = find_command(cmd);
if(iwcmd == NULL)
return 1;
/* Check arg numbers */
if(count < iwcmd->min_count)
{
fprintf(stderr, "iwlist: command `%s' needs more arguments\n", cmd);
return 1;
}
if(count > iwcmd->max_count)
{
fprintf(stderr, "iwlist: command `%s' needs fewer arguments\n", cmd);
return 1;
}
/* Create a channel to the NET kernel. */
if((skfd = iw_sockets_open()) < 0)
{
perror("socket");
return -1;
}
/* do the actual work */
if (dev)
(*iwcmd->fn)(skfd, dev, args, count);
else
iw_enum_devices(skfd, iwcmd->fn, args, count);
/* Close the socket. */
close(skfd);
return 0;
}
Master Thesis Project 2004-12-08 52(52)
Allan Nadhmi Faraj
APPENDIX D Bridge Init script
Because of not risking going through the configuration everytime the PX30 make a reboot or if
something goes wrong I have prepared an init script for the setup that consists of standard
configuration.
#Init script
iwpriv wlan0 wds_add 00:02:6F:31:03:E6 (1)
iwpriv wlan0 wds_add 00:02:6F:30:DA:81
iwpriv wlan0 wds_add 00:02:6F:31:03:EA
iwpriv wlan0 wds_add 00:02:6F:07:23:14
brctl addbr br0 (2)
brctl addif br0 wlan0 (3)
brctl addif br0 eth0
brctl addif br0 wlan0wds0 (4)
brctl addif br0 wlan0wds1
brctl addif br0 wlan0wds2
brctl addif br0 wlan0wds3
/etc/rc.d/init.d/rc.firewall (5)
/etc/rc.d/init.d/sshd start (6)
ifconfig wlan0wds0 0.0.0.0 (7)
ifconfig wlan0wds1 0.0.0.0
ifconfig wlan0wds2 0.0.0.0
ifconfig wlan0wds3 0.0.0.0
ifconfig br0 192.168.0.2 (8)
route add -net 0.0.0.0/0 gw 192.168.0.1 br0 (9)
iwconfig wlan0 channel 3 (10)
iwconfig wlan0 enc ************************** (11)
iwconfig wlan0 essid test_allan (12)
hostname Allan1 (13)
exit 0
(1) This command adds new WDS link connections towards a bridge with a certain MAC address
(2) This command creates a logical bridge interface named br0
(3) This command connects each corresponding interface with the bridge br0
(4) We are also interested in enslaving all of the WDS links to this logical bridge br0
(5) Changing the filtering and firewall parameters
(6) Enables SSH connections
(7) Brings the interface up
(8) Assign an IP address to the bridge interface
(9) Creating an entry for the gateway to use in the routing table
(10) Determine which channel to use
(11) Enable encryption in the wireless interface
(12) Creating an essid for the wireless interface
(13) Changing the hostname of the wireless gateway to Allan1