/* * Check if interface support the right address types... */ int iw_check_addr_type(int skfd, char * ifname) { /* Check the interface address type */ if(iw_check_if_addr_type(skfd, ifname) < 0) return(-1); /* Check the interface address type */ if(iw_check_mac_addr_type(skfd, ifname) < 0) return(-1); return(0); }
/* * Input an address and convert to binary. */ int iw_in_addr(int skfd, const char * ifname, char * bufp, struct sockaddr *sap) { /* Check if it is a hardware or IP address */ if(index(bufp, ':') == NULL) { struct sockaddr if_address; struct arpreq arp_query; /* Check if we have valid interface address type */ if(iw_check_if_addr_type(skfd, ifname) < 0) { fprintf(stderr, "%-8.16s Interface doesn't support IP addresses\n", ifname); return(-1); } /* Read interface address */ if(iw_in_inet(bufp, &if_address) < 0) { fprintf(stderr, "Invalid interface address %s\n", bufp); return(-1); } /* Translate IP addresses to MAC addresses */ memcpy((char *) &(arp_query.arp_pa), (char *) &if_address, sizeof(struct sockaddr)); arp_query.arp_ha.sa_family = 0; arp_query.arp_flags = 0; /* The following restrict the search to the interface only */ /* For old kernels which complain, just comment it... */ strncpy(arp_query.arp_dev, ifname, IFNAMSIZ); if((ioctl(skfd, SIOCGARP, &arp_query) < 0) || !(arp_query.arp_flags & ATF_COM)) { fprintf(stderr, "Arp failed for %s on %s... (%d)\nTry to ping the address before setting it.\n", bufp, ifname, errno); return(-1); } /* Store new MAC address */ memcpy((char *) sap, (char *) &(arp_query.arp_ha), sizeof(struct sockaddr)); #ifdef DEBUG { char buf[20]; printf("IP Address %s => Hw Address = %s\n", bufp, iw_saether_ntop(sap, buf)); } #endif } else /* If it's an hardware address */ { /* 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); } /* Get the hardware address */ if(iw_saether_aton(bufp, sap) == 0) { fprintf(stderr, "Invalid hardware address %s\n", bufp); return(-1); } } #ifdef DEBUG { char buf[20]; printf("Hw Address = %s\n", iw_saether_ntop(sap, buf)); } #endif return(0); }
/* * Set list of addresses specified on command line in the driver. */ static int set_spy_info(int skfd, /* The socket */ char * ifname, /* Dev name */ char * args[], /* Command line args */ int count) /* Args count */ { struct iwreq wrq; int i; int nbr; /* Number of valid addresses */ struct sockaddr hw_address[IW_MAX_SPY]; /* Read command line */ i = 0; /* first arg to read */ nbr = 0; /* Number of args read so far */ /* "off" : disable functionality (set 0 addresses) */ if(!strcmp(args[0], "off")) i = 1; /* skip the "off" */ else { /* "+" : 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) { 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)) { /* 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) { 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 arguments, remaining discarded\n", i); } /* Time to do send addresses to the driver */ wrq.u.data.pointer = (caddr_t) hw_address; wrq.u.data.length = nbr; wrq.u.data.flags = 0; if(iw_set_ext(skfd, ifname, SIOCSIWSPY, &wrq) < 0) { fprintf(stderr, "Interface doesn't accept addresses...\n"); fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno)); return(-1); } return(0); }
/* * Display the spy list of addresses and the associated stats */ static int print_spy_info(int skfd, 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; 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.16s Interface doesn't support wireless statistic collection\n\n", ifname); return(-1); } /* Number of addresses */ n = wrq.u.data.length; /* 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\n", ifname); return(-2); } /* Get range info if we can */ if(iw_get_range_info(skfd, ifname, &(range)) >= 0) has_range = 1; /* Display it */ if(n == 0) printf("%-8.16s No statistics to collect\n", ifname); else printf("%-8.16s Statistics collected:\n", ifname); /* The two lists */ 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_saether_ntop(&hwa[i], temp)); iw_print_stats(temp, sizeof(temp), &qual[i], &range, has_range); printf("%s\n", temp); } if((n > 0) && (has_range) && (range.we_version_compiled > 11)) { 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); } } printf("\n"); return(0); }
/* * Display the list of ap addresses and the associated stats * Exacly the same as the spy list, only with different IOCTL and messages */ static int print_ap_info(int skfd, char * ifname, char * args[], /* Command line args */ int count) /* Args count */ { struct iwreq wrq; char buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * IW_MAX_AP]; char temp[128]; struct sockaddr * hwa; struct iw_quality * qual; iwrange range; int has_range = 0; int has_qual = 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_AP; wrq.u.data.flags = 0; if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0) { fprintf(stderr, "%-8.16s Interface doesn't have a list of Peers/Access-Points\n\n", ifname); return(-1); } /* Number of addresses */ n = wrq.u.data.length; has_qual = wrq.u.data.flags; /* The two lists */ hwa = (struct sockaddr *) buffer; qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n)); /* 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\n", ifname); return(-2); } /* Get range info if we can */ if(iw_get_range_info(skfd, ifname, &(range)) >= 0) has_range = 1; /* Display it */ if(n == 0) printf("%-8.16s No Peers/Access-Point in range\n", ifname); else printf("%-8.16s Peers/Access-Points in range:\n", ifname); for(i = 0; i < n; i++) { if(has_qual) { /* Print stats for this address */ printf(" %s : ", iw_saether_ntop(&hwa[i], temp)); iw_print_stats(temp, sizeof(buffer), &qual[i], &range, has_range); printf("%s\n", temp); } else /* Only print the address */ printf(" %s\n", iw_saether_ntop(&hwa[i], temp)); } printf("\n"); return(0); }