• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/iwinfo/iwinfo_cli.c

  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