📄 iwlib.c
字号:
* Parse a key from the command line. * Return size of the key, or 0 (no key) or -1 (error) * If the key is too long, it's simply truncated... */intiw_in_key(const char * input, unsigned char * key){ int keylen = 0; /* Check the type of key */ if(!strncmp(input, "s:", 2)) { /* First case : as an ASCII string (Lucent/Agere cards) */ keylen = strlen(input + 2); /* skip "s:" */ if(keylen > IW_ENCODING_TOKEN_MAX) keylen = IW_ENCODING_TOKEN_MAX; memcpy(key, input + 2, keylen); } else if(!strncmp(input, "p:", 2)) { /* Second case : as a passphrase (PrismII cards) */ return(iw_pass_key(input + 2, key)); /* skip "p:" */ } else { const char * p; int dlen; /* Digits sequence length */ unsigned char out[IW_ENCODING_TOKEN_MAX]; /* Third case : as hexadecimal digits */ p = input; dlen = -1; /* Loop until we run out of chars in input or overflow the output */ while(*p != '\0') { int temph; int templ; int count; /* No more chars in this sequence */ if(dlen <= 0) { /* Skip separator */ if(dlen == 0) p++; /* Calculate num of char to next separator */ dlen = strcspn(p, "-:;.,"); } /* Get each char separatly (and not by two) so that we don't * get confused by 'enc' (=> '0E'+'0C') and similar */ count = sscanf(p, "%1X%1X", &temph, &templ); if(count < 1) return(-1); /* Error -> non-hex char */ /* Fixup odd strings such as '123' is '01'+'23' and not '12'+'03'*/ if(dlen % 2) count = 1; /* Put back two chars as one byte and output */ if(count == 2) templ |= temph << 4; else templ = temph; out[keylen++] = (unsigned char) (templ & 0xFF); /* Check overflow in output */ if(keylen >= IW_ENCODING_TOKEN_MAX) break; /* Move on to next chars */ p += count; dlen -= count; } /* We use a temporary output buffer 'out' so that if there is * an error, we don't overwrite the original key buffer. * Because of the way iwconfig loop on multiple key/enc arguments * until it finds an error in here, this is necessary to avoid * silently corrupting the encryption key... */ memcpy(key, out, keylen); }#ifdef DEBUG { char buf[IW_ENCODING_TOKEN_MAX * 3]; iw_print_key(buf, sizeof(buf), key, keylen, 0); printf("Got key : %d [%s]\n", keylen, buf); }#endif return(keylen);}/*------------------------------------------------------------------*//* * Parse a key from the command line. * Return size of the key, or 0 (no key) or -1 (error) */intiw_in_key_full(int skfd, const char * ifname, const char * input, unsigned char * key, __u16 * flags){ int keylen = 0; char * p; if(!strncmp(input, "l:", 2)) { struct iw_range range; /* Extra case : as a login (user:passwd - Cisco LEAP) */ keylen = strlen(input + 2) + 1; /* skip "l:", add '\0' */ /* Most user/password is 8 char, so 18 char total, < 32 */ if(keylen > IW_ENCODING_TOKEN_MAX) keylen = IW_ENCODING_TOKEN_MAX; memcpy(key, input + 2, keylen); /* Separate the two strings */ p = strchr((char *) key, ':'); if(p == NULL) { fprintf(stderr, "Error: Invalid login format\n"); return(-1); } *p = '\0'; /* Extract range info */ if(iw_get_range_info(skfd, ifname, &range) < 0) /* Hum... Maybe we should return an error ??? */ memset(&range, 0, sizeof(range)); if(range.we_version_compiled > 15) { printf("flags = %X, index = %X\n", *flags, range.encoding_login_index); if((*flags & IW_ENCODE_INDEX) == 0) { /* Extract range info */ if(iw_get_range_info(skfd, ifname, &range) < 0) memset(&range, 0, sizeof(range)); printf("flags = %X, index = %X\n", *flags, range.encoding_login_index); /* Set the index the driver expects */ *flags |= range.encoding_login_index & IW_ENCODE_INDEX; } printf("flags = %X, index = %X\n", *flags, range.encoding_login_index); } } else /* Simpler routine above */ keylen = iw_in_key(input, key); return(keylen);}/******************* POWER MANAGEMENT SUBROUTINES *******************//*------------------------------------------------------------------*//* * Output a power management value with all attributes... */voidiw_print_pm_value(char * buffer, int buflen, int value, int flags){ /* Check size */ if(buflen < 25) { snprintf(buffer, buflen, "<too big>"); return; } buflen -= 25; /* Modifiers */ if(flags & IW_POWER_MIN) { strcpy(buffer, " min"); /* Size checked */ buffer += 4; } if(flags & IW_POWER_MAX) { strcpy(buffer, " max"); /* Size checked */ buffer += 4; } /* Type */ if(flags & IW_POWER_TIMEOUT) { strcpy(buffer, " timeout:"); /* Size checked */ buffer += 9; } else { strcpy(buffer, " period:"); /* Size checked */ buffer += 8; } /* Display value without units */ if(flags & IW_POWER_RELATIVE) snprintf(buffer, buflen, "%g", ((double) value) / MEGA); else { /* Display value with units */ if(value >= (int) MEGA) snprintf(buffer, buflen, "%gs", ((double) value) / MEGA); else if(value >= (int) KILO) snprintf(buffer, buflen, "%gms", ((double) value) / KILO); else snprintf(buffer, buflen, "%dus", value); }}/*------------------------------------------------------------------*//* * Output a power management mode */voidiw_print_pm_mode(char * buffer, int buflen, int flags){ /* Check size */ if(buflen < 28) { snprintf(buffer, buflen, "<too big>"); return; } /* Print the proper mode... */ switch(flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: strcpy(buffer, "mode:Unicast only received"); /* Size checked */ break; case IW_POWER_MULTICAST_R: strcpy(buffer, "mode:Multicast only received"); /* Size checked */ break; case IW_POWER_ALL_R: strcpy(buffer, "mode:All packets received"); /* Size checked */ break; case IW_POWER_FORCE_S: strcpy(buffer, "mode:Force sending"); /* Size checked */ break; case IW_POWER_REPEATER: strcpy(buffer, "mode:Repeat multicasts"); /* Size checked */ break; default: strcpy(buffer, ""); /* Size checked */ break; }}/***************** RETRY LIMIT/LIFETIME SUBROUTINES *****************//*------------------------------------------------------------------*//* * Output a retry value with all attributes... */voidiw_print_retry_value(char * buffer, int buflen, int value, int flags){ /* Check buffer size */ if(buflen < 18) { snprintf(buffer, buflen, "<too big>"); return; } buflen -= 18; /* Modifiers */ if(flags & IW_RETRY_MIN) { strcpy(buffer, " min"); /* Size checked */ buffer += 4; } if(flags & IW_RETRY_MAX) { strcpy(buffer, " max"); /* Size checked */ buffer += 4; } /* Type lifetime of limit */ if(flags & IW_RETRY_LIFETIME) { strcpy(buffer, " lifetime:"); /* Size checked */ buffer += 10; /* Display value without units */ if(flags & IW_POWER_RELATIVE) snprintf(buffer, buflen, "%g", ((double) value) / MEGA); else { /* Display value with units */ if(value >= (int) MEGA) snprintf(buffer, buflen, "%gs", ((double) value) / MEGA); else if(value >= (int) KILO) snprintf(buffer, buflen, "%gms", ((double) value) / KILO); else snprintf(buffer, buflen, "%dus", value); } } else snprintf(buffer, buflen, " limit:%d", value);}/************************* TIME SUBROUTINES *************************//*------------------------------------------------------------------*//* * Print timestamps * Inspired from irdadump... */voidiw_print_timeval(char * buffer, int buflen, const struct timeval * timev, const struct timezone * tz){ int s; s = (timev->tv_sec - tz->tz_minuteswest * 60) % 86400; snprintf(buffer, buflen, "%02d:%02d:%02d.%06u", s / 3600, (s % 3600) / 60, s % 60, (u_int32_t) timev->tv_usec);}/*********************** ADDRESS SUBROUTINES ************************//* * This section is mostly a cut & past from net-tools-1.2.0 * (Well... This has evolved over the years) * manage address display and input... *//*------------------------------------------------------------------*//* * Check if interface support the right MAC address type... */intiw_check_mac_addr_type(int skfd, const char * ifname){ struct ifreq ifr; /* Get the type of hardware address */ strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if((ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) || ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) && (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211))) { /* Deep trouble... */ fprintf(stderr, "Interface %s doesn't support MAC addresses\n", ifname); return(-1); }#ifdef DEBUG { char buf[20]; printf("Hardware : %d - %s\n", ifr.ifr_hwaddr.sa_family, iw_saether_ntop(&ifr.ifr_hwaddr, buf)); }#endif return(0);}/*------------------------------------------------------------------*//* * Check if interface support the right interface address type... */intiw_check_if_addr_type(int skfd, const char * ifname){ struct ifreq ifr; /* Get the type of interface address */ strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 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 return(0);}#if 0/*------------------------------------------------------------------*//* * Check if interface support the right address types... */intiw_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);}#endif#if 0/*------------------------------------------------------------------*//* * Ask the kernel for the MAC address of an interface. */intiw_get_mac_addr(int skfd, const char * ifname, struct ether_addr * eth, unsigned short * ptype){ struct ifreq ifr; int ret; /* Prepare request */ bzero(&ifr, sizeof(struct ifreq)); strncpy(ifr.ifr_name, ifname, IFNAMSIZ); /* Do it */ ret = ioctl(skfd, SIOCGIFHWADDR, &ifr); memcpy(eth->ether_addr_octet, ifr.ifr_hwaddr.sa_data, 6); *ptype = ifr.ifr_hwaddr.sa_family; return(ret);}#endif/*------------------------------------------------------------------*//* * Display an arbitrary length MAC address in readable format. */char *iw_mac_ntop(const unsigned char * mac, int maclen, char * buf, int buflen){ int i; /* Overflow check (don't forget '\0') */ if(buflen < (maclen * 3 - 1 + 1)) return(NULL); /* First byte */ sprintf(buf, "%02X", mac[0]); /* Other bytes */ for(i = 1; i < maclen; i++) sprintf(buf + (i * 3) - 1, ":%02X", mac[i]); return(buf);}/*------------------------------------------------------------------*//* * Display an Ethernet address in readable format. */voidiw_ether_ntop(const struct ether_addr * eth, char * buf){ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", eth->ether_addr_octet[0], eth->ether_addr_octet[1], eth->ether_addr_octet[2], eth->ether_addr_octet[3], eth->ether_addr_octet[4], eth->ether_addr_octet[5]);}/*------------------------------------------------------------------*//* * Display an Wireless Access Point Socket Address in readable format. * Note : 0x44 is an accident of history, that's what the Orinoco/PrismII * chipset report, and the driver doesn't filter it. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -