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 static const char* format_6ghz_chan_width(uint8_t width) 366 { 367 if (width < ARRAY_SIZE(eht_chan_width)) 368 switch (eht_chan_width[width]) { 369 case 20: return "20 MHz"; 370 case 40: return "40 MHz"; 371 case 80: return "80 MHz"; 372 case 160: return "160 MHz"; 373 case 320: return "320 MHz"; 374 } 375 376 return "unknown"; 377 } 378 379 static const char * print_type(const struct iwinfo_ops *iw, const char *ifname) 380 { 381 const char *type = iwinfo_type(ifname); 382 return type ? type : "unknown"; 383 } 384 385 static char * print_hardware_id(const struct iwinfo_ops *iw, const char *ifname) 386 { 387 static char buf[20]; 388 struct iwinfo_hardware_id ids; 389 390 if (!iw->hardware_id(ifname, (char *)&ids)) 391 { 392 if (strlen(ids.compatible) > 0) 393 snprintf(buf, sizeof(buf), "embedded"); 394 else if (ids.vendor_id == 0 && ids.device_id == 0 && 395 ids.subsystem_vendor_id != 0 && ids.subsystem_device_id != 0) 396 snprintf(buf, sizeof(buf), "USB %04X:%04X", 397 ids.subsystem_vendor_id, ids.subsystem_device_id); 398 else 399 snprintf(buf, sizeof(buf), "%04X:%04X %04X:%04X", 400 ids.vendor_id, ids.device_id, 401 ids.subsystem_vendor_id, ids.subsystem_device_id); 402 } 403 else 404 { 405 snprintf(buf, sizeof(buf), "unknown"); 406 } 407 408 return buf; 409 } 410 411 static char * print_hardware_name(const struct iwinfo_ops *iw, const char *ifname) 412 { 413 static char buf[128]; 414 415 if (iw->hardware_name(ifname, buf)) 416 snprintf(buf, sizeof(buf), "unknown"); 417 418 return buf; 419 } 420 421 static char * print_txpower_offset(const struct iwinfo_ops *iw, const char *ifname) 422 { 423 int off; 424 static char buf[12]; 425 426 if (iw->txpower_offset(ifname, &off)) 427 snprintf(buf, sizeof(buf), "unknown"); 428 else if (off != 0) 429 snprintf(buf, sizeof(buf), "%d dB", off); 430 else 431 snprintf(buf, sizeof(buf), "none"); 432 433 return buf; 434 } 435 436 static char * print_frequency_offset(const struct iwinfo_ops *iw, const char *ifname) 437 { 438 int off; 439 static char buf[12]; 440 441 if (iw->frequency_offset(ifname, &off)) 442 snprintf(buf, sizeof(buf), "unknown"); 443 else if (off != 0) 444 snprintf(buf, sizeof(buf), "%.3f GHz", ((float)off / 1000.0)); 445 else 446 snprintf(buf, sizeof(buf), "none"); 447 448 return buf; 449 } 450 451 static char * print_ssid(const struct iwinfo_ops *iw, const char *ifname) 452 { 453 char buf[IWINFO_ESSID_MAX_SIZE+1] = { 0 }; 454 455 if (iw->ssid(ifname, buf)) 456 memset(buf, 0, sizeof(buf)); 457 458 return format_ssid(buf); 459 } 460 461 static char * print_bssid(const struct iwinfo_ops *iw, const char *ifname) 462 { 463 static char buf[18] = { 0 }; 464 465 if (iw->bssid(ifname, buf)) 466 snprintf(buf, sizeof(buf), "00:00:00:00:00:00"); 467 468 return buf; 469 } 470 471 static char * print_mode(const struct iwinfo_ops *iw, const char *ifname) 472 { 473 int mode; 474 static char buf[128]; 475 476 if (iw->mode(ifname, &mode)) 477 mode = IWINFO_OPMODE_UNKNOWN; 478 479 snprintf(buf, sizeof(buf), "%s", IWINFO_OPMODE_NAMES[mode]); 480 481 return buf; 482 } 483 484 static char * print_channel(const struct iwinfo_ops *iw, const char *ifname) 485 { 486 int ch; 487 if (iw->channel(ifname, &ch)) 488 ch = -1; 489 490 return format_channel(ch); 491 } 492 493 static char * print_center_chan1(const struct iwinfo_ops *iw, const char *ifname) 494 { 495 int ch; 496 if (iw->center_chan1(ifname, &ch)) 497 ch = -1; 498 499 return format_channel(ch); 500 } 501 502 static char * print_center_chan2(const struct iwinfo_ops *iw, const char *ifname) 503 { 504 int ch; 505 if (iw->center_chan2(ifname, &ch)) 506 ch = -1; 507 508 return format_channel(ch); 509 } 510 511 static char * print_frequency(const struct iwinfo_ops *iw, const char *ifname) 512 { 513 int freq; 514 if (iw->frequency(ifname, &freq)) 515 freq = -1; 516 517 return format_frequency(freq); 518 } 519 520 static char * print_txpower(const struct iwinfo_ops *iw, const char *ifname) 521 { 522 int pwr, off; 523 if (iw->txpower_offset(ifname, &off)) 524 off = 0; 525 526 if (iw->txpower(ifname, &pwr)) 527 pwr = -1; 528 else 529 pwr += off; 530 531 return format_txpower(pwr); 532 } 533 534 static char * print_quality(const struct iwinfo_ops *iw, const char *ifname) 535 { 536 int qual; 537 if (iw->quality(ifname, &qual)) 538 qual = -1; 539 540 return format_quality(qual); 541 } 542 543 static char * print_quality_max(const struct iwinfo_ops *iw, const char *ifname) 544 { 545 int qmax; 546 if (iw->quality_max(ifname, &qmax)) 547 qmax = -1; 548 549 return format_quality_max(qmax); 550 } 551 552 static char * print_signal(const struct iwinfo_ops *iw, const char *ifname) 553 { 554 int sig; 555 if (iw->signal(ifname, &sig)) 556 sig = 0; 557 558 return format_signal(sig); 559 } 560 561 static char * print_noise(const struct iwinfo_ops *iw, const char *ifname) 562 { 563 int noise; 564 if (iw->noise(ifname, &noise)) 565 noise = 0; 566 567 return format_noise(noise); 568 } 569 570 static char * print_rate(const struct iwinfo_ops *iw, const char *ifname) 571 { 572 int rate; 573 if (iw->bitrate(ifname, &rate)) 574 rate = -1; 575 576 return format_rate(rate); 577 } 578 579 static char * print_encryption(const struct iwinfo_ops *iw, const char *ifname) 580 { 581 struct iwinfo_crypto_entry c = { 0 }; 582 if (iw->encryption(ifname, (char *)&c)) 583 return format_encryption(NULL); 584 585 return format_encryption(&c); 586 } 587 588 static char * print_hwmodes(const struct iwinfo_ops *iw, const char *ifname) 589 { 590 int modes; 591 if (iw->hwmodelist(ifname, &modes)) 592 modes = -1; 593 594 return format_hwmodes(modes); 595 } 596 597 static const char *print_htmode(const struct iwinfo_ops *iw, const char *ifname) 598 { 599 int mode; 600 const char *name; 601 if (iw->htmode(ifname, &mode)) 602 mode = -1; 603 604 name = iwinfo_htmode_name(mode); 605 if (name) 606 return name; 607 608 return "unknown"; 609 } 610 611 static char * print_mbssid_supp(const struct iwinfo_ops *iw, const char *ifname) 612 { 613 int supp; 614 static char buf[4]; 615 616 if (iw->mbssid_support(ifname, &supp)) 617 snprintf(buf, sizeof(buf), "no"); 618 else 619 snprintf(buf, sizeof(buf), "%s", supp ? "yes" : "no"); 620 621 return buf; 622 } 623 624 static char * print_phyname(const struct iwinfo_ops *iw, const char *ifname) 625 { 626 static char buf[32]; 627 628 if (!iw->phyname(ifname, buf)) 629 return buf; 630 631 return "?"; 632 } 633 634 635 static void print_info(const struct iwinfo_ops *iw, const char *ifname) 636 { 637 printf("%-9s ESSID: %s\n", 638 ifname, 639 print_ssid(iw, ifname)); 640 printf(" Access Point: %s\n", 641 print_bssid(iw, ifname)); 642 printf(" Mode: %s Channel: %s (%s) HT Mode: %s\n", 643 print_mode(iw, ifname), 644 print_channel(iw, ifname), 645 print_frequency(iw, ifname), 646 print_htmode(iw, ifname)); 647 if (iw->center_chan1 != NULL) { 648 printf(" Center Channel 1: %s", 649 print_center_chan1(iw, ifname)); 650 printf(" 2: %s\n", print_center_chan2(iw, ifname)); 651 } 652 printf(" Tx-Power: %s Link Quality: %s/%s\n", 653 print_txpower(iw, ifname), 654 print_quality(iw, ifname), 655 print_quality_max(iw, ifname)); 656 printf(" Signal: %s Noise: %s\n", 657 print_signal(iw, ifname), 658 print_noise(iw, ifname)); 659 printf(" Bit Rate: %s\n", 660 print_rate(iw, ifname)); 661 printf(" Encryption: %s\n", 662 print_encryption(iw, ifname)); 663 printf(" Type: %s HW Mode(s): %s\n", 664 print_type(iw, ifname), 665 print_hwmodes(iw, ifname)); 666 printf(" Hardware: %s [%s]\n", 667 print_hardware_id(iw, ifname), 668 print_hardware_name(iw, ifname)); 669 printf(" TX power offset: %s\n", 670 print_txpower_offset(iw, ifname)); 671 printf(" Frequency offset: %s\n", 672 print_frequency_offset(iw, ifname)); 673 printf(" Supports VAPs: %s PHY name: %s\n", 674 print_mbssid_supp(iw, ifname), 675 print_phyname(iw, ifname)); 676 } 677 678 679 static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) 680 { 681 int i, x, len; 682 char buf[IWINFO_BUFSIZE]; 683 struct iwinfo_scanlist_entry *e; 684 685 if (iw->scanlist(ifname, buf, &len)) 686 { 687 printf("Scanning not possible\n\n"); 688 return; 689 } 690 else if (len <= 0) 691 { 692 printf("No scan results\n\n"); 693 return; 694 } 695 696 for (i = 0, x = 1; i < len; i += sizeof(struct iwinfo_scanlist_entry), x++) 697 { 698 e = (struct iwinfo_scanlist_entry *) &buf[i]; 699 700 printf("Cell %02d - Address: %s\n", 701 x, 702 format_bssid(e->mac)); 703 printf(" ESSID: %s\n", 704 format_ssid(e->ssid)); 705 printf(" Mode: %s Frequency: %s Band: %s Channel: %s\n", 706 IWINFO_OPMODE_NAMES[e->mode], 707 format_frequency(e->mhz), 708 format_band(e->band), 709 format_channel(e->channel)); 710 printf(" Signal: %s Quality: %s/%s\n", 711 format_signal(e->signal - 0x100), 712 format_quality(e->quality), 713 format_quality_max(e->quality_max)); 714 printf(" Encryption: %s\n", 715 format_encryption(&e->crypto)); 716 if (e->ht_chan_info.primary_chan) { 717 printf(" HT Operation:\n"); 718 printf(" Primary Channel: %d\n", 719 e->ht_chan_info.primary_chan); 720 printf(" Secondary Channel Offset: %s\n", 721 ht_secondary_offset[e->ht_chan_info.secondary_chan_off]); 722 printf(" Channel Width: %s\n", 723 format_chan_width(false, e->ht_chan_info.chan_width)); 724 } 725 726 if (e->vht_chan_info.center_chan_1) { 727 printf(" VHT Operation:\n"); 728 printf(" Center Frequency 1: %d\n", 729 e->vht_chan_info.center_chan_1); 730 printf(" Center Frequency 2: %d\n", 731 e->vht_chan_info.center_chan_2); 732 printf(" Channel Width: %s\n", 733 format_chan_width(true, e->vht_chan_info.chan_width)); 734 } 735 736 if (e->he_chan_info.center_chan_1) { 737 printf(" HE Operation:\n"); 738 printf(" Center Frequency 1: %d\n", 739 e->he_chan_info.center_chan_1); 740 printf(" Center Frequency 2: %d\n", 741 e->he_chan_info.center_chan_2); 742 printf(" Channel Width: %s\n", 743 format_6ghz_chan_width(e->he_chan_info.chan_width)); 744 } 745 746 if (e->eht_chan_info.center_chan_1) { 747 printf(" EHT Operation:\n"); 748 printf(" Center Frequency 1: %d\n", 749 e->eht_chan_info.center_chan_1); 750 printf(" Center Frequency 2: %d\n", 751 e->eht_chan_info.center_chan_2); 752 printf(" Channel Width: %s\n", 753 format_6ghz_chan_width(e->eht_chan_info.chan_width)); 754 } 755 756 printf("\n"); 757 } 758 } 759 760 761 static void print_txpwrlist(const struct iwinfo_ops *iw, const char *ifname) 762 { 763 int len, pwr, off, i; 764 char buf[IWINFO_BUFSIZE]; 765 struct iwinfo_txpwrlist_entry *e; 766 767 if (iw->txpwrlist(ifname, buf, &len) || len <= 0) 768 { 769 printf("No TX power information available\n"); 770 return; 771 } 772 773 if (iw->txpower(ifname, &pwr)) 774 pwr = -1; 775 776 if (iw->txpower_offset(ifname, &off)) 777 off = 0; 778 779 for (i = 0; i < len; i += sizeof(struct iwinfo_txpwrlist_entry)) 780 { 781 e = (struct iwinfo_txpwrlist_entry *) &buf[i]; 782 783 printf("%s%3d dBm (%4d mW)\n", 784 (pwr == e->dbm) ? "*" : " ", 785 e->dbm + off, 786 iwinfo_dbm2mw(e->dbm + off)); 787 } 788 } 789 790 791 static void print_freqlist(const struct iwinfo_ops *iw, const char *ifname) 792 { 793 int i, len, freq; 794 char buf[IWINFO_BUFSIZE]; 795 struct iwinfo_freqlist_entry *e; 796 797 if (iw->freqlist(ifname, buf, &len) || len <= 0) 798 { 799 printf("No frequency information available\n"); 800 return; 801 } 802 803 if (iw->frequency(ifname, &freq)) 804 freq = -1; 805 806 for (i = 0; i < len; i += sizeof(struct iwinfo_freqlist_entry)) 807 { 808 e = (struct iwinfo_freqlist_entry *) &buf[i]; 809 810 printf("%s %s (Band: %s, Channel %s) %s\n", 811 (freq == e->mhz) ? "*" : " ", 812 format_frequency(e->mhz), 813 format_band(e->band), 814 format_channel(e->channel), 815 format_freqflags(e->flags)); 816 } 817 } 818 819 820 static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname) 821 { 822 int i, len; 823 char buf[IWINFO_BUFSIZE]; 824 struct iwinfo_assoclist_entry *e; 825 826 if (iw->assoclist(ifname, buf, &len)) 827 { 828 printf("No information available\n"); 829 return; 830 } 831 else if (len <= 0) 832 { 833 printf("No station connected\n"); 834 return; 835 } 836 837 for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) 838 { 839 e = (struct iwinfo_assoclist_entry *) &buf[i]; 840 841 printf("%s %s / %s (SNR %d) %d ms ago\n", 842 format_bssid(e->mac), 843 format_signal(e->signal), 844 format_noise(e->noise), 845 (e->signal - e->noise), 846 e->inactive); 847 848 printf(" RX: %-38s %8d Pkts.\n", 849 format_assocrate(&e->rx_rate), 850 e->rx_packets 851 ); 852 853 printf(" TX: %-38s %8d Pkts.\n", 854 format_assocrate(&e->tx_rate), 855 e->tx_packets 856 ); 857 858 printf(" expected throughput: %s\n\n", 859 format_rate(e->thr)); 860 } 861 } 862 863 864 static char * lookup_country(char *buf, int len, int iso3166) 865 { 866 int i; 867 struct iwinfo_country_entry *c; 868 869 for (i = 0; i < len; i += sizeof(struct iwinfo_country_entry)) 870 { 871 c = (struct iwinfo_country_entry *) &buf[i]; 872 873 if (c->iso3166 == iso3166) 874 return c->ccode; 875 } 876 877 return NULL; 878 } 879 880 static void print_countrylist(const struct iwinfo_ops *iw, const char *ifname) 881 { 882 int len; 883 char buf[IWINFO_BUFSIZE]; 884 char *ccode; 885 char curcode[3]; 886 const struct iwinfo_iso3166_label *l; 887 888 if (iw->countrylist(ifname, buf, &len)) 889 { 890 printf("No country code information available\n"); 891 return; 892 } 893 894 if (iw->country(ifname, curcode)) 895 memset(curcode, 0, sizeof(curcode)); 896 897 for (l = IWINFO_ISO3166_NAMES; l->iso3166; l++) 898 { 899 if ((ccode = lookup_country(buf, len, l->iso3166)) != NULL) 900 { 901 printf("%s %4s %c%c\n", 902 strncmp(ccode, curcode, 2) ? " " : "*", 903 ccode, (l->iso3166 / 256), (l->iso3166 % 256)); 904 } 905 } 906 } 907 908 static void print_htmodelist(const struct iwinfo_ops *iw, const char *ifname) 909 { 910 int i, htmodes = 0; 911 912 if (iw->htmodelist(ifname, &htmodes)) 913 { 914 printf("No HT mode information available\n"); 915 return; 916 } 917 918 for (i = 0; i < IWINFO_HTMODE_COUNT; i++) 919 if (htmodes & (1 << i)) 920 printf("%s ", IWINFO_HTMODE_NAMES[i]); 921 922 printf("\n"); 923 } 924 925 static void lookup_phy(const struct iwinfo_ops *iw, const char *section) 926 { 927 char buf[IWINFO_BUFSIZE]; 928 929 if (!iw->lookup_phy) 930 { 931 fprintf(stderr, "Not supported\n"); 932 return; 933 } 934 935 if (iw->lookup_phy(section, buf)) 936 { 937 fprintf(stderr, "Phy not found\n"); 938 return; 939 } 940 941 printf("%s\n", buf); 942 } 943 944 945 static void lookup_path(const struct iwinfo_ops *iw, const char *phy) 946 { 947 const char *path; 948 949 if (!iw->phy_path || iw->phy_path(phy, &path) || !path) 950 return; 951 952 printf("%s\n", path); 953 } 954 955 int main(int argc, char **argv) 956 { 957 int i, rv = 0; 958 char *p; 959 const struct iwinfo_ops *iw; 960 glob_t globbuf; 961 962 if (argc > 1 && argc < 3) 963 { 964 fprintf(stderr, 965 "Usage:\n" 966 " iwinfo <device> info\n" 967 " iwinfo <device> scan\n" 968 " iwinfo <device> txpowerlist\n" 969 " iwinfo <device> freqlist\n" 970 " iwinfo <device> assoclist\n" 971 " iwinfo <device> countrylist\n" 972 " iwinfo <device> htmodelist\n" 973 " iwinfo <backend> phyname <section>\n" 974 ); 975 976 return 1; 977 } 978 979 if (argc == 1) 980 { 981 glob("/sys/class/net/*", 0, NULL, &globbuf); 982 983 for (i = 0; i < globbuf.gl_pathc; i++) 984 { 985 p = strrchr(globbuf.gl_pathv[i], '/'); 986 987 if (!p) 988 continue; 989 990 iw = iwinfo_backend(++p); 991 992 if (!iw) 993 continue; 994 995 print_info(iw, p); 996 printf("\n"); 997 } 998 999 globfree(&globbuf); 1000 return 0; 1001 } 1002 1003 if (argc > 3) 1004 { 1005 iw = iwinfo_backend_by_name(argv[1]); 1006 1007 if (!iw) 1008 { 1009 fprintf(stderr, "No such wireless backend: %s\n", argv[1]); 1010 rv = 1; 1011 } 1012 else 1013 { 1014 if (!strcmp(argv[2], "path")) { 1015 lookup_path(iw, argv[3]); 1016 return 0; 1017 } 1018 switch (argv[2][0]) 1019 { 1020 case 'p': 1021 lookup_phy(iw, argv[3]); 1022 break; 1023 1024 default: 1025 fprintf(stderr, "Unknown command: %s\n", argv[2]); 1026 rv = 1; 1027 } 1028 } 1029 } 1030 else 1031 { 1032 iw = iwinfo_backend(argv[1]); 1033 1034 if (!iw) 1035 { 1036 fprintf(stderr, "No such wireless device: %s\n", argv[1]); 1037 rv = 1; 1038 } 1039 else 1040 { 1041 for (i = 2; i < argc; i++) 1042 { 1043 switch(argv[i][0]) 1044 { 1045 case 'i': 1046 print_info(iw, argv[1]); 1047 break; 1048 1049 case 's': 1050 print_scanlist(iw, argv[1]); 1051 break; 1052 1053 case 't': 1054 print_txpwrlist(iw, argv[1]); 1055 break; 1056 1057 case 'f': 1058 print_freqlist(iw, argv[1]); 1059 break; 1060 1061 case 'a': 1062 print_assoclist(iw, argv[1]); 1063 break; 1064 1065 case 'c': 1066 print_countrylist(iw, argv[1]); 1067 break; 1068 1069 case 'h': 1070 print_htmodelist(iw, argv[1]); 1071 break; 1072 1073 default: 1074 fprintf(stderr, "Unknown command: %s\n", argv[i]); 1075 rv = 1; 1076 } 1077 } 1078 } 1079 } 1080 1081 iwinfo_finish(); 1082 1083 return rv; 1084 } 1085
This page was automatically generated by LXR 0.3.1. • OpenWrt