1 /* 2 * iwinfo - Wireless Information Library - Command line frontend 3 * 4 * Copyright (C) 2011 Jo-Philipp Wich <xm@subsignal.org> 5 * 6 * The iwinfo library is free software: you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 2 8 * as published by the Free Software Foundation. 9 * 10 * The iwinfo library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * See the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with the iwinfo library. If not, see http://www.gnu.org/licenses/. 17 */ 18 19 #include <stdio.h> 20 #include <glob.h> 21 22 #include "iwinfo.h" 23 24 25 static char * format_bssid(unsigned char *mac) 26 { 27 static char buf[18]; 28 29 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", 30 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 31 32 return buf; 33 } 34 35 static char * format_ssid(char *ssid) 36 { 37 static char buf[IWINFO_ESSID_MAX_SIZE+3]; 38 39 if (ssid && ssid[0]) 40 snprintf(buf, sizeof(buf), "\"%s\"", ssid); 41 else 42 snprintf(buf, sizeof(buf), "unknown"); 43 44 return buf; 45 } 46 47 static const char *format_band(int band) 48 { 49 const char *name; 50 51 name = iwinfo_band_name(band); 52 if (name) 53 return name; 54 55 return "unknown"; 56 } 57 58 static char * format_channel(int ch) 59 { 60 static char buf[16]; 61 62 if (ch <= 0) 63 snprintf(buf, sizeof(buf), "unknown"); 64 else 65 snprintf(buf, sizeof(buf), "%d", ch); 66 67 return buf; 68 } 69 70 static char * format_frequency(int freq) 71 { 72 static char buf[11]; 73 74 if (freq <= 0) 75 snprintf(buf, sizeof(buf), "unknown"); 76 else 77 snprintf(buf, sizeof(buf), "%.3f GHz", ((float)freq / 1000.0)); 78 79 return buf; 80 } 81 82 static char * format_freqflags(uint32_t flags) 83 { 84 static char str[512] = "["; 85 char *pos = str + 1; 86 int i; 87 88 if (!flags) 89 return ""; 90 91 for (i = 0; i < IWINFO_FREQ_FLAG_COUNT; i++) 92 if (flags & (1 << i)) 93 pos += sprintf(pos, "%s, ", IWINFO_FREQ_FLAG_NAMES[i]); 94 95 *(pos - 2) = ']'; 96 *(pos - 1) = 0; 97 98 return str; 99 } 100 101 static char * format_txpower(int pwr) 102 { 103 static char buf[16]; 104 105 if (pwr < 0) 106 snprintf(buf, sizeof(buf), "unknown"); 107 else 108 snprintf(buf, sizeof(buf), "%d dBm", pwr); 109 110 return buf; 111 } 112 113 static char * format_quality(int qual) 114 { 115 static char buf[16]; 116 117 if (qual < 0) 118 snprintf(buf, sizeof(buf), "unknown"); 119 else 120 snprintf(buf, sizeof(buf), "%d", qual); 121 122 return buf; 123 } 124 125 static char * format_quality_max(int qmax) 126 { 127 static char buf[16]; 128 129 if (qmax < 0) 130 snprintf(buf, sizeof(buf), "unknown"); 131 else 132 snprintf(buf, sizeof(buf), "%d", qmax); 133 134 return buf; 135 } 136 137 static char * format_signal(int sig) 138 { 139 static char buf[10]; 140 141 if (!sig) 142 snprintf(buf, sizeof(buf), "unknown"); 143 else 144 snprintf(buf, sizeof(buf), "%d dBm", sig); 145 146 return buf; 147 } 148 149 static char * format_noise(int noise) 150 { 151 static char buf[10]; 152 153 if (!noise) 154 snprintf(buf, sizeof(buf), "unknown"); 155 else 156 snprintf(buf, sizeof(buf), "%d dBm", noise); 157 158 return buf; 159 } 160 161 static char * format_rate(int rate) 162 { 163 static char buf[18]; 164 165 if (rate <= 0) 166 snprintf(buf, sizeof(buf), "unknown"); 167 else 168 snprintf(buf, sizeof(buf), "%d.%d MBit/s", 169 rate / 1000, (rate % 1000) / 100); 170 171 return buf; 172 } 173 174 static char * format_enc_ciphers(int ciphers) 175 { 176 static char str[128] = { 0 }; 177 char *pos = str; 178 int i; 179 180 for (i = 0; i < IWINFO_CIPHER_COUNT; i++) 181 if (ciphers & (1 << i)) 182 pos += sprintf(pos, "%s, ", IWINFO_CIPHER_NAMES[i]); 183 184 *(pos - 2) = 0; 185 186 return str; 187 } 188 189 static char * format_enc_suites(int suites) 190 { 191 static char str[64] = { 0 }; 192 char *pos = str; 193 int i; 194 195 for (i = 0; i < IWINFO_KMGMT_COUNT; i++) 196 if (suites & (1 << i)) 197 pos += sprintf(pos, "%s/", IWINFO_KMGMT_NAMES[i]); 198 199 *(pos - 1) = 0; 200 201 return str; 202 } 203 204 static char * format_encryption(struct iwinfo_crypto_entry *c) 205 { 206 static char buf[512]; 207 char *pos = buf; 208 int i, n; 209 210 if (!c) 211 { 212 snprintf(buf, sizeof(buf), "unknown"); 213 } 214 else if (c->enabled) 215 { 216 /* WEP */ 217 if (c->auth_algs && !c->wpa_version) 218 { 219 if ((c->auth_algs & IWINFO_AUTH_OPEN) && 220 (c->auth_algs & IWINFO_AUTH_SHARED)) 221 { 222 snprintf(buf, sizeof(buf), "WEP Open/Shared (%s)", 223 format_enc_ciphers(c->pair_ciphers)); 224 } 225 else if (c->auth_algs & IWINFO_AUTH_OPEN) 226 { 227 snprintf(buf, sizeof(buf), "WEP Open System (%s)", 228 format_enc_ciphers(c->pair_ciphers)); 229 } 230 else if (c->auth_algs & IWINFO_AUTH_SHARED) 231 { 232 snprintf(buf, sizeof(buf), "WEP Shared Auth (%s)", 233 format_enc_ciphers(c->pair_ciphers)); 234 } 235 } 236 237 /* WPA */ 238 else if (c->wpa_version) 239 { 240 for (i = 0, n = 0; i < 3; i++) 241 if (c->wpa_version & (1 << i)) 242 n++; 243 244 if (n > 1) 245 pos += sprintf(pos, "mixed "); 246 247 for (i = 0; i < 3; i++) 248 if (c->wpa_version & (1 << i)) 249 { 250 if (i) 251 pos += sprintf(pos, "WPA%d/", i + 1); 252 else 253 pos += sprintf(pos, "WPA/"); 254 } 255 256 pos--; 257 258 sprintf(pos, " %s (%s)", 259 format_enc_suites(c->auth_suites), 260 format_enc_ciphers(c->pair_ciphers | c->group_ciphers)); 261 } 262 else 263 { 264 snprintf(buf, sizeof(buf), "none"); 265 } 266 } 267 else 268 { 269 snprintf(buf, sizeof(buf), "none"); 270 } 271 272 return buf; 273 } 274 275 static char * format_hwmodes(int modes) 276 { 277 static char buf[32] = "802.11"; 278 279 if (iwinfo_format_hwmodes(modes, buf + 6, sizeof(buf) - 6) < 1) 280 snprintf(buf, sizeof(buf), "unknown"); 281 282 return buf; 283 } 284 285 static char * format_assocrate(struct iwinfo_rate_entry *r) 286 { 287 static char buf[80]; 288 char *p = buf; 289 int l = sizeof(buf); 290 291 if (r->rate <= 0) 292 { 293 snprintf(buf, sizeof(buf), "unknown"); 294 } 295 else 296 { 297 p += snprintf(p, l, "%s", format_rate(r->rate)); 298 l = sizeof(buf) - (p - buf); 299 300 if (r->is_ht) 301 { 302 p += snprintf(p, l, ", MCS %d, %dMHz", r->mcs, r->mhz); 303 l = sizeof(buf) - (p - buf); 304 } 305 else if (r->is_vht) 306 { 307 p += snprintf(p, l, ", VHT-MCS %d, %dMHz", r->mcs, r->mhz); 308 l = sizeof(buf) - (p - buf); 309 310 if (r->nss) 311 { 312 p += snprintf(p, l, ", VHT-NSS %d", r->nss); 313 l = sizeof(buf) - (p - buf); 314 } 315 } 316 else if (r->is_he) 317 { 318 p += snprintf(p, l, ", HE-MCS %d, %dMHz", r->mcs, r->mhz); 319 l = sizeof(buf) - (p - buf); 320 321 p += snprintf(p, l, ", HE-NSS %d", r->nss); 322 l = sizeof(buf) - (p - buf); 323 324 p += snprintf(p, l, ", HE-GI %d", r->he_gi); 325 l = sizeof(buf) - (p - buf); 326 327 p += snprintf(p, l, ", HE-DCM %d", r->he_dcm); 328 l = sizeof(buf) - (p - buf); 329 } 330 else if (r->is_eht) 331 { 332 p += snprintf(p, l, ", EHT-MCS %d, %dMHz", r->mcs, r->mhz_hi * 256 + r->mhz); 333 l = sizeof(buf) - (p - buf); 334 335 p += snprintf(p, l, ", EHT-NSS %d", r->nss); 336 l = sizeof(buf) - (p - buf); 337 338 p += snprintf(p, l, ", EHT-GI %d", r->eht_gi); 339 l = sizeof(buf) - (p - buf); 340 } 341 } 342 343 return buf; 344 } 345 346 static const char* format_chan_width(bool vht, uint8_t width) 347 { 348 if (!vht && width < ARRAY_SIZE(ht_chan_width)) 349 switch (ht_chan_width[width]) { 350 case 20: return "20 MHz"; 351 case 2040: return "40 MHz or higher"; 352 } 353 354 if (vht && width < ARRAY_SIZE(vht_chan_width)) 355 switch (vht_chan_width[width]) { 356 case 40: return "20 or 40 MHz"; 357 case 80: return "80 MHz"; 358 case 8080: return "80+80 MHz"; 359 case 160: return "160 MHz"; 360 } 361 362 return "unknown"; 363 } 364 365 366 static const char * print_type(const struct iwinfo_ops *iw, const char *ifname) 367 { 368 const char *type = iwinfo_type(ifname); 369 return type ? type : "unknown"; 370 } 371 372 static char * print_hardware_id(const struct iwinfo_ops *iw, const char *ifname) 373 { 374 static char buf[20]; 375 struct iwinfo_hardware_id ids; 376 377 if (!iw->hardware_id(ifname, (char *)&ids)) 378 { 379 if (strlen(ids.compatible) > 0) 380 snprintf(buf, sizeof(buf), "embedded"); 381 else if (ids.vendor_id == 0 && ids.device_id == 0 && 382 ids.subsystem_vendor_id != 0 && ids.subsystem_device_id != 0) 383 snprintf(buf, sizeof(buf), "USB %04X:%04X", 384 ids.subsystem_vendor_id, ids.subsystem_device_id); 385 else 386 snprintf(buf, sizeof(buf), "%04X:%04X %04X:%04X", 387 ids.vendor_id, ids.device_id, 388 ids.subsystem_vendor_id, ids.subsystem_device_id); 389 } 390 else 391 { 392 snprintf(buf, sizeof(buf), "unknown"); 393 } 394 395 return buf; 396 } 397 398 static char * print_hardware_name(const struct iwinfo_ops *iw, const char *ifname) 399 { 400 static char buf[128]; 401 402 if (iw->hardware_name(ifname, buf)) 403 snprintf(buf, sizeof(buf), "unknown"); 404 405 return buf; 406 } 407 408 static char * print_txpower_offset(const struct iwinfo_ops *iw, const char *ifname) 409 { 410 int off; 411 static char buf[12]; 412 413 if (iw->txpower_offset(ifname, &off)) 414 snprintf(buf, sizeof(buf), "unknown"); 415 else if (off != 0) 416 snprintf(buf, sizeof(buf), "%d dB", off); 417 else 418 snprintf(buf, sizeof(buf), "none"); 419 420 return buf; 421 } 422 423 static char * print_frequency_offset(const struct iwinfo_ops *iw, const char *ifname) 424 { 425 int off; 426 static char buf[12]; 427 428 if (iw->frequency_offset(ifname, &off)) 429 snprintf(buf, sizeof(buf), "unknown"); 430 else if (off != 0) 431 snprintf(buf, sizeof(buf), "%.3f GHz", ((float)off / 1000.0)); 432 else 433 snprintf(buf, sizeof(buf), "none"); 434 435 return buf; 436 } 437 438 static char * print_ssid(const struct iwinfo_ops *iw, const char *ifname) 439 { 440 char buf[IWINFO_ESSID_MAX_SIZE+1] = { 0 }; 441 442 if (iw->ssid(ifname, buf)) 443 memset(buf, 0, sizeof(buf)); 444 445 return format_ssid(buf); 446 } 447 448 static char * print_bssid(const struct iwinfo_ops *iw, const char *ifname) 449 { 450 static char buf[18] = { 0 }; 451 452 if (iw->bssid(ifname, buf)) 453 snprintf(buf, sizeof(buf), "00:00:00:00:00:00"); 454 455 return buf; 456 } 457 458 static char * print_mode(const struct iwinfo_ops *iw, const char *ifname) 459 { 460 int mode; 461 static char buf[128]; 462 463 if (iw->mode(ifname, &mode)) 464 mode = IWINFO_OPMODE_UNKNOWN; 465 466 snprintf(buf, sizeof(buf), "%s", IWINFO_OPMODE_NAMES[mode]); 467 468 return buf; 469 } 470 471 static char * print_channel(const struct iwinfo_ops *iw, const char *ifname) 472 { 473 int ch; 474 if (iw->channel(ifname, &ch)) 475 ch = -1; 476 477 return format_channel(ch); 478 } 479 480 static char * print_center_chan1(const struct iwinfo_ops *iw, const char *ifname) 481 { 482 int ch; 483 if (iw->center_chan1(ifname, &ch)) 484 ch = -1; 485 486 return format_channel(ch); 487 } 488 489 static char * print_center_chan2(const struct iwinfo_ops *iw, const char *ifname) 490 { 491 int ch; 492 if (iw->center_chan2(ifname, &ch)) 493 ch = -1; 494 495 return format_channel(ch); 496 } 497 498 static char * print_frequency(const struct iwinfo_ops *iw, const char *ifname) 499 { 500 int freq; 501 if (iw->frequency(ifname, &freq)) 502 freq = -1; 503 504 return format_frequency(freq); 505 } 506 507 static char * print_txpower(const struct iwinfo_ops *iw, const char *ifname) 508 { 509 int pwr, off; 510 if (iw->txpower_offset(ifname, &off)) 511 off = 0; 512 513 if (iw->txpower(ifname, &pwr)) 514 pwr = -1; 515 else 516 pwr += off; 517 518 return format_txpower(pwr); 519 } 520 521 static char * print_quality(const struct iwinfo_ops *iw, const char *ifname) 522 { 523 int qual; 524 if (iw->quality(ifname, &qual)) 525 qual = -1; 526 527 return format_quality(qual); 528 } 529 530 static char * print_quality_max(const struct iwinfo_ops *iw, const char *ifname) 531 { 532 int qmax; 533 if (iw->quality_max(ifname, &qmax)) 534 qmax = -1; 535 536 return format_quality_max(qmax); 537 } 538 539 static char * print_signal(const struct iwinfo_ops *iw, const char *ifname) 540 { 541 int sig; 542 if (iw->signal(ifname, &sig)) 543 sig = 0; 544 545 return format_signal(sig); 546 } 547 548 static char * print_noise(const struct iwinfo_ops *iw, const char *ifname) 549 { 550 int noise; 551 if (iw->noise(ifname, &noise)) 552 noise = 0; 553 554 return format_noise(noise); 555 } 556 557 static char * print_rate(const struct iwinfo_ops *iw, const char *ifname) 558 { 559 int rate; 560 if (iw->bitrate(ifname, &rate)) 561 rate = -1; 562 563 return format_rate(rate); 564 } 565 566 static char * print_encryption(const struct iwinfo_ops *iw, const char *ifname) 567 { 568 struct iwinfo_crypto_entry c = { 0 }; 569 if (iw->encryption(ifname, (char *)&c)) 570 return format_encryption(NULL); 571 572 return format_encryption(&c); 573 } 574 575 static char * print_hwmodes(const struct iwinfo_ops *iw, const char *ifname) 576 { 577 int modes; 578 if (iw->hwmodelist(ifname, &modes)) 579 modes = -1; 580 581 return format_hwmodes(modes); 582 } 583 584 static const char *print_htmode(const struct iwinfo_ops *iw, const char *ifname) 585 { 586 int mode; 587 const char *name; 588 if (iw->htmode(ifname, &mode)) 589 mode = -1; 590 591 name = iwinfo_htmode_name(mode); 592 if (name) 593 return name; 594 595 return "unknown"; 596 } 597 598 static char * print_mbssid_supp(const struct iwinfo_ops *iw, const char *ifname) 599 { 600 int supp; 601 static char buf[4]; 602 603 if (iw->mbssid_support(ifname, &supp)) 604 snprintf(buf, sizeof(buf), "no"); 605 else 606 snprintf(buf, sizeof(buf), "%s", supp ? "yes" : "no"); 607 608 return buf; 609 } 610 611 static char * print_phyname(const struct iwinfo_ops *iw, const char *ifname) 612 { 613 static char buf[32]; 614 615 if (!iw->phyname(ifname, buf)) 616 return buf; 617 618 return "?"; 619 } 620 621 622 static void print_info(const struct iwinfo_ops *iw, const char *ifname) 623 { 624 printf("%-9s ESSID: %s\n", 625 ifname, 626 print_ssid(iw, ifname)); 627 printf(" Access Point: %s\n", 628 print_bssid(iw, ifname)); 629 printf(" Mode: %s Channel: %s (%s) HT Mode: %s\n", 630 print_mode(iw, ifname), 631 print_channel(iw, ifname), 632 print_frequency(iw, ifname), 633 print_htmode(iw, ifname)); 634 if (iw->center_chan1 != NULL) { 635 printf(" Center Channel 1: %s", 636 print_center_chan1(iw, ifname)); 637 printf(" 2: %s\n", print_center_chan2(iw, ifname)); 638 } 639 printf(" Tx-Power: %s Link Quality: %s/%s\n", 640 print_txpower(iw, ifname), 641 print_quality(iw, ifname), 642 print_quality_max(iw, ifname)); 643 printf(" Signal: %s Noise: %s\n", 644 print_signal(iw, ifname), 645 print_noise(iw, ifname)); 646 printf(" Bit Rate: %s\n", 647 print_rate(iw, ifname)); 648 printf(" Encryption: %s\n", 649 print_encryption(iw, ifname)); 650 printf(" Type: %s HW Mode(s): %s\n", 651 print_type(iw, ifname), 652 print_hwmodes(iw, ifname)); 653 printf(" Hardware: %s [%s]\n", 654 print_hardware_id(iw, ifname), 655 print_hardware_name(iw, ifname)); 656 printf(" TX power offset: %s\n", 657 print_txpower_offset(iw, ifname)); 658 printf(" Frequency offset: %s\n", 659 print_frequency_offset(iw, ifname)); 660 printf(" Supports VAPs: %s PHY name: %s\n", 661 print_mbssid_supp(iw, ifname), 662 print_phyname(iw, ifname)); 663 } 664 665 666 static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) 667 { 668 int i, x, len; 669 char buf[IWINFO_BUFSIZE]; 670 struct iwinfo_scanlist_entry *e; 671 672 if (iw->scanlist(ifname, buf, &len)) 673 { 674 printf("Scanning not possible\n\n"); 675 return; 676 } 677 else if (len <= 0) 678 { 679 printf("No scan results\n\n"); 680 return; 681 } 682 683 for (i = 0, x = 1; i < len; i += sizeof(struct iwinfo_scanlist_entry), x++) 684 { 685 e = (struct iwinfo_scanlist_entry *) &buf[i]; 686 687 printf("Cell %02d - Address: %s\n", 688 x, 689 format_bssid(e->mac)); 690 printf(" ESSID: %s\n", 691 format_ssid(e->ssid)); 692 printf(" Mode: %s Frequency: %s Band: %s Channel: %s\n", 693 IWINFO_OPMODE_NAMES[e->mode], 694 format_frequency(e->mhz), 695 format_band(e->band), 696 format_channel(e->channel)); 697 printf(" Signal: %s Quality: %s/%s\n", 698 format_signal(e->signal - 0x100), 699 format_quality(e->quality), 700 format_quality_max(e->quality_max)); 701 printf(" Encryption: %s\n", 702 format_encryption(&e->crypto)); 703 printf(" HT Operation:\n"); 704 printf(" Primary Channel: %d\n", 705 e->ht_chan_info.primary_chan); 706 printf(" Secondary Channel Offset: %s\n", 707 ht_secondary_offset[e->ht_chan_info.secondary_chan_off]); 708 printf(" Channel Width: %s\n", 709 format_chan_width(false, e->ht_chan_info.chan_width)); 710 711 if (e->vht_chan_info.center_chan_1) { 712 printf(" VHT Operation:\n"); 713 printf(" Center Frequency 1: %d\n", 714 e->vht_chan_info.center_chan_1); 715 printf(" Center Frequency 2: %d\n", 716 e->vht_chan_info.center_chan_2); 717 printf(" Channel Width: %s\n", 718 format_chan_width(true, e->vht_chan_info.chan_width)); 719 } 720 721 printf("\n"); 722 } 723 } 724 725 726 static void print_txpwrlist(const struct iwinfo_ops *iw, const char *ifname) 727 { 728 int len, pwr, off, i; 729 char buf[IWINFO_BUFSIZE]; 730 struct iwinfo_txpwrlist_entry *e; 731 732 if (iw->txpwrlist(ifname, buf, &len) || len <= 0) 733 { 734 printf("No TX power information available\n"); 735 return; 736 } 737 738 if (iw->txpower(ifname, &pwr)) 739 pwr = -1; 740 741 if (iw->txpower_offset(ifname, &off)) 742 off = 0; 743 744 for (i = 0; i < len; i += sizeof(struct iwinfo_txpwrlist_entry)) 745 { 746 e = (struct iwinfo_txpwrlist_entry *) &buf[i]; 747 748 printf("%s%3d dBm (%4d mW)\n", 749 (pwr == e->dbm) ? "*" : " ", 750 e->dbm + off, 751 iwinfo_dbm2mw(e->dbm + off)); 752 } 753 } 754 755 756 static void print_freqlist(const struct iwinfo_ops *iw, const char *ifname) 757 { 758 int i, len, freq; 759 char buf[IWINFO_BUFSIZE]; 760 struct iwinfo_freqlist_entry *e; 761 762 if (iw->freqlist(ifname, buf, &len) || len <= 0) 763 { 764 printf("No frequency information available\n"); 765 return; 766 } 767 768 if (iw->frequency(ifname, &freq)) 769 freq = -1; 770 771 for (i = 0; i < len; i += sizeof(struct iwinfo_freqlist_entry)) 772 { 773 e = (struct iwinfo_freqlist_entry *) &buf[i]; 774 775 printf("%s %s (Band: %s, Channel %s) %s\n", 776 (freq == e->mhz) ? "*" : " ", 777 format_frequency(e->mhz), 778 format_band(e->band), 779 format_channel(e->channel), 780 format_freqflags(e->flags)); 781 } 782 } 783 784 785 static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname) 786 { 787 int i, len; 788 char buf[IWINFO_BUFSIZE]; 789 struct iwinfo_assoclist_entry *e; 790 791 if (iw->assoclist(ifname, buf, &len)) 792 { 793 printf("No information available\n"); 794 return; 795 } 796 else if (len <= 0) 797 { 798 printf("No station connected\n"); 799 return; 800 } 801 802 for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) 803 { 804 e = (struct iwinfo_assoclist_entry *) &buf[i]; 805 806 printf("%s %s / %s (SNR %d) %d ms ago\n", 807 format_bssid(e->mac), 808 format_signal(e->signal), 809 format_noise(e->noise), 810 (e->signal - e->noise), 811 e->inactive); 812 813 printf(" RX: %-38s %8d Pkts.\n", 814 format_assocrate(&e->rx_rate), 815 e->rx_packets 816 ); 817 818 printf(" TX: %-38s %8d Pkts.\n", 819 format_assocrate(&e->tx_rate), 820 e->tx_packets 821 ); 822 823 printf(" expected throughput: %s\n\n", 824 format_rate(e->thr)); 825 } 826 } 827 828 829 static char * lookup_country(char *buf, int len, int iso3166) 830 { 831 int i; 832 struct iwinfo_country_entry *c; 833 834 for (i = 0; i < len; i += sizeof(struct iwinfo_country_entry)) 835 { 836 c = (struct iwinfo_country_entry *) &buf[i]; 837 838 if (c->iso3166 == iso3166) 839 return c->ccode; 840 } 841 842 return NULL; 843 } 844 845 static void print_countrylist(const struct iwinfo_ops *iw, const char *ifname) 846 { 847 int len; 848 char buf[IWINFO_BUFSIZE]; 849 char *ccode; 850 char curcode[3]; 851 const struct iwinfo_iso3166_label *l; 852 853 if (iw->countrylist(ifname, buf, &len)) 854 { 855 printf("No country code information available\n"); 856 return; 857 } 858 859 if (iw->country(ifname, curcode)) 860 memset(curcode, 0, sizeof(curcode)); 861 862 for (l = IWINFO_ISO3166_NAMES; l->iso3166; l++) 863 { 864 if ((ccode = lookup_country(buf, len, l->iso3166)) != NULL) 865 { 866 printf("%s %4s %c%c\n", 867 strncmp(ccode, curcode, 2) ? " " : "*", 868 ccode, (l->iso3166 / 256), (l->iso3166 % 256)); 869 } 870 } 871 } 872 873 static void print_htmodelist(const struct iwinfo_ops *iw, const char *ifname) 874 { 875 int i, htmodes = 0; 876 877 if (iw->htmodelist(ifname, &htmodes)) 878 { 879 printf("No HT mode information available\n"); 880 return; 881 } 882 883 for (i = 0; i < IWINFO_HTMODE_COUNT; i++) 884 if (htmodes & (1 << i)) 885 printf("%s ", IWINFO_HTMODE_NAMES[i]); 886 887 printf("\n"); 888 } 889 890 static void lookup_phy(const struct iwinfo_ops *iw, const char *section) 891 { 892 char buf[IWINFO_BUFSIZE]; 893 894 if (!iw->lookup_phy) 895 { 896 fprintf(stderr, "Not supported\n"); 897 return; 898 } 899 900 if (iw->lookup_phy(section, buf)) 901 { 902 fprintf(stderr, "Phy not found\n"); 903 return; 904 } 905 906 printf("%s\n", buf); 907 } 908 909 910 static void lookup_path(const struct iwinfo_ops *iw, const char *phy) 911 { 912 const char *path; 913 914 if (!iw->phy_path || iw->phy_path(phy, &path) || !path) 915 return; 916 917 printf("%s\n", path); 918 } 919 920 int main(int argc, char **argv) 921 { 922 int i, rv = 0; 923 char *p; 924 const struct iwinfo_ops *iw; 925 glob_t globbuf; 926 927 if (argc > 1 && argc < 3) 928 { 929 fprintf(stderr, 930 "Usage:\n" 931 " iwinfo <device> info\n" 932 " iwinfo <device> scan\n" 933 " iwinfo <device> txpowerlist\n" 934 " iwinfo <device> freqlist\n" 935 " iwinfo <device> assoclist\n" 936 " iwinfo <device> countrylist\n" 937 " iwinfo <device> htmodelist\n" 938 " iwinfo <backend> phyname <section>\n" 939 ); 940 941 return 1; 942 } 943 944 if (argc == 1) 945 { 946 glob("/sys/class/net/*", 0, NULL, &globbuf); 947 948 for (i = 0; i < globbuf.gl_pathc; i++) 949 { 950 p = strrchr(globbuf.gl_pathv[i], '/'); 951 952 if (!p) 953 continue; 954 955 iw = iwinfo_backend(++p); 956 957 if (!iw) 958 continue; 959 960 print_info(iw, p); 961 printf("\n"); 962 } 963 964 globfree(&globbuf); 965 return 0; 966 } 967 968 if (argc > 3) 969 { 970 iw = iwinfo_backend_by_name(argv[1]); 971 972 if (!iw) 973 { 974 fprintf(stderr, "No such wireless backend: %s\n", argv[1]); 975 rv = 1; 976 } 977 else 978 { 979 if (!strcmp(argv[2], "path")) { 980 lookup_path(iw, argv[3]); 981 return 0; 982 } 983 switch (argv[2][0]) 984 { 985 case 'p': 986 lookup_phy(iw, argv[3]); 987 break; 988 989 default: 990 fprintf(stderr, "Unknown command: %s\n", argv[2]); 991 rv = 1; 992 } 993 } 994 } 995 else 996 { 997 iw = iwinfo_backend(argv[1]); 998 999 if (!iw) 1000 { 1001 fprintf(stderr, "No such wireless device: %s\n", argv[1]); 1002 rv = 1; 1003 } 1004 else 1005 { 1006 for (i = 2; i < argc; i++) 1007 { 1008 switch(argv[i][0]) 1009 { 1010 case 'i': 1011 print_info(iw, argv[1]); 1012 break; 1013 1014 case 's': 1015 print_scanlist(iw, argv[1]); 1016 break; 1017 1018 case 't': 1019 print_txpwrlist(iw, argv[1]); 1020 break; 1021 1022 case 'f': 1023 print_freqlist(iw, argv[1]); 1024 break; 1025 1026 case 'a': 1027 print_assoclist(iw, argv[1]); 1028 break; 1029 1030 case 'c': 1031 print_countrylist(iw, argv[1]); 1032 break; 1033 1034 case 'h': 1035 print_htmodelist(iw, argv[1]); 1036 break; 1037 1038 default: 1039 fprintf(stderr, "Unknown command: %s\n", argv[i]); 1040 rv = 1; 1041 } 1042 } 1043 } 1044 } 1045 1046 iwinfo_finish(); 1047 1048 return rv; 1049 } 1050
This page was automatically generated by LXR 0.3.1. • OpenWrt