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