X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-wireless-tools.git;a=blobdiff_plain;f=wireless_tools%2Fiwspy.c;h=6e2fae22d3eb033bfcd099aad2553aa79ce6308e;hp=57d9b252bd00ecb77c75feb667de56c7771466e1;hb=41b8e9b1157054ddcb90e68f1b12707811c90361;hpb=358fbc0574da2a7a460cfec4628e470e7affc236 diff --git a/wireless_tools/iwspy.c b/wireless_tools/iwspy.c index 57d9b25..6e2fae2 100644 --- a/wireless_tools/iwspy.c +++ b/wireless_tools/iwspy.c @@ -1,16 +1,16 @@ /* * Wireless Tools * - * Jean II - HPLB '99 + * Jean II - HPLB '99 - HPL 99->04 * * This tool can manipulate the spy list : add addresses and display stat * You need to link this code against "iwlib.c" and "-lm". * * This file is released under the GPL license. - * Copyright (c) 1997-2002 Jean Tourrilhes + * Copyright (c) 1997-2004 Jean Tourrilhes */ -#include "iwlib.h" /* Header */ +#include "iwlib-private.h" /* Private header */ /************************* DISPLAY ROUTINES **************************/ @@ -18,29 +18,34 @@ /* * Display the spy list of addresses and the associated stats */ -static void +static int print_spy_info(int skfd, - char * ifname) + char * ifname, + char * args[], + int count) { struct iwreq wrq; char buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * IW_MAX_SPY]; char temp[128]; - struct sockaddr hwa[IW_MAX_SPY]; - struct iw_quality qual[IW_MAX_SPY]; + struct sockaddr * hwa; + struct iw_quality * qual; iwrange range; int has_range = 0; int n; int i; + /* Avoid "Unused parameter" warning */ + args = args; count = count; + /* Collect stats */ wrq.u.data.pointer = (caddr_t) buffer; wrq.u.data.length = IW_MAX_SPY; wrq.u.data.flags = 0; if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0) { - fprintf(stderr, "%-8.8s Interface doesn't support wireless statistic collection\n\n", ifname); - return; + fprintf(stderr, "%-8.16s Interface doesn't support wireless statistic collection\n\n", ifname); + return(-1); } /* Number of addresses */ @@ -49,8 +54,8 @@ print_spy_info(int skfd, /* 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; + fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n\n", ifname); + return(-2); } /* Get range info if we can */ @@ -59,58 +64,104 @@ print_spy_info(int skfd, /* Display it */ if(n == 0) - printf("%-8.8s No statistics to collect\n", ifname); + printf("%-8.16s No statistics to collect\n", ifname); else - printf("%-8.8s Statistics collected:\n", ifname); + printf("%-8.16s Statistics collected:\n", ifname); /* The two lists */ - - memcpy(hwa, buffer, n * sizeof(struct sockaddr)); - memcpy(qual, buffer + n*sizeof(struct sockaddr), n*sizeof(struct iw_quality)); + hwa = (struct sockaddr *) buffer; + qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n)); for(i = 0; i < n; i++) { /* Print stats for each address */ - printf(" %s : ", iw_pr_ether(temp, hwa[i].sa_data)); - iw_print_stats(temp, &qual[i], &range, has_range); + printf(" %s : ", iw_saether_ntop(&hwa[i], temp)); + iw_print_stats(temp, sizeof(temp), &qual[i], &range, has_range); printf("%s\n", temp); } -#if WIRELESS_EXT > 11 - if((n > 0) && (has_range)) + + if((n > 0) && (has_range) && (range.we_version_compiled > 11)) { - iw_print_stats(temp, &range.avg_qual, &range, has_range); - printf(" typical/average : %s\n", temp); + iwstats stats; + + /* Get /proc/net/wireless */ + if(iw_get_stats(skfd, ifname, &stats, &range, has_range) >= 0) + { + iw_print_stats(temp, sizeof(temp), &stats.qual, &range, has_range); + printf(" Link/Cell/AP : %s\n", temp); + /* Display the static data */ + iw_print_stats(temp, sizeof(temp), + &range.avg_qual, &range, has_range); + printf(" Typical/Reference : %s\n", temp); + } } -#endif /* WIRELESS_EXT > 11 */ printf("\n"); + return(0); } /*------------------------------------------------------------------*/ /* - * Get info on all devices and print it on the screen + * Get spy thresholds from the driver and display */ -static void -print_spy_devices(int skfd) +static int +get_spy_threshold(int skfd, /* The socket */ + char * ifname, /* Dev name */ + char * args[], /* Command line args */ + int count) /* Args count */ { - char buff[1024]; - struct ifconf ifc; - struct ifreq *ifr; - int i; - - /* Get list of active devices */ - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0) + struct iwreq wrq; + struct iw_thrspy threshold; + iwrange range; + int has_range = 0; + + /* Avoid "Unused parameter" warning */ + args = args; count = count; + + /* Time to send thresholds to the driver */ + wrq.u.data.pointer = (caddr_t) &threshold; + wrq.u.data.length = 1; + wrq.u.data.flags = 0; + if(iw_set_ext(skfd, ifname, SIOCGIWTHRSPY, &wrq) < 0) { - fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno)); - return; + fprintf(stderr, "Interface doesn't support thresholds...\n"); + fprintf(stderr, "SIOCGIWTHRSPY: %s\n", strerror(errno)); + return(-1); } - ifr = ifc.ifc_req; - /* Print them */ - for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) - print_spy_info(skfd, ifr->ifr_name); + /* Get range info if we can */ + if(iw_get_range_info(skfd, ifname, &(range)) >= 0) + has_range = 1; + + /* Display thresholds */ + if((has_range) && (threshold.low.level)) + { + /* If the statistics are in dBm */ + if(threshold.low.level > range.max_qual.level) + { + /* Statistics are in dBm (absolute power measurement) */ + printf("%-8.16s Low threshold:%d dBm High threshold:%d dBm\n\n", + ifname, + threshold.low.level - 0x100, threshold.high.level - 0x100); + } + else + { + /* Statistics are relative values (0 -> max) */ + printf("%-8.16s Low threshold:%d/%d High threshold:%d/%d\n\n", + ifname, + threshold.low.level, range.max_qual.level, + threshold.high.level, range.max_qual.level); + } + } + else + { + /* We can't read the range, so we don't know... */ + printf("%-8.16s Low threshold:%d High threshold:%d\n\n", + ifname, + threshold.low.level, threshold.high.level); + } + + return(0); } /************************* SETTING ROUTINES **************************/ @@ -121,9 +172,9 @@ print_spy_devices(int skfd) */ static int set_spy_info(int skfd, /* The socket */ + char * ifname, /* Dev name */ char * args[], /* Command line args */ - int count, /* Args count */ - char * ifname) /* Dev name */ + int count) /* Args count */ { struct iwreq wrq; int i; @@ -132,62 +183,64 @@ set_spy_info(int skfd, /* The socket */ /* Read command line */ i = 0; /* first arg to read */ - nbr = 0; /* Number of args readen so far */ + nbr = 0; /* Number of args read so far */ /* "off" : disable functionality (set 0 addresses) */ if(!strcmp(args[0], "off")) - i = count; /* hack */ - - /* "+" : add all addresses already in the driver */ - if(!strcmp(args[0], "+")) + i = 1; /* skip the "off" */ + else { - char buffer[(sizeof(struct iw_quality) + + /* "+" : add all addresses already in the driver */ + if(!strcmp(args[0], "+")) + { + char buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * IW_MAX_SPY]; - /* Check if we have valid mac address type */ - if(iw_check_mac_addr_type(skfd, ifname) < 0) + /* Check if we have valid mac address type */ + if(iw_check_mac_addr_type(skfd, ifname) < 0) + { + fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n", ifname); + return(-1); + } + + wrq.u.data.pointer = (caddr_t) buffer; + wrq.u.data.length = IW_MAX_SPY; + wrq.u.data.flags = 0; + if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0) + { + fprintf(stderr, "Interface doesn't accept reading addresses...\n"); + fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno)); + return(-1); + } + + /* Copy old addresses */ + nbr = wrq.u.data.length; + memcpy(hw_address, buffer, nbr * sizeof(struct sockaddr)); + + i = 1; /* skip the "+" */ + } + + /* Read other args on command line */ + while((i < count) && (nbr < IW_MAX_SPY)) { - fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n", ifname); - return(-1); + /* Get the address and check if the interface supports it */ + if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0) + continue; + nbr++; } - wrq.u.data.pointer = (caddr_t) buffer; - wrq.u.data.length = 0; - wrq.u.data.flags = 0; - if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0) + /* Check the number of addresses */ + if(nbr == 0) { - fprintf(stderr, "Interface doesn't accept reading addresses...\n"); - fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno)); + fprintf(stderr, "No valid addresses found : exiting...\n"); return(-1); } - - /* Copy old addresses */ - nbr = wrq.u.data.length; - memcpy(hw_address, buffer, nbr * sizeof(struct sockaddr)); - - i = 1; /* skip the "+" */ - } - - /* Read other args on command line */ - while((i < count) && (nbr < IW_MAX_SPY)) - { - /* Get the address and check if the interface supports it */ - if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0) - continue; - nbr++; - } - - /* Check the number of addresses */ - if((nbr == 0) && strcmp(args[0], "off")) - { - fprintf(stderr, "No valid addresses found : exiting...\n"); - return(-1); } /* Check if there is some remaining arguments */ if(i < count) { - fprintf(stderr, "Got only the first %d addresses, remaining discarded\n", IW_MAX_SPY); + fprintf(stderr, "Got only the first %d arguments, remaining discarded\n", i); } /* Time to do send addresses to the driver */ @@ -204,6 +257,70 @@ set_spy_info(int skfd, /* The socket */ return(0); } +/*------------------------------------------------------------------*/ +/* + * Set spy thresholds in the driver from command line + */ +static int +set_spy_threshold(int skfd, /* The socket */ + char * ifname, /* Dev name */ + char * args[], /* Command line args */ + int count) /* Args count */ +{ + struct iwreq wrq; + struct iw_thrspy threshold; + int low_thr; + int high_thr; + + /* Init */ + memset(&threshold, '\0', sizeof(threshold)); + + /* "off" : disable functionality (set 0 addresses) */ + if(!strcmp(args[0], "off")) + { + /* Just send null threshold, will disable it */ + } + else + { + /* Try to get our threshold */ + if(count < 2) + { + fprintf(stderr, "%-8.16s Need two threshold values\n", ifname); + return(-1); + } + if((sscanf(args[0], "%i", &low_thr) != 1) || + (sscanf(args[1], "%i", &high_thr) != 1)) + { + fprintf(stderr, "%-8.16s Invalid threshold values\n", ifname); + return(-1); + } + /* Basic sanity check */ + if(high_thr < low_thr) + { + fprintf(stderr, "%-8.16s Inverted threshold range\n", ifname); + return(-1); + } + /* Copy thresholds */ + threshold.low.level = low_thr; + threshold.low.updated = 0x2; + threshold.high.level = high_thr; + threshold.high.updated = 0x2; + } + + /* Time to send thresholds to the driver */ + wrq.u.data.pointer = (caddr_t) &threshold; + wrq.u.data.length = 1; + wrq.u.data.flags = 0; + if(iw_set_ext(skfd, ifname, SIOCSIWTHRSPY, &wrq) < 0) + { + fprintf(stderr, "Interface doesn't accept thresholds...\n"); + fprintf(stderr, "SIOCSIWTHRSPY: %s\n", strerror(errno)); + return(-1); + } + + return(0); +} + /******************************* MAIN ********************************/ /*------------------------------------------------------------------*/ @@ -214,7 +331,7 @@ int main(int argc, char ** argv) { - int skfd = -1; /* generic raw socket desc. */ + int skfd; /* generic raw socket desc. */ int goterr = 0; /* Create a channel to the NET kernel. */ @@ -226,36 +343,34 @@ main(int argc, /* No argument : show the list of all device + info */ if(argc == 1) - { - print_spy_devices(skfd); - close(skfd); - return(0); - } - - /* Special cases take one... */ - /* Help */ - if((!strncmp(argv[1], "-h", 9)) || - (!strcmp(argv[1], "--help"))) - { + iw_enum_devices(skfd, &print_spy_info, NULL, 0); + else + /* Special cases take one... */ + /* Help */ + if((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "--help"))) fprintf(stderr, "Usage: iwspy interface [+] [MAC address] [IP address]\n"); - close(skfd); - return(0); - } - - /* The device name must be the first argument */ - /* Name only : show spy list for that device only */ - if(argc == 2) - { - print_spy_info(skfd, argv[1]); - close(skfd); - return(0); - } - - /* Otherwise, it's a list of address to set in the spy list */ - goterr = set_spy_info(skfd, argv + 2, argc - 2, argv[1]); + else + /* Version */ + if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) + goterr = iw_print_version_info("iwspy"); + else + /* The device name must be the first argument */ + /* Name only : show spy list for that device only */ + if(argc == 2) + goterr = print_spy_info(skfd, argv[1], NULL, 0); + else + /* Special commands */ + if(!strcmp(argv[2], "setthr")) + goterr = set_spy_threshold(skfd, argv[1], argv + 3, argc - 3); + else + if(!strcmp(argv[2], "getthr")) + goterr = get_spy_threshold(skfd, argv[1], argv + 3, argc - 3); + else + /* Otherwise, it's a list of address to set in the spy list */ + goterr = set_spy_info(skfd, argv[1], argv + 2, argc - 2); /* Close the socket. */ - close(skfd); + iw_sockets_close(skfd); return(goterr); }