OSDN Git Service

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