OSDN Git Service

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