Logo Search packages:      
Sourcecode: wavemon version File versions  Download package

aplst_scr.c

/*
 * wavemon - a wireless network monitoring aplication
 *
 * Copyright (c) 2001-2002 Jan Morgenstern <jan@jm-music.de>
 *
 * wavemon is free software; you can redistribute it and/or modify it under 
 * the terms of the GNU General Public License as published by the Free 
 * Software Foundation; either version 2, or (at your option) any later 
 * version.
 * 
 * wavemon is distributed in the hope that it will be useful, but WITHOUT ANY 
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
 * details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with wavemon; see the file COPYING.  If not, write to the Free Software 
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#include "wavemon.h"
#include <netdb.h>
#include <linux/if.h>
#include <linux/wireless.h>

struct iw_aplist {
      unsigned short    num;
      char        has_quality : 1;

      struct {
            char          addr[MAC_ADDR_MAX];
            struct iw_quality quality;
      } aplist[IW_MAX_AP];
};

/*
 * get a list of access points in range
 * for now this uses the deprecated SIOCGIWAPLIST facility, next revision
 * will use SIOCSIWSCAN (if available)
 */
static int iw_get_aplist(char *ifname, struct iw_aplist *lst)
{
      int skfd;
      struct iwreq iwr;
      unsigned char buf[(sizeof(struct iw_quality) +
                    sizeof(struct sockaddr)) * IW_MAX_AP];
      int i, rv = 1;

      if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            fatal_error("could not open socket");

      memset(lst, 0, sizeof(struct iw_aplist));

      strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
      iwr.u.data.pointer = (caddr_t) buf;
      iwr.u.data.length = IW_MAX_AP;
      iwr.u.data.flags = 0;
      if (ioctl(skfd, SIOCGIWAPLIST, &iwr) >= 0) {
            lst->num = iwr.u.data.length;

            /*
             * copy addresses and quality information (if available) to list array
             */
            for (i = 0; i < lst->num; i++)
                  strncpy(lst->aplist[i].addr,
                        mac_addr(buf + i * sizeof(struct sockaddr)),
                        MAC_ADDR_MAX);

            if ((lst->has_quality = iwr.u.data.flags))
                  for (i = 0; i < lst->num; i++)
                        memcpy(&lst->aplist[i].quality,
                               buf +
                               lst->num * sizeof(struct sockaddr) +
                               i * sizeof(struct iw_quality),
                               sizeof(struct iw_quality));
      } else {
            rv = 0;
      }
      close(skfd);
      return rv;
}

static void display_aplist(char *ifname, WINDOW *w_aplst)
{
      struct iw_aplist axp;
      char  s[0x100];
      int         ysize, xsize;
      int   i;
      
      getmaxyx(w_aplst, ysize, xsize);
      for (i = 1; i < ysize - 1; i++)
            mvwhline(w_aplst, i, 1, ' ', xsize - 2);

      if (iw_get_aplist(ifname, &axp)) {
            if (axp.num) {
                  sprintf(s, "%d access point(s) in range.", axp.num);
                  mvwaddstr(w_aplst, 1, 1, s);

                  if (axp.has_quality) {
                        for (i = 0; i < axp.num; i++) {
                              wmove(w_aplst, 3 + i * 2, 1);
                              sprintf(s, "%2d ", i);
                              waddstr(w_aplst, s);
                              waddstr_b(w_aplst, axp.aplist[i].addr);

                              wmove(w_aplst, 4 + i * 2, 1);
                              sprintf(s, "Link quality: %d, signal level: %d, noise level: %d",
                                          axp.aplist[i].quality.qual, axp.aplist[i].quality.level,
                                          axp.aplist[i].quality.noise);
                              waddstr(w_aplst, s);
                        }
                  } else {
                        for (i = 0; i < axp.num; i++) {
                              wmove(w_aplst, 3 + i, 1);
                              sprintf(s, "%2d ", i);
                              waddstr(w_aplst, s);
                              waddstr_b(w_aplst, axp.aplist[i].addr);
                        }
                        waddstr_center(w_aplst, 4 + axp.num, "No link quality information available.");
                  }

            } else {
                  waddstr_center(w_aplst, (LINES >> 1) - 1, "No access points in range.");
            }
      } else {
            waddstr_center(w_aplst, (LINES >> 1) - 1, "Access point list not available.");
      }
}

int scr_aplst()
{
      WINDOW            *w_aplst, *w_menu;
      struct timer      t1;
      int         key = 0;

      w_aplst = newwin_title(LINES - 1, COLS, 0, 0, "Access point list", 0, 0);
      w_menu = newwin(1, COLS, LINES - 1, 0);
      
      wmenubar(w_menu, 2);
      wmove(w_menu, 1, 0);
      nodelay(w_menu, TRUE); keypad(w_menu, TRUE);

      wrefresh(w_aplst);
      wrefresh(w_menu);
      
      while (key < KEY_F(1) || key > KEY_F(10)) {
            display_aplist(conf.ifname, w_aplst);
            wrefresh(w_aplst);
            wmove(w_menu, 1, 0);
            wrefresh(w_menu);
            start_timer(&t1, 50000);
            while (!end_timer(&t1) && (key = wgetch(w_menu)) <= 0)
                  usleep(5000);

            /* Keyboard shortcuts */
            if (key == 'q')
                  key = KEY_F(10);
            else if (key == 'i')
                  key = KEY_F(1);
      }
      
      werase(w_aplst); wrefresh(w_aplst); delwin(w_aplst);
      werase(w_menu); wrefresh(w_menu); delwin(w_menu);
      
      return key - KEY_F(1);
}

Generated by  Doxygen 1.6.0   Back to index