OSDN Git Service

v24
[android-x86/external-wireless-tools.git] / wireless_tools / iwspy.c
1 /*
2  *      Wireless Tools
3  *
4  *              Jean II - HPLB '99
5  *
6  * This tool can manipulate the spy list : add addresses and display stat
7  * You need to link this code against "iwlib.c" and "-lm".
8  *
9  * This file is released under the GPL license.
10  *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
11  */
12
13 #include "iwlib.h"              /* Header */
14
15 /************************* DISPLAY ROUTINES **************************/
16
17 /*------------------------------------------------------------------*/
18 /*
19  * Display the spy list of addresses and the associated stats
20  */
21 static int
22 print_spy_info(int      skfd,
23                char *   ifname,
24                char *   args[],
25                int      count)
26 {
27   struct iwreq          wrq;
28   char          buffer[(sizeof(struct iw_quality) +
29                         sizeof(struct sockaddr)) * IW_MAX_SPY];
30   char          temp[128];
31   struct sockaddr       hwa[IW_MAX_SPY];
32   struct iw_quality     qual[IW_MAX_SPY];
33   iwrange       range;
34   int           has_range = 0;
35   int           n;
36   int           i;
37
38   /* Avoid "Unused parameter" warning */
39   args = args; count = count;
40
41   /* Collect stats */
42   wrq.u.data.pointer = (caddr_t) buffer;
43   wrq.u.data.length = IW_MAX_SPY;
44   wrq.u.data.flags = 0;
45   if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
46     {
47       fprintf(stderr, "%-8.8s  Interface doesn't support wireless statistic collection\n\n", ifname);
48       return(-1);
49     }
50
51   /* Number of addresses */
52   n = wrq.u.data.length;
53
54   /* Check if we have valid mac address type */
55   if(iw_check_mac_addr_type(skfd, ifname) < 0)
56     {
57       fprintf(stderr, "%-8.8s  Interface doesn't support MAC addresses\n\n", ifname);
58       return(-2);
59     }
60
61   /* Get range info if we can */
62   if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
63     has_range = 1;
64
65   /* Display it */
66   if(n == 0)
67     printf("%-8.8s  No statistics to collect\n", ifname);
68   else
69     printf("%-8.8s  Statistics collected:\n", ifname);
70  
71   /* The two lists */
72
73   memcpy(hwa, buffer, n * sizeof(struct sockaddr));
74   memcpy(qual, buffer + n*sizeof(struct sockaddr), n*sizeof(struct iw_quality));
75
76   for(i = 0; i < n; i++)
77     {
78       /* Print stats for each address */
79       printf("    %s : ", iw_pr_ether(temp, hwa[i].sa_data));
80       iw_print_stats(temp, &qual[i], &range, has_range);
81       printf("%s\n", temp);
82     }
83 #if WIRELESS_EXT > 11
84   if((n > 0) && (has_range))
85     {
86       iw_print_stats(temp, &range.avg_qual, &range, has_range);
87       printf("    typical/average   : %s\n", temp);
88     }
89 #endif /* WIRELESS_EXT > 11 */
90
91   printf("\n");
92   return(0);
93 }
94
95 /************************* SETTING ROUTINES **************************/
96
97 /*------------------------------------------------------------------*/
98 /*
99  * Set list of addresses specified on command line in the driver.
100  */
101 static int
102 set_spy_info(int                skfd,           /* The socket */
103              char *             args[],         /* Command line args */
104              int                count,          /* Args count */
105              char *             ifname)         /* Dev name */
106 {
107   struct iwreq          wrq;
108   int                   i;
109   int                   nbr;            /* Number of valid addresses */
110   struct sockaddr       hw_address[IW_MAX_SPY];
111
112   /* Read command line */
113   i = 0;        /* first arg to read */
114   nbr = 0;      /* Number of args read so far */
115
116   /* "off" : disable functionality (set 0 addresses) */
117   if(!strcmp(args[0], "off"))
118     i = 1;      /* skip the "off" */
119   else
120     {
121       /* "+" : add all addresses already in the driver */
122       if(!strcmp(args[0], "+"))
123         {
124           char  buffer[(sizeof(struct iw_quality) +
125                         sizeof(struct sockaddr)) * IW_MAX_SPY];
126
127           /* Check if we have valid mac address type */
128           if(iw_check_mac_addr_type(skfd, ifname) < 0)
129             {
130               fprintf(stderr, "%-8.8s  Interface doesn't support MAC addresses\n", ifname);
131               return(-1);
132             }
133
134           wrq.u.data.pointer = (caddr_t) buffer;
135           wrq.u.data.length = 0;
136           wrq.u.data.flags = 0;
137           if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
138             {
139               fprintf(stderr, "Interface doesn't accept reading addresses...\n");
140               fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
141               return(-1);
142             }
143
144           /* Copy old addresses */
145           nbr = wrq.u.data.length;
146           memcpy(hw_address, buffer, nbr * sizeof(struct sockaddr));
147
148           i = 1;        /* skip the "+" */
149         }
150
151       /* Read other args on command line */
152       while((i < count) && (nbr < IW_MAX_SPY))
153         {
154           /* Get the address and check if the interface supports it */
155           if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
156             continue;
157           nbr++;
158         }
159
160       /* Check the number of addresses */
161       if(nbr == 0)
162         {
163           fprintf(stderr, "No valid addresses found : exiting...\n");
164           return(-1);
165         }
166     }
167
168   /* Check if there is some remaining arguments */
169   if(i < count)
170     {
171       fprintf(stderr, "Got only the first %d arguments, remaining discarded\n", i);
172     }
173
174   /* Time to do send addresses to the driver */
175   wrq.u.data.pointer = (caddr_t) hw_address;
176   wrq.u.data.length = nbr;
177   wrq.u.data.flags = 0;
178   if(iw_set_ext(skfd, ifname, SIOCSIWSPY, &wrq) < 0)
179     {
180       fprintf(stderr, "Interface doesn't accept addresses...\n");
181       fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno));
182       return(-1);
183     }
184
185   return(0);
186 }
187
188 /******************************* MAIN ********************************/
189
190 /*------------------------------------------------------------------*/
191 /*
192  * The main !
193  */
194 int
195 main(int        argc,
196      char **    argv)
197 {
198   int skfd;                     /* generic raw socket desc.     */
199   int goterr = 0;
200
201   /* Create a channel to the NET kernel. */
202   if((skfd = iw_sockets_open()) < 0)
203     {
204       perror("socket");
205       return(-1);
206     }
207
208   /* No argument : show the list of all device + info */
209   if(argc == 1)
210     iw_enum_devices(skfd, &print_spy_info, NULL, 0);
211   else
212     /* Special cases take one... */
213     /* Help */
214     if((!strncmp(argv[1], "-h", 9)) ||
215        (!strcmp(argv[1], "--help")))
216       fprintf(stderr, "Usage: iwspy interface [+] [MAC address] [IP address]\n");
217     else
218       /* The device name must be the first argument */
219       /* Name only : show spy list for that device only */
220       if(argc == 2)
221         print_spy_info(skfd, argv[1], NULL, 0);
222       else
223         /* Otherwise, it's a list of address to set in the spy list */
224         goterr = set_spy_info(skfd, argv + 2, argc - 2, argv[1]);
225
226   /* Close the socket. */
227   close(skfd);
228
229   return(goterr);
230 }