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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt