source: src/router/services/tools/site_survey_broadcom.c @ 9117

Last change on this file since 9117 was 9117, checked in by BrainSlayer, 5 years ago

block multicast per default to avoid confusion with igmp proxy load

File size: 9.4 KB
Line 
1/*
2 * site_survey_broadcom.c
3 *
4 * Copyright (C) 2006 Sebastian Gottschall <gottschall@dd-wrt.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22
23#include <stdio.h>
24#include <string.h>
25#include <unistd.h>
26#include <signal.h>
27
28#include <typedefs.h>
29#include <bcmnvram.h>
30#include <shutils.h>
31#include <wlioctl.h>
32#include <wlutils.h>
33#include <utils.h>
34
35#define sys_restart() kill(1, SIGHUP)
36#define SITE_SURVEY_DB  "/tmp/site_survey"
37#define SITE_SURVEY_NUM 50
38
39int write_site_survey (void);
40static int open_site_survey (void);
41int write_site_survey (void);
42
43struct site_survey_list
44{
45  uint8 SSID[33];
46  unsigned char BSSID[18];
47  uint8 channel;                /* Channel no. */
48  int16 RSSI;                   /* receive signal strength (in dBm) */
49  int16 phy_noise;              /* noise (in dBm) */
50  uint16 beacon_period;         /* units are Kusec */
51  uint16 capability;            /* Capability information */
52//  unsigned char athcaps;
53  unsigned char ENCINFO[32];    /* encryption info */
54  uint rate_count;              /* # rates in this set */
55  uint8 dtim_period;            /* DTIM period */
56} site_survey_lists[SITE_SURVEY_NUM];
57
58
59static bool
60wpa_ie (uint8 ** wpaie, uint8 ** tlvs, uint * tlvs_len)
61{
62  uint8 *ie = *wpaie;
63  if ((ie[1] >= 6) && !memcmp (&ie[2], WPA_OUI "\x01", 4))
64    {
65      return TRUE;
66    }
67  ie += ie[1] + 2;
68  *tlvs_len -= (int) (ie - *tlvs);
69  *tlvs = ie;
70
71  return FALSE;
72}
73
74static uint8 *
75parse_tlvs (uint8 * tlv_buf, int buflen, uint key)
76{
77  uint8 *cp;
78  int totlen;
79
80  cp = tlv_buf;
81  totlen = buflen;
82
83  /* find tagged parameter */
84  while (totlen >= 2)
85    {
86      uint tag;
87      int len;
88
89      tag = *cp;
90      len = *(cp + 1);
91
92      /* validate remaining totlen */
93      if ((tag == key) && (totlen >= (len + 2)))
94        return (cp);
95
96      cp += (len + 2);
97      totlen -= (len + 2);
98    }
99
100  return NULL;
101}
102
103static char *
104dump_bss_ie (uint8 * cp, uint len)
105{
106  uint8 *wpaie;
107  int i;
108  int n;
109  int offset;
110  uint8 *parse = cp;
111  uint parse_len = len;
112  uint16 capabilities;
113  int unicast_count = 0;
114  uint8 oui[3];
115  uint8 idx = 0;
116
117  while ((wpaie = parse_tlvs (parse, parse_len, DOT11_MNG_WPA_ID)))
118    if (wpa_ie (&wpaie, &parse, &parse_len))
119      break;
120  if (wpaie == NULL)
121//              return "Unknown";
122    return "WEP";               //Eko, testing...
123
124  if ((wpaie[6] | (wpaie[7] << 8)) != WPA_VERSION)
125    return "WPA-Unsupported";   /* WPA version unsupported */
126
127  //We got WPA
128  char sum[64] = { 0 };
129  /* Check for multicast suite */
130  if (wpaie[1] >= 10)
131    {
132      if (!memcmp (&wpaie[8], WPA_OUI, 3))
133        {
134          switch (wpaie[11])
135            {
136            case WPA_CIPHER_NONE:
137              strcat (sum, "MULTINONE ");
138              break;
139            case WPA_CIPHER_WEP_40:
140              strcat (sum, "MULTIWEP64 ");
141              break;
142            case WPA_CIPHER_WEP_104:
143
144              strcat (sum, "MULTIWEP128 ");
145              break;
146            case WPA_CIPHER_TKIP:
147              strcat (sum, "MULTITKIP ");
148              break;
149            case WPA_CIPHER_AES_OCB:
150              strcat (sum, "MULTIAESOCB ");
151              break;
152            case WPA_CIPHER_AES_CCM:
153              strcat (sum, "MULTIAESCCMP ");
154              break;
155            default:            /* unknown WPA cipher */
156              strcat (sum, "MULTIWPAUNKOWN ");
157              break;
158            }
159        }
160    }
161
162  /* Check for unicast suite(s) */
163  if (wpaie[1] >= 12)
164    {
165      unicast_count = (wpaie[12] | (wpaie[13] << 8));
166      for (i = 0; i < unicast_count; i++)
167        {
168
169          if (wpaie[1] < (12 + (i * 4) + 4))
170            break;
171
172          memcpy (oui, &wpaie[2 + 12 + (i * 4)], 3);
173          idx = wpaie[2 + 12 + (i * 4) + 3];
174
175          if (!memcmp (oui, WPA_OUI, 3))
176            {
177              switch (idx)
178                {
179                case WPA_CIPHER_NONE:
180                  break;
181                case WPA_CIPHER_WEP_40:
182                  strcat (sum, "WEP64 ");
183                  break;
184                case WPA_CIPHER_WEP_104:
185                  strcat (sum, "WEP128 ");
186                  break;
187                case WPA_CIPHER_TKIP:
188                  strcat (sum, "TKIP ");
189                  break;
190                case WPA_CIPHER_AES_OCB:
191                  strcat (sum, "AESOCB ");
192                  break;
193                case WPA_CIPHER_AES_CCM:
194                  strcat (sum, "AESCCMP ");
195                  break;
196                default:
197                  break;
198                }
199            }
200          else
201            {
202              strcat (sum, "UNICHIPHERWPAUNKNOWN ");
203            }
204        }
205    }
206  /* Authentication Key Management */
207  /* Fixed 8, Group 4 , 2 + min one Unicast 4 - 2 bytes of VerID and Len */
208  if (wpaie[1] >= 16)
209    {
210      offset = 8 + 4 + 2 + (unicast_count * 4);
211      n = wpaie[offset] + (wpaie[offset + 1] << 8);
212      if (wpaie[1] < (offset + (n * 4)))
213        {
214          return sum;
215        }
216      for (i = 0; i < n; i++)
217        {
218
219          memcpy (oui, &wpaie[offset + 2 + (i * 4)], 3);
220          idx = wpaie[offset + 2 + (i * 4) + 3];
221
222          if (!memcmp (oui, WPA_OUI, 3))
223            {
224              switch (idx)
225                {
226                case RSN_AKM_NONE:
227                  strcat (sum, "WPA-NONE");
228                  break;
229                case RSN_AKM_UNSPECIFIED:
230                  strcat (sum, "WPA");
231                  break;
232                case RSN_AKM_PSK:
233                  strcat (sum, "WPA-PSK");
234                  break;
235                default:
236                  strcat (sum, "WPA-Unknown");
237                  break;
238                }
239            }
240          else
241            {
242              strcat (sum, "WPA-Unknown");
243            }
244        }
245    }
246  return sum;
247}
248
249static char *
250getEncInfo (wl_bss_info_t * bi)
251{
252  if (bi->capability & DOT11_CAP_PRIVACY)
253    {
254      if (bi->ie_length)
255#ifdef HAVE_MSSID
256        return dump_bss_ie ((uint8 *) (((uint8 *) bi) + bi->ie_offset),
257                            bi->ie_length);
258#else
259        return
260          dump_bss_ie ((uint8 *) (((uint8 *) bi) + sizeof (wl_bss_info_t)),
261                       bi->ie_length);
262#endif
263      else
264        return "WEP";
265    }
266  else
267    return "Open";
268}
269
270int
271site_survey_main (int argc, char *argv[])
272{
273  char *name = nvram_safe_get ("wl0_ifname");
274  unsigned char buf[10000];
275  wl_scan_results_t *scan_res = (wl_scan_results_t *) buf;
276  wl_bss_info_t *bss_info;
277  unsigned char mac[20];
278  int i;
279  char *dev = name;
280  unlink (SITE_SURVEY_DB);
281  int ap = 0, oldap = 0;
282  wl_scan_params_t params;
283
284  memset (&params, 0, sizeof (params));
285
286  /* use defaults (same parameters as wl scan) */
287
288  memset (&params.bssid, 0xff, sizeof (params.bssid));
289  if (argc > 1)
290    {
291      params.ssid.SSID_len = strlen (argv[1]);
292      strcpy (params.ssid.SSID, argv[1]);
293    }
294  params.bss_type = DOT11_BSSTYPE_ANY;
295  params.scan_type = -1;
296  params.nprobes = -1;
297  params.active_time = -1;
298  params.passive_time = -1;
299  params.home_time = -1;
300
301  /* can only scan in STA mode */
302#ifndef HAVE_MSSID
303  wl_ioctl (dev, WLC_GET_AP, &oldap, sizeof (oldap));
304  if (oldap > 0)
305    eval ("wl", "ap", "0");
306#endif
307  if (wl_ioctl (dev, WLC_SCAN, &params, 64) < 0)
308    {
309      fprintf (stderr, "scan failed\n");
310      return -1;
311    }
312  sleep (1);
313  bzero (buf, sizeof (buf));
314  scan_res->buflen = sizeof (buf);
315
316  if (wl_ioctl (dev, WLC_SCAN_RESULTS, buf, WLC_IOCTL_MAXLEN) < 0)
317    {
318      fprintf (stderr, "scan results failed\n");
319      return -1;
320    }
321
322  fprintf (stderr, "buflen=[%d] version=[%d] count=[%d]\n", scan_res->buflen,
323           scan_res->version, scan_res->count);
324
325  if (scan_res->count == 0)
326    {
327      cprintf ("Can't find any wireless device\n");
328      goto endss;
329    }
330
331  bss_info = &scan_res->bss_info[0];
332  for (i = 0; i < scan_res->count; i++)
333    {
334      strcpy (site_survey_lists[i].SSID, bss_info->SSID);
335      strcpy (site_survey_lists[i].BSSID,
336              ether_etoa (bss_info->BSSID.octet, mac));
337#ifndef HAVE_RB500
338#ifndef HAVE_MSSID
339      site_survey_lists[i].channel = bss_info->channel;
340#else
341      site_survey_lists[i].channel = bss_info->chanspec & 0xff;
342#endif
343#endif
344      site_survey_lists[i].RSSI = bss_info->RSSI;
345      site_survey_lists[i].phy_noise = bss_info->phy_noise;
346      site_survey_lists[i].beacon_period = bss_info->beacon_period;
347      site_survey_lists[i].capability = bss_info->capability;
348      site_survey_lists[i].rate_count = bss_info->rateset.count;
349      site_survey_lists[i].dtim_period = bss_info->dtim_period;
350      strcpy (site_survey_lists[i].ENCINFO, getEncInfo (bss_info));
351
352      bss_info = (wl_bss_info_t *) ((uint32) bss_info + bss_info->length);
353    }
354  write_site_survey ();
355  open_site_survey ();
356  for (i = 0; i < SITE_SURVEY_NUM && site_survey_lists[i].SSID[0]; i++)
357    {
358      fprintf (stderr,
359               "[%2d] SSID[%20s] BSSID[%s] channel[%2d] rssi[%d] noise[%d] beacon[%d] cap[%x] dtim[%d] rate[%d] enc[%s]\n",
360               i, site_survey_lists[i].SSID, site_survey_lists[i].BSSID,
361               site_survey_lists[i].channel, site_survey_lists[i].RSSI,
362               site_survey_lists[i].phy_noise,
363               site_survey_lists[i].beacon_period,
364               site_survey_lists[i].capability,
365               site_survey_lists[i].dtim_period,
366               site_survey_lists[i].rate_count, site_survey_lists[i].ENCINFO);
367    }
368
369endss:
370#ifndef HAVE_MSSID
371  if (oldap > 0)
372    eval ("wl", "ap", "1");
373#endif
374
375  C_led (0);
376#ifdef HAVE_MSSID
377  eval ("wl", "up");
378#endif
379  return 0;
380}
381
382int
383write_site_survey (void)
384{
385  FILE *fp;
386
387  if ((fp = fopen (SITE_SURVEY_DB, "w")))
388    {
389      fwrite (&site_survey_lists[0], sizeof (site_survey_lists), 1, fp);
390      fclose (fp);
391      return FALSE;
392    }
393  return TRUE;
394}
395
396static int
397open_site_survey (void)
398{
399  FILE *fp;
400
401  bzero (site_survey_lists, sizeof (site_survey_lists));
402
403  if ((fp = fopen (SITE_SURVEY_DB, "r")))
404    {
405      fread (&site_survey_lists[0], sizeof (site_survey_lists), 1, fp);
406      fclose (fp);
407      return TRUE;
408    }
409  return FALSE;
410}
Note: See TracBrowser for help on using the repository browser.