📄 iwcommon.c
字号:
/* * Wireless Tools * * Jean II - HPLB 97->99 - HPL 99->00 * * Common subroutines to all the wireless tools... * * This file is released under the GPL license. */#include "iwcommon.h" /* Header *//************************ SOCKET SUBROUTINES *************************//*------------------------------------------------------------------*//* * Open a socket. * Depending on the protocol present, open the right socket. The socket * will allow us to talk to the driver. */intsockets_open(void){ int ipx_sock = -1; /* IPX socket */ int ax25_sock = -1; /* AX.25 socket */ int inet_sock = -1; /* INET socket */ int ddp_sock = -1; /* Appletalk DDP socket */ inet_sock=socket(AF_INET, SOCK_DGRAM, 0); ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0); ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0); ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0); /* * Now pick any (exisiting) useful socket family for generic queries */ if(inet_sock!=-1) return inet_sock; if(ipx_sock!=-1) return ipx_sock; if(ax25_sock!=-1) return ax25_sock; /* * If this is -1 we have no known network layers and its time to jump. */ return ddp_sock;}/*********************** WIRELESS SUBROUTINES ************************//*------------------------------------------------------------------*//* * Get the range information out of the driver */intget_range_info(int skfd, char * ifname, iwrange * range){ struct iwreq wrq; char buffer[sizeof(iwrange) * 2]; /* Large enough */ /* Cleanup */ memset(buffer, 0, sizeof(range)); strcpy(wrq.ifr_name, ifname); wrq.u.data.pointer = (caddr_t) buffer; wrq.u.data.length = 0; wrq.u.data.flags = 0; if(ioctl(skfd, SIOCGIWRANGE, &wrq) < 0) return(-1); /* Copy stuff at the right place, ignore extra */ memcpy((char *) range, buffer, sizeof(iwrange)); /* Lot's of people have driver and tools out of sync as far as Wireless * Extensions are concerned. It's because /usr/include/linux/wireless.h * and /usr/src/linux/include/linux/wireless.h are different. * We try to catch this stuff here... */ /* For new versions, we can check the version directly, for old versions * we use magic. 300 bytes is a also magic number, don't touch... */ if((WIRELESS_EXT > 10) && (wrq.u.data.length >= 300)) {#if WIRELESS_EXT > 10 /* Version verification - for new versions */ if(range->we_version_compiled != WIRELESS_EXT) { fprintf(stderr, "Warning : Device %s has been compiled with version %d\n", ifname, range->we_version_compiled); fprintf(stderr, "of Wireless Extension, while we are using version %d.\n", WIRELESS_EXT); fprintf(stderr, "Some things may be broken...\n\n"); }#endif /* WIRELESS_EXT > 10 */ } else { /* Version verification - for old versions */ if(wrq.u.data.length != sizeof(iwrange)) { fprintf(stderr, "Warning : Device %s has been compiled with a different version\n", ifname); fprintf(stderr, "of Wireless Extension than ours (we are using version %d).\n", WIRELESS_EXT); fprintf(stderr, "Some things may be broken...\n\n"); } } /* Note : we are only trying to catch compile difference, not source. * If the driver source has not been updated to the latest, it doesn't * matter because the new fields are set to zero */ return(0);}/*------------------------------------------------------------------*//* * Get information about what private ioctls are supported by the driver */intget_priv_info(int skfd, char * ifname, iwprivargs * priv){ struct iwreq wrq; /* Ask the driver */ strcpy(wrq.ifr_name, ifname); wrq.u.data.pointer = (caddr_t) priv; wrq.u.data.length = 0; wrq.u.data.flags = 0; if(ioctl(skfd, SIOCGIWPRIV, &wrq) < 0) return(-1); /* Return the number of ioctls */ return(wrq.u.data.length);}/********************** FREQUENCY SUBROUTINES ***********************//*------------------------------------------------------------------*//* * Convert a floating point the our internal representation of * frequencies. * The kernel doesn't want to hear about floating point, so we use * this custom format instead. */voidfloat2freq(double in, iwfreq * out){ out->e = (short) (floor(log10(in))); if(out->e > 8) { out->m = ((long) (floor(in / pow(10,out->e - 6)))) * 100; out->e -= 8; } else { out->m = in; out->e = 0; }}/*------------------------------------------------------------------*//* * Convert our internal representation of frequencies to a floating point. */doublefreq2float(iwfreq * in){ return ((double) in->m) * pow(10,in->e);}/************************ POWER SUBROUTINES *************************//*------------------------------------------------------------------*//* * Convert a value in dBm to a value in milliWatt. */intdbm2mwatt(int in){ return((int) (floor(pow(10.0, (((double) in) / 10.0)))));}/*------------------------------------------------------------------*//* * Convert a value in milliWatt to a value in dBm. */intmwatt2dbm(int in){ return((int) (ceil(10.0 * log10((double) in))));}/********************** STATISTICS SUBROUTINES **********************//*------------------------------------------------------------------*//* * Output the link statistics, taking care of formating */voidprint_stats(FILE * stream, iwqual * qual, iwrange * range, int has_range){ /* Just do it */ if(has_range && (qual->level != 0)) { /* If the statistics are in dBm */ if(qual->level > range->max_qual.level) { /* Statistics are in dBm (absolute power measurement) */ fprintf(stream, "Quality:%d/%d Signal level:%d dBm Noise level:%d dBm%s\n", qual->qual, range->max_qual.qual, qual->level - 0x100, qual->noise - 0x100, (qual->updated & 0x7) ? " (updated)" : ""); } else { /* Statistics are relative values (0 -> max) */ fprintf(stream, "Quality:%d/%d Signal level:%d/%d Noise level:%d/%d%s\n", qual->qual, range->max_qual.qual, qual->level, range->max_qual.level, qual->noise, range->max_qual.noise, (qual->updated & 0x7) ? " (updated)" : ""); } } else { /* We can't read the range, so we don't know... */ fprintf(stream, "Quality:%d Signal level:%d Noise level:%d%s\n", qual->qual, qual->level, qual->noise, (qual->updated & 0x7) ? " (updated)" : ""); }}/*********************** ENCODING SUBROUTINES ***********************//*------------------------------------------------------------------*//* * Output the encoding key, with a nice formating */voidprint_key(FILE * stream, unsigned char * key, int key_size, int key_flags){ int i; /* Is the key present ??? */ if(key_flags & IW_ENCODE_NOKEY) { /* Nope : print dummy */ printf("**"); for(i = 1; i < key_size; i++) { if((i & 0x1) == 0) printf("-"); printf("**"); } } else { /* Yes : print the key */ printf("%.2X", key[0]); for(i = 1; i < key_size; i++) { if((i & 0x1) == 0) printf("-"); printf("%.2X", key[i]); } }}/******************* POWER MANAGEMENT SUBROUTINES *******************//*------------------------------------------------------------------*//* * Output a power management value with all attributes... */voidprint_pm_value(FILE * stream, int value, int flags){ /* Modifiers */ if(flags & IW_POWER_MIN) fprintf(stream, " min"); if(flags & IW_POWER_MAX) fprintf(stream, " max"); /* Type */ if(flags & IW_POWER_TIMEOUT) fprintf(stream, " timeout:"); else fprintf(stream, " period:"); /* Display value without units */ if(flags & IW_POWER_RELATIVE) fprintf(stream, "%g ", ((double) value) / MEGA); else { /* Display value with units */ if(value >= (int) MEGA) fprintf(stream, "%gs ", ((double) value) / MEGA); else if(value >= (int) KILO) fprintf(stream, "%gms ", ((double) value) / KILO); else fprintf(stream, "%dus ", value); }}/*------------------------------------------------------------------*//* * Output a power management mode */voidprint_pm_mode(FILE * stream, int flags){ /* Print the proper mode... */ switch(flags & IW_POWER_MODE) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -