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".
9 * This file is released under the GPL license.
10 * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
13 #include "iwlib.h" /* Header */
15 /************************* DISPLAY ROUTINES **************************/
17 /*------------------------------------------------------------------*/
19 * Display the spy list of addresses and the associated stats
22 print_spy_info(int skfd,
28 char buffer[(sizeof(struct iw_quality) +
29 sizeof(struct sockaddr)) * IW_MAX_SPY];
31 struct sockaddr hwa[IW_MAX_SPY];
32 struct iw_quality qual[IW_MAX_SPY];
38 /* Avoid "Unused parameter" warning */
39 args = args; count = count;
42 wrq.u.data.pointer = (caddr_t) buffer;
43 wrq.u.data.length = IW_MAX_SPY;
45 if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
47 fprintf(stderr, "%-8.8s Interface doesn't support wireless statistic collection\n\n", ifname);
51 /* Number of addresses */
52 n = wrq.u.data.length;
54 /* Check if we have valid mac address type */
55 if(iw_check_mac_addr_type(skfd, ifname) < 0)
57 fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n\n", ifname);
61 /* Get range info if we can */
62 if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
67 printf("%-8.8s No statistics to collect\n", ifname);
69 printf("%-8.8s Statistics collected:\n", ifname);
73 memcpy(hwa, buffer, n * sizeof(struct sockaddr));
74 memcpy(qual, buffer + n*sizeof(struct sockaddr), n*sizeof(struct iw_quality));
76 for(i = 0; i < n; i++)
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);
84 if((n > 0) && (has_range))
86 iw_print_stats(temp, &range.avg_qual, &range, has_range);
87 printf(" typical/average : %s\n", temp);
89 #endif /* WIRELESS_EXT > 11 */
95 /************************* SETTING ROUTINES **************************/
97 /*------------------------------------------------------------------*/
99 * Set list of addresses specified on command line in the driver.
102 set_spy_info(int skfd, /* The socket */
103 char * args[], /* Command line args */
104 int count, /* Args count */
105 char * ifname) /* Dev name */
109 int nbr; /* Number of valid addresses */
110 struct sockaddr hw_address[IW_MAX_SPY];
112 /* Read command line */
113 i = 0; /* first arg to read */
114 nbr = 0; /* Number of args read so far */
116 /* "off" : disable functionality (set 0 addresses) */
117 if(!strcmp(args[0], "off"))
118 i = 1; /* skip the "off" */
121 /* "+" : add all addresses already in the driver */
122 if(!strcmp(args[0], "+"))
124 char buffer[(sizeof(struct iw_quality) +
125 sizeof(struct sockaddr)) * IW_MAX_SPY];
127 /* Check if we have valid mac address type */
128 if(iw_check_mac_addr_type(skfd, ifname) < 0)
130 fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n", ifname);
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)
139 fprintf(stderr, "Interface doesn't accept reading addresses...\n");
140 fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
144 /* Copy old addresses */
145 nbr = wrq.u.data.length;
146 memcpy(hw_address, buffer, nbr * sizeof(struct sockaddr));
148 i = 1; /* skip the "+" */
151 /* Read other args on command line */
152 while((i < count) && (nbr < IW_MAX_SPY))
154 /* Get the address and check if the interface supports it */
155 if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
160 /* Check the number of addresses */
163 fprintf(stderr, "No valid addresses found : exiting...\n");
168 /* Check if there is some remaining arguments */
171 fprintf(stderr, "Got only the first %d arguments, remaining discarded\n", i);
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)
180 fprintf(stderr, "Interface doesn't accept addresses...\n");
181 fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno));
188 /******************************* MAIN ********************************/
190 /*------------------------------------------------------------------*/
198 int skfd; /* generic raw socket desc. */
201 /* Create a channel to the NET kernel. */
202 if((skfd = iw_sockets_open()) < 0)
208 /* No argument : show the list of all device + info */
210 iw_enum_devices(skfd, &print_spy_info, NULL, 0);
212 /* Special cases take one... */
214 if((!strncmp(argv[1], "-h", 9)) ||
215 (!strcmp(argv[1], "--help")))
216 fprintf(stderr, "Usage: iwspy interface [+] [MAC address] [IP address]\n");
218 /* The device name must be the first argument */
219 /* Name only : show spy list for that device only */
221 print_spy_info(skfd, argv[1], NULL, 0);
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]);
226 /* Close the socket. */