2015-07-17 1:04 GMT+03:00 Stefan Sperling <s...@stsp.name>:
> tcpdump currently prints country elements in 802.11 mgmt frames in hex:
>
>    country 67 65 32 1 11 30,
>
> This diff makes tcpdump display the decoded form instead:
>
>    country 'CA ', channels 1 2 3 4 5 6 7 8 9 10, max TX power 30dB
>
> Also show the power constraint which needs to be subtraced from
> max TX power to get the actual allowed TX power value.
>
> ok?
>
> Index: print-802_11.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 print-802_11.c
> --- print-802_11.c      16 Jul 2015 20:57:13 -0000      1.19
> +++ print-802_11.c      16 Jul 2015 21:52:07 -0000
> @@ -78,6 +78,7 @@ int    ieee80211_hdr(struct ieee80211_fram
>  int     ieee80211_data(struct ieee80211_frame *, u_int);
>  void    ieee80211_print_element(u_int8_t *, u_int);
>  void    ieee80211_print_essid(u_int8_t *, u_int);
> +void    ieee80211_print_country(u_int8_t *, u_int);
>  void    ieee80211_print_htcaps(u_int8_t *, u_int);
>  int     ieee80211_elements(struct ieee80211_frame *, u_int);
>  int     ieee80211_frame(struct ieee80211_frame *, u_int);
> @@ -233,6 +234,36 @@ ieee80211_print_essid(u_int8_t *essid, u
>
>  /* Caller checks len */
>  void
> +ieee80211_print_country(u_int8_t *data, u_int len)
> +{
> +       u_int8_t first_chan, nchan, maxpower;
> +       int i;
> +
> +       while (len > 0) {
> +               if (len < 6)
> +                       break;
> +
> +               /* ignore operating extension Id (values >= 201) */
> +               if (data[3] >= 201 || data[4] >= 201)
> +                       continue;
> +
> +               /* country string */
> +               printf(" '%c%c%c'", data[0], data[1], data[2]);
> +
> +               first_chan = data[3];
> +               nchan = data[4];
> +               maxpower = data[5];
> +
> +               printf(", channels %d", first_chan);
> +               for (i = first_chan + 1; i < nchan; i++)
> +                       printf(" %i", i);

It looks like you simply enumerate from first_chan till nchan; why not
to just print "channels %d-%d" then? Also, with this for loop, in case
of invalid data (nchan < first_chan) you won't have any data printed
at all.

> +               printf(", max TX power %ddB", maxpower);
> +
> +               len -= 6;
> +       }
> +}
> +/* Caller checks len */
> +void
>  ieee80211_print_htcaps(u_int8_t *data, u_int len)
>  {
>         u_int16_t htcaps;
> @@ -392,8 +423,7 @@ ieee80211_elements(struct ieee80211_fram
>                         break;
>                 case IEEE80211_ELEMID_COUNTRY:
>                         printf(", country");
> -                       for (i = len; i > 0; i--, data++)
> -                               printf(" %u", data[0]);
> +                       ieee80211_print_country(data, len);
>                         break;
>                 case IEEE80211_ELEMID_CHALLENGE:
>                         printf(", challenge");
> @@ -436,6 +466,9 @@ ieee80211_elements(struct ieee80211_fram
>                         printf(", htcaps");
>                         if (vflag)
>                                 ieee80211_print_htcaps(data, len);
> +                       break;
> +               case IEEE80211_ELEMID_POWER_CONSTRAINT:
> +                       printf(", power constraint %udB", data[0]);
>                         break;
>                 case IEEE80211_ELEMID_VENDOR:
>                         printf(", vendor");
>

--
  WBR,
  Vadim Zhukov

Reply via email to