/* * Input an address and convert to binary. */ int in_addr(int skfd, 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; /* Read interface address */ if(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... */ strcpy(arp_query.arp_dev, ifname); 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 printf("IP Address %s => Hw Address = %s\n", bufp, pr_ether(sap->sa_data)); #endif } else /* If it's an hardware address */ /* Get the hardware address */ if(in_ether(bufp, sap) < 0) { fprintf(stderr, "Invalid hardware address %s\n", bufp); return(-1); } #ifdef DEBUG printf("Hw Address = %s\n", pr_ether(sap->sa_data)); #endif return(0); }
/* * Display the NWID if possible */ static int print_ap(int skfd, char * ifname, int format) { struct iwreq wrq; /* Get network ID */ strcpy(wrq.ifr_name, ifname); if(ioctl(skfd, SIOCGIWAP, &wrq) < 0) return(-1); /* Print */ printf("%-8.8s Access Point: %s\n", ifname, pr_ether(wrq.u.ap_addr.sa_data)); return(0); }
/* * Check if interface support the right address types... */ int check_addr_type(int skfd, char * ifname) { struct ifreq ifr; /* Get the type of interface address */ strcpy(ifr.ifr_name, ifname); if((ioctl(skfd, SIOCGIFADDR, &ifr) < 0) || (ifr.ifr_addr.sa_family != AF_INET)) { /* Deep trouble... */ fprintf(stderr, "Interface %s doesn't support IP addresses\n", ifname); return(-1); } #ifdef DEBUG printf("Interface : %d - 0x%lX\n", ifr.ifr_addr.sa_family, *((unsigned long *) ifr.ifr_addr.sa_data)); #endif /* Get the type of hardware address */ strcpy(ifr.ifr_name, ifname); if((ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) || (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)) { /* Deep trouble... */ fprintf(stderr, "Interface %s doesn't support MAC addresses\n", ifname); return(-1); } #ifdef DEBUG printf("Hardware : %d - %s\n", ifr.ifr_hwaddr.sa_family, pr_ether(ifr.ifr_hwaddr.sa_data)); #endif return(0); }
/* * Print on the screen in a neat fashion all the info we have collected * on a device. */ static void display_info(struct wireless_info * info, char * ifname) { /* One token is more of less 5 character, 14 tokens per line */ int tokens = 3; /* For name */ /* Display device name and wireless name (name of the protocol used) */ printf("%8.8s %s ", ifname, info->name); /* Display ESSID (extended network), if any */ if(info->has_essid) { if(info->essid_on) { /* Does it have an ESSID index ? */ if((info->essid_on & IW_ENCODE_INDEX) > 1) printf("ESSID:\"%s\" [%d] ", info->essid, (info->essid_on & IW_ENCODE_INDEX)); else printf("ESSID:\"%s\" ", info->essid); } else printf("ESSID:off "); } /* Display NickName (station name), if any */ if(info->has_nickname) printf("Nickname:\"%s\"", info->nickname); /* Formatting */ if(info->has_essid || info->has_nickname) { printf("\n "); tokens = 0; } /* Display Network ID */ if(info->has_nwid) { /* Note : should display right number of digit according to info * in range structure */ if(info->nwid.disabled) printf("NWID:off/any "); else printf("NWID:%X ", info->nwid.value); tokens +=2; } /* Display the current mode of operation */ if(info->has_mode) { printf("Mode:%s ", operation_mode[info->mode]); tokens +=3; } /* Display frequency / channel */ if(info->has_freq) { if(info->freq < KILO) printf("Channel:%d ", info->freq); else { if(info->freq >= GIGA) printf("Frequency:%dGHz freq %d ", info->freq / GIGA,info->freq); else { if(info->freq >= MEGA) printf("Frequency:%dMHz ", info->freq / MEGA); else printf("Frequency:%dkHz ", info->freq / KILO); } } tokens +=4; } /* Display the address of the current Access Point */ if(info->has_ap_addr) { /* A bit of clever formatting */ if(tokens > 8) { printf("\n "); tokens = 0; } tokens +=6; /* Oups ! No Access Point in Ad-Hoc mode */ if((info->has_mode) && (info->mode == IW_MODE_ADHOC)) printf("Cell:"); else printf("Access Point:"); printf(" %s", pr_ether(info->ap_addr.sa_data)); } /* Display the currently used/set bit-rate */ if(info->has_bitrate) { /* A bit of clever formatting */ if(tokens > 11) { printf("\n "); tokens = 0; } tokens +=3; /* Fixed ? */ if(info->bitrate.fixed) printf("Bit Rate="); else printf("Bit Rate:"); if(info->bitrate.value >= GIGA) printf("%dGb/s", info->bitrate.value / GIGA); else if(info->bitrate.value >= MEGA) printf("%dMb/s", info->bitrate.value / MEGA); else printf("%dkb/s", info->bitrate.value / KILO); printf(" "); } #if WIRELESS_EXT > 9 /* Display the Transmit Power */ if(info->has_txpower) { /* A bit of clever formatting */ if(tokens > 11) { printf("\n "); tokens = 0; } tokens +=3; /* Disabled ? */ if(info->txpower.disabled) printf("Tx-Power:off "); else { int dbm; /* Fixed ? */ if(info->txpower.fixed) printf("Tx-Power="); else printf("Tx-Power:"); /* Convert everything to dBm */ if(info->txpower.flags & IW_TXPOW_MWATT) dbm = mwatt2dbm(info->txpower.value); else dbm = info->txpower.value; /* Display */ printf("%d dBm ", dbm); } } #endif /* Display sensitivity */ if(info->has_sens) { /* A bit of clever formatting */ if(tokens > 10) { printf("\n "); tokens = 0; } tokens +=4; /* Fixed ? */ if(info->sens.fixed) printf("Sensitivity="); else printf("Sensitivity:"); if(info->has_range) /* Display in dBm ? */ if(info->sens.value < 0) printf("%d dBm ", info->sens.value); else printf("%d/%d ", info->sens.value, info->range.sensitivity); else printf("%d ", info->sens.value); } printf("\n "); tokens = 0; #if WIRELESS_EXT > 10 /* Display retry limit/lifetime information */ if(info->has_retry) { printf("Retry"); /* Disabled ? */ if(info->retry.disabled) printf(":off"); else { /* Let's check the value and its type */ if(info->retry.flags & IW_RETRY_TYPE) print_retry_value(stdout, info->retry.value, info->retry.flags); /* Let's check if nothing (simply on) */ if(info->retry.flags == IW_RETRY_ON) printf(":on"); } printf(" "); tokens += 5; /* Between 3 and 5, depend on flags */ } #endif /* WIRELESS_EXT > 10 */ /* Display the RTS threshold */ if(info->has_rts) { /* Disabled ? */ if(info->rts.disabled) printf("RTS thr:off "); else { /* Fixed ? */ if(info->rts.fixed) printf("RTS thr="); else printf("RTS thr:"); printf("%d B ", info->rts.value); } tokens += 3; } /* Display the fragmentation threshold */ if(info->has_frag) { /* A bit of clever formatting */ if(tokens > 10) { printf("\n "); tokens = 0; } tokens +=4; /* Disabled ? */ if(info->frag.disabled) printf("Fragment thr:off"); else { /* Fixed ? */ if(info->frag.fixed) printf("Fragment thr="); else printf("Fragment thr:"); printf("%d B ", info->frag.value); } } /* Formating */ if(tokens > 0) printf("\n "); /* Display encryption information */ /* Note : we display only the "current" key, use iwlist to list all keys */ if(info->has_key) { printf("Encryption key:"); if((info->key_flags & IW_ENCODE_DISABLED) || (info->key_size == 0)) printf("off\n "); else { /* Display the key */ print_key(stdout, info->key, info->key_size, info->key_flags); /* Other info... */ if((info->key_flags & IW_ENCODE_INDEX) > 1) printf(" [%d]", info->key_flags & IW_ENCODE_INDEX); if(info->key_flags & IW_ENCODE_RESTRICTED) printf(" Encryption mode:restricted"); if(info->key_flags & IW_ENCODE_OPEN) printf(" Encryption mode:open"); printf("\n "); } } /* Display Power Management information */ /* Note : we display only one parameter, period or timeout. If a device * (such as HiperLan) has both, the user need to use iwlist... */ if(info->has_power) /* I hope the device has power ;-) */ { printf("Power Management"); /* Disabled ? */ if(info->power.disabled) printf(":off\n "); else { /* Let's check the value and its type */ if(info->power.flags & IW_POWER_TYPE) print_pm_value(stdout, info->power.value, info->power.flags); /* Let's check the mode */ print_pm_mode(stdout, info->power.flags); /* Let's check if nothing (simply on) */ if(info->power.flags == IW_POWER_ON) printf(":on"); printf("\n "); } } /* Display statistics */ if(info->has_stats) { info->stats.qual.updated = 0x0; /* Not that reliable, disable */ printf("Link "); print_stats(stdout, &info->stats.qual, &info->range, info->has_range); printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n", info->stats.discard.nwid, info->stats.discard.code, info->stats.discard.misc); } printf("\n"); }
/* * Input an Ethernet address and convert to binary. */ int in_ether(char *bufp, struct sockaddr *sap) { unsigned char *ptr; char c, *orig; int i, val; sap->sa_family = ARPHRD_ETHER; ptr = sap->sa_data; i = 0; orig = bufp; while((*bufp != '\0') && (i < ETH_ALEN)) { val = 0; c = *bufp++; if (isdigit(c)) val = c - '0'; else if (c >= 'a' && c <= 'f') val = c - 'a' + 10; else if (c >= 'A' && c <= 'F') val = c - 'A' + 10; else { #ifdef DEBUG fprintf(stderr, "in_ether(%s): invalid ether address!\n", orig); #endif errno = EINVAL; return(-1); } val <<= 4; c = *bufp++; if (isdigit(c)) val |= c - '0'; else if (c >= 'a' && c <= 'f') val |= c - 'a' + 10; else if (c >= 'A' && c <= 'F') val |= c - 'A' + 10; else { #ifdef DEBUG fprintf(stderr, "in_ether(%s): invalid ether address!\n", orig); #endif errno = EINVAL; return(-1); } *ptr++ = (unsigned char) (val & 0377); i++; /* We might get a semicolon here - not required. */ if (*bufp == ':') { if (i == ETH_ALEN) { #ifdef DEBUG fprintf(stderr, "in_ether(%s): trailing : ignored!\n", orig) #endif ; /* nothing */ } bufp++; } } /* That's it. Any trailing junk? */ if ((i == ETH_ALEN) && (*bufp != '\0')) { #ifdef DEBUG fprintf(stderr, "in_ether(%s): trailing junk!\n", orig); errno = EINVAL; return(-1); #endif } #ifdef DEBUG fprintf(stderr, "in_ether(%s): %s\n", orig, pr_ether(sap->sa_data)); #endif return(0); }